Professional Documents
Culture Documents
Java界面设计
Java界面设计
2、包含组件的组件——组件容器(Container)
3、外观的管理与控制
4、事件与事件处理
5、AWT中的各种组件
6、组件的应用实例
使用AWT(Abstract Window Toolkit)组件
菜单类
菜单类也是一种组件,只不过菜单类并不是由一般的
Component类派生的,而是从MenuComponent类继承
得到的。
使用AWT
Container类
Container类是由Component类派生出来的一种特殊
类,用来表示各种GUI组件的容器,其主要功能包括:
组件的管理:方法add()可以向其中添加一个组件,
remove()删除其中的一个组件,…
布局管理:每个Container类都和一个布局管理器相
联,以确定其中组件的布局。 Container类可以通过
setLayout()方法设置某种布局方式。
常见的Container类有:Frame,Dialog,Panel, Applet等。
使用AWT
布局管理器类
Java中提供了各种布局管理器类来管理各种组件在容器
中的放置状态,这些类都是实现了LayoutManager接口的。
标准的布局管理器类有:
FlowLayout
BorderLayout
GridLayout
CardLayout
GridBagLayout
还可以通过实现LayoutManager接口来定义自己的布局
管理器。
使用AWT
Graphics类
Graphics类是所有用来在组件上进行图形绘制时所使
用的图形环境上下文的父类,它提供了对组件进行图形
绘制的一般方法的接口,一个Graphics对象中封装了用来
进行图形绘制时必须得状态信息,包括:
要绘制的组件对象
当前颜色
当前字体
当前逻辑点操作的功能(XOR和Paint)
当前XOR方式的替代颜色
……
使用AWT
Graphics类还提供了一系列的方法来绘制几何图形、文字、
图象以及动画:
Lines:drawLine()
Rectangles:drawRect(), fillRect() 和 clearRect()
Raised or lowered rectangles:draw3DRect() 和 fill3DRect()
Round-edged rectangles:drawRoundRect() 和 fillRoundRect()
Ovals:drawOval() 和 fillOval()
Arcs:drawArc() 和 fillArc()
Polygons :drawPolygon() 和 fillPolygon()
Text :drawString()
Image :drawImage()
Animation :通过一个循环来完成
使用AWT
事件类:描述各种事件的类,包括AWTEvent类及其子
类、Event类。
字体类:用来表示字体的类,通过它可以在GUI中使用
多种系统支持的字体。
图象类:用来表示与处理图象的类(GIF、JEPG)。
颜色类:封装了各种颜色。
其他类:光标类、各种几何类等 ……
使用AWT
组件及其对等类(peers)
java.awt.peer中有全部awt组件的对等对象的集合,每个
对象都提供了机器相关基本的方法,awt中的组件使用这些
方法来实现机器和操作系统无关的GUI。
组件容器
一个Java的图形用户界面的最基本组成部分就是组件
(Component),组件是一个可以以图形化的方式显示在
屏幕上并能与用户进行交互的对象,比如Button, Checkbox,
Choice, Label, List等。
组件不能独立地显示出来,必须将组件放在特定的对象
中才能显示出来,这就是包含组件的组件——Container
(容器)。容器Container是Component的子类,它本身也
是一个组件,具有组件所有的性质。另外,它还具有容纳
其他组件和容器的功能。
组件容器
列表 按钮 菜单
窗口,对话框 Container
另一个窗口 Container
组件容器
Component
Container
Button Panel
Applet
List Window
Frame
Textfield
Dialog
Checkbox
FileDialog
组件容器
AWT使用Container类来定义最基本的组件容器,它有
两个常用的子类:Window类和Panel类。
Window类还有两个子类:
定义对话框,用Dialog子类。Java还提了一个Dialog
的子类——FileDialog,用它生成文件对话框。
定义一般意义的窗口,用Frame类。
Frame可以用其构造方法Fame(String)来生成,其标题由
String参数指定。一个Frame刚被创建后,其初始大小为
(0,0),而且是不可见的,所以为了使Frame显示出来,
必须在程序中显式地设置一下它的大小。
Demo:Frame
import java.awt.*;
对话框(Dialog)
对话框与Frame相类似,一般用于接收用户的输入数据,实现与用户的交互。它
与一般窗口的区别在于它依赖其他的窗口。对话框分有模式和无模式两种,前者只
让应用程序响应对话框内部事件,后者则可以响应对话框以外的事件,可以通过其
构造方法来设置对话框是否有模式:
Dialog( Parent, Title, isModal ) //父窗口,标题,是否有模式
组件容器
文件对话框(FileDialog)
表示文件选择的对话框,它是有模式对话框。可以用其getFile()方
法来获得要打开或要存储的文件名。
滚动窗口(ScrollPane)
滚动窗口也是容器的一种,象Panel一样,无法单单独使用。使用
滚动窗口可以查看大面积的区域,因为它有滚动条。滚动窗口内只能
放一个组件,因此也无须布局管理器。通常是在滚动窗口中放一个面
板,然后在面板中添加各种组件。滚动窗口中的事件一般由其中的组
件来管理。
组件容器
用户可以从具体的容器中继承来创建自己的
容器,以构造一些个性化的窗口。一般用户通
常要构造一些适合自己需要的对话框,此时,
可以从Dialog中继承。
public class MyFrame extends Frame
{
public static void main(String args[])
{
MyFrame fr = new MyFrame("Frame and FileDialog Test");
fr.setSize(500,500);
fr.setBackground(Color.blue);
fr.setVisible(true);
fr.showDialog();
}
public MyFrame(String str)
{
super(str);
addWindowListener( new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
public void showDialog()
{
FileDialog fd = new FileDialog(this, "FileDialog");
fd.setVisible(true);
}
}
public class MyPanelInFrame extends Frame
{
public MyPanelInFrame(String str)
{
super(str);
addWindowListener( new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
public static void main(String args[])
{
MyPanelInFrame fr = new MyPanelInFrame("Panel in Frame");
Panel pan = new Panel();
fr.setSize(500,500);
fr.setBackground(Color.green);
fr.setLayout(null);
pan.setSize(200,200);
pan.setBackground(Color.yellow);
pan.setLocation(100,100);
Button b1 = new Button("Help");
Button b2 = new Button("Test");
pan.add(b1);
pan.add(b2);
fr.add(pan);
fr.setVisible(true);
}
}
AWT的组件
组件的应用步骤
//CheckboxGroup
CheckboxGroup cbg = new CheckboxGroup();
add( new Checkbox(“one”, cbg, true) );
add( new Checkbox(“two”, cbg, false) );
add( new Checkbox(“three”, cbg, false) );
//Choice
Choice ch = new Choice();
pan.add(ch);
ch.add( “Green” );
ch.add( “Red” );
ch.add( “Blue” );
AWT的显示组件
标签(Label)
静态文字,多用于指示信息,无事件。
单行文本区(TextField)——TextComponent
只能显示一行信息,当按回车键后,会产生ActionEvent事件,可以
用ActionListener来监听。
文本输入区(TextArea) ——TextComponent
可以显示多行信息,并且有滚动条支持。按回车键后并不产生事件,
如果要判断是否完成输入,需要用其他方法,如用一个结束按钮。
列表(List)
列表提供了很多文本选项,可以同时看到多项,也有滚动条的支持,
并且可以单选或多选。当用户单选或多选时,会产生ItemEvent事件。
Demo:显示组件
// TextField
TextField tf1, tf2, tf3, tf4;
tf1 = new TextField(); // a blank text field
tf2 = new TextField("", 20); // blank field of 20 columns
tf3 = new TextField("Hello!"); // predefined text displayed
tf4 = new TextField("Hello", 30); // predefined text in 30 columns
//TextArea
add( new TextArea("Hello", 5, 40); );
//List
List lst = new List(4, false);
lst.add("Mercury");
lst.add("Venus");
lst.add("Earth");
lst.add("JavaSoft");
lst.add("Mars");
lst.add("Neptune");
add(lst);
AWT的组件
滚动条(Scrollbar)
滚动条一般不单独使用,它通常与另一个组件联合使用,用以指示
另一个组件的变化情况。一般情况下,它可以用ScrollPane代替。
画布(Canvas)
画布类在使用时必须被继承,它本身并不做任何事情,它只是在屏
幕上生成了一个矩形空白区域,使应用程序能够在上面任意作画,如写
文字、画各种图形、接收键盘或鼠标输入等。如果想在画布上完成图画
功能,必须重写其paint()方法。
画布监听各种鼠标、键盘事件,只需实现KeyListener、
MouseMotionListener和MouseListener接口即可。
当在画布中输入字符时,必须先调用requestFoucus()方法为画布获
得输入焦点,一般在mouseClicked()方法中调用该方法。
AWT的组件
菜单
菜单与其他组件不同,无法直接添加到容器的某一位置,
也无法用布局管理器对其加以控制,它由以下概念支撑:
9 菜单条(MenuBar)
只能添加到Frame中(用setMenuBar()),作为摆放菜单的容器。
9 菜单(Menu)
菜单项容器,负责显示并控制其中的菜单项。它支持菜单嵌套。
9 菜单项(MenuItem)
真正的动作,可以用ActionListener监听其事件(ActionEvent)。
9 复选框菜单项(CheckboxMenuItem)
真正的动作, 可以用ItemListener监听其事件(ItemEvent)。
9 弹出式菜单(PopupMenu)
与菜单相似,也是菜单项容器。
AWT的组件
用户可以从Component中继承来创建自己的轻量级组件,
此时,在新的组件中一般要实现(重写)以下方法:
构造方法:
如果组件要响应事件(如鼠标按键),构造方法中必须
调用enableEvents()方法;
更改组件状态的方法:
比如setText()方法等,在这些方法中,如果状态的变化
引起了组件外观的变化,则需要调用repaint()方法,如果组
件的尺寸发生了变化,则在调用repaint()方法前还需要调用
invalidate()方法;
AWT的组件
组件的绘制方法:
paint(),还包括组件最佳尺寸getPreferredSize()和最小尺
寸getMinimumSize()方法等。
组件的事件监听器注册方法和取消注册方法:
addActionListener()和removeActionListener(),在
这两个方法中要调用AWTEventMulticaster 类中的方法来实
现;
contains()方法:
如果组件只响应一定区域中发生的事件;
组件状态改变及事件产生方法:
processXXXX(),如processMouseEvent()
组件的应用
菜单
画布
单行文本输入区
按钮
复选框
下拉式菜单
列表
文本输入区
……
版面布局
0
0 1 3
1 2 3 4
4 4 5
5
版面布局
为了使生成的图形用户界面具有良好的平台无
关性,Java语言提供了布局管理器来管理组件在容
器中的布局,而不使用直接设置组件的位置和大小
的方式。每个容器都要一个布局管理器,容器中组
件的定位都由它来决定。当容器需要对某个组件进
行定位时,就会调用其对应的布局管理器。
版面布局
在程序中安排组件的位置和大小时,应注意:
容器中布局管理器负责各组件的大小和位置,用户无
法在这种情况下设置组件的这些属性,如试图调用
setLocation(), setSize(), setBounds()等。
如果用户确实需要自己设置组件的大小和位置,则应
取消该容器的布局管理器,方法为:
setLayout(null)
但用户必须使用setLocation(), setSize(), setBounds()
等方法为组件设置大小和位置,不过程序将系统相关。
版面布局
在容器中所有组件的布局都由布局管理器来控制,每
个容器,如Panel、Windows或Frame都有各自缺省的布局
管理器,程序员也可以在程序中指定一个新的布局管理器。
Java语言中包含五种布局管理器:
FlowLayout:Panel和Applet的缺省布局管理器
BorderLayout:Window、Dialog和Frame的缺省布局管理器
GridLayout
CardLayout
GridBagLayout
版面布局
FlowLayout布局方式是将组件一排一排地依次放置,它
自动调用组件的getPreferredSize()方法,使用组件的最佳尺
寸来显示组件。当容器被重新设置大小后,则布局也会随之
发生改变:各组件的大小不变,但相对位置会发生变化。
FlowLayout类有三种构造方法:
public FlowLayout()
使用缺省居中对齐方式,组件间的水平和竖直间距为缺
省值5个象素。
public FlowLayout(int alignment)
使用指定的对齐方式(FlowLayout.LEFT,FlowLayout.RIGHT,
FlowLayout.Center),水平和竖直间距为缺省值5象素。
public FlowLayout(int alignment, int horizontalGap, int
verticalGap)
使用指定的对齐方式,水平和竖直间距也为指定值。
Demo: flowlayout
import java.awt.*;
public class flowlayoutTest{
public static void main(String args[]){
Frame frObj = new Frame("FlowLayout testting!");
frObj.setLayout(new FlowLayout(FlowLayout.LEFT,50,50));
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3");
Button button4 = new Button("button4");
Button button5 = new Button("button5");
Button button6 = new Button("button6");
frObj.setBounds(100,100,300,250);
frObj.add(button1);
frObj.add(button2);
frObj.add(button3);
frObj.add(button4);
frObj.add(button5);
frObj.add(button6);
frObj.setVisible(true);
}
}
public class FlowWindow extends Frame
{
public FlowWindow()
{
setLayout( new FlowLayout() );
setFont(new Font("Helvetica", Font.PLAIN, 14));
add(new Button("Button 1"));
add(new Button("2"));
add(new Button("Button 3"));
add(new Button("Long-Named Button 4"));
add(new Button("Button 5"));
}
public boolean handleEvent(Event e)
{
if (e.id == Event.WINDOW_DESTROY) {
System.exit(0);
}
return super.handleEvent(e);
}
public static void main(String args[])
{
FlowWindow window = new FlowWindow();
window.setTitle("FlowWindow Application");
window.pack();
window.show();
}
}
版面布局
BorderLayout布局方式提供了更复杂的布局控制方法,
它包括5个区域:North, South, East, West和Center,其方
位依据上北下南左西右东。当容器的尺寸发生变化时,各组
件的相对位置不变,但中间部分组件的尺寸会发生变化,南
北组件的高度不变,东西组件的宽度不变。
BorderLayout类有二种构造方法:
public BorderLayout()
各组件间的水平和竖直间距为缺省值0个象素。
public BorderLayout(int horizontalGap, int verticalGap)
各组件间的水平和竖直间距为指定值。
版面布局
如果容器使用了BorderLayout布局方式,则用add()方法
往容器中添加组件时必须指明添加的位置,否则组件将无法
正确显示(不同的布局管理器,向容器中添加组件的方法也
不同)。
add(“West”, new Button(“West”));
add(“North”, new Button(“North”));
add(new Button(“West”), BorderLayout.SOUTH);
若没有指明放置位置,则表明为默认得“Center”方位。
每个区域只能添加一个组件,若添加多个,则只能显示
一个。如果想在一个区域添加多个组件,则必须先在该区域
放一个容器,再将多个组件放在该容器中。
若每个区域或若干个区域没有放置组件,东西南北区域
将不会有预留,而中间区域将置空。
Demo:borderlayout
import java.awt.*;
public class borderlayoutTest{
public static void main(String args[]){
Frame frObj = new Frame("BorderLayout testting!");
Button button1 = new Button("East");
Button button2 = new Button("West");
Button button3 = new Button("South");
Button button4 = new Button("North");
frObj.add("East",button1);
frObj.add("West",button2);
frObj.add("South",button3);
frObj.add("North",button4);
frObj.setBounds(100,100,260,160);
frObj.setVisible(true);
}
}
public class BorderWindow extends Frame
{
public BorderWindow()
{
setLayout(new BorderLayout(5,5));
setFont(new Font("Helvetica", Font.PLAIN, 14));
add("North", new Button("North"));
add("South", new Button("South"));
add("East", new Button("East"));
add("West", new Button("West"));
add("Center", new Button("Center"));
}
public boolean handleEvent(Event e)
{
if (e.id == Event.WINDOW_DESTROY) {
System.exit(0);
}
return super.handleEvent(e);
}
public static void main(String args[])
{
BorderWindow window = new BorderWindow();
window.setTitle("BorderWindow Application");
window.pack();
window.show();
}
}
版面布局
GridLayout布局方式可以使容器中的各组件呈网格状分
布。容器中各组件的高度和宽度相同,当容器的尺寸发生变
化时,各组件的相对位置不变,但各自的尺寸会发生变化。
各组件的排列方式为:从上到下,从左到右。
与BorderLayout类相类似,如果想在一个网格单元中添加
多个组件,则必须先在该网格单元放一个容器,再将多个组
件放在该容器中。
版面布局
GridLayout类有三种构造方法:
public GridLayout()
在一行中放置所有的组件,各组件间的水平间距为0象
素。
public GridLayout(int rows, int cols)
生成一个rows行,cols列的管理器,最多能放置
rows*cols个组件。
rows或cols可以有一个为0。若rows为0,这表示每行放
置cols个组件,根据具体组件数,可以有任意多行;若cols
为0,这表示共有rows行,根据具体组件数,每行可以放置
任意多个组件
组件间的水平和竖直间距为0象素。
public GridLayout(int rows, int cols, int horizontalGap, int
verticalGap )
Demo:gridlayout
import java.awt.*;
public class gridlayoutTest{
public static void main(String args[]){
Frame frObj = new Frame("GridLayout testting!");
Button button1 = new Button("East");
Button button2 = new Button("West");
Button button3 = new Button("South");
Button button4 = new Button("North");
frObj.setLayout(new GridLayout(2,2));
frObj.add(button1);
frObj.add(button2);
frObj.add(button3);
frObj.add(button4);
frObj.setBounds(100,100,260,160);
frObj.setVisible(true);
}
}
public class GridWindow extends Frame
{
public GridWindow()
{
setLayout(new GridLayout(0,2));
setFont(new Font("Helvetica", Font.PLAIN, 14));
GridBagLayout是获取GridBagConstraints实例中
的值为某个组件设置了空间限制,当往容器中添加
了该组件后,该GridBagConstraints实例还可继续用
于其他组件,当然其中值需要做相应的调整。
Demo:gridbaglayout
import java.awt.*;
import java.applet.Applet;
public class gridbaglayoutTest{
public static void main(String args[]){
Frame frObj = new Frame("GridBagLayout testting !");
GridBagLayout gridObj = new GridBagLayout();
GridBagConstraints conObj = new GridBagConstraints();
conObj.fill = GridBagConstraints.HORIZONTAL;
frObj.setLayout(gridObj);
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3");
Button button4 = new Button("button4");
Button button5 = new Button("button5");
Button button6 = new Button("button6");
Demo:gridbaglayout
gridObj.setConstraints(button1,conObj);
conObj.weightx = 1.0;
frObj.add(button1);
gridObj.setConstraints(button2,conObj);
frObj.add(button2);
conObj.gridwidth = GridBagConstraints.REMAINDER;
gridObj.setConstraints(button3,conObj);
frObj.add(button3);
conObj.weightx = 0.0;
conObj.gridwidth = GridBagConstraints.RELATIVE;
gridObj.setConstraints(button4,conObj);
frObj.add(button4);
conObj.gridwidth = GridBagConstraints.REMAINDER;
gridObj.setConstraints(button5,conObj);
gridObj.setConstraints(button6,conObj);
frObj.add(button5);
frObj.add(button6);
frObj.setSize(300,240);
frObj.setVisible(true);
}
}
版面布局
用户可以通过实现LayoutManager接口来定义自己的布局管
理器。 LayoutManager接口要求实现它的类必须实现以下五
个方法:
public void addLayoutComponent(String name, Component comp)
public void removeLayoutComponent(Component comp)
public Dimension preferredLayoutSize(Container parent)
public Dimension minimumLayoutSize(Container parent)
public void layoutContainer(Container parent)
此外还应至少实现一个构造方法以及toString()方法。
DiagonalLayout.java实现了一个让组件呈对角线分布的布
局管理器,每行只有一个组件。
Demo:Mixlayout
import java.awt.*;
public class MixLayoutTest{
public static void main(String args[]){
Frame frObj = new Frame("ZongHeLayout testting !");
Panel firstPanel = new Panel();
Panel secondPanel = new Panel();
Panel thirdPanel = new Panel();
GridBagLayout gridObj = new GridBagLayout();
GridBagConstraints conObj = new GridBagConstraints();
conObj.fill = GridBagConstraints.HORIZONTAL;
firstPanel.setLayout(gridObj);
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3");
Button button4 = new Button("button4");
Button button5 = new Button("button5");
Button button6 = new Button("button6");
Button button7 = new Button("button7");
Button button8 = new Button("button8");
Button button9 = new Button("button9");
gridObj.setConstraints(button1,conObj);
conObj.weightx = 1.0;
firstPanel.add(button1);
gridObj.setConstraints(button2,conObj);
firstPanel.add(button2);
conObj.gridwidth = GridBagConstraints.RELATIVE;
gridObj.setConstraints(button3,conObj);
firstPanel.add(button3);
frObj.add("North",firstPanel);
secondPanel.setLayout(new FlowLayout());
secondPanel.add(button7);
secondPanel.add(button8);
secondPanel.add(button9);
frObj.add("South",secondPanel);
thirdPanel.setLayout(new GridLayout(2,1));
thirdPanel.add(button4);
thirdPanel.add(button5);
frObj.add("East",thirdPanel);
frObj.add("West",button6);
frObj.setSize(300,240);
frObj.setVisible(true);
}
}
Swing介绍
可插的外观和感觉
应用程序看上去是与平台有关的
有客户化的Swing组件
Swing的体系结构
它是围绕着实现AWT各个部分的API构筑的
大多数组件不象AWT那样使用与平台相关的实现
图显示了JFC各个部分之间的相互关系。Java2D,Accessibility,Drag
& Drop,和Accessibility API是AWT和JFC的一部分,但它们不属于
Swing。这是因为,这些组件使用了一些本地代码,而Swing却不是这
样的。
Swing 是 围 绕 着 一 个 称 为 JComponent 的 新 组 件 构 建 的 , 而
JComponent则由AWT的容器类扩展而来。
JApplet JButton
JComboBox JOptionPane
JList JLabel
JScrollPane JTable
JScrollBar JSlider
JTooltip JTree