无法将组件添加到扩展JFrame的类中

问题描述:

我正在尝试编写生命游戏。但是,无论我多么努力地尝试,我似乎无法使用按钮将Cell组件添加到框架上。如果我创建一个新框架并添加它们,它们确实会出现,但即便如此,我似乎也无法添加多个组件。无法将组件添加到扩展JFrame的类中

因此,我如何将组件添加到框架上,以及如何添加多个组件? 谢谢!

这里是我的代码:

import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 

public class Visuals extends JFrame implements ActionListener{ 

    private static Board b; 
    private GameOfLife g; 
    private JButton nextGen; 
    private JButton random; 

    public Visuals(Board b){ 
     super("The Game of Life"); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


     JPanel panel=new JPanel(); 
     nextGen = new JButton("Next Generation"); 
     panel.add(nextGen); 
     nextGen.addActionListener(this); 

     random = new JButton("Random"); 
     panel.add(random); 
     random.addActionListener(this); 
     this.add(panel); 

     this.setSize(800, 700); 
     this.setVisible(true); 


     /*for(int i=0, yShift=80; i<b.getRow(); i++, yShift+=20){ 
      for (int j=0, xShift=30; j<b.getCol(); j++, xShift+=20){ 
       Cell c= new Cell(xShift,yShift,i,j); 
       this.add(c); 
      } 
     }*/ 
     Cell c= new Cell(100,100,1,1); 
     Cell d= new Cell(200,200,1,1); 
     this.add(c); 
     this.add(d); 

     JFrame frame=new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(800, 700); 
     frame.setVisible(true); 

     frame.add(c); 
     frame.add(d); 

    } 

    public void paint(Graphics g){ 
     super.paint(g); 
     for(int i=0, yShift=80; i<b.getRow(); i++, yShift+=20){ 
      for (int j=0, xShift=30; j<b.getCol(); j++, xShift+=20){  
       if(b.getSpot(i, j)==1){ 
        g.setColor(Color.red); 
        g.fillRect(xShift, yShift, 10, 10); 
       } 
       else{ 
        g.setColor(Color.white); 
        g.fillRect(xShift, yShift, 10, 10); 
       } 
      } 
     } 
    } 

    public static void main(String[] cnbe){ 
     b= new Board (30,30); 
     Visuals v = new Visuals(b); 
    } 

    public void actionPerformed(ActionEvent event) { 
     Object cause = event.getSource(); 
     if(cause == nextGen){ 
      GameOfLife g=new GameOfLife(b); 
      g.nextGeneration(); 
      System.out.println(g); 
      this.repaint(); 
     } 
     if(cause == random){ 
      GameOfLife g=new GameOfLife(b); 
      g.random(); 
      System.out.println(g); 
      this.repaint(); 
     } 
    } 

    public class Cell extends JComponent{ 
     int row; 
     int col; 
     int x; 
     int y; 
     Rectangle r; 

     public Cell(int x, int y, int row, int col){ 
      r= new Rectangle(x,y,10,10); 
       this.row=row; 
       this.col=col; 
       this.x=x; 
       this.y=y; 

     } 


     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      g.drawString("DRAW ME",200,200); 
      Graphics2D g2= (Graphics2D) g; 
      g2.setColor(Color.green); 
      r= new Rectangle(x,y,100,100); 
      g2.fill(r); 

      /*if(b.getSpot(row, col)==1){ 

       g.setColor(Color.red); 
       g.fillRect(x, y, 10, 10); 
      } 
      else{ 

       g.setColor(Color.white); 
       g.fillRect(x, y, 10, 10); 
      }*/ 
     } 

     class MousePressListener implements MouseListener{ 

      public void mousePressed(MouseEvent event) { 
       /*int x= event.getX(); 
       int y= event.getY(); 
       if(x>r.getX() && x<r.getX()+10 && y>r.getY() && y<r.getY()+10){ 
        if(b.getSpot(row, col)==1){ 
         b.setSpot(row, col, 0); 
         repaint(); 
        } 
        else{ 
         b.setSpot(row, col, 1); 
         repaint(); 
        } 
       }*/ 
      } 

      public void mouseReleased(MouseEvent arg0) { 
      } 
      public void mouseClicked(MouseEvent arg0) { 
      } 
      public void mouseEntered(MouseEvent arg0) { 
      } 
      public void mouseExited(MouseEvent arg0) { 
      } 

     } 


    } 

} 
+3

您与帧布局管理器发生冲突。默认情况下,一个'JFrame'将使用'BorderLayout',每次你添加一个新的组件到框架时,它将取代你之前添加的任何东西(到中心位置)。查看[布局管理器视觉指南](http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html)和[使用布局管理器](http://docs.oracle.com)。 COM/JavaSE的/教程/ uiswing /布局/ using.html)。 – MadProgrammer

+0

此外,组件只能属于一个容器,因此当您将单元格添加到第一个框架,然后将其添加到第二个框架时,它们将从第一个框架开始移除 – MadProgrammer

+2

为什么此代码使用多个框架?看看[使用多个JFrames,好/坏实践?](http://stackoverflow.com/a/9554657/418556) –

您使用布局管理器的一个问题。每次向JFrame添加组件时,都会覆盖已有的组件。我对生命游戏不太熟悉,但我不认为你希望你的细胞成为JComponents。您可以代表您的主板以布尔数组,代表着活着和死的状态,这样你的视觉构造变为:

public Visuals(Board b) { 
    super("The Game of Life"); 
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    Container container = getContentPane(); // 1 
    JPanel panel = new JPanel(new FlowLayout()); // 2 
    nextGen = new JButton("Next Generation"); 
    panel.add(nextGen); 
    nextGen.addActionListener(this); 

    random = new JButton("Random"); 
    panel.add(random); 
    random.addActionListener(this); 
    container.add(panel); // 3 

    setSize(800, 700); 
    setVisible(true); 

} 

在你的主板类,你将代表董事会作为数组:

public class Board{ 
    private boolean[][] board; 

    public Board(int x, int y) { 

     board = new boolean[x][y]; 
    } 
} 

然后在GameOfLife类的nextGeneration方法中,执行您正在执行的任何计算并设置板上位置的真/假(或活/死)状态。

你Visuals.paint方法就变成这样的:

public void paint(Graphics g) { 
    super.paint(g); 
    for (int i = 0, yShift = 80; i < b.getRow(); i++, yShift += 20) { 
     for (int j = 0, xShift = 30; j < b.getCol(); j++, xShift += 20) { 
      if (b.isAlive(i, j)) { 
       g.setColor(Color.red); 
       g.fillRect(xShift, yShift, 10, 10); 
      } else { 
       g.setColor(Color.white); 
       g.fillRect(xShift, yShift, 10, 10); 
      } 
     } 
    } 
} 

iaAlive在该位置刚好返回板阵列的价值:

public boolean isAlive(int i, int j) { 
    return board[i][j]; 
} 

但是就像我说的,我不熟悉游戏。

+0

谢谢大家,我用GridLayout解决了我的问题,所以我甚至不必担心关于我的组件的x和y。顺便说一句罗伯特,我用JComponents来为它们添加鼠标监听器。 – user1874103