【问题标题】:JLayeredPane with a JDialog带有 JDialog 的 JLayeredPane
【发布时间】:2012-11-29 23:23:40
【问题描述】:

在将 JLayeredPane 添加到 JDialog 时,我无法使任何组件出现在 JLayeredPane 上。

我也无法找到一个网络资源表明这可以在一个合理大小的代码块中完成。 iv 看到的每一个景象都“声称”这是可以做到的,然后给出了一个令人作呕的长解决方案。

我想要的是在一个 JLayered 窗格中添加一个 Button 并将一个带有图标的 JLabel 也放在这个窗格上。在英语中,我想要一个带有图标的按钮,该按钮位于其文本的前面。

那是 awt Button,因为我一直无法找到一种方法让系统看起来像摇摆 JButton。

编辑:你能帮我解决一些更具体的问题吗?我觉得我的帖子有点含糊。

Button button = new Button("ok");
JDialog dialog = new JDialog(null,"Windows",Dialog.ModalityType.APPLICATION_MODAL);
dialog.getLayeredPane().add(button);
dialog.pack();
dialog.setVisible(true);

【问题讨论】:

  • “无法找到一种方法使系统看起来像摇摆的 JButton。” 请参阅 UIManager.getSystemLookAndFeelClassName()
  • “可以在一个合理大小的代码块中完成。” 将一些(行数)设置为“合理”。 “每一次看到“声称”都可以做到这一点”链接到您查看的前 3 个页面。
  • single didits 会很好...我发现网络景点喜欢以三位数发布解决方案。然后,由于时间分配不当,我发现自己可以将其减少到 5-10 行代码......只是想我会节省几个小时并四处询问
  • “只是想我会节省几个小时并四处询问” 在向 SO 提出问题之前,您应该进行几个小时的研究。 -1 表示“没有显示任何研究工作”。
  • “你应该成为一名教师,你会完全适应当今的教育系统”,就“在问题论坛上对无意教书的人进行评分”而言

标签: java swing jdialog jlayeredpane


【解决方案1】:

我似乎没有任何问题...

public class TestLayeredDialog {

    public static void main(String[] args) {
        new TestLayeredDialog();
    }

    public TestLayeredDialog() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JDialog dialog = new JDialog();
                dialog.setModal(true);
                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                dialog.setLayout(new BorderLayout());
                dialog.add(new MyContent());
                dialog.pack();
                dialog.setLocationRelativeTo(null);
                dialog.setVisible(true);

                System.exit(0);
            }
        });
    }

    public class MyContent extends JLayeredPane {

        public MyContent() {
            JLabel label = new JLabel("Hello new world");
            label.setSize(label.getPreferredSize());
            label.setLocation(0, 0);
            add(label);

            Dimension size = getPreferredSize();

            JButton button = new JButton("Click me");
            button.setSize(button.getPreferredSize());
            button.setLocation(size.width - button.getWidth(), size.height - button.getHeight());
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    SwingUtilities.getWindowAncestor(MyContent.this).dispose();
                }
            });
            add(button);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}

请记住,JLayeredPane 没有布局管理器。您将负责管理子组件的大小和位置,这就是重点。

更新了新示例

public class TestLayeredDialog {

    public static void main(String[] args) {
        new TestLayeredDialog();
    }

    public TestLayeredDialog() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JDialog dialog = new JDialog();
                dialog.setModal(true);
                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                dialog.setLayout(new BorderLayout());

                JLabel label = new JLabel("Hello new world");
                label.setSize(label.getPreferredSize());
                label.setLocation(0, 0);
                dialog.getLayeredPane().add(label, new Integer(1));

                dialog.setSize(100, 100);
                dialog.setLocationRelativeTo(null);
                dialog.setVisible(true);

                System.exit(0);
            }
        });
    }
}

JRootPane 的分层窗格负责(除其他外)布置内容窗格和菜单栏。它还用于(在某些情况下)显示弹出窗口等内容。

阅读How to Use Root Panes

您可以选择将组件放在根窗格的分层窗格中。如果 你这样做了,那么你应该知道某些深度被定义为 用于特定功能,您应该使用深度作为 故意的。否则,您的组件可能无法与 其他。这是一个图表,显示了功能层及其 关系:

使用这个,意味着您正在与屏幕上已经存在的组件竞争。

除非你有很好的理由来搞乱这个组件,否则我建议你避免它,因为 1- 将来可能会更改(组件的层位置)和 2- 它可能会干扰其他组件由 Swing API 使用

【讨论】:

  • 我不能使用 dialog.getLayeredPane(),反对创建一个扩展 JLayeredPane 的新类吗?
  • 是的,你可以,问题是,你应该这样做。
  • 我没有意识到你可以像这样在全局声明中设置 uiManager。我认为您必须专门为组件执行此操作。
【解决方案2】:

这个example 似乎与添加到构造函数的以下行一起工作:

this.addMouseListener(new MouseHandler(this));
this.add(new JLabel("Label"));
this.add(new JButton(UIManager.getIcon("html.pendingImage")));

【讨论】:

  • LayerDemo extends JDialog 需要不同的关闭操作。
  • 是的,这看起来好多了...你能帮我做一些更特别的事情吗?我想我在我的帖子里有点迷糊。
  • 请编辑您的问题以包含一个sscce,以展示您遇到的任何问题。现有的两个答案中的任何一个都可能合适。注释中的代码在很大程度上是不可读的; ImageIO.read()` 可能是更好的选择。
  • 我为您迁移了代码,但您需要在 sscce 上工作。您应该能够编辑自己的问题。
  • @blackDog 看看How to Use Layered Panes,你基本上是在争夺层位而输了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多