JAVA 在 JMenuItem[] 构造函数中声明未初始化的 JMenuItem() 项

JAVA declaring uninitialized JMenuItem() items inside JMenuItem[] constructor

我有这个代码:

JMenuItem itemA;
JMenuItem itemB;
JMenuItem itemC;
JMenuItem[] items = {itemA, itemB, itemC};

我想做的是在 JMenuItem 数组构造函数中声明那些 JMenuItems,这样我就可以省去几行其他不必要的代码(即首先摆脱那些单独项目的初始声明)。我期望符合这个虚构代码的东西:

JMenuItem[] items = {JMenuItem itemA, JMenuItem itemB, JMenuItem itemC};

...但这当然行不通。谁能告诉我该怎么做? 顺便说一句,这些项目稍后在代码中初始化。

替换这个

JMenuItem[] items = {JMenuItem itemA, JMenuItem itemB, JMenuItem itemC};

有了这个

JMenuItem[] items = {null, null, null}; //option 1
JMenuItem[] items = new JMenuItem[3]; //option 2

你可以这样初始化数组:

JMenuItem[] items = {new JMenuItem(), new JMenuItem(), new JMenuItem()};

然后使用 items[0]、items[1]、items[2] 代替 itemA、itemB、itemC。

没有必要为了声明变量而声明变量 - 尽可能在靠近使用它们的地方声明它们。由于您没有将 items 的可见性设置为 private 或类似的,我假设您的代码存在于方法中,可能是 window 的构造函数。在那种情况下,我建议使用 RAII 的(精神):在同一条语句中初始化和声明。我的代码看起来像

JMenuItem[] items = {
    new JMenuItem(openFileAction),
    new JMenuItem(saveFileAction),
    new JMenuItem(exitApplicationAction)
};

这假设您正在使用 Action 的子类,或者更好的是 AbstractAction 来为每个项目提供标签、快捷方式、名称、图标和 actionPerformed 代码。动作的优点是它们的名字比itemA好记得多,可以在多个地方调用(和显示)(如按钮,作为项目,在多种类型的菜单中),并且它们可以enabled/disabled 在所有这些取决于应用程序的状态(例如,当没有文件要保存时,saveFileAction 可以在任何地方禁用)。

其实,我会更进一步。由于菜单一旦创建就很少需要更改,并且您可以访问它们对 enable/disable 的内部操作,因此您可以完全跳过声明 items

JMenu fileMenu = new JMenu("File");
fileMenu.add(new JMenuItem(openFileAction));
// ... 

编辑关于如何定义 "everything in one go":

我更喜欢使用 Actions 而不是 JMenuItems,因为操作更灵活(因为它们可以在多个地方使用)。你可以在一次调用中给一个动作一个标签和它的代码,这类似于你可以用 JMenuItems:

做的事情
Action exitApplicationAction = new AbstractAction("Exit application") {
    public void actionPerformed(ActionEvent ae) {
      System.exit(0);
    }
};

但是,拥有 AbstractAction 的自制子类(此处称为 AllInOneAction)允许使用最少的样板一次设置 所有内容(注意它比上面的例子更短并且做的更多!):

Action exitApplicationAction = new AllInOneAction(
   "Exit application", "exit.png", "Exit the program",
   KeyEvent.VK_E, "control shift E", () -> System.exit(0));

在内部,在该子类中,您将设置一堆操作键:

public AllInOneAction(Object name, String iconName, String tooltip,
        Integer mnemonic, String accelerator, Runnable callback) {
    super("" + name); // allows your name to be an enum, useful for lookup
    putValue(Action.SHORT_DESCRIPTION, tooltip);
    putValue(Action.MNEMONIC_KEY, mnemonic);
    putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(accelerator));
    BufferedImage icon = loadImage(iconName); 
    BufferedImage small = scaleImage(icon, 16, 16);   
    putValue(Action.LARGE_ICON_KEY, new ImageIcon(icon));
    putValue(Action.SMALL_ICON, new ImageIcon(small));
    this.callback = callback;
}

请注意,loadImagescaleImage 的实现留作练习,但这已经是 "how to populate my JMenu" 原始问题的一个足够大的弯路了。