Gui SwingWorker ...在重绘之前没有更新所有内容
我的 gui 是一个 50x50 GridLayout,使用 SwingWorker 进行更新。
GridLayout 中的每个网格都有一个具有特定强度的 GridGraphic 组件。
默认强度 = 0,这只是黑色分量。如果强度 = 5,则网格显示为黑色并带有黄点。
当按下 Step 按钮时,StepManager 应该遍历所有网格并更新其强度,然后立即重新绘制所有内容,但 StepManager 在第一个 GridGraphic 的值强度 = 5 后停止执行。
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class Gui extends JFrame{
private JPanel buttonPanel, populationPanel, velocityPanel, gridPanel;
private JButton setupButton, stepButton, goButton;
private JLabel populationNameLabel, velocityNameLabel, populationSliderValueLabel, velocitySliderValueLabel;
private JSlider populationSlider, velocitySlider;
private GridGraphic [] [] gridGraphic;
private int agents = 125;
private int velocity = 500;
private boolean resetGrid;
private StepManager step;
public Gui() {
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//Set up JButtons
buttonPanel = new JPanel();
setupButton = new JButton("Setup");
stepButton = new JButton("Step");
goButton = new JButton("Go");
buttonPanel.add(setupButton);
buttonPanel.add(stepButton);
buttonPanel.add(goButton);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
add(buttonPanel, c);
public GridGraphic getGridGraphic(int n1, int n2){
return gridGraphic[n1][n2];
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
Gui gui = new Gui();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Display the window.
gui.pack();
gui.setVisible(true);
gui.setResizable(false);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
My gui is a 50x50 GridLayout that updates using the SwingWorker.
Each grid in the GridLayout has a GridGraphic component which has a specific intensity.
Default intensity = 0, which is just a black component. If intensity = 5, then the grid appears black with a yellow dot.
When the Step button is pushed, the StepManager is supposed to go through all the grids and update their intensity and then repaint everything at once, but the StepManager stops executing after the first GridGraphic that has a alue with an intensity = 5.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class Gui extends JFrame{
private JPanel buttonPanel, populationPanel, velocityPanel, gridPanel;
private JButton setupButton, stepButton, goButton;
private JLabel populationNameLabel, velocityNameLabel, populationSliderValueLabel, velocitySliderValueLabel;
private JSlider populationSlider, velocitySlider;
private GridGraphic [] [] gridGraphic;
private int agents = 125;
private int velocity = 500;
private boolean resetGrid;
private StepManager step;
public Gui() {
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//Set up JButtons
buttonPanel = new JPanel();
setupButton = new JButton("Setup");
stepButton = new JButton("Step");
goButton = new JButton("Go");
buttonPanel.add(setupButton);
buttonPanel.add(stepButton);
buttonPanel.add(goButton);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
add(buttonPanel, c);
public GridGraphic getGridGraphic(int n1, int n2){
return gridGraphic[n1][n2];
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
Gui gui = new Gui();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Display the window.
gui.pack();
gui.setVisible(true);
gui.setResizable(false);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信发生的情况是该步骤是在单独的线程中执行的,因此当您对其调用执行方法时,它会开始在单独的线程中执行,这可能会在您调用重绘方法后完成执行。您想要的是在工作人员完成其任务后调用重绘。查看 SwingWorker 的 did() 方法。
I believe what happens is that step is executed in a separate thread, so when you call execute method on it, it starts executing in a separate thread, which may finish executing way after you call the repaint method. What you want is to call repaint after the worker is finished with its task. Look into SwingWorker's done() method.
你有什么例外吗?
在您的代码中
,我可以看到 ArrayIndexOutOfBoundsException,因为如果 i 或 j 为 0 并且 grid[i][0] 和/或 grid[0][j] 具有强度,您可能正在访问 grid[-1][-1] 5.
编辑:另一件事。执行 SwingWorker 后,您似乎只重新绘制 GUI 一次。但是,SwingWorker 是一个线程,因此重绘将在工作线程启动后立即执行,而不是在其完成后执行。尝试在完成方法中调用重绘。
Do you get some sort of exception?
In your code
I can see an ArrayIndexOutOfBoundsException, because you may be accessing grid[-1][-1] if i or j are 0 and grid[i][0] and/or grid[0][j] have an intensity of 5.
Edit: Another thing. It seems you are repainting your GUI only once, after executing the SwingWorker. But, the SwingWorker is a thread, so the repaint will be executed immediately after the worker started, not after it's finished. Try calling repaint in your done method.