我使用Java制作了一个简单的扫雷游戏。我想让用户点击 单击炸弹以重置游戏时的空格键。我还提示用户在游戏开始之前选择棋盘的尺寸。我有一个5x5 10x10和20x20尺寸的电路板。
我在玩游戏时注意到,单击空格键时,20x20板是唯一会重置的板。因此,KeyListener
仅在组件集中时起作用。因此,我使用方法JFrame.getFocusOwner()
来查看哪个组件具有焦点。
我在每种尺寸下玩了3次游戏。单击5x5和10x10按钮并显示每个板时,焦点为空。当我在20x20板上执行相同的操作时,重点是JPanel或MinesweeperGame,这就是关键侦听器起作用的原因。谁能解释一下为什么20x20板的代码相同时5x5和10x10板为什么没有空焦点。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import static java.lang.System.*;
public class MinesweeperGame extends JPanel {
private MinesweeperCells cells;
private int mouseX,mouseY;
private int mouseButton;
private boolean isTitle=true;
private JButton fiveByFive;
private JButton tenByTen;
private JButton twentyByTwenty;
private JButton start;
private static JFrame frame;
public MinesweeperGame() {
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent event) {
mouseX=event.getX();
mouseY=event.getY();
mouseButton=event.getButton();
repaint();
}
});
addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent event) {
System.out.println(cells.getDead());
if(event.getKeyChar()==KeyEvent.VK_SPACE&&cells.getDead()) {
cells.createCells();
cells.isDead(false);
repaint();
}
}
});
setFocusable(true);
cells = new MinesweeperCells();
showTitle();
}
public Color getBackground() {
return new Color(196,206,211);
}
public Dimension getPreferredSize() {
return new Dimension(800,800);
}
public void paintComponent(Graphics window) {
super.paintComponent(window);
Graphics2D g2d = (Graphics2D)window;
System.out.println("JPanel: "+isFocusOwner());
out.println("5Button: "+fiveByFive.isFocusOwner());
out.println("10Button: "+tenByTen.isFocusOwner());
out.println("20Button: "+twentyByTwenty.isFocusOwner());
out.println("Button: "+start.isFocusOwner());
out.println(frame.getFocusOwner()+"\n");
if(isTitle) {
GradientPaint gradient = new GradientPaint(0,0,new Color(119,125,132),800,800,Color.WHITE);
g2d.setPaint(gradient);
window.fillRect(0,0,800,800);
} else {
if(mouseButton==MouseEvent.BUTTON1) {
cells.isRevealed(mouseX,mouseY);
} else if(mouseButton==MouseEvent.BUTTON3) {
cells.isFlag(mouseX,mouseY);
mouseButton=0;
}
mouseX=0;
mouseY=0;
cells.paintCells(window);
}
}
public void showTitle() {
setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
JLabel title = new JLabel("Minesweeper");
title.setFont(new Font("Lucida Grande",Font.PLAIN,100));
title.setForeground(Color.BLACK);
constraints.gridx=0;
constraints.gridy=0;
add(title,constraints);
start = new JButton("Start");
constraints.gridx=0;
constraints.gridy=2;
add(start,constraints);
fiveByFive = new JButton("5 x 5");
tenByTen = new JButton("10 x 10");
twentyByTwenty = new JButton("20 x 20");
ActionListener buttonAction = new ActionListener() {
public void actionPerformed(ActionEvent event) {
if(event.getSource()==start) {
remove(title);
remove(start);
constraints.gridx=0;
constraints.gridy=0;
add(fiveByFive,constraints);
constraints.gridx=0;
constraints.gridy=1;
add(tenByTen,constraints);
constraints.gridx=0;
constraints.gridy=2;
add(twentyByTwenty,constraints);
} else {
isTitle=false;
if(event.getSource()==fiveByFive) {
cells.setGridSize(5,5);
} else if(event.getSource()==tenByTen) {
cells.setGridSize(10,10);
} else if(event.getSource()==twentyByTwenty) {
cells.setGridSize(20,20);
}
remove(fiveByFive);
remove(tenByTen);
remove(twentyByTwenty);
}
revalidate();
repaint();
}
};
fiveByFive.addActionListener(buttonAction);
tenByTen.addActionListener(buttonAction);
twentyByTwenty.addActionListener(buttonAction);
start.addActionListener(buttonAction);
}
public static void createAndShowGUI() {
frame = new JFrame("Minesweeper");
frame.setLocation(300,0);
frame.setResizable(false);
frame.add(new MinesweeperGame());
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}