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;
}
请注意,loadImage
和 scaleImage
的实现留作练习,但这已经是 "how to populate my JMenu" 原始问题的一个足够大的弯路了。
我有这个代码:
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;
}
请注意,loadImage
和 scaleImage
的实现留作练习,但这已经是 "how to populate my JMenu" 原始问题的一个足够大的弯路了。