【问题标题】:Having trouble making the JPanels inside Jgrid react to change immediately无法让 Jgrid 中的 JPanel 立即对更改做出反应
【发布时间】:2020-08-01 01:30:29
【问题描述】:

我目前正在尝试使用 Swing 在 Java 中编写 John Conway 的人生游戏。然而,我在GridLayout 中遇到了关于JPanel 单元格的问题。这是有问题的代码

    GameOfLifeFrame(int size, int generations, Random random, boolean[][] grid, final GameOfLife life) {
    super("Game of life");
    this.size = size;
    this.generations = generations;
    this.random = random;
    this.grid = grid;
    this.life = life;
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(300, 300);
    var contentPane = getContentPane();
    contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
    JLabel generationMaker = new JLabel("Generation: ");
    add(generationMaker);
    JLabel alive = new JLabel("Alive: 0");
    add(alive);

    var gridPanel = new JPanel();
    gridPanel.setLayout(new GridLayout(size, size, 0, 0));
    contentPane.add(gridPanel);
    var cellArray = new javax.swing.JPanel[size][size];
    for (var i = 0; i < size; i++) {
        for (var j = 0; j < size; j++) {
            var cell = new JPanel();
            cellArray[i][j] = cell;
            cell.setBorder(BorderFactory.createLineBorder(Color.BLACK));
            gridPanel.add(cell);
        }
    }
    contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
    var button = new JButton();
    button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            generateGrid(cellArray);
            alive.setText("Alive: " + countAlive(life.grid));
            incrementGeneration();
            generationMaker.setText("Generation #" + generationCounter);
        }
    });
    contentPane.add(button);
    setVisible(true);
}

private void generateGrid(JPanel[][] cellArray) {
    var grid2 = getGrid();
    fillInPanels(cellArray, grid2);
    life.grid = grid2;
}

protected void fillInPanels(javax.swing.JPanel[][] panelArray, boolean[][] grid) {
    for (var i = 0; i < size; i++) {
        for (var j = 0; j < size; j++) {
            if (grid[i][j]) {
                panelArray[i][j].setBackground(Color.BLACK);
            } else {
                panelArray[i][j].setBackground(Color.WHITE);
            }
        }
    }
}

它运行良好,是康威生命游戏的一个很好的模拟器,但它有一个奇怪的效果,整个屏幕不会立即改变,但你可以看到单个单元格发生变化,而不是立即改变,就在我按下按钮的时候。这是因为双缓冲吗?当屏幕上存活的细胞较少时,它会更好地工作,这就是它实际上开始快速运行的时候。

Here is how it is like on a 35 by 35 size grid

问题的根源是什么,我该如何解决?如果我的问题或帖子格式不佳,请原谅我,这是我第一次在这里发帖。

【问题讨论】:

  • 为了获得更好的帮助,请尽快发布正确的minimal reproducible example 来证明您的问题。可能你正在做一些自定义绘画并且在paintComponent 中有一些东西暂停你的程序。但是here 是我前几次做的 GoL MRE 的一个例子。您可以将其与您当前的程序进行比较或发布请求的 MRE,以便我们对其进行测试并查看问题所在
  • 我对我的程序进行了更多编辑,结果发现问题是每次我更改一个单元格时,在这种情况下是黑色到白色,反之亦然,整个电路板都会重新绘制。我只是在fillInPanels 处于活动状态时将setVisible 设置为false,并在完成后返回true。我想现在我应该回答我自己的问题,对吗?
  • 你可以这样做或完全删除问题,这取决于你:)

标签: java swing conways-game-of-life


【解决方案1】:

问题的原因是每次我将瓷砖的油漆颜色从黑色更改为白色或反之亦然时,都会重新绘制网格。在执行fillInPanels 时将setVisible 设置为false,然后将其设置回true 即可解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 2021-08-22
    • 1970-01-01
    相关资源
    最近更新 更多