Questo è il mio codice Splash Screen,battente con barra di avanzamento
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 + "...");
}
});
}
}
Dal metodo principale che sto invocando come questo,
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);
}
}
});
}
Nel costruttore di AppFrame io chiamo, splashScreen .setProgress (msg, val) metodo per aggiornare la barra di avanzamento. Ma lo splash non viene mostrato. Viene visualizzato solo alla fine quando il frame viene visualizzato solo per una frazione di secondo, anche se il carico richiede molto tempo. Ma se metto queste tre linee
SplashScreen splashScreen = new SplashScreen(new ImageIcon("images/splash.jpg"));
splashScreen.showScreen();
AppFrame frame = new AppFrame(splashScreen);
fuori del invokeLater() la schermata di avvio viene visualizzata e gli aggiornamenti barra di avanzamento bene. Credo che gli aggiornamenti della GUI dovrebbero essere in invokeLater. Quale potrebbe essere il problema?
Btw, AppFrame carica vari pannelli della mia applicazione.
Modifica: Un esempio del mio AppFrame è mostrato sotto.
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);
}
}
* "Credo che gli aggiornamenti della GUI dovrebbero essere in invokeLater." * O 'invokeAndWait'. Ma faccio un po 'di logging, mi aspetto che troverete gli orari tra il completamento di 'splashScreen.showScreen();' e 'AppFrame frame = new AppFrame (splashScreen);' è molto meno di quanto ci si aspetti. Si noti inoltre che i migliori schizzi sono rigorosamente AWT (no Swing). –
Ciò significa che dovrei usare Window o Frame invece di JWindow? Grazie. – Praveen
Sì, usa 'Finestra' o' Cornice'. Guarda anche in 'MediaTracker' /' Canvas' e 'EventQueue' - ci devono essere ** no ** Swing import o classi usate, o l'intero pacchetto Swing viene caricato prima. –