使用循环在一个 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 名称应以大写字母开头。了解这一点并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。