如何在 Java JFrame 中制作一堆可点击的面板
How to make a bunch of clickable panels in Java JFrame
我正在尝试使用 JFrame 在 Java 中重新创建生命游戏。我已经完成了大部分程序,但有一件事让我很烦恼。如何制作一堆可点击的字段(面板),以便用户可以输入自己的模式,而不是计算机每次随机生成模式?
您可以使用 GridLayout 布局管理器将所有 JPanel 放在一个网格中,并为每个 JPanel 添加 MouseAdapter 实例 class 和 addMouseListener() 以监听鼠标点击以翻转它们的状态. MouseAdapter 的实例将覆盖 mouseClicked() 并在该函数内翻转 JPanel 的状态。
这只是为了制作一个完整的示例,但这里将创建框架并设置其布局管理器:
public static void main(String[] args) {
JFrame frame = new JFrame();
int width = 200, height = 200;
frame.setSize(width, height);
int rows = width/10, cols = height/10;
frame.setLayout(new GridLayout(rows, cols));
// add all the cells
for(int j = 0; j < cols; j++) {
for(int i = 0; i < rows; i++) {
frame.add(new Cell(i, j));
}
}
frame.setVisible(true);
}
然后对于每个单元格,我们都有这样的实例 class:
class Cell extends JPanel {
int row, col;
public static final int STATE_DEAD = 0;
public static final int STATE_ALIVE = 1;
int state = STATE_DEAD;
public Cell(int row, int col) {
this.row = row;
this.col = col;
// MouseAdapter tells a component how it should react to mouse events
MouseAdapter mouseAdapter = new MouseAdapter() {
// using mouseReleased because moving the mouse slightly
// while clicking will register as a drag instead of a click
@Override
public void mouseReleased(MouseEvent e) {
flip();
repaint(); // redraw the JPanel to reflect new state
}
};
// assign that behavior to this JPanel for mouse button events
addMouseListener(mouseAdapter);
}
// Override this method to change drawing behavior to reflect state
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// fill the cell with black if it is dead
if(state == STATE_DEAD) {
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
public void flip() {
if(state == STATE_DEAD) {
state = STATE_ALIVE;
} else {
state = STATE_DEAD;
}
}
}
或者,您可以重写一个 JPanel 的 paintComponent() 方法,并执行上述操作但同时使用 addMouseMotionListener(),这样您的一个面板就可以跟踪鼠标所在的绘制网格单元格,并且您可以控制它们的绘制方式。
我正在尝试使用 JFrame 在 Java 中重新创建生命游戏。我已经完成了大部分程序,但有一件事让我很烦恼。如何制作一堆可点击的字段(面板),以便用户可以输入自己的模式,而不是计算机每次随机生成模式?
您可以使用 GridLayout 布局管理器将所有 JPanel 放在一个网格中,并为每个 JPanel 添加 MouseAdapter 实例 class 和 addMouseListener() 以监听鼠标点击以翻转它们的状态. MouseAdapter 的实例将覆盖 mouseClicked() 并在该函数内翻转 JPanel 的状态。
这只是为了制作一个完整的示例,但这里将创建框架并设置其布局管理器:
public static void main(String[] args) {
JFrame frame = new JFrame();
int width = 200, height = 200;
frame.setSize(width, height);
int rows = width/10, cols = height/10;
frame.setLayout(new GridLayout(rows, cols));
// add all the cells
for(int j = 0; j < cols; j++) {
for(int i = 0; i < rows; i++) {
frame.add(new Cell(i, j));
}
}
frame.setVisible(true);
}
然后对于每个单元格,我们都有这样的实例 class:
class Cell extends JPanel {
int row, col;
public static final int STATE_DEAD = 0;
public static final int STATE_ALIVE = 1;
int state = STATE_DEAD;
public Cell(int row, int col) {
this.row = row;
this.col = col;
// MouseAdapter tells a component how it should react to mouse events
MouseAdapter mouseAdapter = new MouseAdapter() {
// using mouseReleased because moving the mouse slightly
// while clicking will register as a drag instead of a click
@Override
public void mouseReleased(MouseEvent e) {
flip();
repaint(); // redraw the JPanel to reflect new state
}
};
// assign that behavior to this JPanel for mouse button events
addMouseListener(mouseAdapter);
}
// Override this method to change drawing behavior to reflect state
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// fill the cell with black if it is dead
if(state == STATE_DEAD) {
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
public void flip() {
if(state == STATE_DEAD) {
state = STATE_ALIVE;
} else {
state = STATE_DEAD;
}
}
}
或者,您可以重写一个 JPanel 的 paintComponent() 方法,并执行上述操作但同时使用 addMouseMotionListener(),这样您的一个面板就可以跟踪鼠标所在的绘制网格单元格,并且您可以控制它们的绘制方式。