I am currently learning about multithreading in Java and ran into an interesting problem.
I have a “loader” class which reads some CSV file.
public class LoaderThread implements Runnable{
@Override
public void run(){
//do some fancy stuff
}
}
Furthermore I have a SplashScreen which I want to be shown while the data is loading.
import javax.swing.JLabel;
import javax.swing.JWindow;
import javax.swing.SwingConstants;
public class SplashScreen extends JWindow{
JWindow jwin = new JWindow();
public SplashScreen(){
jwin.getContentPane().add(new JLabel("Loading...please wait!",SwingConstants.CENTER));
jwin.setBounds(200, 200, 200, 100);
jwin.setLocationRelativeTo(null);
jwin.setVisible(true);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
jwin.setVisible(false);
jwin.dispose();
}
}
The code is run from my main class when the user clicks on a button:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
final Thread t = new Thread() {
@Override
public void run() {
LoaderThread myRunnable = new LoaderThread();
Thread myThread = new Thread(myRunnable);
myThread.setDaemon(true);
myThread.start();
while(myThread.isAlive()==true)
{
SplashScreen ss = new SplashScreen();
}
}
};
t.start(); // call back run()
Thread.currentThread().interrupt();
}
This setup is working but the message is “blinking” when the loading takes longer than 3 secs and is shown for at least 3 secs, even though the loading process might be shorter.
I am now wondering if it is possible to show the message for as long as the loading thread is running. Not longer and not shorter.
Thanks in advance!
This is a perfect example of where an observer pattern would work well. One way to do this easily in Swing is to use a SwingWorker for your background thread. Show the splash screen when you execute the SwingWorker. Before executing the SwingWorker, add a PropertyChangeListener to it, and when it returns with SwingWorker.StateValue.DONE, get rid of the splash screen.
Also, don’t call
Thread.sleep(...)on the Swing event thread like you’re doing as that’s a guarantee for disaster.Edit 1
Regarding your comment —
This is being called on the Swing event thread, otherwise known as the EDT or Event Dispatch Thread:
This will put your whole application to sleep making it completely non-responsive, and so it is recommended that you never call
Thread.sleep(...)on the EDT.Edit 2
example code: