Java - 将 JButton 数组添加到 JFrame
Java - adding JButton array to JFrame
我正在尝试将 2D JButton 数组添加到 JFrame,我没有收到任何错误,只是 JButton 没有显示。
创建 JButton:
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]);
}
}
}
}
draw方法调用的地方:
public class TTTthread extends TTT implements Runnable {
int[][] map = new int[3][3];
TTTGrid grid = new TTTGrid(frame, map, 100, 100);
@Override
public void run() {
try {
while (true) {
grid.Draw();
Thread.sleep(20);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果您的代码是 运行,就像我认为的那样 运行,您似乎正试图以每秒 50 次的速度向 GUI 添加 9 个 JButton!按钮太多了——你确定这是你想要做的吗?通过在 Swing 事件线程之外进行 Swing 调用(很多 次 Swing 调用!),您的代码也与 Swing 线程规则相冲突。
您的主要解决方案很可能
- 将您的 9 个 JButton 添加到使用
GridLayout(3, 3)
的 JPanel
- 仅一次而不是每秒 50 次
- 然后将该 JPanel 添加到您的 GUI,BorderLayout.CENTER 并确保不要使用
null
布局。
- 不要尝试设置这些 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();
}
});
}
}
我正在尝试将 2D JButton 数组添加到 JFrame,我没有收到任何错误,只是 JButton 没有显示。
创建 JButton:
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]);
}
}
}
}
draw方法调用的地方:
public class TTTthread extends TTT implements Runnable {
int[][] map = new int[3][3];
TTTGrid grid = new TTTGrid(frame, map, 100, 100);
@Override
public void run() {
try {
while (true) {
grid.Draw();
Thread.sleep(20);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果您的代码是 运行,就像我认为的那样 运行,您似乎正试图以每秒 50 次的速度向 GUI 添加 9 个 JButton!按钮太多了——你确定这是你想要做的吗?通过在 Swing 事件线程之外进行 Swing 调用(很多 次 Swing 调用!),您的代码也与 Swing 线程规则相冲突。
您的主要解决方案很可能
- 将您的 9 个 JButton 添加到使用
GridLayout(3, 3)
的 JPanel
- 仅一次而不是每秒 50 次
- 然后将该 JPanel 添加到您的 GUI,BorderLayout.CENTER 并确保不要使用
null
布局。 - 不要尝试设置这些 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();
}
});
}
}