2

所以,我正在尝试为大量按钮定义一组方法,我想我可以在 for 循环中完成它,但是我遇到了一个我无法破译的语法错误......这是一个我想使用的代码的简化版本......错误是:“令牌上的语法错误,错位的构造”

JMenu blocks = new JMenu("Block");
menuBar.add(blocks);

for (int i=0; i < 9; i++){
  public void action() {
      System.out.println(i+"");
  }
  JMenuItem blockName = new JMenuItem(i+"");
  blockName.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent arg0) {
          action();
      }
  });
  blocks.add(blockName);
}
4

7 回答 7

3

删除您的action方法并将您的代码放入 ActionListener

  public void actionPerformed(ActionEvent arg0) {
      System.out.println(i+"");
      // ... etc.
  }

正如其他人在他们的答案中提到的那样,i将无法从内部访问actionPerformed。具体来说,请参阅@dasblinkenlight 的答案以获得更彻底的回应。

于 2012-09-25T13:49:35.663 回答
2

您正在另一个方法中定义一个新方法:

  public void action() {
      System.out.println(i+"");
  }

您需要在当前方法之外提取它。

于 2012-09-25T13:49:35.867 回答
2

Java 方法不是第一类对象(或第二类或第三类对象;事实上,方法根本不是对象)。您需要将该方法移动到其中一个类中 - 您的顶级类或您定义的匿名内部类,如下所示:

for (int i=0; i < 9; i++) {
    // You cannot access i from methods of the anonymous inner class
    // because it is not final, but you can make a final copy
    final int iCopy = i;
    JMenuItem blockName = new JMenuItem(i+"");
    blockName.addActionListener(new ActionListener() {
        // It is OK to define additional methods here:
        public void action() {
            System.out.println(iCopy+"");
        }
        public void actionPerformed(ActionEvent arg0) {
            action();
        }
    });
    blocks.add(blockName);
}
于 2012-09-25T13:54:34.803 回答
1

你不能有一个方法声明 insede for 循环。循环必须在方法体中。

 private void init(JMenu blocks) {
   for (int i=0; i < 9; i++){

    JMenuItem blockName = new JMenuItem(i+"");
    blockName.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent arg0) {
              handleAction(arg0);
          }
      });
    blocks.add(blockName);
  }
}


   public void handleAction(ActionEvent event) {

       Object source = event.getSource(); 

       if(source instanceof JMenuItem) {
           JMenuItem item = (JMenuItem) source;
           System.out.println(item.getName());
       ) 
   }
于 2012-09-25T13:49:58.313 回答
1

那根本是无效Java的。Action考虑在你的 for 循环中创建一个实例并使用该操作来支持JMenuItem,例如

JMenu blocks = new JMenu("Block");
menuBar.add(blocks);

for (int i=0; i < 9; i++){
    Action action = new AbstractAction(){
      public void actionPerformed( ActionEvent e ){
        System.out.println( "Whatever but not i as that cannot be accessed" );
        System.out.println( "or you need to introduce a final variable" );
      }
    };  
    JMenuItem blockName = new JMenuItem(i+"");
    blockName.setAction( action );  
    blocks.add(blockName);
}
于 2012-09-25T13:51:16.087 回答
1

你也可以这样做

    for (int i = 0; i < 9; i++) {
        JMenuItem blockName = new JMenuItem(i + "");
        blockName.setAction(new MyAction(i));
        blocks.add(blockName);
    }
}

class MyAction extends AbstractAction {
    int param;

    public MyAction(int myParameter) {
        param = myParameter;
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println(String.valueOf(param));
    }
}
于 2012-09-25T16:50:47.970 回答
0

您可以定义嵌套方法,只是嵌套类 [内部类],或嵌套在方法中的类 [本地类]。

如果你想让你ActionListener知道i,你不能直接,否则你会偶然发现这样的错误:

局部变量 i 从内部类中访问;需要声明为final

所以你应该扩展你的JMenuItem,或者更好地设计你的应用程序,以便将 UI 与当前模型状态分离。

于 2012-09-25T13:58:38.370 回答