【问题标题】:Java: A Thread don't modify the GUI even with SwingUtilities.invokeLaterJava:即使使用 SwingUtilities.invokeLater,线程也不会修改 GUI
【发布时间】:2016-04-24 00:42:47
【问题描述】:

我对这段代码有疑问:

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 中的线程工作正常,但是任何对显示的修改都不会影响 GUI,即使使用了 invokeLater。

display.add(visualizza, BorderLayout.SOUTH)

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

对不起,我的英语不好,提前感谢您的回复。

【问题讨论】:

    标签: java multithreading swing user-interface invokelater


    【解决方案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 交互。

    其次,在更新 UI 后致电 revalidaterepaint...

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

    在更新 UI 时,Swing 是懒惰的,这是一件好事,因为它允许您进行彻底的更改,并且只有在您准备好时才更新 UI。

    我还鼓励您改用SwingWorker,因为它具有可用于将更新与 EDT 同步的功能。更多详情请见Worker Threads and SwingWorker

    【讨论】:

    • 很高兴能帮上忙
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 2019-05-03
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    相关资源
    最近更新 更多