Java-将JButton数组添加到JFrame

Java-将JButton数组添加到JFrame,java,arrays,swing,jbutton,Java,Arrays,Swing,Jbutton,我正在尝试将2D JButton数组添加到JFrame,我没有得到任何错误,只是JButton没有显示 创建JButtons: public class TTTGrid { private static JFrame frame; private static int[][] coords; private static int width, height; public TTTGrid(JFrame frame,int[][] coords, int width, int height){

我正在尝试将2D JButton数组添加到JFrame,我没有得到任何错误,只是JButton没有显示

创建JButtons:

public class TTTGrid {
private static JFrame frame;
private static int[][] coords;
private static int width, height;
public TTTGrid(JFrame frame,int[][] coords, int width, int height){
    this.frame = frame;
    this.coords = coords;
    this.width = width;
    this.height = height;
}
static JButton map[][] = new JButton[3][3];

public void Draw(){
    for(int i = 0; i<coords.length; i++){
        for(int j = 0; j<coords[i].length; j++){
            map[i][j] = new JButton();
            map[i][j].setBounds(i*100, j*100, width, height);
            frame.add(map[i][j]);

        }
    }
}

}

如果您的代码像我认为的那样运行,那么您似乎试图每秒50次向GUI添加9个JButton!按钮太多了--你确定这就是你想要做的吗?您的代码还通过在Swing事件线程之外进行Swing调用(大量Swing调用!)而与Swing线程规则相悖

您的主要解决方案可能是

  • 将9个JButton添加到使用
    GridLayout(3,3)
  • 只做一次,而不是每秒50次
  • 然后将该JPanel添加到GUI BorderLayout.CENTER中,并确保不使用
    null
    layouts
  • 不要试图设置这些jbutton的边界、大小或位置,而是让布局管理器开始工作
  • 摆脱while循环,改为使用Swing的事件驱动模型将代码更改为更多的事件驱动
  • 尽量使用非静态变量和方法,使您的类成为真正的OOPS兼容类,使它们能够利用OOPS编程的好处,包括降低程序复杂性和互连性(减少耦合)

比如说

import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;

public class MyTttFoo extends JPanel {
   // it's OK for constants to be static
   private static final long serialVersionUID = 1L;
   private static final int ROWS = 3;

   // use a larger Font to make buttons larger
   private static final Font BTN_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 60);
   private static final String BLANK = "   ";
   private static final String X = "X";
   private static final String O = "O";

   // but not most variables
   private JButton[][] buttonGrid = new JButton[ROWS][ROWS];

   public MyTttFoo() {
      setBackground(Color.black);

      // use layout managers to help you create your GUI
      setLayout(new GridLayout(ROWS, ROWS, 1, 1));
      ActionListener btnListener = new ButtonListener();
      // create your buttons and add them only **once**
      for (int row = 0; row < buttonGrid.length; row++) {
         for (int col = 0; col < buttonGrid[row].length; col++) {
            JButton button = new JButton(BLANK);
            button.setFont(BTN_FONT);
            button.addActionListener(btnListener);
            add(button);  // add button to a gridlayout using component
            buttonGrid[row][col] = button; // and assign into the array
         }
      }
   }

   private class ButtonListener implements ActionListener {
      private boolean xTurn = true;

      @Override
      public void actionPerformed(ActionEvent e) {
         AbstractButton btn = (AbstractButton) e.getSource();
         String txt = btn.getText();
         if (txt.equals(BLANK)) {
            if (xTurn) {
               btn.setText(X);
            } else {
               btn.setText(O);               
            }
            xTurn = !xTurn;
         } 
      }
   }

   private static void createAndShowGui() {
      MyTttFoo mainPanel = new MyTttFoo();

      JFrame frame = new JFrame("MyTttFoo");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
导入java.awt.Color;
导入java.awt.Font;
导入java.awt.GridLayout;
导入java.awt.event.*;
导入javax.swing.*;
公共类MyTttFoo扩展了JPanel{
//常数可以是静态的
私有静态最终长serialVersionUID=1L;
私有静态最终整数行=3;
//使用较大字体使按钮变大
私有静态最终字体BTN_Font=新字体(Font.SANS_SERIF,Font.BOLD,60);
私有静态最终字符串BLANK=“”;
私有静态最终字符串X=“X”;
私有静态最终字符串O=“O”;
//但不是大多数变量
私有JButton[][]buttonGrid=新JButton[行][行];
公共MyTttFoo(){
挫折背景(颜色:黑色);
//使用布局管理器帮助您创建GUI
setLayout(新的GridLayout(行,行,1,1));
ActionListener btnListener=新建按钮Listener();
//创建按钮并仅添加**一次**
对于(int row=0;row
如果您的代码像我认为的那样运行,那么您似乎试图每秒50次向GUI添加9个JButton!按钮太多了--你确定这就是你想要做的吗?您的代码还通过在Swing事件线程之外进行Swing调用(大量Swing调用!)而与Swing线程规则相悖

您的主要解决方案可能是

  • 将9个JButton添加到使用
    GridLayout(3,3)
  • 只做一次,而不是每秒50次
  • 然后将该JPanel添加到GUI BorderLayout.CENTER中,并确保不使用
    null
    layouts
  • 不要试图设置这些jbutton的边界、大小或位置,而是让布局管理器开始工作
  • 摆脱while循环,改为使用Swing的事件驱动模型将代码更改为更多的事件驱动
  • 尽量使用非静态变量和方法,使您的类成为真正的OOPS兼容类,使它们能够利用OOPS编程的好处,包括降低程序复杂性和互连性(减少耦合)

比如说

import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;

public class MyTttFoo extends JPanel {
   // it's OK for constants to be static
   private static final long serialVersionUID = 1L;
   private static final int ROWS = 3;

   // use a larger Font to make buttons larger
   private static final Font BTN_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 60);
   private static final String BLANK = "   ";
   private static final String X = "X";
   private static final String O = "O";

   // but not most variables
   private JButton[][] buttonGrid = new JButton[ROWS][ROWS];

   public MyTttFoo() {
      setBackground(Color.black);

      // use layout managers to help you create your GUI
      setLayout(new GridLayout(ROWS, ROWS, 1, 1));
      ActionListener btnListener = new ButtonListener();
      // create your buttons and add them only **once**
      for (int row = 0; row < buttonGrid.length; row++) {
         for (int col = 0; col < buttonGrid[row].length; col++) {
            JButton button = new JButton(BLANK);
            button.setFont(BTN_FONT);
            button.addActionListener(btnListener);
            add(button);  // add button to a gridlayout using component
            buttonGrid[row][col] = button; // and assign into the array
         }
      }
   }

   private class ButtonListener implements ActionListener {
      private boolean xTurn = true;

      @Override
      public void actionPerformed(ActionEvent e) {
         AbstractButton btn = (AbstractButton) e.getSource();
         String txt = btn.getText();
         if (txt.equals(BLANK)) {
            if (xTurn) {
               btn.setText(X);
            } else {
               btn.setText(O);               
            }
            xTurn = !xTurn;
         } 
      }
   }

   private static void createAndShowGui() {
      MyTttFoo mainPanel = new MyTttFoo();

      JFrame frame = new JFrame("MyTttFoo");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
导入java.awt.Color;
导入java.awt.Font;
导入java.awt.GridLayout;
导入java.awt.event.*;
导入javax.swing.*;
公共类MyTttFoo扩展了JPanel{
//常数可以是静态的
私有静态最终长serialVersionUID=1L;
私有静态最终整数行=3;
//使用较大字体使按钮变大
私有静态最终字体BTN_Font=新字体(Font.SANS_SERIF,Font.BOLD,60);
私有静态最终字符串BLANK=“”;
私有静态最终字符串X=“X”;
私有静态最终字符串O=“O”;
//但不是大多数变量
私有JButton[][]buttonGrid=新JButton[行][行];
公共MyTttFoo(){
挫折背景(颜色:黑色);
//使用布局管理器帮助您创建GUI
setLayout(新的GridLayout(行,行,1,1));
ActionListener btnListener=新建按钮Listener();
//创建按钮并仅添加**一次**
对于(int row=0;row