Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating swing components correctly

Tags:

java

swing

I have been setting values on swing components just like I would any other variable, however I came across this page - https://bitguru.wordpress.com/2007/03/21/will-the-real-swing-single-threading-rule-please-stand-up/ - and it seems that I be making all changes to swing components using an event dispatching thread -

So, is this correct, should I change all the code where I updated swing components from this

    String name = this.getNameTextfield().getText();
    String password = new String(this.getPasswordField().getPassword());
    String confirmPassword = new String(this.getConfirmPasswordField().getPassword());

to this?

java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
               String name = this.getNameTextfield().getText();
               String password = new String(this.getPasswordField().getPassword());
               String confirmPassword = new String(this.getConfirmPasswordField().getPassword());
            }
        });

Is that the standard practise?

Edit: Oops, just copied and pasted some of my component related code, overlooked the fact that it wasnt updating componenets.

like image 377
Jim_CS Avatar asked Mar 13 '12 08:03

Jim_CS


2 Answers

The Swing bible has a chapter on concurrency, bottom line:

all code that creates or interacts with Swing components must run on the event dispatch thread

(emphasis is mine)

So yes, you always have to ensure that all your access, reading or writing, happens on the EDT.

On the bright side: once the application is started correctly on the EDT, you already are on it and nearly all access naturally happens on the EDT. That's not the case only if you explicitly started another thread (f.i. for doing a lengthy background task) and need to report back into the ui: then you have to wrap the access calls into invokeLater (or use a SwingWorker which does so internally)

like image 175
kleopatra Avatar answered Sep 30 '22 18:09

kleopatra


Strings are immutable - the following lines are pretty much equivalent

String password = new String(this.getPasswordField().getPassword());
String password = this.getPasswordField().getPassword();

You're not modifying the components.

If you were updating them, then only if the update was from another Thread. If for example you were updating a text field from a ActionListener attached to a button then it would be unnecessary as you're already on the Event-Dispatch-Thread.

For maximum correctness you should determine if you're on the EDT first.

Runnable update = new Runnable() {
    @Override
    public void run() {
        getNameTextfield().setText("foo");
    }
};
if (SwingUtilities.isEventDispatchThread()) {
    update.run();
} else {
    SwingUtilities.invokeLater(update);
}
like image 21
Adam Avatar answered Sep 30 '22 17:09

Adam