【问题标题】:Repaint only working when I click the button仅当我单击按钮时重绘才有效
【发布时间】:2014-01-28 22:59:28
【问题描述】:

您好,我已经为模拟实现了一个 MVC,并且当我遍历一组代理并更新它们在二维数组中的位置时,我正在使用 JPanel 来绘制每个模拟循环。但是,重绘方法对我来说不能正常工作,当我单击一次开始按钮时,JPanel 应该会自动保持刷新。但是,如果我一直点击开始按钮,那么会用代理的更新位置重新绘制 JPanel 我做错了什么??

GUI Class:
    public class MainGUI implements Runnable {

        public static void main(String[] args) {
            EventQueue.invokeLater(new MainGUI());
        }

        @Override
        public void run() {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(new MainPanel());
            f.pack();
            f.setLocationRelativeTo(null);
            f.setSize(400, 400);
            f.setVisible(true);
            f.repaint();
        }

        class MainPanel extends JPanel {

            public MainPanel() {
                super(new BorderLayout());

                Simulator model = new Simulator();
                GridView view1 = new GridView(model);
                Controller control = new Controller(model, view1);
                JLabel label = new JLabel("Welcome to the ABM Simulation");


                this.add(label, BorderLayout.NORTH);
                this.add(view1, BorderLayout.CENTER);
                this.add(control, BorderLayout.SOUTH);
            }
        }


    }

    View Class:

        public class GridView extends JPanel {

            private Simulator sim;
            private int rows;
            private int cols;
            private Agent[][] current2DArray;

            public GridView(Simulator sim) {
                this.sim = sim;
                this.rows = sim.getGrid().getRow();
                this.cols = sim.getGrid().getColumn();
                this.current2DArray = sim.getGrid().getGrid();

                JPanel canvas = new JPanel();
                canvas.setLayout(null);
                canvas.setPreferredSize(new Dimension(rows, cols));
            }

            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                setBackground(Color.GRAY);

                for(Agent agent : sim.getAgents()) {
                    g.setColor(agent.getColor());
                    g.fill3DRect(agent.getLocation().getRow(), agent.getLocation().getCol(), 5, 5, true);
               repaint();
                }
            }

        public void drawAgents(Graphics g) {
            g.setColor(Color.GRAY);
            g.fillRect(0,0,rows,cols);
            for(int row = 0; row < current2DArray.length; row++) {
                for(int col = 0; col < current2DArray[row].length; col++) {
                    if(current2DArray[row][col] instanceof Cop) {
                        if(current2DArray[row][col].getState() == 1) {
                            g.setColor(Color.RED); 
                            g.fill3DRect(row, col, 5, 5, true);
                        }
                        else if(current2DArray[row][col].getState() == 2) {
                            //no nothing
                        }

                    }
                    else if(current2DArray[row][col] instanceof Citizen) {
                        if(current2DArray[row][col].getState() == 3) {
                            g.setColor(Color.BLACK);
                            g.fill3DRect(row, col, 5, 5, true);
                        }
                        else if(current2DArray[row][col].getState() == 4) {
                            //no nothing
                        }
                    }
                    else if(current2DArray[row][col] == null) {
                        //if empty do nothing
                    }
                }
            }
        }
    }

public class Controller extends JPanel {
    private Simulator sim;
    private GridView view;
    private JButton start = new JButton("Start");

    public Controller(Simulator sim, GridView view) {
        this.sim = sim;
        this.view = view;
        this.add(start);
        start.addActionListener(new ButtonHandler());
    }

    private class ButtonHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            String cmd = e.getActionCommand(); {
                if("Start".equals(cmd)) {
                    sim.resumeSimulation();
                }
            }
        }

    }
}

【问题讨论】:

  • 您似乎在 GridView 构造函数的这段代码中有 3 行冗余。您创建了一个“JPanel 画布”,但从未将其分配给任何东西。

标签: java swing user-interface model-view-controller repaint


【解决方案1】:

如果你想要一个恒定的帧速率,那么你可以设置一个Timer 来强制你的面板重新绘制。

Swing 对象通常会尽可能少做,除非它们的组件或您另有说明,并期望从那时起合作会导致心痛。

【讨论】:

    【解决方案2】:

    在每个模拟周期后在您的 JPanel 上调用 repaint() 以重新绘制它。无意中按下按钮会触发此操作。

    因此,在模拟可以访问的某处创建对面板的引用,然后调用repaint() 方法,即myGridView.repaint()

    【讨论】:

    • 在一个模拟周期完成后,为什么要向面板发送信号以重新绘制()?
    猜你喜欢
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    相关资源
    最近更新 更多