Update JLabel repeatedly with results of long running task
Use a Swing Timer
for repeating tasks & a SwingWorker
for long running tasks. E.G. of both below - it uses a Timer
to repeatedly perform a 'long running' task (a ping) in a SwingWorker
.
See Concurrency in Swing for more details on the Event Dispatch Thread and doing long running or repeating tasks in a GUI.
This code combines a long running task ('pinging' a server) using SwingWorker
invoked from a repeating task (updating the JLabel
repeatedly with the times) using a Swing based Timer
.
import java.awt.event.*;
import javax.swing.*;
import java.net.Socket;
public class LabelUpdateUsingTimer {
static String hostnameOrIP = "stackoverflow.com";
int delay = 5000;
JLabel label = new JLabel("0000");
LabelUpdateUsingTimer() {
label.setFont(label.getFont().deriveFont(120f));
ActionListener timerListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new PingWorker().execute();
}
};
Timer timer = new Timer(delay, timerListener);
timer.start();
JOptionPane.showMessageDialog(
null, label, hostnameOrIP, JOptionPane.INFORMATION_MESSAGE);
timer.stop();
}
class PingWorker extends SwingWorker {
int time;
@Override
protected Object doInBackground() throws Exception {
time = pingTime();
return new Integer(time);
}
@Override
protected void done() {
label.setText("" + time);
}
};
public static int pingTime() {
Socket socket = null;
long start = System.currentTimeMillis();
try {
socket = new Socket(hostnameOrIP, 80);
} catch (Exception weTried) {
} finally {
if (socket != null) {
try {
socket.close();
} catch (Exception weTried) {}
}
}
long end = System.currentTimeMillis();
return (int) (end - start);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
new LabelUpdateUsingTimer();
}
};
SwingUtilities.invokeLater(r);
}
}
How to force java to draw swing label?
Try this
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();
Using Swingworker to constantly update a GUI
Here is a complete example i really like Swing Worker Example
You have to use publish()
and override process()
Example:
class Worker extends SwingWorker<Void, String> {
@Override
protected void doInBackground() throws Exception {
//here you make heavy task this is running in another thread not in EDT
//process after some time call publish()
}
@Override
protected void process(List<String> chunks) {
//this is executed in the EDT
//here you update your label
}
}
Swing - revalidate of UI not happening
The thing is, that actions in public void actionPerformed(ActionEvent ae)
method execute in Swing thread. The changes are not shown till all of actions are executed. You can, for example, perform your doStaff
method in another thread.
For more details, see this topic. I had the same problem.
Related Topics
How to Convert Int[] to Integer[] in Java
Java 11 Package Javax.Xml.Bind Does Not Exist
Cannot Create an Array of Linkedlists in Java
Picking a Random Element from a Set
Generate a Random Double in a Range
Java Simpledateformat Always Returning January for Month
Calling One Jframe from Another Using Timer Without Any Buttons
Sockets: Discover Port Availability Using Java
How to Delete Stuff Printed to Console by System.Out.Println()
Getting the Filenames of All Files in a Folder
Java 8: Lambda-Streams, Filter by Method with Exception
How to Instantiate an Inner Class with Reflection in Java
Good Way to Encapsulate Integer.Parseint()