简体   繁体   English

秋千上的EDT(傻瓜)

[英]EDT on Swing (for Dummies)

So, I'm just working on a little game, which works quite fine, except for the GUI. 所以,我只是在做一个小游戏,除了GUI之外,它的工作非常好。 Basically, I need to modify the GUI when clicking a button. 基本上,我需要在单击按钮时修改GUI。 I realize that I have to run my code on the EDT to do so, using this code: 我意识到我必须在EDT上运行我的代码,使用以下代码:

EventQueue.invokeLater(new Runnable () {
    @Override
    public void run() {
        // some code
    }
});

I just don't now which part of my code is concerned by this. 我现在不知道我的代码的哪一部分与此有关。 The part where I create the GUI (the constructor of my class)? 我创建GUI的部分(我班级的构造函数)? Or only the part where i modify the values (in that case Listener.actionPerformed() )? 或者只是我修改值的部分(在那种情况下是Listener.actionPerformed() )? Actually I tested bot of this, neither worked. 实际上我测试了这个机器人,既没有奏效。

Now what I want to know is how do I modify the following code to update the Button when i click it? 现在我想知道的是当我点击它时如何修改以下代码来更新Button? Do I have to embed parts of it in the code above or am I completely wrong? 我是否必须在上面的代码中嵌入部分内容,或者我完全错了?

package edttest;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class EDTtest {
    public static void main(String[] args) {
        GUI gui = new GUI ();
    }

    private static class GUI extends JFrame {

        int x;

        public GUI () {
            x = 0;
            setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
            JButton button = new JButton (String.valueOf(x));
            button.addActionListener(new Listener ());
            JLabel label = new JLabel (String.valueOf(x));
            add (label, BorderLayout.NORTH);
            add (button);
            pack();
            setVisible (true);
        }

        private class Listener implements ActionListener {

            @Override
            public void actionPerformed(ActionEvent e) {
                x++;
                System.out.println (x);
            }
        }
    }
}

Whether or not you execute this code on the EDT will do nothing to your label. 是否在EDT上执行此代码将对您的标签无效。 It is not because you increment x that the label will update itself. 这不是因为你增加x标签将自行更新。 You need to call label#setText with the updated value. 您需要使用更新的值调用label#setText

Concerning your question around the EDT. 关于你在EDT周围的问题。 All access/modifications/creation/... of Swing components should happen on the EDT. Swing组件的所有访问/修改/创建/ ...都应该在EDT上进行。 This means you should wrap the contents of your main method in an SwingUtilities#invoke... . 这意味着你应该将主方法的内容包装在SwingUtilities#invoke... Every event that is triggered through the UI (eg the click on a button) will already be processed on the EDT. 通过UI触发的每个事件(例如点击按钮)都将在EDT上处理。 So no need to explicitly schedule a Runnable on the EDT in your listener. 因此,无需在侦听器中明确地在EDT上安排Runnable

When in doubt, you can always check whether you are on the EDT by using EventQueue#isDispatchThread . 如有疑问,您可以使用EventQueue#isDispatchThread检查您是否在EDT。

I would also suggest to read the Concurrency in Swing tutorial 我还建议阅读Swutch中Concurrency教程

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

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