添加菜单栏
在 Swing 中创建菜单提供另一个具有自然层次结构的组件示例。创建一个 JMenuBar
,它包含一个或多个 JMenu
,JMenu
进而包含一个或多个 JMenuItem
。
为了创建包含 Exit
菜单项的 File
菜单,在 Gwitter.groovy 中添加清单 11 中的代码:
File
菜单
import groovy.swing.SwingBuilder import javax.swing.* import java.awt.* class Gwitter{ static void main(String[] args){ def gwitter = new Gwitter() gwitter.show() } void show(){ def swingBuilder = new SwingBuilder() def customMenuBar = { swingBuilder.menuBar{ menu(text: "File", mnemonic: 'F') { menuItem(text: "Exit", mnemonic: 'X', actionPerformed: { dispose() }) } } } swingBuilder.frame(title:"Gwitter", defaultCloseOperation:JFrame.EXIT_ON_CLOSE, size:[400,500], show:true) { customMenuBar() } } } |
请注意 customMenuBar
闭包的嵌套层次结构。为了便于阅读,这里添加了换行和缩进,但是同样很容易在同一行中定义它。定义这个闭包之后,在 frame
闭包中调用它。再次输入 groovy Gwitter
,确认会出现 File
菜单,见图 4。选择 File > Exit,关闭这个应用程序。
再看看 清单 11。注意,actionPerformed
处理函数定义为闭包,而不是匿名类。与相应的 Java 代码相比,这样的代码更干净、更容易阅读。
现在,添加一些表单元素以执行搜索。
回页首
添加搜索面板
经验丰富的 Swing 开发人员善于用单独的 JPanel
组装出最终的应用程序。这些容器组件可以方便地把相似、相关的组件分组在一起。
例如,Gwitter 需要一个 JTextField
(让用户能够输入搜索条件)和一个 JButton
(用于提交请求)。把这两个组件分组在一个searchPanel
闭包中是有意义的,见清单 12:
import groovy.swing.SwingBuilder import javax.swing.* import java.awt.* class Gwitter{ def searchField static void main(String[] args){ def gwitter = new Gwitter() gwitter.show() } void show(){ def swingBuilder = new SwingBuilder() def customMenuBar = { swingBuilder.menuBar{ menu(text: "File", mnemonic: 'F') { menuItem(text: "Exit", mnemonic: 'X', actionPerformed: {dispose() }) } } } def searchPanel = { swingBuilder.panel(constraints: BorderLayout.NORTH){ searchField = textField(columns:15) button(text:"Search", actionPerformed:{ /* TODO */ } ) } } swingBuilder.frame(title:"Gwitter", defaultCloseOperation:JFrame.EXIT_ON_CLOSE, size:[400,500], show:true) { customMenuBar() searchPanel() } } } |
开始处理面板之后,就要选择适当的 LayoutManger
。在默认情况下,JPanel
使用 FlowLayout
。这意味着 textField
和 button
挨着水平排列。
JFrame
的 contentPane
不太一样 — 它在默认情况下使用 BorderLayout
。这意味着在框架中添加 searchPanel
时需要指定它应该出现在哪个区域:NORTH
、SOUTH
、EAST
、WEST
或 CENTER
。(如果您的地理知识实在糟糕,也可以使用PAGE_START
、PAGE_END
、LINE_START
、LINE_END
和 CENTER
)。关于 Swing 中可用的各种 LayoutManager
的更多信息,请参见 参考资料。
注意,searchField
变量是在类级声明的。因此,按钮等其他组件也可以访问它。其他组件都是匿名的。快速浏览一下类属性,就会看出某些组件比较重要。
您可能已经注意到按钮的 actionPerformed
监听器目前没有做任何事情。现在实际上还不需要它做什么。在实现它之前,需要在应用程序中添加另一个面板:用来显示搜索结果的面板。