简体   繁体   English

我应该在EDT中分配/创建秋千元素吗?

[英]Should I allocate/create swing elements into EDT?

Should I create swing elements into EDT? 我应该在EDT中创建摆动元素吗?

I got the concurrency problems with editing non thread-safe graphics elements, but I'm creating them, they aren't shown yet, and if they are a lot or they take some time to be allocated that would freeze the GUI, doesn't it? 我在编辑非线程安全的图形元素时遇到了并发性问题,但是我正在创建它们,但尚未显示它们,如果它们太多或需要花费一些时间分配而冻结了GUI,则不会。是吗?

Here an example where I use EDT to display but not to create my GUI structure: 在下面的示例中,我使用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();
        }

    }
}

is it fine since the elements weren't displayed yet? 因为元素还没有显示好吗? or should I move all into initUI() ? 还是应该将所有内容移到initUI()

In the Swing separable model architecture , a view component listens to its model. 在Swing 可分离模型体系结构中 ,视图组件侦听其模型。 Because a view may respond arbitrarily to events generated by model updates, the corresponding model must also be updated on the EDT. 因为视图可以任意响应模型更新生成的事件,所以相应的模型必须在EDT上进行更新。 You can mitigate latency via one of two basic approaches: 您可以通过以下两种基本方法之一来减少延迟:

Swing Threading Policy states: Swing线程策略状态:

In general Swing is not thread safe. 通常,Swing不是线程安全的。 All Swing components and related classes, unless otherwise documented, must be accessed on the event dispatching thread. 除非另有说明,否则所有Swing组件和相关类都必须在事件分发线程上进行访问。 Typical Swing applications do processing in response to an event generated from a user gesture. 典型的Swing应用程序会根据用户手势生成的事件进行处理。 For example, clicking on a JButton notifies all ActionListeners added to the JButton. 例如,单击JButton会通知添加到JButton的所有ActionListener。 As all events generated from a user gesture are dispatched on the event dispatching thread, most developers are not impacted by the restriction. 由于从用户手势生成的所有事件都分配在事件分配线程上,因此大多数开发人员不受此限制的影响。

Where the impact lies, however, is in constructing and showing a Swing application. 但是,影响所在在于构建和显示Swing应用程序。 Calls to an application's main method, or methods in Applet, are not invoked on the event dispatching thread. 在事件分配线程上不会调用对应用程序的主方法或Applet中的方法的调用。 As such, care must be taken to transfer control to the event dispatching thread when constructing and showing an application or applet. 因此,在构造和显示应用程序或小程序时,必须注意将控制权转移到事件分发线程。 The preferred way to transfer control and begin working with Swing is to use invokeLater. 转移控制权并开始使用Swing的首选方法是使用invokeLater。 The invokeLater method schedules a Runnable to be processed on the event dispatching thread. invokeLater方法可调度要在事件分配线程上处理的Runnable。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM