Gui SwingWorker ...在重绘之前没有更新所有内容

发布于 2024-12-10 04:53:28 字数 2269 浏览 1 评论 0原文

我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一梦浮鱼 2024-12-17 04:53:28

我相信发生的情况是该步骤是在单独的线程中执行的,因此当您对其调用执行方法时,它会开始在单独的线程中执行,这可能会在您调用重绘方法后完成执行。您想要的是在工作人员完成其任务后调用重绘。查看 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.

甲如呢乙后呢 2024-12-17 04:53:28

你有什么例外吗?

在您的代码中

   for(int i = 0; i < 50; i++){
        for(int j = 0; j < 50; j++){
            if(grid[i][j].getIntensity()==5){
                grid[i][j].setDefault();
                grid[i-1][j-1].setAgent();
            }
        }
    }

,我可以看到 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

   for(int i = 0; i < 50; i++){
        for(int j = 0; j < 50; j++){
            if(grid[i][j].getIntensity()==5){
                grid[i][j].setDefault();
                grid[i-1][j-1].setAgent();
            }
        }
    }

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文