0

我正在创建自己的对话框,它基本上是一个 JPanel,设置为 JFrame 上的玻璃窗格。我想让我的对话框模态化,因为在对话框可见时不执行 setVisible() 之后的所有代码,一旦对话框关闭,setVisible() 之后的其余代码必须继续。

为此,我使用线程来显示我的对话框。我知道 SwingUtilities.invokeLater() 方法必须用于更新 gui,因为它是在另一个线程中执行的。但是我的对话框没有显示在屏幕上。

这是我的代码示例:

final JFrame frame = new JFrame();
frame.setBounds(0, 0, 1024, 768);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);

JButton button = new JButton("Text");
button.setBounds(200, 300, 110, 50);
button.addActionListener(new ActionListener() {

    boolean dispose;

    public void actionPerformed(ActionEvent e) {
        try {
            Thread thread = new Thread(new Runnable() {
                public void run() {
                    final JPanel panelGlass = new JPanel(null);
                    panelGlass.setBounds(frame.getBounds());
                    panelGlass.setBackground(Color.red);
                    frame.setGlassPane(panelGlass);

                    JButton btnClose = new JButton("close");
                    btnClose.setBounds(100, 100, 110, 50);
                    btnClose.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                            dispose = true;
                        }
                    });
                    panelGlass.add(btnClose);

                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            dispose = false;
                            panelGlass.setVisible(true);
                        }
                    });

                    while (!dispose) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    panelGlass.setVisible(false);
                }
            });
            thread.start();
            thread.join();
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
});
frame.getContentPane().add(button);

frame.setVisible(true);

为什么我的对话框没有显示?

4

3 回答 3

1

问题在这里:

thread.start();
thread.join();

您启动线程,但您立即等待它完成。这会阻止 UI 线程并且不允许它处理您的SwingUtilities.invokeLater更新。

我真的看不出这个join呼吁存在的任何充分理由。

于 2012-11-01T16:12:29.040 回答
1

你不能那样做,因为

  • 您正在从事件调度线程以外的线程访问 Swing 组件
  • 发生所有 UI 绘制的事件调度线程完全被对Thread.join().

您应该能够使用 Java 7 的SecondaryLoop执行您想要的操作,但我从未使用过它。

于 2012-11-01T16:15:21.253 回答
1
  • frame.getRootPane.setGlassPane

  • 你的想法很好,但必须从键盘来消费()事件,只使用 e.consume()添加 KeyListener 因为 GlassPane 只消费鼠标事件

  • 也可以使用 GlassPane 创建整个 Gui,

  • 里面的actionperformed显示准备好的GlassPane,然后启动一个Runnable.Thread

  • 我有一个关于乘法玻璃板的问题

  • 使用JLayer Java7,基于JXLayer Java6

  • 您的问题是预订示例,原因是为什么 SwingWorker 是用 Java 实现的

手机回复

于 2012-11-01T22:12:56.940 回答