关于GridLayout和paintComponent方法的Java Swing问题

时间:2009-11-30 04:03:14

标签: java user-interface swing paintcomponent

在这个程序中,我们需要创建一个8x8网格的“LifeCell”小部件。教师没有提到小部件必须是Shape的对象所以我继续使用GridLayout类。 GridLayout类工作正常(以及我知道,因为没有可视化辅助来确认。)该程序的目标是玩生命游戏,用户可以点击其中一个LifeCell小部件和在“活着”或“死亡”之间切换。

我的问题很大程度上依赖于让细胞被涂上。这可能是我的代码的问题,但我不是100%肯定。

Program2.java

public class Program2 extends JPanel implements ActionListener {
private LifeCell[][] board; // Board of life cells.
private JButton next; // Press for next generation.
private JFrame frame; // The program frame.

public Program2() {
    // The usual boilerplate constructor that pastes the main
    // panel into a frame and displays the frame. It should
    // invoke the "init" method before packing the frame
    frame = new JFrame("LIFECELL!");
    frame.setContentPane(this);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.init();
    frame.pack();
    frame.setVisible(true);
}
    public void init() {
    // Create the user interface on the main panel. Construct
    // the LifeCell widgets, add them to the panel, and store
    // them in the two-dimensional array "board". Create the
    // "next" button that will show the next generation.
    LifeCell[][] board = new LifeCell[8][8];
    this.setPreferredSize(new Dimension(600, 600));
    this.setBackground(Color.white);
    this.setLayout(new GridLayout(8, 8));
    // here is where I initialize the LifeCell widgets
    for (int u = 0; u < 8; u++) {
        for (int r = 0; r < 8; r++) {
            board[u][r] = new LifeCell(board, u, r);
            this.add(board[u][r]);
            this.setVisible(true);

        }
    }

LifeCell.java

 public class LifeCell extends JPanel implements MouseListener {
   private LifeCell[][] board; // A reference to the board array.
   private boolean alive;      // Stores the state of the cell.
   private int row, col;       // Position of the cell on the board.
   private int count;          // Stores number of living neighbors.

   public LifeCell(LifeCell[][] b, int r, int c) {
       // Initialize the life cell as dead.  Store the reference
       // to the board array and the board position passed as
       // arguments.  Initialize the neighbor count to zero.
       // Register the cell as listener to its own mouse events.
       this.board = b;
       this.row = r;
       this.col = c;
       this.alive = false;
       this.count = 0;
       addMouseListener(this);
   }   

这是paintComponent方法:

   public void paintComponent(Graphics gr) {
       // Paint the cell.  The cell must be painted differently
       // when alive than when dead, so the user can clearly see
       // the state of the cell.
           Graphics2D g = (Graphics2D) gr;
           super.paintComponent(gr);
           g.setPaint(Color.BLUE);
   }

我不需要确切的解决方案来修复它,但我最终想要让它工作。

感谢。

编辑:

我添加了更多的Program2.java类,明天我可以回来看看我要去睡觉了,我很感谢所有的帮助。

编辑#2:

当我用8x8 GridLayout每个单独的“单元格”填充我的框架时,我真正的困惑是因为缺少更好的单词是LifeCell类型。如何绘制每种LifeCell种不同的颜色?如果这对你们有任何意义,我可以尝试尽可能地修改它。而且,我会看那个网站,谢谢你。

可以找到here分配,以避免对我的问题和/或代码段产生任何混淆。

3 个答案:

答案 0 :(得分:2)

JPanel没有默认的首选大小或可见内容。你需要添加一些可见的组件(例如JLabel)或给它一个首选的大小。

除此之外,如果你按照以下方式进行设置,你的布局应该有效:

JFrame frame = new JFrame();
Container cp = frame.getContentPane();
cp.setLayout(new GridLayout(8, 8));
for (int i = 0; i < 8; i++)
    for (int j = 0; j < 8; j++)
        cp.add(new JLabel(i + "-" + j));
frame.pack();
frame.setVisible(true);

答案 1 :(得分:1)

为什么你的LifeCell甚至有一个paintComponent()方法?没有必要做自定义绘画。您可以使用以下命令更改任何组件的背景颜色:

setBackground( Color.BLUE ) 

除此之外,你的问题对我没有意义。首先你声明你需要使用一个Shape对象,但我没有在你的代码中的任何地方看到一个Shape对象,那你为什么要提这个问题来混淆这个问题?

我真的不明白你的问题,我们没有足够的代码提供任何真实的建议。

如果您需要更多帮助,请发布显示问题的SSCCE

答案 2 :(得分:1)

alt text

你走在正确的轨道上。

如果你想使用一个现有的组件(比如JPanel,JLabel,JButton等),你可以更好地尊重组件已经做的事情,并且只需要参数化所需的内容。

因此,在您使用JPanel的情况下,此(以及其他JComponents)具有可以更改的background属性。因此,不要试图将组件绘制成你自己(这就是现在失败的组件),而只需设置该值并让油漆自己绘制。

您可以添加“getLifeColor”,它根据单元格状态返回不同的颜色:

   private Color getLifeColor() {
       return this.alive?liveColor:deadColor;
   } 

然后让细胞用这种颜色绘制背景:

  public void paintComponent(Graphics gr) {
       setBackground( getLifeColor() );
       super.paintComponent( gr );
  }

之后,您只需将单元格的状态设置为活动或死亡,组件将以相应的颜色显示:

alt text

Here's您发布的代码的简短自包含正确示例(SSCCE)+实时/死色使用情况。我想你可以从那里继续。