[英]GUI has to wait until splashscreen finishes executing
I have a SplashScreen class which displays a image and a progress bar until some databases are initialized. 我有一个SplashScreen类,它显示图像和进度条,直到初始化某些数据库为止。 I want that after the splashscreen ends a new window is opened.
我希望启动画面结束后打开一个新窗口。 I have the following code:
我有以下代码:
public class Gui{
private static final String IMG_PATH = "../opt/images/splashscreendef.jpg";
public static void main(String[] args) throws ClassNotFoundException,
InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Gui ui = new Gui();
}
});
}
private inTouchGui() {
InitSplashScreen splash = null;
splash = new InitSplashScreen();
try {
splash.initUI();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
BufferedImage img = null;
try {
img = ImageIO.read(new File(IMG_PATH));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ImageIcon icon = new ImageIcon(img);
JLabel label = new JLabel(icon);
JOptionPane.showMessageDialog(null, label);
}
} }
public class InitSplashScreen {
private JDialog dialog;
private JProgressBar progress;
public void initUI() throws MalformedURLException {
showSplashScreen();
SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>(){
@Override
protected Void doInBackground() throws Exception {
Thread thread = new Thread(new InitProcess());
thread.start();
int i = 0;
while (thread.isAlive()){
i++;
Thread.sleep(200);// Loading of databases
publish(i);// Notify progress
}
if (i < 10){
for (i = 0; i < 100; i++){
Thread.sleep(50);// We simulate loading even if database is fully loaded
publish(i);// Notify progress
}
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
progress.setValue(chunks.get(chunks.size() - 1));
}
@Override
protected void done() {
hideSplashScreen();
}
};
worker.execute();
}
protected void hideSplashScreen() {
dialog.setVisible(false);
dialog.dispose();
}
protected void showSplashScreen() throws MalformedURLException {
dialog = new JDialog((Frame) null);
dialog.setModal(false);
dialog.setUndecorated(true);
JLabel background = new JLabel(new ImageIcon("splashscreendef.jpg"));
background.setLayout(new BorderLayout());
dialog.add(background);
progress = new JProgressBar();
background.add(progress, BorderLayout.SOUTH);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
}
}
When I run the code I get at the same time both the splash screen and the image window, I have tried to use worker.get()
but then nothing appears in screen. 当我运行代码时,同时显示初始屏幕和图像窗口,我尝试使用
worker.get()
但是屏幕上什么也没有出现。 Could you give me some advice? 你能给我一些建议吗? I am pretty new to Java Swing.
我对Java Swing很陌生。
By the way, would it be possible (with possible meaning not a insane load of code and hours to make it work) to implement a login window like this one, for example? 顺便说一句,是否有可能(例如,可能不会耗费大量代码和大量时间才能使其正常工作)来实现这样的登录窗口?
http://designsparkle.com/wp-content/uploads/2014/06/a-simple-html-css-login-for.jpg http://designsparkle.com/wp-content/uploads/2014/06/a-simple-html-css-login-for.jpg
Thanks in advice. 感谢您的建议。
Change your way of thinking 改变思维方式
Initialise and show the splash screen, when it's finished, initialise and show the Gui
初始化并显示启动屏幕,完成后初始化并显示
Gui
This will require to have some way to tell who ever initialised the splash screen that it has completed, to do this, you can use a PropertyChangeListener
... 这将需要某种方法来告诉谁初始化了初始屏幕,即完成了该操作,您可以使用
PropertyChangeListener
...
public class InitSplashScreen {
//...
public void initUI(PropertyChangeListener listener) throws MalformedURLException {
showSplashScreen();
SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
//...
};
worker.addPropertyChangeListener(listener);
worker.execute();
}
Then you listen for the state
change property and check the state of the work... 然后,您侦听
state
更改属性并检查工作状态。
public static void main(String[] args) throws ClassNotFoundException,
InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
InitSplashScreen splashScreen = new InitSplashScreen();
try {
splashScreen.initUI(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
String name = evt.getPropertyName();
if ("state".equalsIgnoreCase(name)) {
SwingWorker worker = (SwingWorker) evt.getSource();
if (worker.getState().equals(SwingWorker.StateValue.DONE)) {
Gui ui = new Gui();
}
}
}
});
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
}
});
}
But remember, you need to remove the splash screen from the Gui
code. 但是请记住,您需要从
Gui
代码中删除初始屏幕。
You can also use this to "get" any information from the SwingWorker
that the Gui
might need and pass it as a parameter to the constructor or via setters depending on your needs 您还可以使用它从
SwingWorker
中“获取” Gui
可能需要的任何信息,并将其作为参数传递给构造函数或通过setter传递,具体取决于您的需求。
Also, to me, this... 另外,对我来说
Thread thread = new Thread(new InitProcess());
thread.start();
Looks like a strange thing to do within a SwingWoker
. 在
SwingWoker
看起来很奇怪。 You could simply leave the JProgressBar
in indeterminate mode if you don't know how much work is required 如果您不知道需要多少工作,则可以简单地将
JProgressBar
保留为不确定模式
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.