重新绘制仅在我单击按钮时工作

时间:2014-01-28 22:59:29

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

您好我已经为模拟实现了一个MVC,并且当我遍历一组代理并更新它们在2D数组中的位置时,我正在使用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();
                }
            }
        }

    }
}

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

Swing对象通常会尽可能少地做,除非他们的组件或你告诉他们,并期望从那时起的合作会导致心痛。