java - 我应该将 swing 元素分配/创建到 EDT 中吗?

标签 java swing event-dispatch-thread

我应该在 EDT 中创建 swing 元素吗?

我遇到了编辑非线程安全图形元素的并发问题,但我正在创建它们,它们还没有显示,如果它们很多或者它们需要一些时间来分配会卡住 GUI ,不是吗?

这里是我使用 EDT 来显示但不创建我的 GUI 结构的示例:

public class Launcher {
    private final SwingWorker worker;
    private final JFrame frame;
    private final JLabel label;
    private final JProgressBar progressBar;

    public Launcher() {

        // init user interface
        frame = new JFrame();
        JPanel panel = new JPanel(new BorderLayout());
        label = new JLabel("Launching...", SwingConstants.CENTER);
        progressBar = new JProgressBar(0, 100);
        progressBar.setIndeterminate(true);
        panel.add(label, BorderLayout.CENTER);
        panel.add(progressBar, BorderLayout.PAGE_END);
        initUI(panel);
        worker = new LauncherWorker(this);
        worker.addPropertyChangeListener((PropertyChangeListener)this);
    }

    private void initUI(final Component panel) {
        if (!SwingUtilities.isEventDispatchThread()) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    DirectaChatLauncher.this.initUI(panel);
                } //run()
            });
            return;
        }
        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(panel, BorderLayout.PAGE_END);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if ("progress".equals(evt.getPropertyName())) {
            int progress = (Integer) evt.getNewValue();
            progressBar.setValue(progress);
        }
    }

    private void setProgression(final String msg) {
        label.setText(msg);
    }

    class LauncherWorker extends SwingWorker<Boolean, String> {

        private final Launcher LAUNCHER;

        public LauncherWorker(Launcher launcher) {
            super();
            LAUNCHER = launcher;
        }

        @Override
        protected Boolean doInBackground() throws Exception {
            setProgress(0);
            publish("Started");
            ...
            setProgress(100);
            publish("Launched");
            Thread.sleep(1000);
            return Boolean.TRUE;
        }

        @Override
        protected void process(List<String> chunks) {
            LAUNCHER.setProgression(chunks.get(0));
        }

        @Override
        public void done() {
            LAUNCHER.done();
        }

    }
}

还好吗,因为元素还没有显示?还是应该全部移到 initUI() 中?

最佳答案

在 Swing 中 separable model architecture ,一个 View 组件监听它的模型。因为 View 可能会任意响应模型更新生成的事件,所以相应的模型必须在 EDT 上更新。您可以通过以下两种基本方法之一来减少延迟:

关于java - 我应该将 swing 元素分配/创建到 EDT 中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33520222/

相关文章:

java - 向 JSlider 旁边的 JLabel 添加颜色

java - 如何使用postman调用REST API进行azure文件存储?

java - 可以覆盖@FindBy 的父类(super class)

java - 消失时可调整大小的布局 Swing JPanel

java - IllegalArgumentException:创建 SpinnerListModel 时序列元素无效

java - 从可运行程序更新 GUI

java - 你如何在 Java 中#include 文件?

java - JPopupMenu 没有显示在屏幕上?

java - 更新 edt 中的 swing 组件

java - Java 中的 EDT,它是如何工作的,它的行为是否像普通线程(单线程或多线程)?