java菜单实现
直接在措施片中安顿一个菜单是不行能的(Java 1.0,Java1.1和Swing库不答允),因为它们是针对应用措施的。继承,假如您不相信我而且确定在措施片中可以公道地拥有菜单,那么您可以去试验一下。措施片中没有setMenuBar()要领,而这种要领是附在菜单中的(我们会看到它可以公道地在措施片发生一个帧,而且帧包括菜单)。
有四种差异范例的MenuComponent(菜单组件),所有的菜单组件发源于抽象类:菜单条(我们可以在一个事件帧里拥有一个菜单条),菜单去支配一个单独的下拉菜单可能子菜单、菜单项来说明菜单里一个单个的元素,以及发源于MenuItem,发生查抄符号(checkmark)去显示菜单项是否被选择的CheckBoxMenuItem。
差异的系统利用差异的资源,对Java和AWT而言,我们必需在源代码中手工汇编所有的菜单。
//: Menu1.java // Menus work only with Frames. // Shows submenus, checkbox menu items // and swapping menus. import java.awt.*; public class Menu1 extends Frame { String[] flavors = { "Chocolate", "Strawberry", "Vanilla Fudge Swirl", "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", "Praline Cream", "Mud Pie" }; TextField t = new TextField("No flavor", 30); MenuBar mb1 = new MenuBar(); Menu f = new Menu("File"); Menu m = new Menu("Flavors"); Menu s = new Menu("Safety"); // Alternative approach: CheckboxMenuItem[] safety = { new CheckboxMenuItem("Guard"), new CheckboxMenuItem("Hide") }; MenuItem[] file = { new MenuItem("Open"), new MenuItem("Exit") }; // A second menu bar to swap to: MenuBar mb2 = new MenuBar(); Menu fooBar = new Menu("fooBar"); MenuItem[] other = { new MenuItem("Foo"), new MenuItem("Bar"), new MenuItem("Baz"), }; Button b = new Button("Swap Menus"); public Menu1() { for(int i = 0; i < flavors.length; i++) { m.add(new MenuItem(flavors[i])); // Add separators at intervals: if((i+1) % 3 == 0) m.addSeparator(); } for(int i = 0; i < safety.length; i++) s.add(safety[i]); f.add(s); for(int i = 0; i < file.length; i++) f.add(file[i]); mb1.add(f); mb1.add(m); setMenuBar(mb1); t.setEditable(false); add("Center", t); // Set up the system for swapping menus: add("North", b); for(int i = 0; i < other.length; i++) fooBar.add(other[i]); mb2.add(fooBar); } public boolean handleEvent(Event evt) { if(evt.id == Event.WINDOW_DESTROY) System.exit(0); else return super.handleEvent(evt); return true; } public boolean action(Event evt, Object arg) { if(evt.target.equals(b)) { MenuBar m = getMenuBar(); if(m == mb1) setMenuBar(mb2); else if (m == mb2) setMenuBar(mb1); } else if(evt.target instanceof MenuItem) { if(arg.equals("Open")) { String s = t.getText(); boolean chosen = false; for(int i = 0; i < flavors.length; i++) if(s.equals(flavors[i])) chosen = true; if(!chosen) t.setText("Choose a flavor first!"); else t.setText("Opening "+ s +". Mmm, mm!"); } else if(evt.target.equals(file[1])) System.exit(0); // CheckboxMenuItems cannot use String // matching; you must match the target: else if(evt.target.equals(safety[0])) t.setText("Guard the Ice Cream! " + "Guarding is " + safety[0].getState()); else if(evt.target.equals(safety[1])) t.setText("Hide the Ice Cream! " + "Is it cold? " + safety[1].getState()); else t.setText(arg.toString()); } else return super.action(evt, arg); return true; } public static void main(String[] args) { Menu1 f = new Menu1(); f.resize(300,200); f.show(); } } ///:~
在这个措施中,我制止了为每个菜单编写典范的冗长的add()列表挪用,因为那看起来像很多的无用的符号。取而代之的是,我安顿菜单项到数组中,然后在一个for的轮回中通过每个数组挪用add()简朴地跳过。这样的话,增加和淘汰菜单项变得没那么讨厌了。
作为一个可选择的要领(我发明这很难令我满足,因为它需要更多的分派)CheckboxMenuItems在数组的句柄中被建设是被称为安详建设;这对数组文件和其它的文件而言是真正的安详。
措施中建设了不是一个而是二个的菜单条来证明菜单条在措施运行时能被互换激活。我们可以看到菜单条奈何构成菜单,每个菜单奈何构成菜单项(MenuItems),chenkboxMenuItems可能其它的菜单(发生子菜单)。当菜单组合后,可以用setMenuBar()要领安装到此刻的措施中。值得留意的是当按钮被压下时,它将查抄当前的菜单安装利用getMenuBar(),然后安顿其它的菜单条在它的位置上。
当测试是“open”(即开始)时,留意拼写和大写,假如开始时没有工具,Java发出no error(没有错误)的信号。这种字符串较量是一个明明的措施设计错误源。
校验和非校验的菜单项自动地运行,与之相关的CheckBoxMenuItems着实令人受惊,这是因为一些原因它们不答允字符串匹配。(这好像是自相抵牾的,尽量字符串匹配并不是一种很好的步伐。)因此,我们可以匹配一个方针工具而不是它们的标签。当演示时,getState()要领用来显示状态。我们同样可以用setState()改变CheckboxMenuItem的状态。
我们大概会认为一个菜单可以公道地置入高出一个的菜单条中。这看似公道,因为所有我们忽略的菜单条的add()要领都是一个句柄。然而,假如我们试图这样做,这个功效将会变得很是的别扭,而远非我们所但愿获得的功效。(很难知道这是一个编程中的错误可能说是他们试图使它以这种要领去运行所发生的。)这个例子同样向我们展示了为什么我们需要成立一个应用措施以替代措施片。(这是因为应用措施能支持菜单,而措施片是不能直接利用菜单的。)我们从帧处担任取代从措施片处担任。别的,我们为类建一个构建器以代替init()安装事件。最后,我们建设一个main()要领而且在我们建的新型工具里,调解它的巨细,然后挪用show()。它与措施片只在很小的处所有差异之处,然而这时它已经是一个独立的配置窗口应用措施而且我们可以利用菜单。