SwingWorker process() 更新 gui 泛型

发布于 2024-12-12 08:31:26 字数 10718 浏览 3 评论 0原文

我正在尝试使用 SwingWorker 来更新我的 gui。

我试图更新的 gui 部分是带有 GridLayout [50][50] 的 JPanel (gridPanel)。
GridLayout 中的每个网格都有一个自定义的 GridGraphic JComponent。

在 SwingWorker 的 doInBackground() 中,我更新了代表某种颜色的每个 GridGraphic。然后,我将其发布到 process() 用于更新 gui 的列表。不过,GUI 并没有更新。

有没有办法在不调用 repaint() 的情况下做到这一点。

如何修复我的 SwingWorker 以便 GUI 具有响应能力。我想为 gridPanel 返回什么,它是一个响应变化的 GridGraphic 组件的 [50][50] GridLayout

SwingWorker 在 stepButton.addActionListener(new ActionListener()........ ......在 SlimeGui

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;


public class SlimeGui extends JFrame{

    private JPanel buttonPanel, populationPanel, velocityPanel;
    private JPanel gridPanel = new JPanel(new GridLayout(50, 50));
    private JButton setupButton, stepButton, goButton;
    private JLabel populationNameLabel, velocityNameLabel, populationSliderValueLabel, velocitySliderValueLabel;
    private JSlider populationSlider, velocitySlider;
    private GridGraphic [] [] gridGraphic;
    private GridGraphic test;
    private int agents = 125;
    private int velocity = 500;
    private boolean resetGrid;


    public SlimeGui() {

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


        //Set up population JSlider     
        populationPanel = new JPanel();
        populationNameLabel = new JLabel("     Population");
        populationSliderValueLabel = new JLabel(Integer.toString(agents));
        populationSlider = new JSlider(JSlider.HORIZONTAL,0, 1000, 125);
        populationSlider.setMajorTickSpacing(125);
        populationSlider.setPaintTicks(true);
        populationSlider.addChangeListener(new PopulationSliderListener());

        populationPanel.add(populationNameLabel);
        populationPanel.add(populationSlider);
        populationPanel.add(populationSliderValueLabel);

        c.gridx = 0;
        c.gridy = 2;
        add(populationPanel, c);    


        //Set up veolicty JSlider
        velocityPanel = new JPanel();
        velocityNameLabel = new JLabel("        Velocity");
        velocitySliderValueLabel = new JLabel(Integer.toString(velocity));
        velocitySlider = new JSlider(JSlider.HORIZONTAL,0, 1000, 500);
        velocitySlider.setMajorTickSpacing(125);
        velocitySlider.setPaintTicks(true);
        velocitySlider.addChangeListener(new VelocitySliderListener());

        velocityPanel.add(velocityNameLabel);
        velocityPanel.add(velocitySlider);
        velocityPanel.add(velocitySliderValueLabel);

        c.gridx = 0;
        c.gridy = 3;
        add(velocityPanel, c);  


        //Set up grid with GridGraphic objects
        gridGraphic = new GridGraphic[50][50];

        for(int i = 0; i < 50; i++){
            for(int j = 0; j < 50; j++){
                gridGraphic[i][j] = new GridGraphic();
                gridPanel.add(gridGraphic[i][j]);
            }
        }

        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 3;

        add(gridPanel, c);


        //Set up ActionListener for the 'Setup' JButton
        setupButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                int n1=0;
                int n2=0;

                //resets the grid so there are no agents
                if(resetGrid){
                    for(int i = 0; i < 50; i++){
                        for(int j = 0; j < 50; j++){
                            gridGraphic[i][j].setDefault();
                        }
                    }
                }

                //sets a random number of positions for GridGraphics
                for (int numOfAgenets = 0; numOfAgenets < agents; numOfAgenets++){
                    int lowerB = 0;
                    int upperB = 50;                    

                    n1 = (lowerB + (int)(Math.random()*(upperB-lowerB))); //random number 1
                    n2 = (lowerB + (int)(Math.random()*(upperB-lowerB))); //random number 2

                    System.out.println("Choosing random agent "+(numOfAgenets+1)+":  "+n1 +" "+n2);

                    //sets the GridGraphic to an agent if it's available
                    if (gridGraphic[n1][n2].getIntensity() == 0)
                        gridGraphic[n1][n2].setAgent();

                    //if the GridGraphic is already an agent, it continues to search 
                    else if(gridGraphic[n1][n2].getIntensity() == 5){
                        while(gridGraphic[n1][n2].getIntensity() == 5){
                            n1 = (lowerB + (int)(Math.random()*(upperB-lowerB)));
                            n2 = (lowerB + (int)(Math.random()*(upperB-lowerB)));
                        }
                        gridGraphic[n1][n2].setAgent();
                    }                   
                }   

                repaint();
                resetGrid = true;
            }
        }); 


        //Set up ActionListener for the 'Step' JButton
        stepButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                StepManager step = new StepManager(SlimeGui.this);
                step.execute();
                //repaint();
            }
        });

    }


    class PopulationSliderListener implements ChangeListener{
        public void stateChanged(ChangeEvent e){
            agents = ((JSlider)e.getSource()).getValue();

            populationSliderValueLabel.setText(Integer.toString(agents));
            System.out.println("Population of agents:  " + agents);
        }
    }


    class VelocitySliderListener implements ChangeListener{
        public void stateChanged(ChangeEvent e){
            velocity = ((JSlider)e.getSource()).getValue();

            velocitySliderValueLabel.setText(Integer.toString(velocity));
            System.out.println("Velocity(ms) of agents:  " + velocity);
        }
    }


    public Integer getVelocity(){
        return velocity;
    }

    public GridGraphic getGridGraphic(int n1, int n2){
        return gridGraphic[n1][n2];
    }

    public GridGraphic [][] getGridGraphic(){
        return gridGraphic;
    }

    public void setGridGraphicArray(GridGraphic xxx, int n1, int n2 ){
        gridGraphic[n1][n2] = xxx;
    }

    public void setGridPanel(GridGraphic[][] xxx){
        for(int i = 0; i < 50; i++){
            for(int j = 0; j < 50; j++){
               gridPanel.add(xxx[i][j]);
            }
        }
    }



    /**
     * 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.
        SlimeGui slime = new SlimeGui();
        slime.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Display the window.
        slime.pack();
        slime.setVisible(true);
        slime.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();
            }
        });
    }
}

我的 SwingWorker

import java.util.List;
import java.awt.*;
import javax.swing.*;
import java.util.concurrent.ExecutionException;

public class StepManager extends SwingWorker<Void, GridGraphic>{

    private SlimeGui gui;

    public StepManager(SlimeGui sg){
         gui=sg;
    }

    @Override
    protected Void doInBackground() throws Exception{   
        for(int i = 0; i < 50; i++){
            for(int j = 0; j < 50; j++){

                if(gui.getGridGraphic(i,j).getIntensity()==5){
                    if (i==0){
                        gui.getGridGraphic(i,j).setDefault();
                        gui.getGridGraphic(49,j).setAgent();
                    }
                    else{
                        gui.getGridGraphic(i,j).setDefault();
                        gui.getGridGraphic(i-1,j).setAgent();
                    }
                }
                publish(gui.getGridGraphic(i,j));
            }
        }
        return null;
    }

    @Override
    protected void process(List <GridGraphic> gg){                  
        int k=0;
        for ( int i = 0; i < 50; i++ ){
            for(int j = 0; j < 50; j++){
                gui.setGridGraphicArray(gg.get(k),i,j);
                k++;
            }
        }
        gui.setGridPanel(gui.getGridGraphicArray());
        System.out.println("process has completed");
    }

    @Override
    protected void done(){          
        System.out.println("doInBackground has completed");
    }
}

我的 GridGraphic

import java.awt.*;
import javax.swing.*;

public class GridGraphic extends JComponent {

    private int intensity = 0;

    public GridGraphic() {
        //setBorder(BorderFactory.createLineBorder(Color.BLUE));
    }

    public void paintComponent(Graphics g) {

        //paints the GridGraphic black
        if (intensity == 0){
            super.paintComponent(g);
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());
        }

        //paints the GridGraphic black with a yellow dot
        else if (intensity == 5){
            super.paintComponent(g);
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.YELLOW);
            g.fillOval(3, 3, getWidth()/2, getHeight()/2);
        }

        //paints the GridGraphic dark yellow (pheromone)
        if (intensity == 2){
            super.paintComponent(g);
            g.setColor(Color.BLACK.brighter());
            g.fillRect(0, 0, getWidth(), getHeight());
        }     
    }


    public Dimension getPreferredSize() {
        return new Dimension(10, 10);
    }

    public void setAgent(){
        intensity = 5;
    }

    public void setPheromone1(){
        intensity = 2;
    }

    public void setDefault(){
        intensity = 0;
    }

    public int getIntensity(){
        return intensity;
    }
}

Im trying to use SwingWorker to update my gui.

The part of my gui that I'm trying to update is a JPanel (gridPanel) with a GridLayout [50][50].
Each grid in the GridLayout has a custom GridGraphic JComponent.

In the doInBackground() of my SwingWorker, I update each GridGraphic which represents some color. Then, I publish it to a List that the process() uses to update the gui. Though, the gui isn't updating.

Is there a way to do this without calling repaint().

How do I fix my SwingWorker so the gui is responsive. What do I want to return in order for the gridPanel, which is a [50][50] GridLayout of GridGraphic components responsive to changes

The SwingWorker is executed in the stepButton.addActionListener(new ActionListener()...............in SlimeGui

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;


public class SlimeGui extends JFrame{

    private JPanel buttonPanel, populationPanel, velocityPanel;
    private JPanel gridPanel = new JPanel(new GridLayout(50, 50));
    private JButton setupButton, stepButton, goButton;
    private JLabel populationNameLabel, velocityNameLabel, populationSliderValueLabel, velocitySliderValueLabel;
    private JSlider populationSlider, velocitySlider;
    private GridGraphic [] [] gridGraphic;
    private GridGraphic test;
    private int agents = 125;
    private int velocity = 500;
    private boolean resetGrid;


    public SlimeGui() {

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


        //Set up population JSlider     
        populationPanel = new JPanel();
        populationNameLabel = new JLabel("     Population");
        populationSliderValueLabel = new JLabel(Integer.toString(agents));
        populationSlider = new JSlider(JSlider.HORIZONTAL,0, 1000, 125);
        populationSlider.setMajorTickSpacing(125);
        populationSlider.setPaintTicks(true);
        populationSlider.addChangeListener(new PopulationSliderListener());

        populationPanel.add(populationNameLabel);
        populationPanel.add(populationSlider);
        populationPanel.add(populationSliderValueLabel);

        c.gridx = 0;
        c.gridy = 2;
        add(populationPanel, c);    


        //Set up veolicty JSlider
        velocityPanel = new JPanel();
        velocityNameLabel = new JLabel("        Velocity");
        velocitySliderValueLabel = new JLabel(Integer.toString(velocity));
        velocitySlider = new JSlider(JSlider.HORIZONTAL,0, 1000, 500);
        velocitySlider.setMajorTickSpacing(125);
        velocitySlider.setPaintTicks(true);
        velocitySlider.addChangeListener(new VelocitySliderListener());

        velocityPanel.add(velocityNameLabel);
        velocityPanel.add(velocitySlider);
        velocityPanel.add(velocitySliderValueLabel);

        c.gridx = 0;
        c.gridy = 3;
        add(velocityPanel, c);  


        //Set up grid with GridGraphic objects
        gridGraphic = new GridGraphic[50][50];

        for(int i = 0; i < 50; i++){
            for(int j = 0; j < 50; j++){
                gridGraphic[i][j] = new GridGraphic();
                gridPanel.add(gridGraphic[i][j]);
            }
        }

        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 3;

        add(gridPanel, c);


        //Set up ActionListener for the 'Setup' JButton
        setupButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                int n1=0;
                int n2=0;

                //resets the grid so there are no agents
                if(resetGrid){
                    for(int i = 0; i < 50; i++){
                        for(int j = 0; j < 50; j++){
                            gridGraphic[i][j].setDefault();
                        }
                    }
                }

                //sets a random number of positions for GridGraphics
                for (int numOfAgenets = 0; numOfAgenets < agents; numOfAgenets++){
                    int lowerB = 0;
                    int upperB = 50;                    

                    n1 = (lowerB + (int)(Math.random()*(upperB-lowerB))); //random number 1
                    n2 = (lowerB + (int)(Math.random()*(upperB-lowerB))); //random number 2

                    System.out.println("Choosing random agent "+(numOfAgenets+1)+":  "+n1 +" "+n2);

                    //sets the GridGraphic to an agent if it's available
                    if (gridGraphic[n1][n2].getIntensity() == 0)
                        gridGraphic[n1][n2].setAgent();

                    //if the GridGraphic is already an agent, it continues to search 
                    else if(gridGraphic[n1][n2].getIntensity() == 5){
                        while(gridGraphic[n1][n2].getIntensity() == 5){
                            n1 = (lowerB + (int)(Math.random()*(upperB-lowerB)));
                            n2 = (lowerB + (int)(Math.random()*(upperB-lowerB)));
                        }
                        gridGraphic[n1][n2].setAgent();
                    }                   
                }   

                repaint();
                resetGrid = true;
            }
        }); 


        //Set up ActionListener for the 'Step' JButton
        stepButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                StepManager step = new StepManager(SlimeGui.this);
                step.execute();
                //repaint();
            }
        });

    }


    class PopulationSliderListener implements ChangeListener{
        public void stateChanged(ChangeEvent e){
            agents = ((JSlider)e.getSource()).getValue();

            populationSliderValueLabel.setText(Integer.toString(agents));
            System.out.println("Population of agents:  " + agents);
        }
    }


    class VelocitySliderListener implements ChangeListener{
        public void stateChanged(ChangeEvent e){
            velocity = ((JSlider)e.getSource()).getValue();

            velocitySliderValueLabel.setText(Integer.toString(velocity));
            System.out.println("Velocity(ms) of agents:  " + velocity);
        }
    }


    public Integer getVelocity(){
        return velocity;
    }

    public GridGraphic getGridGraphic(int n1, int n2){
        return gridGraphic[n1][n2];
    }

    public GridGraphic [][] getGridGraphic(){
        return gridGraphic;
    }

    public void setGridGraphicArray(GridGraphic xxx, int n1, int n2 ){
        gridGraphic[n1][n2] = xxx;
    }

    public void setGridPanel(GridGraphic[][] xxx){
        for(int i = 0; i < 50; i++){
            for(int j = 0; j < 50; j++){
               gridPanel.add(xxx[i][j]);
            }
        }
    }



    /**
     * 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.
        SlimeGui slime = new SlimeGui();
        slime.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Display the window.
        slime.pack();
        slime.setVisible(true);
        slime.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 SwingWorker

import java.util.List;
import java.awt.*;
import javax.swing.*;
import java.util.concurrent.ExecutionException;

public class StepManager extends SwingWorker<Void, GridGraphic>{

    private SlimeGui gui;

    public StepManager(SlimeGui sg){
         gui=sg;
    }

    @Override
    protected Void doInBackground() throws Exception{   
        for(int i = 0; i < 50; i++){
            for(int j = 0; j < 50; j++){

                if(gui.getGridGraphic(i,j).getIntensity()==5){
                    if (i==0){
                        gui.getGridGraphic(i,j).setDefault();
                        gui.getGridGraphic(49,j).setAgent();
                    }
                    else{
                        gui.getGridGraphic(i,j).setDefault();
                        gui.getGridGraphic(i-1,j).setAgent();
                    }
                }
                publish(gui.getGridGraphic(i,j));
            }
        }
        return null;
    }

    @Override
    protected void process(List <GridGraphic> gg){                  
        int k=0;
        for ( int i = 0; i < 50; i++ ){
            for(int j = 0; j < 50; j++){
                gui.setGridGraphicArray(gg.get(k),i,j);
                k++;
            }
        }
        gui.setGridPanel(gui.getGridGraphicArray());
        System.out.println("process has completed");
    }

    @Override
    protected void done(){          
        System.out.println("doInBackground has completed");
    }
}

My GridGraphic

import java.awt.*;
import javax.swing.*;

public class GridGraphic extends JComponent {

    private int intensity = 0;

    public GridGraphic() {
        //setBorder(BorderFactory.createLineBorder(Color.BLUE));
    }

    public void paintComponent(Graphics g) {

        //paints the GridGraphic black
        if (intensity == 0){
            super.paintComponent(g);
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());
        }

        //paints the GridGraphic black with a yellow dot
        else if (intensity == 5){
            super.paintComponent(g);
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.YELLOW);
            g.fillOval(3, 3, getWidth()/2, getHeight()/2);
        }

        //paints the GridGraphic dark yellow (pheromone)
        if (intensity == 2){
            super.paintComponent(g);
            g.setColor(Color.BLACK.brighter());
            g.fillRect(0, 0, getWidth(), getHeight());
        }     
    }


    public Dimension getPreferredSize() {
        return new Dimension(10, 10);
    }

    public void setAgent(){
        intensity = 5;
    }

    public void setPheromone1(){
        intensity = 2;
    }

    public void setDefault(){
        intensity = 0;
    }

    public int getIntensity(){
        return intensity;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(1

孤者何惧 2024-12-19 08:31:26

堆栈跟踪中的行号指示异常发生的位置。 StepManager 中的 gui 属性为 null。它从未被初始化。

The line number in the stack trace indicates where the exception occurs. Your gui attribute in StepManager is null. It's never initialized.

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