通过图形用户界面(Graphics User Interface,GUI),用户和程序之间可以方便地进行交互。Java的java.awt包,即Java抽象窗口工具包(Abstract Window Toolkit,AWT)提供了许多用来设计GUI的组件类。
容器类(Container)和组件类(Component)。javax.swing包中的JComponent类是java.awt包中Container类的一个直接子类,是java.awt包中Component类的一个间接子类,学习GUI编程主要是学习Component类的一些重要子类。
JFrame类的实例就是一个底层容器,即通常所称的窗口,JDialog类的实例也是一个底层容器,即通常所称的对话框。当需要一个窗口时,可使用 JFrame 或其子类创建一个对象。
菜单条、菜单、菜单项是窗口常用的组件,菜单放在菜单条梨,菜单项放在菜单里。
JComponent类的子类JMenubar负责创建菜单条,即JMenubar的一个实例就是一个菜单条。JFrame类有一个将菜单条放置到窗口中的方法:
setJmenuBar(JMenuBar bar);
该方法将菜单条添加到窗口的顶端,但只能向窗口添加一个菜单条。
JComponent类的子类JMenu负责创建菜单,即JMenu的一个实例就是一个菜单。
JComponent类的子类JMenuItem负责创建菜单项,即JMenuItem的一个实例就是一个菜单项。
JMenu是JMenuItem的子类,因此菜单本身也是一个菜单项,当把一个菜单看作菜单项添加到某个菜单中时,称这样的菜单为一个子菜单。
用图标类Icon声明一个图标,然后使用其子类ImageIcon类创建一个图标,
Icon icon = new ImageIcon("a.gif");
然后菜单项调用setIcon(Icon icon)方法将图标设置为icon。
常用组件都是JComponent的子类
允许用户在文本框中输入单行文本。
允许用户在文本区中输入多行文本。
允许用户单机按钮。
标签为用户提供提示信息。
为用户提供多项选择,复选框的右面有个名字,并提供两种状态,一种是选中,另一种是未选中,用户通过单机该组件切换状态。
为用户提供单项选择。
为用户提供单项选择。用户可以在下拉列表中看到第一个选项和它旁边的箭头按钮,当用户单击箭头按钮时,选项列表打开。
允许用户在密码框中输入单行密码,密码框的默认回显字符时 ‘*’ 。密码框可以使用 setEchoChar(char c) 重新设置回显字符,当用户输入密码时,密码框只显示回显字符。密码框调用 char[] getPassword()方法可以返回用户在密码框中输入的密码。
Jcomponent是Container的子类,因此JComponent子类创建的组件也都是容器,但我们很少将 JButton、JTextField、JCheckBox 等组件当容器来使用。JComponent专门提供了一些经常用来添加组件的容器。相对于 JFrame 底层容器,本节提到的容器被习惯地称为中间容器,中间容器必须被添加到底层容器中才能发挥作用。(中间容器不能独自存在)
经常使用 JPanel创建一个面板,再向这个面板添加组件,然后把这个面板添加到其他容器中。 JPanel面板的默认布局时 FlowLatout 布局。
把组件添加到容器中时,希望控制组件在容器中的位置,就需要学习有关布局的知识,本节介绍java.awt包中的 FlowLayout、BorderLayout、CardLayout、GridLayout 布局类。
容器可以使用方法
setLayout(布局对象);
设置自己的布局。
FlowLayout类的一个常用构造方法如下:
FlowLayout();
该构造方法可以创建一个居中对齐的布局对象。使用FlowLayout布局的容器使用add方法将组件顺序地添加到容器中,组件按照加入的先后顺序从左向右排列,一行排满之后就转到下一行继续从左至右排列,每一行中的组件都居中排列,组件之间的默认水平和垂直间隙是5个像素。组件的大小为默认的最佳大小,例如,按钮的大小刚好能保证显示其上面的名字。对于添加到使用 FlowLayout布局的容器中的组件,组件调用 setSize(int x, int y)设置的大小无效,如果需要改变最佳大小,组件需调用 public void setPreferredSize(Dimension preferredSize)设置大小,例如:
button.setPreferredSize(new Dimension(20,20));
FlowLayout布局对象调用 setAlignment(int align)方法可以重新设置布局的对齐方式,其中align可以取值 FlowLayout.LEFT、FlowLayout.CENTER、FlowLayout.RIGHT。
BorderLayout也是一种简单的布局策略,如果一个容器使用这种布局,那么容器空间分为东、西、南、北、中5个区域,中间的区域最大。每加入一个组件都应该指明把这个组件加在哪个区域中,区域由BorderLayout中的静态常量CENTER、NORTH、SOUTH、WEST、EAST表示,例如,一个使用BorderLayout布局的容器 con,可以使用add方法将一个组件b添加到中心区域。
con.add(b.BorderLayout.CENTER);
添加到某个区域的组件将占据整个区域。每个区域只能放置一个组件,如果再放一个组件,会覆盖原来的,使用BorderLayout布局的容器最多能添加5个组件,如果容器中需要加入超过5个组件,就必须使用容器的嵌套或改用其他的布局策略。
使用CardLayout的容器可以容纳多个组件,这些组件将层叠放入容器中,最先加入容器的是第一张(在最上面),依次向下排序。使用该布局的特点是,同一时刻容器只能从这些组件中选出一个来显示,就像叠“扑克牌”,每次只能显示其中的一张,这个被显示的组件将占据所有的容器空间。
假设有一个容器con,那么,使用 CardLayout 的一般步骤如下。
CardLayout card = new CardLayout();
把容器划分成若干行若干列的网格区域,调用add(Component c)将组件c加入容器,每个网格都是相同大小并且强制组件与网格的大小相同。
空布局容器可以准确地定位组件在容器中的位置和大小。setBounds(int a,intb,int width,int height)方法是所有组件都拥有地一个方法,组件调用该方法可以设置本身地大小和在容器中的位置。
例如,p是个容器
p.setLayout(null);
首先容器p使用add©方法添加组件,然后组件c再调用setBounds(int a,int b,int width, int height)设置组件在容器p中的位置和本身地大小。组件都是一个矩形结构。
当用户输入后按enter、单击、选择,都发生界面事件。
掌握事件源、监视器、处理事件的接口这3个概念。
能够产生时间的对象都可以称为事件源,如文本框、按钮、下拉菜单。也就是说,事件源必须是一个对象,而且这个对象必须是Java认为能够发生事件的对象。
需要一个对象对事件源进行监视,然后做出处理。事件源通过调用相应的方法将某个对象注册为自己的监视器。
addActionListener(监视器);
对于注册了监视器的文本框,在文本框获得输入焦点后,如果用户按enter,Java运行环境就自动用ActionEvent类创建一个对象,即发生了ActionEvent事件。
事件源注册监视器后,会导致某种结果,通知监视器,监视器会做出处理。
监视器是一个对象,为了处理事件源发生的事件,监视器会自动调用一个方法来处理事件。对象可以调用创建它的那个类中的方法,Java规定:为了让监视器能对事件源发生的事件进行处理,创建该监视器对象的类必须声明实现相应的接口,即必须在类体中重写接口中所有的方法,那么当事件源发生事件时,监视器就自动调用被类重写的接口方法。
Java要求监视器必须和一个专用于处理事件的方法实施绑定,要求创建监视器的类必须实现Java规定的接口,该接口中要专用于处理事件的方法。
文本框、按钮、菜单项、密码框和单选按钮都可以出发ActionEvent事件,即都可以称为ActionEvent事件的事件源。
Java规定能触发ActionEvent事件的组件使用方法addActionListener(ActionListener listen)将实现ActionListener接口的类的实例注册为事件源的监视器,Java提供的这个方法的参数时接口类型,Java是面向接口设计的这个方法。
ActionListener接口在java.awt.event包中,该接口中只有一个方法 public void actionPerformed(ActionEvent e)。
事件源出发ActionEvent事件后,监视器调用接口中的方法 actionPerformed(ActionEvent e) 对发生的事件做出处理。当监视器调用 actionPerformed(ActionEvent e) 方法时,ActionEvent 类事先创建的事件对象就会传递给该方法的参数 e。
ActionEvent类有如下常用的方法:
注:能触发ActionEvent事件的事件源可以事先使用setCommand(String s)设置出发事件后封装到事件中的一个称作“命令”的字符串,以改变封装到事件中的默认“命令”。