0

我早些时候以更大的形式发布了这个问题,并希望以一种允许社区更好地帮助我的方式再次发布它,减少关于你们所有人的信息。

从根本上说,我有这段代码,解释如下:

for(JMenuItem x : chem3_x_y){
  x.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent k) {
      new SwingImplementation(1, tt+1);
    }
  }); 
  gEleven[6].add(x);
  tt++;
}
tt=0;

首先,我循环遍历数组 chem3_x_y 中的所有 JMenuItem-s

然后,我将 ActionListener 添加到“x”或数组的每个项目,它创建一个新的 SwingImplementation,其参数为 1,变量“tt”

在此之后,JMenu gEleven收到有问题的 JMenuItem,然后我将 tt 增加 1。

上述代码的目的是自动化将 JMenuItems 添加到 gEleven 并将 ActionListeners 添加到每个 Menu Item 的过程。

问题是,为变量 'tt' 传递的参数始终相同,为 1,就好像将 'tt' 参数为 1 的动作侦听器应用于每个 JMenuItem - 为什么会这样,以及如何使用不断增加的tt为每个JMenuItem创建一个 ActionListener ,参数为 (1, tt) 而 tt 始终为 1

4

2 回答 2

3

您的问题是tt直到调用侦听器才增加。虽然您的动作侦听器代码是内联的,但实际上,它并非全部同步运行 -actionPerformed()在调用动作侦听器之前不会被调用。所以tt在你循环的时候永远不要改变。

你想要的是这样的:

class MyListener implements ActionListener {
  private final int tt;

  MyListener (int tt) { 
    this.tt = tt;
  }

  public void actionPerformed(ActionEvent k) {
     new SwingImplementation(1, tt+1);
  }
}

for(JMenuItem x : chem3_x_y){
  x.addActionListener(new MyListener(tt++)); 
  gEleven[6].add(x);
}

这样您就可以递增 tt 并将结果存储在final与需要该值的侦听器相关的字段中。

于 2013-10-28T02:10:05.493 回答
2

编辑:您可能的意思不是tt + 1tt++,而是。我无法从发布的代码中看出。也许,寻找一个tt隐藏预期变量的变量。基于此示例,下面的相应代码使用++i. 还可以考虑使用Action来封装您的侦听器。

图片

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.io.File;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JToolBar;

/**
 * @see https://stackoverflow.com/a/19626219/230513
 * @see https://stackoverflow.com/questions/4038605
 */
public class FileMenu {

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {

            public void run() {
                new FileMenu().create();
            }
        });
    }

    void create() {
        File userDir = new File(System.getProperty("user.dir"));
        File[] files = userDir.listFiles();

        JMenu menu = new JMenu("Recent Files");
        JToolBar toolBar = new JToolBar(JToolBar.VERTICAL);
        JLabel label = new JLabel(" ", JLabel.CENTER);
        int i = 0;
        for (File f : files) {
            if (f.isFile() && !f.isHidden()) {
                RecentFile rf = new RecentFile(f, label, ++i);
                menu.add(new JMenuItem(rf.getAction()));
                toolBar.add(rf);
            }
        }
        JMenuBar menuBar = new JMenuBar();
        menuBar.add(menu);

        JFrame f = new JFrame("FileMenu");
        f.setJMenuBar(menuBar);
        f.add(toolBar, BorderLayout.CENTER);
        f.add(label, BorderLayout.SOUTH);
        f.pack();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

class RecentFile extends AbstractAction {

    private final File file;
    private final JLabel label;

    public RecentFile(final File file, final JLabel label, int i) {
        this.file = file;
        this.label = label;
        this.putValue(Action.NAME, String.valueOf(i) + " " + file.getName());
        this.putValue(Action.SHORT_DESCRIPTION, file.getAbsolutePath());
    }

    public void actionPerformed(ActionEvent e) {
        label.setText(file.getName());

    }

    public Action getAction() {
        return this;
    }
}
于 2013-10-28T02:12:12.733 回答