JLabels随机填写

时间:2016-05-23 00:47:29

标签: java swing

我有一个扩展JLabel的类叫做Cell:Inside Cell有两种方法,kill()revive()。当一个Cell恢复时,它会使用setBackground()更改其颜色。我有一个名为LifePanel的JPanel,其中包含这些Cell的矩阵。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;

public class LifeDriver {
    public static void main(String[] args) {
        System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
        SwingUtilities.invokeLater( new Runnable() {
           public void run()
           {
               JFrame frame = new JFrame("Life");
               frame.setSize(950, 800);
               frame.setLocationRelativeTo(null);
               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
               frame.setContentPane(new MainPanel(80, 100));
               frame.setVisible(true);
           }
        } );
    }
}

class MainPanel extends JPanel {
    private LifePanel p;
    private ControlPanel c;
    private JScrollPane pane;

    public MainPanel(int ro, int co) {
        setLayout(new BorderLayout());
        p = new LifePanel(ro, co);
        p.setPreferredSize(new Dimension(740, 740));
        pane = new JScrollPane(p);
        pane.setBorder(null);
        pane.setAutoscrolls(true);
        add(pane, BorderLayout.CENTER);
        c = new ControlPanel(p);
        add(c, BorderLayout.NORTH);
    }
}

class ControlPanel extends JPanel {
    private JButton random;
    private LifePanel lp;

    public ControlPanel(LifePanel p) {
        lp = p;
        random = new JButton("Random");
        random.addActionListener(new Listener());
        add(random);
    }

    private class Listener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            try {
                double prob = Double.parseDouble(JOptionPane
                        .showInputDialog("Percentage Probability?"));
                lp.randomize(prob);
            } catch (Exception f) {
            }
        }
    }
}

class LifePanel extends JPanel {
    private Cell[][] grid;
    private Timer t;
    private static int nR, nC;

    public LifePanel(int row, int column) {
        nR = row;
        nC = column;
        setLayout(new GridLayout(nR, nC, 1, 1));
        grid = new Cell[nR][nC];
        for (int r = 0; r < nR; r++)
            for (int c = 0; c < nC; c++) {
                grid[r][c] = new Cell();
                add(grid[r][c]);
            }
    }

    public void randomize(double percent) {
        for (int r = 0; r < nR; r++)
            for (int c = 0; c < nC; c++)
                if (Math.random() < percent / 100)
                    grid[r][c].revive();
                else
                    grid[r][c].kill(false);
    }
}

class Cell extends JLabel {
    private Color deadCellColor = new Color(245, 245, 245);

    public Cell() {
        this.setBackground(deadCellColor);
        this.setOpaque(true);
        this.setAlive(false);
    }

    public void kill(boolean removeCell) {
        this.setAlive(false);
    }

    public void revive() {
        this.setAlive(true);
    }

    public void setAlive(boolean arg) {
        if (arg) {
            this.changeColor();
        } else {
            this.setBackground(deadCellColor);
        }
    }

    private void changeColor() {
        setBackground(Color.RED);
    }
}

当我调用randomize时,它可以工作(随机设置每个JLabel的颜色),但不是我期望它的方式。每个标签的颜色不是一次只出现,而是以随机方式出现(类似于powerpoint中的溶解效果?)。颜色甚至不是逐列逐列显示,正如for循环可能建议的那样。它看起来完全随机,即使订单是预先确定的。关于它为什么这样做的任何想法?

1 个答案:

答案 0 :(得分:3)

要在更改单元格状态时避免更新,您只需更改父面板LifePanel的可见性即可。像这样:

public void randomize(double percent) {
    // No updates while we change state
    setVisible(false);
    for (int r = 0; r < nR; r++) {
        for (int c = 0; c < nC; c++) {
            if (Math.random() < percent / 100)
                grid[r][c].revive();
            else
                grid[r][c].kill(false);
        }
    }
    // Update now
    setVisible(true);
}

我怀疑无论是跟踪脏矩形(即需要在屏幕上重新绘制的东西)都没有按照预期的方式排序实际的重新绘制更新。这似乎是这种情况,因为在更新所有单元格之后要求重新绘制LifePanel似乎也可以按预期工作:

public void randomize(double percent) {
    for (int r = 0; r < nR; r++) {
        for (int c = 0; c < nC; c++) {
            if (Math.random() < percent / 100)
                grid[r][c].revive();
            else
                grid[r][c].kill(false);
        }
    }
    // Force redraw of whole panel
    this.repaint();
}