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
Java String - See If a String Contains Only Numbers and Not Letters
Getting Mail from Gmail into Java Application Using Imap
Checked VS Unchecked Exception
Java: Join Array of Primitives with Separator
Why Main() Method Is Needed in Java Main Class
Javamail API to Imail -- Java.Net.Socketexception: Permission Denied: Connect
Getting an Attribute Value in Xml Element
Create a Jtds Connection String
Java, How to Implement a Shift Cipher (Caesar Cipher)
Is There a Method for String Conversion to Title Case
Jdbc Connection to Mssql Server in Windows Authentication Mode
Java Web Start Support in Java 9 and Beyond
Dragging a Jlabel Around the Screen
Obtaining the Array Class of a Component Type
How to Change the Arrow Style in a Jcombobox
Java.Lang.Stackoverflowerror While Using a Regex to Parse Big Strings