使用循环在一个 class 中为另一个 class 的多个实例中的按钮添加 ActiveListeners
Using a Loop to add ActiveListeners in one class for a button in multiple instances of another class
我有一个名为 InstructionBlock
的 class,它是一个 JPanel
在我的主窗体(一个 JFrame)上,我创建了 InstructionBlock
的 6 个实例。我需要让我的主窗体根据 InstructionBlock
实例中按下的按钮做一些事情,它需要知道哪些实例按下了按钮。
我在 class InstructionBlock
中有以下代码:
public void InstBlockAddActionListener(ActionListener al) {
CheckMarkClicked.addActionListener(al);
}
我已将 InstructionBlock
的实例添加到我的主窗体中,如下所示:
ArrayList<InstructionBlock> instructionPane = new ArrayList<>();
int i;
for (int i = 0; i<6;i++) {
instructionPane.add(new InstructionBlock());
InstructionLayer.add(instructionPane.get(i));
}
现在我遇到了一个问题:
for (i = 0; i<6;i++) {
instructionPane.get(i).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(i+1);});
}
当我按下第一个按钮时,我希望传递值 1,但我传递的值是 7
我知道我可以这样做:
instructionPane.get(0).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(1);});
instructionPane.get(1).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(2);});
instructionPane.get(2).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(3);});
instructionPane.get(3).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(4);});
instructionPane.get(4).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(5);});
instructionPane.get(5).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(6);});
但我不知道为什么循环不起作用。还有其他方法可以让它发挥作用吗?
您的问题在这里:
for (i = 0; i<6;i++) {
instructionPane.get(i).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(i+1);});
}
您必须使 i
成为 class 的一个字段才能编译,并且通过这样做,您将其设置为 7,并且在此 for 循环完成后仅设置为 7。要解决这个问题,不要使用 class 字段,而是使用内部最终变量,例如:
for (int j = 0; j < 6; j++) {
final int finalIndex = j + 1;
instructionPane.get(j).InstBlockAddActionListener((ActionEvent ae) -> {
InstructionCheckMarkButtonPressed(finalIndex);
});
}
作为附带建议,为了现在帮助我们和将来帮助您自己,请编辑您的代码并更改您的变量名称以符合 Java Java naming conventions。变量名称应全部以小写字母开头,而 class 名称应以大写字母开头。了解这一点并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。
我有一个名为 InstructionBlock
的 class,它是一个 JPanel
在我的主窗体(一个 JFrame)上,我创建了 InstructionBlock
的 6 个实例。我需要让我的主窗体根据 InstructionBlock
实例中按下的按钮做一些事情,它需要知道哪些实例按下了按钮。
我在 class InstructionBlock
中有以下代码:
public void InstBlockAddActionListener(ActionListener al) {
CheckMarkClicked.addActionListener(al);
}
我已将 InstructionBlock
的实例添加到我的主窗体中,如下所示:
ArrayList<InstructionBlock> instructionPane = new ArrayList<>();
int i;
for (int i = 0; i<6;i++) {
instructionPane.add(new InstructionBlock());
InstructionLayer.add(instructionPane.get(i));
}
现在我遇到了一个问题:
for (i = 0; i<6;i++) {
instructionPane.get(i).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(i+1);});
}
当我按下第一个按钮时,我希望传递值 1,但我传递的值是 7
我知道我可以这样做:
instructionPane.get(0).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(1);});
instructionPane.get(1).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(2);});
instructionPane.get(2).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(3);});
instructionPane.get(3).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(4);});
instructionPane.get(4).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(5);});
instructionPane.get(5).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(6);});
但我不知道为什么循环不起作用。还有其他方法可以让它发挥作用吗?
您的问题在这里:
for (i = 0; i<6;i++) {
instructionPane.get(i).InstBlockAddActionListener((ActionEvent ae) -> {InstructionCheckMarkButtonPressed(i+1);});
}
您必须使 i
成为 class 的一个字段才能编译,并且通过这样做,您将其设置为 7,并且在此 for 循环完成后仅设置为 7。要解决这个问题,不要使用 class 字段,而是使用内部最终变量,例如:
for (int j = 0; j < 6; j++) {
final int finalIndex = j + 1;
instructionPane.get(j).InstBlockAddActionListener((ActionEvent ae) -> {
InstructionCheckMarkButtonPressed(finalIndex);
});
}
作为附带建议,为了现在帮助我们和将来帮助您自己,请编辑您的代码并更改您的变量名称以符合 Java Java naming conventions。变量名称应全部以小写字母开头,而 class 名称应以大写字母开头。了解这一点并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。