在主程序加载大量数据时,我遇到了显示加载程序的问题。下面是一个名为 SplashScreen 的类,它显示了.gif加载器的动画。
公共类SplashScreen扩展了JWindow {
public SplashScreen() {
super();
Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/resources/load.gif"));
try {
if (image != null) {
JLabel imageLabel = new JLabel();
imageLabel.setIcon(new ImageIcon(image));
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(imageLabel, BorderLayout.CENTER);
this.pack();
Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
Dimension labelSize = imageLabel.getPreferredSize();
setLocation(screenSize.width / 2 - (labelSize.width / 2),
screenSize.height / 2 - (labelSize.height / 2));
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
dispose();
}
});
addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
dispose();
}
});
}
} catch (Exception ex) {
}
}
运行这段代码的结果是:
但是当我想加载大量数据(比如100万条记录)时,我有类似的东西:
我使用Thread,EventQueue.invokeLater和SwingUtilities在单独的Thread中显示SplashScreen,但它不起作用。加载大量数据时,它始终为空白。不幸的是,我必须说使用EventQueue或SwingUtilities非常困难,因为你无法结束这些实用程序启动的任务。
答案 0 :(得分:0)
我终于想出了如何正确实施这个案例。
1)实现SplashScreen,它将显示加载程序(.gif)
public class SplashScreen extends JWindow {
public SplashScreen() {
super();
Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/resources/load.gif"));
try {
if (image != null) {
JLabel imageLabel = new JLabel();
imageLabel.setIcon(new ImageIcon(image));
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(imageLabel, BorderLayout.CENTER);
this.pack();
Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
Dimension labelSize = imageLabel.getPreferredSize();
setLocation(screenSize.width / 2 - (labelSize.width / 2),
screenSize.height / 2 - (labelSize.height / 2));
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
dispose();
}
});
addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
dispose();
}
});
}
} catch (Exception ex) {
}
}
@Override
public void dispose() {
setVisible(false);
}
}
2)Init ScheduledExecutorService
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
3)实现负责显示SplashScreen的线程
Thread splashThread = new Thread(new Runnable() {
public void run() {
setSplashScreen(new SplashScreen());
getSplashScreen().setVisible(true);
getSplashScreen().toFront();
getSplashScreen().setAlwaysOnTop(true);
}
});
4)安排新创建的线程
executor.schedule(splashThread, 0, TimeUnit.MILLISECONDS);
5)当需要处理SplashScreen时
getSplashScreen().dispose();
此外,您可以创建单独的线程来检查是否需要处理SplashScreen。
private void invokeExecutor() {
executor.scheduleAtFixedRate(new DoneTask(), 0, 200, TimeUnit.MILLISECONDS);
}
private class DoneTask implements Runnable {
@Override
public void run() {
if (fileWorker.isDone()) { //SwingWorker
getSplashScreen().dispose();
}
}
}