【问题标题】:Gui SwingWorker ... not updating everything before repaintGui SwingWorker ...在重绘之前不更新所有内容
【发布时间】:2011-10-18 04:34:53
【问题描述】:

我的 gui 是一个 50x50 的 GridLayout,它使用 SwingWorker 进行更新。

GridLayout 中的每个网格都有一个具有特定强度的 GridGraphic 组件。
默认强度 = 0,这只是一个黑色分量。如果强度 = 5,则网格显示为黑色并带有一个黄点。

当按下 Step 按钮时,StepManager 应该遍历所有网格并更新它们的强度,然后立即重新绘制所有内容,但 StepManager 在第一个具有强度 = 5 的值的 GridGraphic 之后停止执行。

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();
            }
        });
    }
}

【问题讨论】:

    标签: user-interface swingworker


    【解决方案1】:

    我相信发生的情况是该步骤在单独的线程中执行,因此当您对其调用 execute 方法时,它开始在单独的线程中执行,该线程可能会在您调用 repaint 方法后完成执行。您想要的是在工作人员完成任务后调用重绘。查看 SwingWorker 的 done() 方法。

    【讨论】:

    • SwingWorker 的finished() 方法?
    【解决方案2】:

    你有什么例外吗?

    在您的代码中

       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 是一个线程,因此重绘将在 worker 启动后立即执行,而不是在它完成后执行。尝试在你的 done 方法中调用 repaint。

    【讨论】:

    • 一切都编译并运行,没有任何运行时错误。奇怪吧。为什么gui在遇到的第一个强度= 5的网格之后重新绘制,而不是更新所有网格然后重新绘制
    • 由于您是随机设置数组对象,因此您迟早会遇到 AIOOBE。您可以在每次循环迭代时打印 i 和 j 以查看 worker 是否真的停止(我不明白它为什么应该停止)。这也可能是重绘问题,请参阅我的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多