Question

So, I'm just working on a little game, which works quite fine, except for the GUI. Basically, I need to modify the GUI when clicking a button. I realize that I have to run my code on the EDT to do so, using this code:

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)? Or only the part where i modify the values (in that case 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? 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);
            }
        }
    }
}
Was it helpful?

Solution

Whether or not you execute this code on the EDT will do nothing to your label. It is not because you increment x that the label will update itself. You need to call label#setText with the updated value.

Concerning your question around the EDT. All access/modifications/creation/... of Swing components should happen on the EDT. This means you should wrap the contents of your main method in an SwingUtilities#invoke.... Every event that is triggered through the UI (e.g. the click on a button) will already be processed on the EDT. So no need to explicitly schedule a Runnable on the EDT in your listener.

When in doubt, you can always check whether you are on the EDT by using EventQueue#isDispatchThread.

I would also suggest to read the Concurrency in Swing tutorial

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top