This is my screensaver code,
public class SplashScreen extends JWindow { private static final long serialVersionUID = 1L; private BorderLayout borderLayout = new BorderLayout(); private JLabel imageLabel = new JLabel(); private JProgressBar progressBar = new JProgressBar(0, 100); public SplashScreen(ImageIcon imageIcon) { imageLabel.setIcon(imageIcon); setLayout(borderLayout); add(imageLabel, BorderLayout.CENTER); add(progressBar, BorderLayout.SOUTH); pack(); setLocationRelativeTo(null); } public void showScreen() { SwingUtilities.invokeLater(new Runnable() { public void run() { setVisible(true); } }); } public void close() { SwingUtilities.invokeLater(new Runnable() { public void run() { setVisible(false); dispose(); } }); } public void setProgress(final String message, final int progress) { SwingUtilities.invokeLater(new Runnable() { public void run() { progressBar.setValue(progress); if (message == null) { progressBar.setStringPainted(false); } else { progressBar.setStringPainted(true); } progressBar.setString("Loading " + message + "..."); } }); } }
From the main method that I call this way
public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { try { UIManager.setLookAndFeel(UIManager .getSystemLookAndFeelClassName()); SplashScreen splashScreen = new SplashScreen(new ImageIcon("images/splash.jpg")); splashScreen.showScreen(); AppFrame frame = new AppFrame(splashScreen); } catch (Exception e) { appLogger.error(e.getMessage(), e); } } }); }
In the AppFrame constructor, I call the splashScreen.setProgress (msg, val) method to update the progress bar. But the surge is not displayed. It is displayed only at the end, when the frame is displayed only for a split second, even if the download takes a long time. But if I put these three lines
SplashScreen splashScreen = new SplashScreen(new ImageIcon("images/splash.jpg")); splashScreen.showScreen(); AppFrame frame = new AppFrame(splashScreen);
outside of invokeLater (), a splash screen is displayed, and the progress bar updates beautifully. I believe GUI updates should be in invokeLater. What could be the problem?
Btw, AppFrame loads various panels of my application.
Edit: Below is the layout of my AppFrame.
public class AppFrame extends JFrame { public AppFrame(SplashScreen splashScreen) { JPanel test = new JPanel(); test.setLayout(new GridLayout(0, 10)); splashScreen.setProgress("jlabel", 10); for(int i = 0; i < 10000; i++) { test.add(new JButton("Hi..." + i)); splashScreen.setProgress("jbutton", (int)(i * 0.1)); } add(new JScrollPane(test)); setPreferredSize(new Dimension(800, 600)); pack(); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setLocationRelativeTo(null); splashScreen.setProgress("complete", 100); setVisible(true); } }