Refreshing Gui by Another Thread in Java (Swing)

Refreshing GUI by another thread in java (swing)

If you make the status field thread safe, then you can call setStatus directly from your background thread. To make the status thread-safe, put changes in a synchronize block, and make the variable volatile so updates on other threads become visible.

E.g.

public class Frame extends JFrame implements Runnable {
private volatile Status status = 1;
...
@Override
public void run() {
switch (status) {
case 1:
...
case 2:
...
}

public void updateGUI(Status status) {
setStatus(status);
SwingUtilities.invokeLater(this);
}

private synchronized void setStatus(Status status) {
this.status = status;
}

With these changes in place, it's ok to call setStatus from any thread.

updating gui from thread(another class)

How do I update the gui label with the stopwatch ms,sec,min?

Carefully, Swing is not thread safe and you should not modify it's state outside of the context of the Event Dispatching Thread.

One approach would be to use an Observer Pattern, where by your timer triggers updates to which the UI can respond.

A simpler solution might to use a Swing Timer over a Thread, because a Swing Timer is executes its notifications within the context of the EDT

Consider having a look at Concurrency in Swing and How to use Swing Timers for more details

java updating UI components from another thread

Swing is not thread safe and is single threaded. You should never update UI components from outside the Event Dispatching Thread, equally, you should never run long running processes or blocking code within the EDT, as this will prevent it from processing new events within the event queue, causing your app to look like it's hung...because it has...

Take a look at Concurrency in Swing for more details.

After scratching my head for a while, I realised, the simple solution would be to just use javax.swing.Timer

You want to repeat the update at a regular interval (300 milliseconds) and update the UI, perfect, the Swing Timer is capable of scheduling updates at regular intervals and executes it call back within the context of the EDT!

It also has the ability to consolidate repeated calls. This means, if there is already a "timer" action in the event queue, the timer will not generate a new one, preventing from flooding the EDT and cause possible performance issues...

javax.swing.Timer timer = new Timer(300, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jtfIP.setEnabled(!Start && !autoRec);
jtfPort.setEnabled(!Start && !autoRec);
jtfSlaveID.setEnabled(!Start && !autoRec);
jtfTimeout.setEnabled(!Start && !autoRec);
jtfReqInterval.setEnabled(!Start && !autoRec);
jCheckBox1.setEnabled(!Start && !autoRec);
jCBReconnect.setEnabled(!Start && !autoRec);

if (db != null) {
if (!db.getIsOpen()) {
jPBD.setBackground(Color.RED);
jPBD.setForeground(Color.WHITE);
jPBD.setText("ER");
} else {
jPBD.setBackground(Color.GREEN);
jPBD.setForeground(Color.BLACK);
jPBD.setText("OK ");
}
} else {
jPBD.setBackground(Color.RED);
jPBD.setForeground(Color.WHITE);
jPBD.setText(" ER ");
}

if (autoRec){
jbtnConnect.setText("Auto");
if (Start && Connected) {
jbtnConnect.setForeground(Color.BLACK);
jbtnConnect.setBackground(Color.GREEN);
} else {
jbtnConnect.setForeground(Color.WHITE);
jbtnConnect.setBackground(Color.RED);
}
} else {
if (Start) {
jbtnConnect.setText("Disconnect");
jbtnConnect.setForeground(Color.BLACK);
jbtnConnect.setBackground(Color.GREEN);

} else {
jbtnConnect.setText("Connect");
jbtnConnect.setForeground(Color.WHITE);
jbtnConnect.setBackground(Color.RED);
}
}

jtfErroriCitire.setText(String.valueOf(totalErrors));
}
});
timer.start();

See How to use Swing Timers for more details

Update Java Swing component from a background thread

No, number 4 is wrong since you're changing the state of a Swing component off of the EDT, the Swing event thread. Either wrap jtextarea.setText(newMessage); inside of a Runnable and queue it on the Swing event thread via: SwingUtilities.invokeLater(Runnable r), or use a SwingWorker for your background thread and use the publish/process method pair to update your Swing GUI from the background thread.

Please check out:

  • SwingWorker with publish/process example
  • Lesson: Concurrency in Swing


Related Topics



Leave a reply



Submit