组件在绘制之前等待后面的代码执行
Component waits for later code to execute before it draws
我有一个名为 WaitBox 的 class 我想弹出它,显示一个进度条,然后在进度条达到 100% 时关闭。现在,它弹出了,但奇怪的是,它等到代码完成后才在 WaitBox 中绘制组件(进度条)...
当我 运行 下面的代码时,JDialog 弹出,但它只是白色的,就像在其上绘制组件之前的样子。它 运行 是它下面的代码(嵌套的 for 循环),完成后,它在 JDialog 上绘制组件。为什么会发生这种情况,我该如何解决?
等待框class:
public class WaitBox extends JDialog implements Runnable {
private static final long serialVersionUID = 1L;
private int width = 450;
private int height = 200;
public static int widthOfBar = 400;
private int heightOfBar = 50;
private JPanel container;
private JProgressBar progressBar;
private Thread thread;
private boolean running = false;
public WaitBox() {
initializeComponents();
add(container);
pack();
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
setTitle("Loading...");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}
private void initializeComponents() {
container = new JPanel();
container.setPreferredSize(new Dimension(width, height));
progressBar = new JProgressBar(0, widthOfBar);
progressBar.setPreferredSize(new Dimension(widthOfBar, heightOfBar));
progressBar.setStringPainted(true);
progressBar.setValue(0);
container.add(progressBar);
}
public void run() {
while (running) {
System.out.println(Fill.currentPos);
progressBar.setValue((int) Fill.currentPos);
if (progressBar.getValue() >= widthOfBar) running = false;
}
stop();
}
public synchronized void start() {
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
setCursor(null);
dispose();
}
}
如何称呼:
WaitBox waitBox = new WaitBox();
waitBox.start();
for (int yy = 0; yy < Constants.map_height; yy++) {
for (int xx = 0; xx < Constants.map_width; xx++) {
image.setRGB(xx * 32, yy * 32, 32, 32, pixels, 0, 32);
}
}
您的 stop
方法正在等待 thread
结束,这会阻塞事件调度线程。
有关详细信息,请参阅 Concurrency in Swing
你的run
方法违反了Swing的单线程规则,从事件调度线程外部更新UI,记住,Swing是单线程的,但也不是线程安全的。
您应该考虑改用 SwingWorker
,它有进步和 PropertyChange
支持。有关详细信息,请参阅 Worker Threads and SwingWorker
其中演示:
- Issues with SwingWorker and JProgressBar
- java swingworker thread to update main Gui
- Progress Bar Java
- JProgressBar isn't progressing
- SwingWorker in another SwingWorker's done method
- SwingWorker In multithreaded Jframes
- Progress Bar Java
其他地方
我有一个名为 WaitBox 的 class 我想弹出它,显示一个进度条,然后在进度条达到 100% 时关闭。现在,它弹出了,但奇怪的是,它等到代码完成后才在 WaitBox 中绘制组件(进度条)...
当我 运行 下面的代码时,JDialog 弹出,但它只是白色的,就像在其上绘制组件之前的样子。它 运行 是它下面的代码(嵌套的 for 循环),完成后,它在 JDialog 上绘制组件。为什么会发生这种情况,我该如何解决?
等待框class:
public class WaitBox extends JDialog implements Runnable {
private static final long serialVersionUID = 1L;
private int width = 450;
private int height = 200;
public static int widthOfBar = 400;
private int heightOfBar = 50;
private JPanel container;
private JProgressBar progressBar;
private Thread thread;
private boolean running = false;
public WaitBox() {
initializeComponents();
add(container);
pack();
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
setTitle("Loading...");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}
private void initializeComponents() {
container = new JPanel();
container.setPreferredSize(new Dimension(width, height));
progressBar = new JProgressBar(0, widthOfBar);
progressBar.setPreferredSize(new Dimension(widthOfBar, heightOfBar));
progressBar.setStringPainted(true);
progressBar.setValue(0);
container.add(progressBar);
}
public void run() {
while (running) {
System.out.println(Fill.currentPos);
progressBar.setValue((int) Fill.currentPos);
if (progressBar.getValue() >= widthOfBar) running = false;
}
stop();
}
public synchronized void start() {
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
setCursor(null);
dispose();
}
}
如何称呼:
WaitBox waitBox = new WaitBox();
waitBox.start();
for (int yy = 0; yy < Constants.map_height; yy++) {
for (int xx = 0; xx < Constants.map_width; xx++) {
image.setRGB(xx * 32, yy * 32, 32, 32, pixels, 0, 32);
}
}
您的 stop
方法正在等待 thread
结束,这会阻塞事件调度线程。
有关详细信息,请参阅 Concurrency in Swing
你的run
方法违反了Swing的单线程规则,从事件调度线程外部更新UI,记住,Swing是单线程的,但也不是线程安全的。
您应该考虑改用 SwingWorker
,它有进步和 PropertyChange
支持。有关详细信息,请参阅 Worker Threads and SwingWorker
其中演示:
- Issues with SwingWorker and JProgressBar
- java swingworker thread to update main Gui
- Progress Bar Java
- JProgressBar isn't progressing
- SwingWorker in another SwingWorker's done method
- SwingWorker In multithreaded Jframes
- Progress Bar Java
其他地方