GUI 必须等到启动画面完成执行
GUI has to wait until splashscreen finishes executing
我有一个 SplashScreen class,它显示一个图像和一个进度条,直到一些数据库被初始化。我希望在启动画面结束后打开一个新的 window。我有以下代码:
主要class
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);
}
}
启动画面class
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);
}
}
当我 运行 我同时获得初始屏幕和图像 window 的代码时,我尝试使用 worker.get()
但屏幕上什么也没有出现。你能给我一些建议吗?我是 Java Swing 的新手。
顺便说一下,是否有可能(可能意味着不是疯狂的代码负载和时间来让它工作)像这样实现登录 window,例如?
http://designsparkle.com/wp-content/uploads/2014/06/a-simple-html-css-login-for.jpg
谢谢指教。
改变你的思维方式
初始化并显示启动画面,完成后,初始化并显示 Gui
这将需要一些方法来告诉谁初始化了初始屏幕它已经完成,为此,您可以使用 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();
}
然后您监听 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();
}
}
});
}
但请记住,您需要从 Gui
代码中删除启动画面。
您还可以使用它来 "get" SwingWorker
中 Gui
可能需要的任何信息,并将其作为参数传递给构造函数或根据您的需要通过设置器传递
另外,对我来说,这...
Thread thread = new Thread(new InitProcess());
thread.start();
在 SwingWoker
内做这件事看起来很奇怪。如果您不知道需要多少工作,您可以简单地将 JProgressBar
保持在 indeterminate 模式
我有一个 SplashScreen class,它显示一个图像和一个进度条,直到一些数据库被初始化。我希望在启动画面结束后打开一个新的 window。我有以下代码:
主要class
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);
}
}
启动画面class
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);
}
}
当我 运行 我同时获得初始屏幕和图像 window 的代码时,我尝试使用 worker.get()
但屏幕上什么也没有出现。你能给我一些建议吗?我是 Java Swing 的新手。
顺便说一下,是否有可能(可能意味着不是疯狂的代码负载和时间来让它工作)像这样实现登录 window,例如?
http://designsparkle.com/wp-content/uploads/2014/06/a-simple-html-css-login-for.jpg
谢谢指教。
改变你的思维方式
初始化并显示启动画面,完成后,初始化并显示 Gui
这将需要一些方法来告诉谁初始化了初始屏幕它已经完成,为此,您可以使用 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();
}
然后您监听 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();
}
}
});
}
但请记住,您需要从 Gui
代码中删除启动画面。
您还可以使用它来 "get" SwingWorker
中 Gui
可能需要的任何信息,并将其作为参数传递给构造函数或根据您的需要通过设置器传递
另外,对我来说,这...
Thread thread = new Thread(new InitProcess());
thread.start();
在 SwingWoker
内做这件事看起来很奇怪。如果您不知道需要多少工作,您可以简单地将 JProgressBar
保持在 indeterminate 模式