Java:即使使用SwingUtilities.invokeLater

时间:2016-04-24 00:42:47

标签: java multithreading swing user-interface invokelater

我对此代码有疑问:

public class Gui_01 extends JFrame {

private JPanel display;
private ActionListener visualizza() {
    ActionListener evento = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {

            display.removeAll();

            Thread t = new Thread(new Runnable() {
                public void run() {
                    JPanel visualizza = new JPanel();
                    visualizza.add(new JLabel("Test", SwingConstants.CENTER));

                    display.add(visualizza, BorderLayout.SOUTH);

                    updateProgress(visualizza);
                }
            }
            );

            t.start();
        }
    };
    return evento;
}

private void updateProgress(final JPanel visualizza) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            display.add(visualizza, BorderLayout.SOUTH);
        }
    });
}}

我不明白为什么代码不能正常工作,线程t和updateProgress中的线程工作正常,但是即使使用invokeLater,对显示的任何修改都不会影响GUI。

display.add(visualizza, BorderLayout.SOUTH)

此代码不修改gui,我知道这是正常的(由于Swing),但为什么invokeLater不起作用。

抱歉我的英文不好,提前感谢您的回复。

1 个答案:

答案 0 :(得分:1)

首先删除线程中的display.add(visualizza, BorderLayout.SOUTH);语句。因为你永远不应该从EDT的上下文之外更新或修改UI ...

Thread t = new Thread(new Runnable() {
    public void run() {
        JPanel visualizza = new JPanel();
        visualizza.add(new JLabel("Test", SwingConstants.CENTER));

        //display.add(visualizza, BorderLayout.SOUTH);

        updateProgress(visualizza);
    }
}

事实上,我不鼓励您在EDT之外创建UI元素,因为您无法保证何时可以开始与UI进行交互。

其次,在您更新用户界面后致电revalidaterepaint ...

private void updateProgress(final JPanel visualizza) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            display.add(visualizza, BorderLayout.SOUTH);
            display.revalidate();
            display.repaint();
        }
    });
}}

在更新用户界面时,Swing很懒,这是一件好事,因为它可以让你进行全面的更改,只有在你准备好时才更新用户界面。

我还鼓励您使用SwingWorker,因为它具有可用于将更新与EDT同步的功能。有关详细信息,请参阅Worker Threads and SwingWorker