我有一个带回家的任务,我需要制作一个数独板,显示板上文件的整数,并允许有人点击JButton并输入缺失值。
我已经使用JPanel显示该板并将文本文件打印到各个按钮但我无法弄清楚如何让addActionListener获取任何缺少值的按钮。它仅适用于空白的最后一个按钮。 (空白按钮的值为0)。
我的问题是为什么最后一个空白按钮仅被定位。共有6个,但只有最后一个在点击后会弹出对话框?
public class MyCustomeFrame extends JFrame {
private int[][] numbers;
private String[] nums;
JButton b1;
JButton b2;
JButton b3;
JButton b4;
private JPanel p2;
public MyCustomeFrame() {
// Create the border layout
setLayout(new BorderLayout(5, 5));
// Create a new panel for the buttons to be placed on
JPanel p1 = new JPanel();
// Create 3 buttons
b1 = new JButton("Load");
b2 = new JButton("Save");
b3 = new JButton("Check");
// Adds the 3 buttons to the panel
p1.add(b1);
p1.add(b2);
p1.add(b3);
// Create the event handlers for when the button is pressed
b1.addActionListener(new MyButtonHandler());
b2.addActionListener(new MyButtonHandler());
b3.addActionListener(new MyButtonHandler());
// Place the panel south in the window
add(p1, BorderLayout.SOUTH);
p2 = new JPanel();
// Define the grid parameters
p2.setLayout(new GridLayout(9, 9, 5, 5));
// Show the grid
add(p2, BorderLayout.CENTER);
int[][] numbers = new int[9][9];
int rowIdx = 0;
//This is where i read the input file located on my computer and place the numbers on the Sudoku board
try {
BufferedReader bReader = new BufferedReader(new FileReader(
"C:\\Users\\Derek\\Desktop\\input.txt"));
String line = bReader.readLine();
while (line != null) {
nums = line.split(",");
for (int i = 0; i < numbers[0].length; i++) {
numbers[rowIdx][i] = Integer.parseInt(nums[i]);
// This creates the individual buttons that are then placed on the board
if (numbers[rowIdx][i] >= 1) {
p2.add(new JButton(nums[i]));
} else {
//this is where I'm having the issue
b4 = new JButton(" ");
p2.add(b4);
b4.addActionListener(new MyButtonHandler());
}
}
rowIdx++;
line = bReader.readLine();
}
bReader.close();
} catch (FileNotFoundException g) {
System.out.println("File Not Found!");
} catch (IOException g) {
System.out.println("Something went wrong...Try Again");
g.printStackTrace();
}
}
class MyButtonHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
System.out.println("Loading File...");
} else if (e.getSource() == b2) {
System.out.println("Saving File...");
try {
BufferedWriter bWriter = new BufferedWriter(new FileWriter(
new File("C:\\SudokuSave.txt"), true));
bWriter.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} else if (e.getSource() == b3) {
System.out.println("Checking Solution...");
} else if (e.getSource() == b4) {
System.out.println("clicked");
JOptionPane.showInputDialog("Input a number between 1 - 9");
}
}
}
}
答案 0 :(得分:2)
Vyacheslav在https://stackoverflow.com/a/21803753
中已经指出了问题的原因一些提示:
您应该使用适当的变量名称。调用JButton b2
非常糟糕。如果是“加载”按钮,则将其命名为loadButton
。如果是“保存”按钮,请将其命名为saveButton
。代码(最多)写入一次,但可能读取数百次。在最好的情况下,Java代码应该像散文一样阅读。
在构造函数中读取带有硬编码名称的文件,以构建GUI组件,这是一种非常糟糕的做法。您应该考虑创建一些“数据模型”,其中包含可以创建GUI的信息,并分割
的过程。这也可以让您比打印更好地处理例外
System.out.println("Something went wrong...Try Again");
为了解决您的问题,您可以考虑使用匿名侦听器。创建一个负责所有按钮的ActionListener
不是很灵活。通常,您只想将按钮上的单击与对单个(私有)方法的单个调用相关联。例如,您可以编写
JButton saveButton = new JButton("Save");
saveButton.addActionListener(new ActionListener() {
{
@Override
public void actionPerformed(ActionEvent) {
saveButtonWasPressed();
}
});
特别是对于具有类似功能的多个按钮的情况,此方法提供了一个优势:您可以为每个按钮创建匿名侦听器,每个按钮包含有关的所需信息单击按钮 - 大致应用于您的代码:
if (numbers[rowIdx][i] == 0) {
JButton b = new JButton(" ");
panel.add(b);
b.addActionListener(createActionListener(rowIdx, i));
}
...
private ActionListener createActionListener(
final int row, final int column) {
ActionListener actionListener = new ActionListener() {
{
@Override
public void actionPerformed(ActionEvent) {
System.out.println("Pressed button in row "+row+", column "+column);
}
};
return actionListener;
}
答案 1 :(得分:1)
您的错误很简单 - for
的每次迭代都会为JButton
变量分配一个新的b4
对象引用,所以最后b4
指的是最后JButton
你创造了。