第 6章 图形用户界面 GUI
第 6章 图形用户界面 GUI
?图形用户界面的概念
?建立图形用户界面
?几个重要的图形组件
? *GUI组件包与 JComponent
6.1图形用户界面的概念
?对计算机而言,用户界面 是用户和计算机之
间进行信息交互的界面,用户通过这个界面
得到程序运行的状态或输出的信息,向计算
机输入用户数据,操纵和控制程序的运行。
计算机的用户界面由用户可以直接操纵的键
盘,鼠标和用户可以直接感知的显示屏幕、
喇叭等器件构成
DOS 命令行界面
Windows图形界面
6.2 建立图形用户界面
?建立和添加组件 (Components)
?Java的事件处理
?组件 JPanel与布局管理器( Layout
Managers)
建立一个图形界面的内容
?通过建立和添加组件形成图形界面的屏幕显
示部分
?通过事件处理的设计定义当用户点击这些组
件或进行键盘操作后程序所执行的动作
?通过设置布局管理器定义图形组件的位置安
置
组件
?所谓 组件,就是专门用于建立图形界面的
Java类。换句话说,图形界面是由这些组件
有机构成的。最常用的组件有 视窗框架
( JFrame),标签 ( JLabel),命令按钮
( JButton),文本框 ( JTextField、
JTextArea)等等。建立图形界面的第一步,
是要建立图形组件,也就是创建图形组件对
象,然后通过组件添加,形成组件之间的层
次结构
例 6-1的图形界面
建立和添加组件 (Components)
?图形用户界面的组件层次
?组件 JFrame和 JLabel
?组件 JTextField和 JButton
图形用户界面的组件层次
? 将组件 JLabel设置为组件 JFrame的下一层组件,是
用 JFrame的 Add方法实现的
? 如果一个组件可以成为另一个组件的上一层组件,
这个组件称为 容器组件 ( Container),否则称为 原
子组件 ( Atomic Component)
层次图中组件的对应关系
J T e x tFie ld 1 J L a b e l1 J T e x t F i e l d 2 J L a b e l 2
J P a n e l1
JBu tton 1 J Bu tton 2
J P a n e l 2
JFra m e
组件类 层次图中编号 生成的对象 图形界面中的作用
JFrame 无 AdderFrame 产生 AdderFrame视窗框架。
JPanel 1 panel1 添加 Jpanel1,2,JTextField1,2组件。
JPanel 2 panel2 添加 JButton1,2组件。
JTextField 1 TOprand1 接收加数,显示初值为,0.0”。
JLabel 1 LAdd 显示加号,+”。
JTextField 2 TOprand2 接收被加数,显示初值为,0.0”。
JLabel 2 LSum 显示和,显示初值为,=0.0”。
JButton 1 BAdd 命令按钮,显示,Add!”。
JButton 2 BClear 命令按钮,显示,Clear!”。
组件 JFrame和 JLabel
?视窗框架组件 JFrame用于建立一个主窗口,
是其它组件赖以添加的最基础的容器组件
?标签组件 JLabel用于显示一些程序输出信息,
可以是数据或提示信息
JFrame常用的构造方法和成员方法
构造方法 用途
JFrame( ) 创建无标题的视窗对象。
JFrame(String title) 创建以 title为标题的视窗对象。
成员方法
Container getContentPane( ) 获得 JFrame的容器,在此容器上才可以添加其它组件。
继承而来的方法
public void pack( ) 将视窗尺寸调整到能够显示所有组件的合适大小。
void
setResizable(boolean b ) 将窗体大小设置为可调(可通过鼠标拖动调整)。
public void
setSize(int width,int height) 设置窗体大小。
public void
setVisible(boolean b) 设置窗体是否可见。
public void show( ) 显示窗体内容
public void
addWindowListener(WindowListener l) 添加指定的视窗事件监听器 l。
JLabel常用的构造方法和成员方法
构造方法 用途
JLabel() 创建无显示内容的标签对象。
JLabel(String text) 创建显示内容为字符串 text的标签对象。
成员方法
String getText( ) 得到作为标签显示内容的字符串。
void setText(String text) 将字符串 text设置为标签的显示内容。
演示 JFrame和 JLabel的用法
//装入组件及其超类组件所在的包
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUIDemo1{
public static void main(String[ ] args) {
JFrame frame = new JFrame("GUIDemo1");//创建视窗对象
JLabel label = new JLabel(" 学 好 Java 用 处 大! ");//创建标签对象
frame.getContentPane( ).add(label);//将标签对象添加到视窗对象的容器中
//定义事件处理
frame.addWindowListener(new WindowAdapter( ){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.pack( );//调整视窗尺寸
frame.setVisible(true);//将视窗设置为可见
}
}
常用的 Container方法
成员方法 用途
Component
add(Component comp) 将指定组件依次添加到容器。
void
setLayout(LayoutManager mgr) 为容器设置布局管理器。
继承而来的方法
public void
setSize(int width,int height) 设置容器大小。
public void
setVisible(boolean b) 设置容器是否可见。
组件 JTextField和 JButton
?单行文本框组件 JTextField既可以用于显示输
出信息,又可以用于接受输入信息
?命令按钮组件 JButton用于接收用户的命令
常用的 JTextField方法
构造方法 用途
JTextField( ) 创建单行文本框对象。
JTextField(int columns) 创建指定列数的单行文本框对象。
JTextField(String text) 创建以字符串 text为指定内容的单行文本框对象。
JTextField(String text,int columns) 创建具有指定列数的、以字符串 text为指定内容的单行文本框对象。
成员方法
void addActionListener(ActionListener l) 为单行文本框添加事件监听器 l以接收来自单行文本框的 action事件。
继承而来的方法
void setText( String text) 将字符串 text的内容设置为单行文本框的内容。
String getText() 得到单行文本框的内容。
void setEditable(boolean b) 设置单行文本框的内容是否可编辑。
常用的 JButton方法
构造方法 用途
JButton (String text) 创建以字符串 text为显示内容的命令按钮对象。
成员方法
void
addActionListener(Action
Listener l)
为命令按钮组件对象添加事件监听器 l以接收来自该对象
的 action事件。
演示单行文本框和命令按钮
import java.awt.event.*;
import javax.swing.*;
public class GUIDemo2{
public static void main(String[ ] args) { //图形界面的屏幕显示部分
JFrame frame = new JFrame("GUIDemo1");
final JTextField Text= new JTextField(" 学 好 Java 用 处 大 ! ");
JButton Button = new JButton("按钮 ");
frame.getContentPane( ).setLayout(new FlowLayout( ));//设置布局管理器
frame.getContentPane( ).add(Text);
frame.getContentPane( ).add(Button);
frame.pack( );
frame.setVisible(true); //图形界面的事件处理部分
Button.addActionListener(new ActionListener( ){
public void actionPerformed(ActionEvent e){
Text.setText("这是 JTextField和 JButton的一个示例 ");
}
});
frame.addWindowListener(new WindowAdapter( ){
public void windowClosing(WindowEvent e) {
System.exit(0);
} });
}
例 6-2的图形界面
( a)开始的界面 ( b)点击按钮后变化
Java的事件处理
?事件处理四要素
?事件处理的三种做法
?事件类 EventObject
事件处理四要素
? Java中,当点击了某个按钮,或组件的状态发生了
某种变化,或按下了某个键,等等,都被认为是产
生了某个 事件
? 导致事件产生的组件称为 事件源
? 从事件处理的机制看,设计事件处理要解决的问题
主要有:如何识别事件源,如何识别事件,如何监
听事件
? 如何定义 事件服务程序,即当监听到某个事件源的
某个事件产生后,程序所执行的动作
? 事件源、事件、事件监听和事件服务程序是事件处
理的四个要素。
事件处理设计要做三件事
? 给作为事件源的组件添加事件监听器
? 设计一个执行该事件监听器接口的类,这个
类中给出对应的事件服务程序代码,这个含
有事件服务程序的类称为 事件服务类,事件
服务程序代码在事件服务类的 事件服务方法
中
? 用上述的事件服务类创建一个对象,作为上
述事件监听器的实参
主要的 Java事件监听器
监听器类型 监听的事件
ActionListener 用户点击命令按钮,在单行文本框键入内容后按回车键,或选择了一
个菜单项。
WindowListener 用户关闭主视窗( Jframe对象)。
MouseListener 当鼠标箭头到达某一组件时用户按动鼠标按钮。
MouseMotionListener 用户在组件上移动鼠标。
ComponentListener 组件变成可见。
FocusListener 组件得到键盘聚焦。
ListSelectionListener 组件表格或列表的选择发生变化。
事件处理的三种做法
? 建立事件服务类,创建事件服务类对象,为事件源
添加事件监听器,并将已创建的事件服务类对象作
为事件监听器的实参;
? 建立事件服务类,为事件源添加事件监听器,在事
件监听器的实参位置直接创建事件服务类对象;
? 为事件源添加事件监听器,在事件监听器的实参位
置建立无名的事件服务类,并用该类创建事件服务
类对象。
第一种 Button的事件处理的做法
//建立事件服务类
class ButtonActionListener implements ActionListener{
public void actionPerformed(ActionEvent e){
Text.setText("这是 JTextField和 JButton的一个示例 ");
}
}
//创建事件服务对象
ButtonActionListener myButtonActionListener=new ButtonActionListener( );
//为事件源添加事件监听器,并将已创建的事件服务类对象作为事件监听器的实参
Button.addActionListener(myButtonActionListener);
第二种 Button的事件处理的做法
//建立事件服务类
class ButtonActionListener implements ActionListener{
public void actionPerformed(ActionEvent e){
Text.setText("这是 JTextField和 JButton的一个示例 ");
}
}
//为事件源添加事件监听器,在事件监听器的实参位置直接创建事件服务类对象
Button.addActionListener(new ButtonActionListener( ));
一个加法器的例子
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Adder implements ActionListener {
JFrame AdderFrame;
JTextField TOprand1; //被加数
JTextField TOprand2; //加数
JLabel LAdd,LSum; //加号,和
JButton BAdd; //Add!按钮
int i=0;
public Adder( ) { //建立图形界面的屏幕显示部分
AdderFrame = new JFrame("AdderFrame");
TOprand1 = new JTextField("0.0");
TOprand2 = new JTextField("0.0");
LAdd=new JLabel("+");
LSum=new JLabel("= ");
BAdd=new JButton("Add!");
AdderFrame.getContentPane( ).setLayout(new FlowLayout( ));
AdderFrame.getContentPane( ).add(TOprand1);
AdderFrame.getContentPane( ).add(LAdd);
AdderFrame.getContentPane( ).add(TOprand2);
AdderFrame.getContentPane( ).add(LSum);
AdderFrame.getContentPane( ).add(BAdd);
AdderFrame.pack( );
AdderFrame.setVisible(true);
//为命令按钮添加事件监听器,监听器的实参是 Adder类的对象
BAdd.addActionListener(this); // Adder类的事件服务方法
public void actionPerformed(ActionEvent event) { //事件服务代码
i=(i+1)%2;
if(i==1){ //i为奇数,求和
int sum= (int)(Double.valueOf(TOprand1.getText( )).doubleValue( )
+Double.valueOf(TOprand2.getText( )).doubleValue( ));
LSum.setText("="+sum);
}else{ //i为偶数,清零
TOprand1.setText("0.0");
TOprand2.setText("0.0");
LSum.setText("= ");
};
}
AdderFrame.addWindowListener(new WindowAdapter( ){//主视窗关闭的事件处理
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[ ] args) {
Adder adder = new Adder( );
}
}
例 6-3的图形界面
( a)开始的界面 ( b)做了加法后的界面
事件类 EventObject
?Java中的事件类就是为此而提供的机制。
Java的事件处理框架中,事件服务程序代码
包含在事件服务方法的方法体中,事件服务
方法的参数就是事件类对象(严格地讲,是
EventObject的相关子类的对象),事件服务
代码可以从中得到有关事件的信息
事件类 EventObjec的结构
成员变量 说明
protected Object source 事件最初赖以产生的对象。
构造方法
EventObject(Object source) 构造一个原型事件。
方法
Object getSource( ) 得到事件最初赖以产生的对象。
String toString( ) 返回事件类 EventObject对象的 String型表示。
组件 JPanel与布局管理器
?布局管理器 FlowLayout
?布局管理器 BorderLayout
?组件 JPanel
布局管理
?当一个容器组件上要添加多个组件时,就有
一个添加组件的位置问题,即要把这些组件
添加到容器组件的什么位置上。 Java中用布
局管理器来进行布局管理。在向一个容器组
件添加组件之前,先要用容器组件的
setLayout方法设置容器组件的布局管理器,
指定容器组件上的组件布局,以后添加到容
器组件的组件,就照此布局进行排列入位。
布局管理器 FlowLayout
?当将布局管理器设置为 FlowLayout时,添加
到容器组件上的组件将按照添加的次序在一
行上从左至右排列入位。如果一行排列不下,
则一行排满后从下一行继续排列。在每一行
中,组件将根据创建 FlowLayout对象时的说
明进行居中、左对齐或右对齐
布局管理器 FlowLayout的构造方法
public FlowLayout( );
public FlowLayout(int alignment);
public FlowLayout(int alignment,int
horizontalGap,int verticalGap);
其中参数 alignment说明组件的对齐方式
演示 FlowLayout的用法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Adder1 implements ActionListener {
JFrame AdderFrame;
JTextField TOprand1;
JTextField TOprand2;
JLabel LAdd,LSum;
JButton BAdd,BClear;
public Adder1( ) { // 建立主窗口和容器
AdderFrame = new JFrame("AdderFrame");
TOprand1 = new JTextField("0.0");
TOprand2 = new JTextField("0.0");
LAdd=new JLabel("+");
LSum=new JLabel("= ");
BAdd=new JButton("Add!");
BClear=new JButton("Clear!"); // 监听 BAdd按钮的事件
BAdd.addActionListener(this); // Bclear事件处理
BClear.addActionListener(new ActionListener( ){
public void actionPerformed(ActionEvent event){
TOprand1.setText("0.0");
TOprand2.setText("0.0");
LSum.setText("= "); }
});
//设置布局管理器为 FlowLayout
AdderFrame.getContentPane( ).setLayout(new FlowLayout( ));
AdderFrame.getContentPane( ).add(TOprand1);
AdderFrame.getContentPane( ).add(LAdd);
AdderFrame.getContentPane( ).add(TOprand2);
AdderFrame.getContentPane( ).add(LSum);
AdderFrame.getContentPane( ).add(BAdd);
AdderFrame.getContentPane( ).add(BClear);
//Window关闭事件处理
AdderFrame.addWindowListener(new WindowAdapter( ){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
AdderFrame.pack( );
AdderFrame.setVisible(true);
} // Badd事件处理
public void actionPerformed(ActionEvent event) {
int sum= (int)(Double.valueOf(TOprand1.getText( )).doubleValue( )
+Double.valueOf(TOprand2.getText( )).doubleValue( ));
LSum.setText("="+sum);
}
public static void main(String[ ] args) {
Adder1 adder1 = new Adder1( );
}
}
上例的图形界面
( a)开始的界面及点击 Clear按钮后的界面 ( b)做了加法后的界面
布局管理器 BorderLayout
? 当将布局管理器设置为 BorderLayout时,组件将被
分布在地图上东西南北中五个区域。添加组件时要
指明这个组件的位置。通常,容器组件只添加不足
五个组件。
? BorderLayout类有如下的构造方法,
BorderLayout( );
BorderLayout(int horizontalGap,int verticalGap);
? 其中,参数 horizontalGap和 verticalGap分别指定组
件之间的水平间隙和垂直间隙
组件 JPanel
?面板组件 JPanel是一个中间层次的容器组件,
一方面 JPanel对象可以包含其它组件,另一
方面 JPanel对象又可以被添加到另一个容器
组件上。通过 JPanel和布局管理器的配合使
用,可以设计出层次更丰富、结构更复杂的
图形用户界面
常用的 JPanel类的成员方法
构造方法 说明
JPanel( ) 创建一个面板对象,其默认布局管理器是
FlowLayout。
JPanel(LayoutManager layout) 创建一个具有指定布局管理器的面板对象。
继承而来的成员方法
public void
setVisible(boolean b)
设置面板是否可见。
public void setLayout(LayoutManager mgr) 设置面板布局管理器。
public void
setSize(int width,int height)
设置面板大小。
public Component add(Component comp) 向面板添加组件
public void add(Component comp,Object
constraints)
按指定位置向面板添加组件。
演示 JPanel和布局管理器
BorderLayout的用法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Adder2 implements ActionListener {
JFrame AdderFrame;
JTextField TOprand1;
JTextField TOprand2;
JLabel LAdd,LSum;
JButton BAdd,BClear;
JPanel panel1,panel2;
public Adder2( ) { // 建立顶层容器组件对象
AdderFrame = new JFrame("AdderFrame");
TOprand1 = new JTextField("0.0");
TOprand2 = new JTextField("0.0");
LAdd=new JLabel("+");
LSum=new JLabel("= 0.0 ");
BAdd=new JButton(" Add! ");
BClear=new JButton("Clear!");
panel1=new JPanel( );
panel2=new JPanel( );
//监听来自 Badd的事件
BAdd.addActionListener(this);
//按钮 Bclear的事件处理
BClear.addActionListener(new ActionListener( ){
public void actionPerformed(ActionEvent event){
TOprand1.setText("0.0");
TOprand2.setText("0.0");
LSum.setText("= 0.0 ");
}
});
//建立中间容器面板 panel1,panel1的布局管理器为 FlowLayout
panel1.setLayout(new FlowLayout( ));
panel1.add(TOprand1);
panel1.add(LAdd);
panel1.add(TOprand2);
panel1.add(LSum);
//建立中间容器面板 panel2,panel2的布局管理器为 FlowLayout
panel2.setLayout(new FlowLayout( ));
panel2.add(BAdd);
panel2.add(BClear);
//建立顶层容器 ContentPane,ContentPane的布局管理器为 BorderLayout
AdderFrame.getContentPane( ).setLayout(new BorderLayout( ));
AdderFrame.getContentPane( ).add(panel1,BorderLayout.NORTH);
AdderFrame.getContentPane( ).add(panel2,BorderLayout.SOUTH);
//窗口关闭事件处理
AdderFrame.addWindowListener(new WindowAdapter( ){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
AdderFrame.pack( );
AdderFrame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
int sum= (int)(Double.valueOf(TOprand1.getText( )).doubleValue( )
+Double.valueOf(TOprand2.getText( )).doubleValue( ));
LSum.setText("="+sum);
}
public static void main(String[ ] args) {
Adder2 adder2 = new Adder2( );
}
}
上例的图形界面
( a)开始的界面及点击 Clear按钮后的界面 ( b)做了加法后的界面
几个重要的图形组件
?JCheckBox
?JRadioButton和 RadioButtonGroup
?JTextArea和 JScrollPane
?JTabbedPane
JCheckBox
?在图形界面中,程序常常会给出几项选择,
并允许用户在多项选择中选择一项或多项。
复选框按钮组件 JcheckBox可用于接收用户
的这种多选输入
常用的 JcheckBox的方法
构造方法 说明
JCheckBox( ) 创建一个初始未被选中的复选框按钮组件对象。
JCheckBox(String text) 创建一个初始未被选中的复选框按钮组件对象,对象的
显示内容是 text的内容。
JCheckBox(String text,
boolean selected)
创建一个初始已被选中的复选框按钮组件对象,对象的
显示内容是 text的内容。
继承而来的成员方法
void addItemListener(ItemListener l) 为复选框按钮组件对象添加事件监听器 l以接收来自该对
象的 item事件。
void setSelected(boolean b) 设置复选框按钮组件对象是否被选中。
void setMnemonic(
KeyEvent.VK_ keyName )
设置产生与选择复选框按钮组件对象等效事件的键。
演示 JcheckBox的用法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUIDemo3 extends JPanel {
JCheckBox right1;
JCheckBox right2;
JCheckBox right4;
JCheckBox right8;
StringBuffer choices;
JLabel displayLabel;
public GUIDemo3( ) {
right1 = new JCheckBox("1");
right1.setMnemonic(KeyEvent.VK_4);
right1.setSelected(true);
right2 = new JCheckBox("2");
right2.setMnemonic(KeyEvent.VK_3);
right2.setSelected(true);
right4 = new JCheckBox("4");
right4.setMnemonic(KeyEvent.VK_2);
right4.setSelected(true);
right8 = new JCheckBox("8");
right8.setMnemonic(KeyEvent.VK_1);
right8.setSelected(true);
//创建事件服务类 CheckBoxListener的对象 myListener
CheckBoxListener myListener = new CheckBoxListener( );
//为 right1,right2,right4,right8添加事件监听器
right1.addItemListener(myListener);
right2.addItemListener(myListener);
right4.addItemListener(myListener);
right8.addItemListener(myListener);
//初始化 choices
choices = new StringBuffer("0000");
//创建标签对象
displayLabel = new JLabel(choices.toString( ));
//创建面板对象 checkPanel
JPanel checkPanel = new JPanel( );
//将复选框按钮添加到 checkPanel的同一列
checkPanel.setLayout(new GridLayout(0,1));
checkPanel.add(right1);
checkPanel.add(right2);
checkPanel.add(right4);
checkPanel.add(right8);
setLayout(new BorderLayout( ));
add(checkPanel,BorderLayout.WEST);
add(displayLabel,BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(10,60,10,60));//设置边距
}
//复选框的事件服务类
class CheckBoxListener implements ItemListener {
public void itemStateChanged(ItemEvent e) {
int index = 0;
char c = '-';
Object source = e.getItemSelectable( );
if (source == right8) {
index = 0;
c = '8';
} else if (source == right4) {
index = 1;
c = '4';
} else if (source == right2) {
index = 2;
c = '2';
} else if (source == right1) {
index = 3;
c = '1';
}
if (e.getStateChange( ) == ItemEvent.DESELECTED)
c = '-';
choices.setCharAt(index,c);
displayLabel.setText(choices.toString( ));
}
}
public static void main(String s[ ]) {
JFrame frame = new JFrame("CheckBoxDemo");
//主窗口关闭事件处理
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setContentPane(new GUIDemo3( ));
frame.pack( );
frame.setVisible(true);
}
}
例 6-6的图形界面
( a)全部选中的界面 ( b)选中 2个复选框的界面 ( c)均未选中的界面
JRadioButton和 RadioButtonGroup
?如果程序提供给用户几种选择,但只允许用
户选择其中一种(通常是必须选择一种),
则可以采用单选按钮组件 JRadioButton。
JRadioButton用于接收用户的单选输入。按
钮组组件 ButtonGroup与 JRadioButton配合使
用,建立多个单选按钮之间的这种单选关系
常用的 JRadioButton方法
构造方法 说明
JRadioButton( ) 创建 JradioButton对象,初始状态:未被选中,没有文本
提示信息。
JRadioButton(String text) 创建 JradioButton对象,初始状态:未被选中,文本提示
信息是 text的内容。
JRadioButton(String text,
boolean selected)
创建 JradioButton对象,初始状态:已被选中,文本提示
信息是 text的内容。
继承而来的成员方法
void setSelected(boolean b) 设置 JradioButton对象是否被选中。
void setText( String text) 设置 JradioButton对象文本提示信息。
public void
setActionCommand(String
actionCommand)
设置 JradioButton对象的事件命令。
常用的 ButtonGroup方法
构造方法 说明
ButtonGroup( ) 创建 ButtonGroup对象。
继承而来的成员方法
void add(AbstractButton rt) 将组件 rt添加到按钮组 ButtonGroup对象中。
void remove(AbstractButton rt) 将组件 rt从按钮组 ButtonGroup对象中移去。
演示 JradioButton和 ButtonGroup用法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUIDemo4 extends JPanel {
static JFrame frame;
static String birdString = "鸟 ";
static String catString = "猫 ";
static String dogString = "狗 ";
static String rabbitString = "兔 ";
JLabel display;
public GUIDemo4( ) { // 创建单选按钮对象
JRadioButton birdButton = new JRadioButton(birdString);
birdButton.setMnemonic(KeyEvent.VK_B);
birdButton.setActionCommand(birdString);
JRadioButton catButton = new JRadioButton(catString);
catButton.setMnemonic(KeyEvent.VK_C);
catButton.setActionCommand(catString);
JRadioButton dogButton = new JRadioButton(dogString);
dogButton.setMnemonic(KeyEvent.VK_D);
dogButton.setActionCommand(dogString);
JRadioButton rabbitButton = new JRadioButton(rabbitString);
rabbitButton.setMnemonic(KeyEvent.VK_R);
rabbitButton.setActionCommand(rabbitString);
//将单选按钮组成一组,建立它们之间的单选关系
ButtonGroup group = new ButtonGroup( );
group.add(birdButton);
group.add(catButton);
group.add(dogButton);
group.add(rabbitButton);
//为单选按钮添加事件监听器
RadioListener myListener = new RadioListener( );
birdButton.addActionListener(myListener);
catButton.addActionListener(myListener);
dogButton.addActionListener(myListener);
rabbitButton.addActionListener(myListener);
//建立标签对象 display
display = new JLabel("这是 RadioButton的一个示例。 ");
display.setPreferredSize(new Dimension(180,60));//设置标签对象的大小
JPanel radioPanel = new JPanel( );
radioPanel.setLayout(new GridLayout(0,1));//按钮对象按一列添加到面板
radioPanel.add(birdButton);
radioPanel.add(catButton);
radioPanel.add(dogButton);
radioPanel.add(rabbitButton);
setLayout(new BorderLayout( ));
add(radioPanel,BorderLayout.WEST);
add(display,BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(20,20,20,0));
}
//事件服务类
class RadioListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
display.setText( " 你选中了 "+e.getActionCommand( )+"。 ");
}
}
public static void main(String s[ ]) {
frame = new JFrame("RadioButtonDemo");
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.getContentPane( ).add(new GUIDemo4( ),BorderLayout.CENTER);
frame.pack( );
frame.setVisible(true);
}
}
例 6-7的图形界面
( a)开始的界面 ( b)选中了单选按钮“鸟”的界面
一个算术测试程序
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CalcuExercises {
//创建所需组件对象
static JFrame frame = new JFrame("算术练习测验 ");
static JPanel PRadio=new JPanel( );//单选按钮面板
static JRadioButton BAdd=new JRadioButton("做加法 ");//加法按钮
static JRadioButton BSub=new JRadioButton("做减法 ");//减法按钮
static JRadioButton BMul=new JRadioButton("做乘法 "); //乘法按钮
static JRadioButton BDiv=new JRadioButton("做除法 "); //除法按钮
static ButtonGroup group = new ButtonGroup( ); //单选按钮组
static JPanel PCheck=new JPanel( ); //复选框面板
static JCheckBox Total=new JCheckBox("显示已做题数 ");//是否显示“已做题数”复选框,
//选中则显示
static JCheckBox Right=new JCheckBox("显示做对题数 ");//是否显示“做对题数”复选框,
//选中则显示
static JPanel PCalcu=new JPanel( ); //运算面板
static JLabel LOperand1=new JLabel(" ");//操作数 1
static JLabel LOpcode=new JLabel("+"); //加号
static JLabel LOperand2=new JLabel(" ");//操作数 2
static JLabel LEqu=new JLabel("="); //等号
static JTextField Answer=new JTextField("0000");//计算结果
static JButton Ok=new JButton("确认 !"); //确认按钮
static JPanel PRecord=new JPanel( ); //记录面板
static int totalNunmber=0; //已做题数
static int rightNumber=0; //做对题数
static JLabel LTotal=new JLabel(" 已做 "+totalNunmber+" 题 ");//显示已做题数
static JLabel LRight=new JLabel(" 做对 "+rightNumber+" 题 "); //显示做对题数
static JPanel PCombine=new JPanel( ); //组合面板
static JPanel Exercise=new JPanel( ); //顶层面板
int calcuType=1; //运算类型。 1:加,2:减,3:乘,4:除
int totalSelected=1;
int rightSelected=1;
public CalcuExercises( ){
//建立运算类型单选按钮面板
PRadio.setLayout(new GridLayout(0,1));
BAdd.setSelected(true);
group.add(BAdd);
group.add(BSub);
group.add(BMul);
group.add(BDiv);
PRadio.add(BAdd);
PRadio.add(BSub);
PRadio.add(BMul);
PRadio.add(BDiv);
PRadio.setBorder(BorderFactory.createEmptyBorder(0,30,0,20));
Total.setSelected(true);
Right.setSelected(true);
//建立显示控制复选框面板
PCheck.setLayout(new GridLayout(0,1));
PCheck.add(Total);
PCheck.add(Right);
//建立运算面板
PCalcu.setLayout(new FlowLayout( ));
PCalcu.setBorder(BorderFactory.createEmptyBorder(0,0,20,0));
PCalcu.add(LOperand1);
PCalcu.add(LOpcode);
PCalcu.add(LOperand2);
PCalcu.add(LEqu);
PCalcu.add(Answer);
//建立运算结果记录显示面板
PRecord.setLayout(new FlowLayout( ));
PRecord.add(LTotal);
PRecord.add(LRight);
PRecord.setBorder(BorderFactory.createEmptyBorder(20,0,0,0));
//建立组合面板,含有运算面板和运算结果记录显示面板,两面板在组合面板中上下布局
PCombine.setLayout(new BorderLayout( ));
PCombine.add(PCalcu,BorderLayout.NORTH);
PCombine.add(Ok,BorderLayout.CENTER);
PCombine.add(PRecord,BorderLayout.SOUTH);
//建立顶层面板
Exercise.setLayout(new FlowLayout( ));
Exercise.add(PCombine);
Exercise.add(PRadio);
Exercise.add(PCheck);
Exercise.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
ButtonListener myButtonListener=new ButtonListener( );
Ok.addActionListener(myButtonListener);
CheckBoxListener myCheckBoxListener = new CheckBoxListener( );
Total.addItemListener(myCheckBoxListener);
Right.addItemListener(myCheckBoxListener);
BAdd.setActionCommand("+");
BSub.setActionCommand("-");
BMul.setActionCommand("*");
BDiv.setActionCommand("/");
RadioListener myRadioListener = new RadioListener( );
BAdd.addActionListener(myRadioListener);
BSub.addActionListener(myRadioListener);
BMul.addActionListener(myRadioListener);
BDiv.addActionListener(myRadioListener);
int x,y,temp;
String s=new String( );
//产生随机数,作为参与运算的操作数,置于 x,y中
//确保 x,y不为 0且 x>y
x=(int)(90*Math.random( ));
while(x==0){x=(int)(90*Math.random( ));};
y=(int)(90*Math.random( ));
while(y==0){y=(int)(90*Math.random( ));};
if(y>x){temp=x;x=y;y=temp;};
LOperand1.setText(s.valueOf(" "+x+" "));
LOperand2.setText(s.valueOf(" "+y+" "));
frame.getContentPane( ).setLayout(new FlowLayout( ));
frame.getContentPane( ).add(Exercise);
frame.pack( );
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
})
}
//命令按钮事件服务类
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
int x,y,z,temp;
String s=new String( );
z=(int)Integer.valueOf(Answer.getText( ).trim( )).intValue( );
x=(int)Integer.valueOf(LOperand1.getText( ).trim( )).intValue( );
y=(int)Integer.valueOf(LOperand2.getText( ).trim( )).intValue( );
if(calcuType==1){if(x+y==z){rightNumber++;};}else
if(calcuType==2){if(x-y==z){rightNumber++;};}else
if(calcuType==3){if(x*y==z){rightNumber++;};}else
{if(x/y==z){rightNumber++;};};
x=(int)(90*Math.random( ));while(x==0){x=(int)(90*Math.random( ));};
y=(int)(90*Math.random( )); while(y==0){y=(int)(90*Math.random( ));};
if(y>x){temp=x;x=y;y=temp;};
LOperand1.setText(s.valueOf(" "+x+" "));
LOperand2.setText(s.valueOf(" "+y+" "));
totalNunmber++;
LTotal.setText("已做 "+totalNunmber+"题 ");
LRight.setText("做对 "+rightNumber+"题 ");
if(totalNunmber>100)System.exit(0);
}
}
class CheckBoxListener implements ItemListener { //复选框事件服务类
public void itemStateChanged(ItemEvent e) {
Object source = e.getItemSelectable( );
if (source == Total) {
totalSelected =(totalSelected+1)%2;
} else if (source == Right) {
rightSelected =(rightSelected+1)%2;
};
if(totalSelected==1){LTotal.setVisible(true);}else{LTotal.setVisible(false);};
if(rightSelected==1){LRight.setVisible(true);}else{LRight.setVisible(false);};
}
}
class RadioListener implements ActionListener { //单选按钮事件服务类
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand( ).equals("+")){ calcuType=1;LOpcode.setText("+");}
else if(e.getActionCommand( ).equals("-")){ calcuType=2;LOpcode.setText("-");}
else if(e.getActionCommand( ).equals("*")){ calcuType=3;LOpcode.setText("*");}
else { calcuType=4;LOpcode.setText("/");};
}
}
public static void main(String s[ ]) { //主方法
CalcuExercises exe1=new CalcuExercises( );
}
}
开始的界面
点击了“做减法”单选按钮后的界面
两复选框“显示已做题数”和
“显示做对题数”均未选中的界
面
JTextArea和 JScrollPane
?多行文本框组件 JTextArea允许用户编辑具有
多行的文本,这一组件既可以用于输出信息,
也可以用于接收信息。滚动窗格组件
JScrollPane是又一种中间层次的容器组件,
当窗格含有的内容显示不下时,允许用户使
用水平方向和垂直方向的滚动条上下左右移
动窗格的内容,从而可以看见窗格含有的全
部内容
常用的 JTextArea方法
构造方法 说明
JTextArea(int rows,int columns) 创建一个具有指定行数和列数 JTextArea对象。
JTextArea(String text) 创建一个显示指定文本内容的 JTextArea对象,所显示的文本内容为空。
JTextArea(String text,int rows,int columns) 创建一个显示指定文本内容并具有指定行数和列数的 JTextArea对象。
成员方法
void append(String str) 将所给 str内容添加到显示的文本内容之后。
void insert(String str,int pos) 将所给 str内容插入到显示的文本的指定位置。
void replaceRange(String str,int start,int end) 将显示文本中从 start开始至 end结束的部分替换为指定内容 str。
继承而来的成员方法
public void
setEditable(boolean b)
设置 JTextArea对象是否可被用户编辑。
String getText() 得到 JTextArea对象的显示文本内容。
void setText(String t) 将显示文本内容设置成指定内容。
常用的 JScrollPane方法
构造方法 说明
JScrollPane( ) 创建一个没有显示口的 JScrollPane对象,它的垂直方向和水平方向的滚动条会在需要时出现。
JScrollPane(Component view)
创建一个包含组件对象 view ( view中含有要显示的内容,
下同)的 JScrollPane对象,它的垂直方向和水平方向
的滚动条会在显示口过小不能显示出全部显示内容时
出现。
JScrollPane(Component view,int
vsbPolicy,int hsbPolicy)
创建一个在显示口中显示 view内容的 JScrollPane对象,它
的滚动条出现方式由参数 vsbPolicy和 hsbPolicy给出。
演示 JTextArea和 JScrollPane的用法
?多行文本框组件 JTextArea允许用户编辑具有
多行的文本,这一组件既可以用于输出信息,
也可以用于接收信息。滚动窗格组件
JScrollPane是又一种中间层次的容器组件,
当窗格含有的内容显示不下时,允许用户使
用水平方向和垂直方向的滚动条上下左右移
动窗格的内容,从而可以看见窗格含有的全
部内容
常用的 JTextArea方法
构造方法 说明
JTextArea(int rows,int columns) 创建一个具有指定行数和列数 JTextArea对象。
JTextArea(String text) 创建一个显示指定文本内容的 JTextArea对象,所显示的文本内容为空。
JTextArea(String text,int rows,int
columns)
创建一个显示指定文本内容并具有指定行数和列数的 JTextArea对象。
成员方法
void append(String str) 将所给 str内容添加到显示的文本内容之后。
void insert(String str,int pos) 将所给 str内容插入到显示的文本的指定位置。
void replaceRange(String str,int start,
int end)
将显示文本中从 start开始至 end结束的部分替换为指定内容 str。
继承而来的成员方法
public void
setEditable(boolean b)
设置 JTextArea对象是否可被用户编辑。
String getText() 得到 JTextArea对象的显示文本内容。
void setText(String t) 将显示文本内容设置成指定内容。
常用的 JScrollPane方法
构造方法 说明
JScrollPane( ) 创建一个没有显示口的 JScrollPane对象,它的垂直方
向和水平方向的滚动条会在需要时出现。
JScrollPane(Component view) 创建一个包含组件对象 view ( view中含有要显示的内
容,下同)的 JScrollPane对象,它的垂直方向和
水平方向的滚动条会在显示口过小不能显示出全
部显示内容时出现。
JScrollPane(Component view,int
vsbPolicy,int hsbPolicy)
创建一个在显示口中显示 view内容的 JScrollPane对象,
它的滚动条出现方式由参数 vsbPolicy和 hsbPolicy
给出。
演示 JTextArea和 JScrollPane的用法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUIDemo5 extends JPanel implements ActionListener {
JTextField textField;
JTextArea textArea;
String newline = "\n";
public GUIDemo5( ) {
//创建所需组件对象
textField = new JTextField(20);
textField.addActionListener(this);
textArea = new JTextArea(5,20);
textArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(textArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
//将组件添加到面板
GridBagLayout gridBag = new GridBagLayout( );
setLayout(gridBag);
GridBagConstraints c = new GridBagConstraints( );
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.HORIZONTAL;
gridBag.setConstraints(textField,c);
add(textField);
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
gridBag.setConstraints(scrollPane,c);
add(scrollPane);
} // textField的事件服务方法
public void actionPerformed(ActionEvent evt) {
String text = textField.getText( );
textArea.append(text + newline);
textField.selectAll( );
}
public static void main(String[ ] args){
JFrame frame=new JFrame("GUIDemo5"); //主窗口关闭事件处理
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.getContentPane( ).add(new GUIDemo5( ));
frame.pack( );
frame.setVisible(true);
};
}
例 6-9的图形界面
JTabbedPane
? 标签面板组件 JTabbedPane也是一种中间层次的容
器组件,它将多个面板集成在一个组件中,每个面板
有一个标签(这里的标签是一种小标题,起到提示
面板内容的作用,与 JLabel的含义有区别)。当选
中某个标签时,组件显示对应的面板内容,而组件
中未被选中的面板则不予显示。当图形界面的功能
较多时,可以将这些功能分类,并使用标签面板将
实现某一类功能的组件安排到标签面板组件的某一
块面板上,使图形界面更加简洁清晰
常用的 JTabbedPane的方法
构造方法 说明
public JTabbedPane( ) 创建一个 JTabbedPane对象。
成员方法
void addTab(String title,Icon icon,
Component component,String tip)
将组件 component添加到标签面板对象的一个面板上,这
个面板的标签是字符串 title和 /或图标 icon,面板标签
的提示信息是 tip的内容。
演示 JTabbedPane的用法
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUIDemo6 extends JPanel {
public GUIDemo6( ) {
//建立标签面板
JTabbedPane tabbedPane = new JTabbedPane( );
Component panel1 = makeTextPanel("你选中了标签 1");
tabbedPane.addTab("标签 1",null,panel1,null);
tabbedPane.setSelectedIndex(0);
Component panel2 = makeTextPanel("你选中了标签 2");
tabbedPane.addTab("标签 2",null,panel2,null);
Component panel3 = makeTextPanel("你选中了标签 3");
tabbedPane.addTab("标签 3",null,panel3,null);
Component panel4 = makeTextPanel("你选中了标签 4");
tabbedPane.addTab("标签 4",null,panel4,null);
setLayout(new GridLayout(0,1));
add(tabbedPane);
}
// makeTextPanel方法,返回值类型为 Component
protected Component makeTextPanel(String text) {
JPanel panel = new JPanel( );
JLabel filler = new JLabel(text);
filler.setHorizontalAlignment(JLabel.CENTER);
panel.setLayout(new GridLayout(1,1));
panel.add(filler);
return panel;
}
public static void main(String[ ] args) {
JFrame frame = new JFrame("TabbedPaneDemo");
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.getContentPane( ).add(new GUIDemo6( ));
frame.setSize(400,125);
frame.setVisible(true);
}
}
例 6-10的图形界面
成绩处理程序
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ScoreSort extends JPanel {
class Student{
int SNumber=0,Score=0;
}
Student[ ] st=new Student[10];//设所能处理的成绩个数为 10
int i;
JTextField TNumberIn=new JTextField(8);//学号输入框
JTextField TScoreIn=new JTextField(8);//成绩输入框
JTextField TNumberQuery=new JTextField(8);//学号查询框
JTextField TScoreQuery=new JTextField(8);//成绩查询框
JTextArea textArea = new JTextArea(5,20);//显示排序结果
public ScoreSort( ) { //数组元素初始化
int i=0;
for(i=0;i<st.length;i++){
st[i]=new Student( );
};
JTabbedPane tabbedPane = new JTabbedPane( );
//建立输入面板
JPanel panel1 =new JPanel( );
panel1.setLayout(new BorderLayout( ));
JLabel LNumberIn=new JLabel("请输入学号,");
JPanel Panel11=new JPanel( );
Panel11.setLayout(new FlowLayout( ));
Panel11.add(LNumberIn);
Panel11.add(TNumberIn);
panel1.add(Panel11,BorderLayout.NORTH);
JLabel LScoreIn=new JLabel("请输入成绩,");
JPanel Panel12=new JPanel( );
Panel12.setLayout(new FlowLayout( ));
Panel12.add(LScoreIn);
Panel12.add(TScoreIn);
panel1.add(Panel12,BorderLayout.CENTER);
JButton BIn=new JButton("确 认 ");
panel1.add(BIn,BorderLayout.SOUTH);
BIn.addActionListener(new InActionListener( ));
tabbedPane.addTab("成绩输入 ",null,panel1,null);
tabbedPane.setSelectedIndex(0);//一开始选中“成绩输入”标签面板
//建立排序面板
JPanel panel2 =new JPanel( );
JButton BSort=new JButton(" 排 序 ");
BSort.addActionListener(new SortActionListener( ));
textArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(textArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
GridBagLayout gridBag = new GridBagLayout( );
panel2.setLayout(gridBag);
GridBagConstraints c = new GridBagConstraints( );
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
gridBag.setConstraints(scrollPane,c);
panel2.add(scrollPane);
c.fill = GridBagConstraints.HORIZONTAL;
gridBag.setConstraints(BSort,c);
panel2.add(BSort);
tabbedPane.addTab("成绩排序 ",null,panel2,null);
//建立查询面板
JPanel panel3 = new JPanel( );
panel3.setLayout(new BorderLayout( ));
JLabel LNumberQuery=new JLabel("请输入学号,");
JPanel Panel31=new JPanel( );
Panel31.setLayout(new FlowLayout( ));
Panel31.add(LNumberQuery);
Panel31.add(TNumberQuery);
panel3.add(Panel31,BorderLayout.NORTH);
TScoreQuery.setEditable(false);
JLabel LScoreQuery=new JLabel("您的成绩是,");
JPanel Panel32=new JPanel( );
Panel32.setLayout(new FlowLayout( ));
Panel32.add(LScoreQuery);
Panel32.add(TScoreQuery);
panel3.add(Panel32,BorderLayout.CENTER);
JButton BQuery=new JButton("查 询 ");
panel3.add(BQuery,BorderLayout.SOUTH);
BQuery.addActionListener(new QueryActionListener( ));
tabbedPane.addTab("成绩查询 ",null,panel3,null);
setLayout(new GridLayout(0,1));
add(tabbedPane);
}
class InActionListener implements ActionListener{ //事件处理 ------成绩输入事件服务
public void actionPerformed(ActionEvent event){
if(i<st.length){
st[i].SNumber=Integer.valueOf(TNumberIn.getText( )).intValue( );
st[i].Score=Integer.valueOf(TScoreIn.getText( )).intValue( );
};
i++;
}
}
class SortActionListener implements ActionListener{ //成绩排序事件服务
public void actionPerformed(ActionEvent event){
int i,j,temp;
String s=new String( );
for(i=0;i<st.length-1;i++)
for(j=i+1;j<st.length;j++){
if(st[i].Score<st[j].Score){
temp=st[i].Score;st[i].Score=st[j].Score;st[j].Score=temp;
temp=st[i].SNumber;st[i].SNumber=st[j].SNumber;st[j].SNumber=temp;
};};
textArea.setText("学号 成绩 \n");
for(i=0;i<st.length;i++){
if(st[i].SNumber!=0){
textArea.append(s.valueOf(st[i].SNumber)+ " "+s.valueOf(st[i].Score)+"\n");
};};
}
}
//成绩查询事件服务
class QueryActionListener implements ActionListener{
public void actionPerformed(ActionEvent event){
int keyWord,i=0;
String s=new String( );
keyWord=Integer.valueOf(TNumberQuery.getText( )).intValue( );
for(i=0;i<st.length;i++)
if(st[i].SNumber==keyWord){
TScoreQuery.setText(s.valueOf(st[i].Score));
break;
};
if(i>=st.length)
TScoreQuery.setText("未找到您的成绩 ");
}
}
//主方法
public static void main(String[ ] args) {
JFrame frame = new JFrame("成绩处理 ");
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.getContentPane( ).add(new ScoreSort( ));
frame.setSize(300,160);
frame.setVisible(true);
}
}
例 6-10的图形界面
*GUI组件包与 JComponent
?Swing和 AWT包
?JComponent
Swing和 AWT包
?在于 Swing组件不含有任何与平台有关的本
地代码。 Swing组件的这个特点使得基于
Swing组件的图形界面程序具有良好的跨平
台性能
?此外,即使最简单的 Swing组件也提供了比
AWT组件更强的功能
一个基于 AWT的程序转换到基于
Swing的程序
? 为要被转换的程序保留一个备份
? 移去所有对 java.awt包的引用
? 对于 applet程序,还要移去装入 java.applet.*的语句和对 java.applet.Applet的引用
? 装入 Swing包
? 小心线程安全问题 —— AWT是线程安全的,但 Swing不是
? 将每个 AWT组件改成与它对应的或最接近的 Swing组件
? 相应地改变对 add和 setLayout方法的调用 —— 在使用 AWT组件时,可以直接向 frames、
dialogs、和 applets添加组件,并可以直接设置这些组件的布局管理器,但在使用 Swing
组件时则必须先添加一个 content pane
? 根据绘画( paint)的类型,将绘画代码移出其 paint 和 update方法并移入适当的组件
? 使用编译程序找出其它需要修改的地方作适当地修改
? 运行这个转换到 Swing的程序
? 比较程序的 Swing版本和 AWT版本,作出使用 Swing组件可能作出的进一步的改进
? 清理这个转换到 Swing的程序代码,确保这个程序代码正确地使用了 Swing的特色
AWT组件和与之对应或最接近的
Swing组件
AWT组件 对应或最接近的 Swing组件
java.applet.Applet JApplet
Button JButton
Canvas JPanel,JLabel,或其它合适的 Swing 组件
Checkbox JCheckBox 或 JRadioButton
CheckboxMenuItem JCheckBoxMenuItem
Choice JComboBox
Dialog Jdialog或 JOptionPane
FileDialog JFileChooser
Frame JFrame
Label JLabel
List JList
Menu JMenu
MenuBar JMenuBar
MenuItem JMenuItem
Panel JPanel
PopupMenu JPopupMenu
Scrollbar JScrollPane 或 JSlider或 JProgressBar
ScrollPane JScrollPane
TextArea JTextArea
TextField JTextField
Window Jwindow或 JToolTip
JComponent
?除了顶层容器组件,所有以,J”为开始字母
的 Swing组件都是 JComponent的子类
?JFrame不是 JComponent的子类,因为
JFrame实现了一个顶层容器。 JComponent
类继承了 Container类,而 Container类本身又
继承了 Component类
JComponent的继承层次图
java.lang.Object
|
+--java.awt.Component
|
+--java.awt.Container
|
+--javax.swing.JComponent
JComponent类为它的子类提供的常用功能
?提示信息条( Tool tips)
?边界设置( Borders)
?键盘动作生成( Keyboard-generated actions)
?属性存取( Properties)
?布局管理支持( Support for layout)
定制组件外形
成员方法 用途
void setBorder(Border)
Border getBorder( )
(in JComponent)
设置或得到组件的边界。
void setForeground(Color)
Color getForeground( )
void setBackground(Color)
Color getBackground( )
(in java.awt.Component)
设置或得到组件的前景或背景颜色。
void setOpaque(boolean) 设置组件是否为透明。
boolean isOpaque 得到组件是否为透明的设置值。
void setFont(Font)
Font getFont( )
(in java.awt.Component)
设置或得到组件的字体字形信息。
FontMetrics getFontMetrics(Font)
(in java.awt.Component)
得到组件字体的写法布局信息。
设置组件状态
成员方法 用途
void setToolTipText(String)
(in JComponent)
设置组件提示信息条的提示信息内容。
void setEnabled(boolean b)
boolean isEnabled( )
(in java.awt.Component)
设置或测试组件是否能够对用户的输入和产生的事件作
出响应。
void setLocale(Locale l)
Locale getLocale()
(in java.awt.Component)
设置或得到 Locale类的对象。
void setCursor(Cursor)
Cursor getCursor()
(in java.awt.Component)
设置或得到鼠标指针图象。
void setVisible(boolean)
boolean isVisible( )
(in java.awt.Component)
设置或测试组件是否可见。
处理事件
成员方法 用途
void addComponentListener(ComponentListener)
void removeComponentListener(ComponentListener)
(in java.awt.Component)
向组件添加组件监听器,或从组件移去其监听器。当被监听的组件
被隐藏、显示、移动或调整大小时,组件监听器被唤醒。
void addKeyListener(KeyListener)
void removeKeyListener(KeyListener l)
(in java.awt.Component)
向组件添加键监听器,或从组件移去键监听器。当用户操作键盘和
被监听的组件被键盘聚焦时,键监听器被唤醒。
addMouseListener(MouseListener l)
void removeMouseListener(MouseListener)
(in java.awt.Component)
向组件添加鼠标移动监听器,或从组件移去鼠标移动监听器。当用
户在被监听的组件边界范围内移动鼠标时,鼠标移动监听器被
唤醒。
void addContainerListener(ContainerListener)
void removeContainerListener(ContainerListener)
(in java.awt.Container)
向容器添加容器监听器,或从容器移去容器监听器。当向被监听的
容器添加组件,或从被监听的容器中移去组件时,容器监听器
被唤醒。
void addFocusListener(FocusListener)
void removeFocusListener(FocusListener)
(in java.awt.Component)
向组件添聚焦监听器,或从组件移去聚焦监听器。当被监听的组件
得到或失去键盘聚焦时,聚焦监听器被唤醒。
Component getNextFocusableComponent( )
void setNextFocusableComponent(Component)
(in JComponent)
得到或设置下一个可聚焦的组件。 null表示聚焦管理器将自动选择下
一个可聚焦的组件。
void requestFocus( )
boolean hasFocus( )
(in java.awt.Component)
组件请求得到键盘聚焦,或测试组件是否得到了键盘聚焦。
boolean contains(int,int)
boolean contains(Point p)
(in java.awt.Component)
测试指定的点是否在组件范围内。
Component getComponentAt(int,int)
(in java.awt.Container)
得到含有指定点的组件。
绘制组件
成员方法 用途
void repaint( )
void repaint(int,int,int,int)
(in java.awt.Component)
请求对组件重新绘制,或对组件的指定区域重新绘制。
void repaint(Rectangle)
(in JComponent)
请求对组件的指定区域重新绘制。
void revalidate()
(in JComponent)
请求对组件和组件所影响的容器组件重新布局。
void paintComponent(Graphics)
(in JComponent)
绘制组件。
设置组件层次
成员方法 用途
Component add(Component)
Component add(Component,int)
void add(Component,Object)
(in java.awt.Container)
将指定组件添加到容器组件上。
void remove(int)
void remove(Component comp)
void removeAll( )
(in java.awt.Container)
从容器组件中移去指定组件。
JRootPane getRootPane()
(in JComponent)
得到组件所在组件层次的最顶层组件。
Container getParent()
(in java.awt.Component)
得到组件所在组件层次的直接上层组件。
int getComponentCount()
(in java.awt.Container)
得到容器组件中包含的组件数。
Component getComponent(int)
Component[] getComponents()
(in java.awt.Container)
得到容器组件中包含的指定组件。
组件布局
成员方法 用途
void setPreferredSize(Dimension)
void setMaximumSize(Dimension)
void setMinimumSize(Dimension)
(in JComponent)
设置组件大小(单位是象素,下同)。
Dimension getPreferredSize( )
Dimension getMaximumSize( )
Dimension getMinimumSize( )
(in java.awt.Component)
得到组件大小尺寸。
void setAlignmentX(float)
void setAlignmentY(float)
(in JComponent)
将组件设置为沿 x轴或沿 y轴排列。
float getAlignmentX()
float getAlignmentY()
(in java.awt.Component)
得到组件沿 x轴或沿 y轴排列的参数。
void setLayout(LayoutManager)
LayoutManager getLayout()
(in java.awt.Container)
设置组件的布局管理器。
得到组件的大小和位置信息
成员方法 用途
int getWidth( )
int getHeight( )
(in java.awt.Component)
得到组件的宽度或高度 ( 单位是象素, 下同 ) 。
Dimension getSize( )
Dimension getSize(Dimension)
(in java.awt.Component)
得到组件当前的大小尺寸 。
int getX( )
int getY( )
(in java.awt.Component)
得到组件的从它直接上层组件左上角算起的 x坐标或 y坐标 。
Point getLocation( )
Point getLocation(Point)
Point getLocationOnScreen( )
(in java.awt.Component)
得到组件的从它直接上层组件左上角算起的当前位置 。
Insets getInsets( )
(in java.awt.Container)
得到组件的 Insets值 。 Insets值描述容器组件距它边界的边距 。
说明组件的绝对尺寸和位置
成员方法 用途
void setLocation(int,int)
void setLocation(Point)
(in java.awt.Component)
设置组件的位置, 单位是象素 ( 下同 ), 从该组
件的直接上层组件的左上角算起 ( 下同 ) 。
void setSize(int,int)
void setSize(Dimension)
(in java.awt.Component)
设置组件的大小 。
void setBounds(int,int,int,int)
void setBounds(Rectangle)
(in java.awt.Component)
设置组件的大小和位置 。
第 6章 图形用户界面 GUI
?图形用户界面的概念
?建立图形用户界面
?几个重要的图形组件
? *GUI组件包与 JComponent
6.1图形用户界面的概念
?对计算机而言,用户界面 是用户和计算机之
间进行信息交互的界面,用户通过这个界面
得到程序运行的状态或输出的信息,向计算
机输入用户数据,操纵和控制程序的运行。
计算机的用户界面由用户可以直接操纵的键
盘,鼠标和用户可以直接感知的显示屏幕、
喇叭等器件构成
DOS 命令行界面
Windows图形界面
6.2 建立图形用户界面
?建立和添加组件 (Components)
?Java的事件处理
?组件 JPanel与布局管理器( Layout
Managers)
建立一个图形界面的内容
?通过建立和添加组件形成图形界面的屏幕显
示部分
?通过事件处理的设计定义当用户点击这些组
件或进行键盘操作后程序所执行的动作
?通过设置布局管理器定义图形组件的位置安
置
组件
?所谓 组件,就是专门用于建立图形界面的
Java类。换句话说,图形界面是由这些组件
有机构成的。最常用的组件有 视窗框架
( JFrame),标签 ( JLabel),命令按钮
( JButton),文本框 ( JTextField、
JTextArea)等等。建立图形界面的第一步,
是要建立图形组件,也就是创建图形组件对
象,然后通过组件添加,形成组件之间的层
次结构
例 6-1的图形界面
建立和添加组件 (Components)
?图形用户界面的组件层次
?组件 JFrame和 JLabel
?组件 JTextField和 JButton
图形用户界面的组件层次
? 将组件 JLabel设置为组件 JFrame的下一层组件,是
用 JFrame的 Add方法实现的
? 如果一个组件可以成为另一个组件的上一层组件,
这个组件称为 容器组件 ( Container),否则称为 原
子组件 ( Atomic Component)
层次图中组件的对应关系
J T e x tFie ld 1 J L a b e l1 J T e x t F i e l d 2 J L a b e l 2
J P a n e l1
JBu tton 1 J Bu tton 2
J P a n e l 2
JFra m e
组件类 层次图中编号 生成的对象 图形界面中的作用
JFrame 无 AdderFrame 产生 AdderFrame视窗框架。
JPanel 1 panel1 添加 Jpanel1,2,JTextField1,2组件。
JPanel 2 panel2 添加 JButton1,2组件。
JTextField 1 TOprand1 接收加数,显示初值为,0.0”。
JLabel 1 LAdd 显示加号,+”。
JTextField 2 TOprand2 接收被加数,显示初值为,0.0”。
JLabel 2 LSum 显示和,显示初值为,=0.0”。
JButton 1 BAdd 命令按钮,显示,Add!”。
JButton 2 BClear 命令按钮,显示,Clear!”。
组件 JFrame和 JLabel
?视窗框架组件 JFrame用于建立一个主窗口,
是其它组件赖以添加的最基础的容器组件
?标签组件 JLabel用于显示一些程序输出信息,
可以是数据或提示信息
JFrame常用的构造方法和成员方法
构造方法 用途
JFrame( ) 创建无标题的视窗对象。
JFrame(String title) 创建以 title为标题的视窗对象。
成员方法
Container getContentPane( ) 获得 JFrame的容器,在此容器上才可以添加其它组件。
继承而来的方法
public void pack( ) 将视窗尺寸调整到能够显示所有组件的合适大小。
void
setResizable(boolean b ) 将窗体大小设置为可调(可通过鼠标拖动调整)。
public void
setSize(int width,int height) 设置窗体大小。
public void
setVisible(boolean b) 设置窗体是否可见。
public void show( ) 显示窗体内容
public void
addWindowListener(WindowListener l) 添加指定的视窗事件监听器 l。
JLabel常用的构造方法和成员方法
构造方法 用途
JLabel() 创建无显示内容的标签对象。
JLabel(String text) 创建显示内容为字符串 text的标签对象。
成员方法
String getText( ) 得到作为标签显示内容的字符串。
void setText(String text) 将字符串 text设置为标签的显示内容。
演示 JFrame和 JLabel的用法
//装入组件及其超类组件所在的包
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUIDemo1{
public static void main(String[ ] args) {
JFrame frame = new JFrame("GUIDemo1");//创建视窗对象
JLabel label = new JLabel(" 学 好 Java 用 处 大! ");//创建标签对象
frame.getContentPane( ).add(label);//将标签对象添加到视窗对象的容器中
//定义事件处理
frame.addWindowListener(new WindowAdapter( ){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.pack( );//调整视窗尺寸
frame.setVisible(true);//将视窗设置为可见
}
}
常用的 Container方法
成员方法 用途
Component
add(Component comp) 将指定组件依次添加到容器。
void
setLayout(LayoutManager mgr) 为容器设置布局管理器。
继承而来的方法
public void
setSize(int width,int height) 设置容器大小。
public void
setVisible(boolean b) 设置容器是否可见。
组件 JTextField和 JButton
?单行文本框组件 JTextField既可以用于显示输
出信息,又可以用于接受输入信息
?命令按钮组件 JButton用于接收用户的命令
常用的 JTextField方法
构造方法 用途
JTextField( ) 创建单行文本框对象。
JTextField(int columns) 创建指定列数的单行文本框对象。
JTextField(String text) 创建以字符串 text为指定内容的单行文本框对象。
JTextField(String text,int columns) 创建具有指定列数的、以字符串 text为指定内容的单行文本框对象。
成员方法
void addActionListener(ActionListener l) 为单行文本框添加事件监听器 l以接收来自单行文本框的 action事件。
继承而来的方法
void setText( String text) 将字符串 text的内容设置为单行文本框的内容。
String getText() 得到单行文本框的内容。
void setEditable(boolean b) 设置单行文本框的内容是否可编辑。
常用的 JButton方法
构造方法 用途
JButton (String text) 创建以字符串 text为显示内容的命令按钮对象。
成员方法
void
addActionListener(Action
Listener l)
为命令按钮组件对象添加事件监听器 l以接收来自该对象
的 action事件。
演示单行文本框和命令按钮
import java.awt.event.*;
import javax.swing.*;
public class GUIDemo2{
public static void main(String[ ] args) { //图形界面的屏幕显示部分
JFrame frame = new JFrame("GUIDemo1");
final JTextField Text= new JTextField(" 学 好 Java 用 处 大 ! ");
JButton Button = new JButton("按钮 ");
frame.getContentPane( ).setLayout(new FlowLayout( ));//设置布局管理器
frame.getContentPane( ).add(Text);
frame.getContentPane( ).add(Button);
frame.pack( );
frame.setVisible(true); //图形界面的事件处理部分
Button.addActionListener(new ActionListener( ){
public void actionPerformed(ActionEvent e){
Text.setText("这是 JTextField和 JButton的一个示例 ");
}
});
frame.addWindowListener(new WindowAdapter( ){
public void windowClosing(WindowEvent e) {
System.exit(0);
} });
}
例 6-2的图形界面
( a)开始的界面 ( b)点击按钮后变化
Java的事件处理
?事件处理四要素
?事件处理的三种做法
?事件类 EventObject
事件处理四要素
? Java中,当点击了某个按钮,或组件的状态发生了
某种变化,或按下了某个键,等等,都被认为是产
生了某个 事件
? 导致事件产生的组件称为 事件源
? 从事件处理的机制看,设计事件处理要解决的问题
主要有:如何识别事件源,如何识别事件,如何监
听事件
? 如何定义 事件服务程序,即当监听到某个事件源的
某个事件产生后,程序所执行的动作
? 事件源、事件、事件监听和事件服务程序是事件处
理的四个要素。
事件处理设计要做三件事
? 给作为事件源的组件添加事件监听器
? 设计一个执行该事件监听器接口的类,这个
类中给出对应的事件服务程序代码,这个含
有事件服务程序的类称为 事件服务类,事件
服务程序代码在事件服务类的 事件服务方法
中
? 用上述的事件服务类创建一个对象,作为上
述事件监听器的实参
主要的 Java事件监听器
监听器类型 监听的事件
ActionListener 用户点击命令按钮,在单行文本框键入内容后按回车键,或选择了一
个菜单项。
WindowListener 用户关闭主视窗( Jframe对象)。
MouseListener 当鼠标箭头到达某一组件时用户按动鼠标按钮。
MouseMotionListener 用户在组件上移动鼠标。
ComponentListener 组件变成可见。
FocusListener 组件得到键盘聚焦。
ListSelectionListener 组件表格或列表的选择发生变化。
事件处理的三种做法
? 建立事件服务类,创建事件服务类对象,为事件源
添加事件监听器,并将已创建的事件服务类对象作
为事件监听器的实参;
? 建立事件服务类,为事件源添加事件监听器,在事
件监听器的实参位置直接创建事件服务类对象;
? 为事件源添加事件监听器,在事件监听器的实参位
置建立无名的事件服务类,并用该类创建事件服务
类对象。
第一种 Button的事件处理的做法
//建立事件服务类
class ButtonActionListener implements ActionListener{
public void actionPerformed(ActionEvent e){
Text.setText("这是 JTextField和 JButton的一个示例 ");
}
}
//创建事件服务对象
ButtonActionListener myButtonActionListener=new ButtonActionListener( );
//为事件源添加事件监听器,并将已创建的事件服务类对象作为事件监听器的实参
Button.addActionListener(myButtonActionListener);
第二种 Button的事件处理的做法
//建立事件服务类
class ButtonActionListener implements ActionListener{
public void actionPerformed(ActionEvent e){
Text.setText("这是 JTextField和 JButton的一个示例 ");
}
}
//为事件源添加事件监听器,在事件监听器的实参位置直接创建事件服务类对象
Button.addActionListener(new ButtonActionListener( ));
一个加法器的例子
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Adder implements ActionListener {
JFrame AdderFrame;
JTextField TOprand1; //被加数
JTextField TOprand2; //加数
JLabel LAdd,LSum; //加号,和
JButton BAdd; //Add!按钮
int i=0;
public Adder( ) { //建立图形界面的屏幕显示部分
AdderFrame = new JFrame("AdderFrame");
TOprand1 = new JTextField("0.0");
TOprand2 = new JTextField("0.0");
LAdd=new JLabel("+");
LSum=new JLabel("= ");
BAdd=new JButton("Add!");
AdderFrame.getContentPane( ).setLayout(new FlowLayout( ));
AdderFrame.getContentPane( ).add(TOprand1);
AdderFrame.getContentPane( ).add(LAdd);
AdderFrame.getContentPane( ).add(TOprand2);
AdderFrame.getContentPane( ).add(LSum);
AdderFrame.getContentPane( ).add(BAdd);
AdderFrame.pack( );
AdderFrame.setVisible(true);
//为命令按钮添加事件监听器,监听器的实参是 Adder类的对象
BAdd.addActionListener(this); // Adder类的事件服务方法
public void actionPerformed(ActionEvent event) { //事件服务代码
i=(i+1)%2;
if(i==1){ //i为奇数,求和
int sum= (int)(Double.valueOf(TOprand1.getText( )).doubleValue( )
+Double.valueOf(TOprand2.getText( )).doubleValue( ));
LSum.setText("="+sum);
}else{ //i为偶数,清零
TOprand1.setText("0.0");
TOprand2.setText("0.0");
LSum.setText("= ");
};
}
AdderFrame.addWindowListener(new WindowAdapter( ){//主视窗关闭的事件处理
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[ ] args) {
Adder adder = new Adder( );
}
}
例 6-3的图形界面
( a)开始的界面 ( b)做了加法后的界面
事件类 EventObject
?Java中的事件类就是为此而提供的机制。
Java的事件处理框架中,事件服务程序代码
包含在事件服务方法的方法体中,事件服务
方法的参数就是事件类对象(严格地讲,是
EventObject的相关子类的对象),事件服务
代码可以从中得到有关事件的信息
事件类 EventObjec的结构
成员变量 说明
protected Object source 事件最初赖以产生的对象。
构造方法
EventObject(Object source) 构造一个原型事件。
方法
Object getSource( ) 得到事件最初赖以产生的对象。
String toString( ) 返回事件类 EventObject对象的 String型表示。
组件 JPanel与布局管理器
?布局管理器 FlowLayout
?布局管理器 BorderLayout
?组件 JPanel
布局管理
?当一个容器组件上要添加多个组件时,就有
一个添加组件的位置问题,即要把这些组件
添加到容器组件的什么位置上。 Java中用布
局管理器来进行布局管理。在向一个容器组
件添加组件之前,先要用容器组件的
setLayout方法设置容器组件的布局管理器,
指定容器组件上的组件布局,以后添加到容
器组件的组件,就照此布局进行排列入位。
布局管理器 FlowLayout
?当将布局管理器设置为 FlowLayout时,添加
到容器组件上的组件将按照添加的次序在一
行上从左至右排列入位。如果一行排列不下,
则一行排满后从下一行继续排列。在每一行
中,组件将根据创建 FlowLayout对象时的说
明进行居中、左对齐或右对齐
布局管理器 FlowLayout的构造方法
public FlowLayout( );
public FlowLayout(int alignment);
public FlowLayout(int alignment,int
horizontalGap,int verticalGap);
其中参数 alignment说明组件的对齐方式
演示 FlowLayout的用法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Adder1 implements ActionListener {
JFrame AdderFrame;
JTextField TOprand1;
JTextField TOprand2;
JLabel LAdd,LSum;
JButton BAdd,BClear;
public Adder1( ) { // 建立主窗口和容器
AdderFrame = new JFrame("AdderFrame");
TOprand1 = new JTextField("0.0");
TOprand2 = new JTextField("0.0");
LAdd=new JLabel("+");
LSum=new JLabel("= ");
BAdd=new JButton("Add!");
BClear=new JButton("Clear!"); // 监听 BAdd按钮的事件
BAdd.addActionListener(this); // Bclear事件处理
BClear.addActionListener(new ActionListener( ){
public void actionPerformed(ActionEvent event){
TOprand1.setText("0.0");
TOprand2.setText("0.0");
LSum.setText("= "); }
});
//设置布局管理器为 FlowLayout
AdderFrame.getContentPane( ).setLayout(new FlowLayout( ));
AdderFrame.getContentPane( ).add(TOprand1);
AdderFrame.getContentPane( ).add(LAdd);
AdderFrame.getContentPane( ).add(TOprand2);
AdderFrame.getContentPane( ).add(LSum);
AdderFrame.getContentPane( ).add(BAdd);
AdderFrame.getContentPane( ).add(BClear);
//Window关闭事件处理
AdderFrame.addWindowListener(new WindowAdapter( ){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
AdderFrame.pack( );
AdderFrame.setVisible(true);
} // Badd事件处理
public void actionPerformed(ActionEvent event) {
int sum= (int)(Double.valueOf(TOprand1.getText( )).doubleValue( )
+Double.valueOf(TOprand2.getText( )).doubleValue( ));
LSum.setText("="+sum);
}
public static void main(String[ ] args) {
Adder1 adder1 = new Adder1( );
}
}
上例的图形界面
( a)开始的界面及点击 Clear按钮后的界面 ( b)做了加法后的界面
布局管理器 BorderLayout
? 当将布局管理器设置为 BorderLayout时,组件将被
分布在地图上东西南北中五个区域。添加组件时要
指明这个组件的位置。通常,容器组件只添加不足
五个组件。
? BorderLayout类有如下的构造方法,
BorderLayout( );
BorderLayout(int horizontalGap,int verticalGap);
? 其中,参数 horizontalGap和 verticalGap分别指定组
件之间的水平间隙和垂直间隙
组件 JPanel
?面板组件 JPanel是一个中间层次的容器组件,
一方面 JPanel对象可以包含其它组件,另一
方面 JPanel对象又可以被添加到另一个容器
组件上。通过 JPanel和布局管理器的配合使
用,可以设计出层次更丰富、结构更复杂的
图形用户界面
常用的 JPanel类的成员方法
构造方法 说明
JPanel( ) 创建一个面板对象,其默认布局管理器是
FlowLayout。
JPanel(LayoutManager layout) 创建一个具有指定布局管理器的面板对象。
继承而来的成员方法
public void
setVisible(boolean b)
设置面板是否可见。
public void setLayout(LayoutManager mgr) 设置面板布局管理器。
public void
setSize(int width,int height)
设置面板大小。
public Component add(Component comp) 向面板添加组件
public void add(Component comp,Object
constraints)
按指定位置向面板添加组件。
演示 JPanel和布局管理器
BorderLayout的用法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Adder2 implements ActionListener {
JFrame AdderFrame;
JTextField TOprand1;
JTextField TOprand2;
JLabel LAdd,LSum;
JButton BAdd,BClear;
JPanel panel1,panel2;
public Adder2( ) { // 建立顶层容器组件对象
AdderFrame = new JFrame("AdderFrame");
TOprand1 = new JTextField("0.0");
TOprand2 = new JTextField("0.0");
LAdd=new JLabel("+");
LSum=new JLabel("= 0.0 ");
BAdd=new JButton(" Add! ");
BClear=new JButton("Clear!");
panel1=new JPanel( );
panel2=new JPanel( );
//监听来自 Badd的事件
BAdd.addActionListener(this);
//按钮 Bclear的事件处理
BClear.addActionListener(new ActionListener( ){
public void actionPerformed(ActionEvent event){
TOprand1.setText("0.0");
TOprand2.setText("0.0");
LSum.setText("= 0.0 ");
}
});
//建立中间容器面板 panel1,panel1的布局管理器为 FlowLayout
panel1.setLayout(new FlowLayout( ));
panel1.add(TOprand1);
panel1.add(LAdd);
panel1.add(TOprand2);
panel1.add(LSum);
//建立中间容器面板 panel2,panel2的布局管理器为 FlowLayout
panel2.setLayout(new FlowLayout( ));
panel2.add(BAdd);
panel2.add(BClear);
//建立顶层容器 ContentPane,ContentPane的布局管理器为 BorderLayout
AdderFrame.getContentPane( ).setLayout(new BorderLayout( ));
AdderFrame.getContentPane( ).add(panel1,BorderLayout.NORTH);
AdderFrame.getContentPane( ).add(panel2,BorderLayout.SOUTH);
//窗口关闭事件处理
AdderFrame.addWindowListener(new WindowAdapter( ){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
AdderFrame.pack( );
AdderFrame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
int sum= (int)(Double.valueOf(TOprand1.getText( )).doubleValue( )
+Double.valueOf(TOprand2.getText( )).doubleValue( ));
LSum.setText("="+sum);
}
public static void main(String[ ] args) {
Adder2 adder2 = new Adder2( );
}
}
上例的图形界面
( a)开始的界面及点击 Clear按钮后的界面 ( b)做了加法后的界面
几个重要的图形组件
?JCheckBox
?JRadioButton和 RadioButtonGroup
?JTextArea和 JScrollPane
?JTabbedPane
JCheckBox
?在图形界面中,程序常常会给出几项选择,
并允许用户在多项选择中选择一项或多项。
复选框按钮组件 JcheckBox可用于接收用户
的这种多选输入
常用的 JcheckBox的方法
构造方法 说明
JCheckBox( ) 创建一个初始未被选中的复选框按钮组件对象。
JCheckBox(String text) 创建一个初始未被选中的复选框按钮组件对象,对象的
显示内容是 text的内容。
JCheckBox(String text,
boolean selected)
创建一个初始已被选中的复选框按钮组件对象,对象的
显示内容是 text的内容。
继承而来的成员方法
void addItemListener(ItemListener l) 为复选框按钮组件对象添加事件监听器 l以接收来自该对
象的 item事件。
void setSelected(boolean b) 设置复选框按钮组件对象是否被选中。
void setMnemonic(
KeyEvent.VK_ keyName )
设置产生与选择复选框按钮组件对象等效事件的键。
演示 JcheckBox的用法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUIDemo3 extends JPanel {
JCheckBox right1;
JCheckBox right2;
JCheckBox right4;
JCheckBox right8;
StringBuffer choices;
JLabel displayLabel;
public GUIDemo3( ) {
right1 = new JCheckBox("1");
right1.setMnemonic(KeyEvent.VK_4);
right1.setSelected(true);
right2 = new JCheckBox("2");
right2.setMnemonic(KeyEvent.VK_3);
right2.setSelected(true);
right4 = new JCheckBox("4");
right4.setMnemonic(KeyEvent.VK_2);
right4.setSelected(true);
right8 = new JCheckBox("8");
right8.setMnemonic(KeyEvent.VK_1);
right8.setSelected(true);
//创建事件服务类 CheckBoxListener的对象 myListener
CheckBoxListener myListener = new CheckBoxListener( );
//为 right1,right2,right4,right8添加事件监听器
right1.addItemListener(myListener);
right2.addItemListener(myListener);
right4.addItemListener(myListener);
right8.addItemListener(myListener);
//初始化 choices
choices = new StringBuffer("0000");
//创建标签对象
displayLabel = new JLabel(choices.toString( ));
//创建面板对象 checkPanel
JPanel checkPanel = new JPanel( );
//将复选框按钮添加到 checkPanel的同一列
checkPanel.setLayout(new GridLayout(0,1));
checkPanel.add(right1);
checkPanel.add(right2);
checkPanel.add(right4);
checkPanel.add(right8);
setLayout(new BorderLayout( ));
add(checkPanel,BorderLayout.WEST);
add(displayLabel,BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(10,60,10,60));//设置边距
}
//复选框的事件服务类
class CheckBoxListener implements ItemListener {
public void itemStateChanged(ItemEvent e) {
int index = 0;
char c = '-';
Object source = e.getItemSelectable( );
if (source == right8) {
index = 0;
c = '8';
} else if (source == right4) {
index = 1;
c = '4';
} else if (source == right2) {
index = 2;
c = '2';
} else if (source == right1) {
index = 3;
c = '1';
}
if (e.getStateChange( ) == ItemEvent.DESELECTED)
c = '-';
choices.setCharAt(index,c);
displayLabel.setText(choices.toString( ));
}
}
public static void main(String s[ ]) {
JFrame frame = new JFrame("CheckBoxDemo");
//主窗口关闭事件处理
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setContentPane(new GUIDemo3( ));
frame.pack( );
frame.setVisible(true);
}
}
例 6-6的图形界面
( a)全部选中的界面 ( b)选中 2个复选框的界面 ( c)均未选中的界面
JRadioButton和 RadioButtonGroup
?如果程序提供给用户几种选择,但只允许用
户选择其中一种(通常是必须选择一种),
则可以采用单选按钮组件 JRadioButton。
JRadioButton用于接收用户的单选输入。按
钮组组件 ButtonGroup与 JRadioButton配合使
用,建立多个单选按钮之间的这种单选关系
常用的 JRadioButton方法
构造方法 说明
JRadioButton( ) 创建 JradioButton对象,初始状态:未被选中,没有文本
提示信息。
JRadioButton(String text) 创建 JradioButton对象,初始状态:未被选中,文本提示
信息是 text的内容。
JRadioButton(String text,
boolean selected)
创建 JradioButton对象,初始状态:已被选中,文本提示
信息是 text的内容。
继承而来的成员方法
void setSelected(boolean b) 设置 JradioButton对象是否被选中。
void setText( String text) 设置 JradioButton对象文本提示信息。
public void
setActionCommand(String
actionCommand)
设置 JradioButton对象的事件命令。
常用的 ButtonGroup方法
构造方法 说明
ButtonGroup( ) 创建 ButtonGroup对象。
继承而来的成员方法
void add(AbstractButton rt) 将组件 rt添加到按钮组 ButtonGroup对象中。
void remove(AbstractButton rt) 将组件 rt从按钮组 ButtonGroup对象中移去。
演示 JradioButton和 ButtonGroup用法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUIDemo4 extends JPanel {
static JFrame frame;
static String birdString = "鸟 ";
static String catString = "猫 ";
static String dogString = "狗 ";
static String rabbitString = "兔 ";
JLabel display;
public GUIDemo4( ) { // 创建单选按钮对象
JRadioButton birdButton = new JRadioButton(birdString);
birdButton.setMnemonic(KeyEvent.VK_B);
birdButton.setActionCommand(birdString);
JRadioButton catButton = new JRadioButton(catString);
catButton.setMnemonic(KeyEvent.VK_C);
catButton.setActionCommand(catString);
JRadioButton dogButton = new JRadioButton(dogString);
dogButton.setMnemonic(KeyEvent.VK_D);
dogButton.setActionCommand(dogString);
JRadioButton rabbitButton = new JRadioButton(rabbitString);
rabbitButton.setMnemonic(KeyEvent.VK_R);
rabbitButton.setActionCommand(rabbitString);
//将单选按钮组成一组,建立它们之间的单选关系
ButtonGroup group = new ButtonGroup( );
group.add(birdButton);
group.add(catButton);
group.add(dogButton);
group.add(rabbitButton);
//为单选按钮添加事件监听器
RadioListener myListener = new RadioListener( );
birdButton.addActionListener(myListener);
catButton.addActionListener(myListener);
dogButton.addActionListener(myListener);
rabbitButton.addActionListener(myListener);
//建立标签对象 display
display = new JLabel("这是 RadioButton的一个示例。 ");
display.setPreferredSize(new Dimension(180,60));//设置标签对象的大小
JPanel radioPanel = new JPanel( );
radioPanel.setLayout(new GridLayout(0,1));//按钮对象按一列添加到面板
radioPanel.add(birdButton);
radioPanel.add(catButton);
radioPanel.add(dogButton);
radioPanel.add(rabbitButton);
setLayout(new BorderLayout( ));
add(radioPanel,BorderLayout.WEST);
add(display,BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(20,20,20,0));
}
//事件服务类
class RadioListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
display.setText( " 你选中了 "+e.getActionCommand( )+"。 ");
}
}
public static void main(String s[ ]) {
frame = new JFrame("RadioButtonDemo");
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.getContentPane( ).add(new GUIDemo4( ),BorderLayout.CENTER);
frame.pack( );
frame.setVisible(true);
}
}
例 6-7的图形界面
( a)开始的界面 ( b)选中了单选按钮“鸟”的界面
一个算术测试程序
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CalcuExercises {
//创建所需组件对象
static JFrame frame = new JFrame("算术练习测验 ");
static JPanel PRadio=new JPanel( );//单选按钮面板
static JRadioButton BAdd=new JRadioButton("做加法 ");//加法按钮
static JRadioButton BSub=new JRadioButton("做减法 ");//减法按钮
static JRadioButton BMul=new JRadioButton("做乘法 "); //乘法按钮
static JRadioButton BDiv=new JRadioButton("做除法 "); //除法按钮
static ButtonGroup group = new ButtonGroup( ); //单选按钮组
static JPanel PCheck=new JPanel( ); //复选框面板
static JCheckBox Total=new JCheckBox("显示已做题数 ");//是否显示“已做题数”复选框,
//选中则显示
static JCheckBox Right=new JCheckBox("显示做对题数 ");//是否显示“做对题数”复选框,
//选中则显示
static JPanel PCalcu=new JPanel( ); //运算面板
static JLabel LOperand1=new JLabel(" ");//操作数 1
static JLabel LOpcode=new JLabel("+"); //加号
static JLabel LOperand2=new JLabel(" ");//操作数 2
static JLabel LEqu=new JLabel("="); //等号
static JTextField Answer=new JTextField("0000");//计算结果
static JButton Ok=new JButton("确认 !"); //确认按钮
static JPanel PRecord=new JPanel( ); //记录面板
static int totalNunmber=0; //已做题数
static int rightNumber=0; //做对题数
static JLabel LTotal=new JLabel(" 已做 "+totalNunmber+" 题 ");//显示已做题数
static JLabel LRight=new JLabel(" 做对 "+rightNumber+" 题 "); //显示做对题数
static JPanel PCombine=new JPanel( ); //组合面板
static JPanel Exercise=new JPanel( ); //顶层面板
int calcuType=1; //运算类型。 1:加,2:减,3:乘,4:除
int totalSelected=1;
int rightSelected=1;
public CalcuExercises( ){
//建立运算类型单选按钮面板
PRadio.setLayout(new GridLayout(0,1));
BAdd.setSelected(true);
group.add(BAdd);
group.add(BSub);
group.add(BMul);
group.add(BDiv);
PRadio.add(BAdd);
PRadio.add(BSub);
PRadio.add(BMul);
PRadio.add(BDiv);
PRadio.setBorder(BorderFactory.createEmptyBorder(0,30,0,20));
Total.setSelected(true);
Right.setSelected(true);
//建立显示控制复选框面板
PCheck.setLayout(new GridLayout(0,1));
PCheck.add(Total);
PCheck.add(Right);
//建立运算面板
PCalcu.setLayout(new FlowLayout( ));
PCalcu.setBorder(BorderFactory.createEmptyBorder(0,0,20,0));
PCalcu.add(LOperand1);
PCalcu.add(LOpcode);
PCalcu.add(LOperand2);
PCalcu.add(LEqu);
PCalcu.add(Answer);
//建立运算结果记录显示面板
PRecord.setLayout(new FlowLayout( ));
PRecord.add(LTotal);
PRecord.add(LRight);
PRecord.setBorder(BorderFactory.createEmptyBorder(20,0,0,0));
//建立组合面板,含有运算面板和运算结果记录显示面板,两面板在组合面板中上下布局
PCombine.setLayout(new BorderLayout( ));
PCombine.add(PCalcu,BorderLayout.NORTH);
PCombine.add(Ok,BorderLayout.CENTER);
PCombine.add(PRecord,BorderLayout.SOUTH);
//建立顶层面板
Exercise.setLayout(new FlowLayout( ));
Exercise.add(PCombine);
Exercise.add(PRadio);
Exercise.add(PCheck);
Exercise.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
ButtonListener myButtonListener=new ButtonListener( );
Ok.addActionListener(myButtonListener);
CheckBoxListener myCheckBoxListener = new CheckBoxListener( );
Total.addItemListener(myCheckBoxListener);
Right.addItemListener(myCheckBoxListener);
BAdd.setActionCommand("+");
BSub.setActionCommand("-");
BMul.setActionCommand("*");
BDiv.setActionCommand("/");
RadioListener myRadioListener = new RadioListener( );
BAdd.addActionListener(myRadioListener);
BSub.addActionListener(myRadioListener);
BMul.addActionListener(myRadioListener);
BDiv.addActionListener(myRadioListener);
int x,y,temp;
String s=new String( );
//产生随机数,作为参与运算的操作数,置于 x,y中
//确保 x,y不为 0且 x>y
x=(int)(90*Math.random( ));
while(x==0){x=(int)(90*Math.random( ));};
y=(int)(90*Math.random( ));
while(y==0){y=(int)(90*Math.random( ));};
if(y>x){temp=x;x=y;y=temp;};
LOperand1.setText(s.valueOf(" "+x+" "));
LOperand2.setText(s.valueOf(" "+y+" "));
frame.getContentPane( ).setLayout(new FlowLayout( ));
frame.getContentPane( ).add(Exercise);
frame.pack( );
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
})
}
//命令按钮事件服务类
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
int x,y,z,temp;
String s=new String( );
z=(int)Integer.valueOf(Answer.getText( ).trim( )).intValue( );
x=(int)Integer.valueOf(LOperand1.getText( ).trim( )).intValue( );
y=(int)Integer.valueOf(LOperand2.getText( ).trim( )).intValue( );
if(calcuType==1){if(x+y==z){rightNumber++;};}else
if(calcuType==2){if(x-y==z){rightNumber++;};}else
if(calcuType==3){if(x*y==z){rightNumber++;};}else
{if(x/y==z){rightNumber++;};};
x=(int)(90*Math.random( ));while(x==0){x=(int)(90*Math.random( ));};
y=(int)(90*Math.random( )); while(y==0){y=(int)(90*Math.random( ));};
if(y>x){temp=x;x=y;y=temp;};
LOperand1.setText(s.valueOf(" "+x+" "));
LOperand2.setText(s.valueOf(" "+y+" "));
totalNunmber++;
LTotal.setText("已做 "+totalNunmber+"题 ");
LRight.setText("做对 "+rightNumber+"题 ");
if(totalNunmber>100)System.exit(0);
}
}
class CheckBoxListener implements ItemListener { //复选框事件服务类
public void itemStateChanged(ItemEvent e) {
Object source = e.getItemSelectable( );
if (source == Total) {
totalSelected =(totalSelected+1)%2;
} else if (source == Right) {
rightSelected =(rightSelected+1)%2;
};
if(totalSelected==1){LTotal.setVisible(true);}else{LTotal.setVisible(false);};
if(rightSelected==1){LRight.setVisible(true);}else{LRight.setVisible(false);};
}
}
class RadioListener implements ActionListener { //单选按钮事件服务类
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand( ).equals("+")){ calcuType=1;LOpcode.setText("+");}
else if(e.getActionCommand( ).equals("-")){ calcuType=2;LOpcode.setText("-");}
else if(e.getActionCommand( ).equals("*")){ calcuType=3;LOpcode.setText("*");}
else { calcuType=4;LOpcode.setText("/");};
}
}
public static void main(String s[ ]) { //主方法
CalcuExercises exe1=new CalcuExercises( );
}
}
开始的界面
点击了“做减法”单选按钮后的界面
两复选框“显示已做题数”和
“显示做对题数”均未选中的界
面
JTextArea和 JScrollPane
?多行文本框组件 JTextArea允许用户编辑具有
多行的文本,这一组件既可以用于输出信息,
也可以用于接收信息。滚动窗格组件
JScrollPane是又一种中间层次的容器组件,
当窗格含有的内容显示不下时,允许用户使
用水平方向和垂直方向的滚动条上下左右移
动窗格的内容,从而可以看见窗格含有的全
部内容
常用的 JTextArea方法
构造方法 说明
JTextArea(int rows,int columns) 创建一个具有指定行数和列数 JTextArea对象。
JTextArea(String text) 创建一个显示指定文本内容的 JTextArea对象,所显示的文本内容为空。
JTextArea(String text,int rows,int columns) 创建一个显示指定文本内容并具有指定行数和列数的 JTextArea对象。
成员方法
void append(String str) 将所给 str内容添加到显示的文本内容之后。
void insert(String str,int pos) 将所给 str内容插入到显示的文本的指定位置。
void replaceRange(String str,int start,int end) 将显示文本中从 start开始至 end结束的部分替换为指定内容 str。
继承而来的成员方法
public void
setEditable(boolean b)
设置 JTextArea对象是否可被用户编辑。
String getText() 得到 JTextArea对象的显示文本内容。
void setText(String t) 将显示文本内容设置成指定内容。
常用的 JScrollPane方法
构造方法 说明
JScrollPane( ) 创建一个没有显示口的 JScrollPane对象,它的垂直方向和水平方向的滚动条会在需要时出现。
JScrollPane(Component view)
创建一个包含组件对象 view ( view中含有要显示的内容,
下同)的 JScrollPane对象,它的垂直方向和水平方向
的滚动条会在显示口过小不能显示出全部显示内容时
出现。
JScrollPane(Component view,int
vsbPolicy,int hsbPolicy)
创建一个在显示口中显示 view内容的 JScrollPane对象,它
的滚动条出现方式由参数 vsbPolicy和 hsbPolicy给出。
演示 JTextArea和 JScrollPane的用法
?多行文本框组件 JTextArea允许用户编辑具有
多行的文本,这一组件既可以用于输出信息,
也可以用于接收信息。滚动窗格组件
JScrollPane是又一种中间层次的容器组件,
当窗格含有的内容显示不下时,允许用户使
用水平方向和垂直方向的滚动条上下左右移
动窗格的内容,从而可以看见窗格含有的全
部内容
常用的 JTextArea方法
构造方法 说明
JTextArea(int rows,int columns) 创建一个具有指定行数和列数 JTextArea对象。
JTextArea(String text) 创建一个显示指定文本内容的 JTextArea对象,所显示的文本内容为空。
JTextArea(String text,int rows,int
columns)
创建一个显示指定文本内容并具有指定行数和列数的 JTextArea对象。
成员方法
void append(String str) 将所给 str内容添加到显示的文本内容之后。
void insert(String str,int pos) 将所给 str内容插入到显示的文本的指定位置。
void replaceRange(String str,int start,
int end)
将显示文本中从 start开始至 end结束的部分替换为指定内容 str。
继承而来的成员方法
public void
setEditable(boolean b)
设置 JTextArea对象是否可被用户编辑。
String getText() 得到 JTextArea对象的显示文本内容。
void setText(String t) 将显示文本内容设置成指定内容。
常用的 JScrollPane方法
构造方法 说明
JScrollPane( ) 创建一个没有显示口的 JScrollPane对象,它的垂直方
向和水平方向的滚动条会在需要时出现。
JScrollPane(Component view) 创建一个包含组件对象 view ( view中含有要显示的内
容,下同)的 JScrollPane对象,它的垂直方向和
水平方向的滚动条会在显示口过小不能显示出全
部显示内容时出现。
JScrollPane(Component view,int
vsbPolicy,int hsbPolicy)
创建一个在显示口中显示 view内容的 JScrollPane对象,
它的滚动条出现方式由参数 vsbPolicy和 hsbPolicy
给出。
演示 JTextArea和 JScrollPane的用法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUIDemo5 extends JPanel implements ActionListener {
JTextField textField;
JTextArea textArea;
String newline = "\n";
public GUIDemo5( ) {
//创建所需组件对象
textField = new JTextField(20);
textField.addActionListener(this);
textArea = new JTextArea(5,20);
textArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(textArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
//将组件添加到面板
GridBagLayout gridBag = new GridBagLayout( );
setLayout(gridBag);
GridBagConstraints c = new GridBagConstraints( );
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.HORIZONTAL;
gridBag.setConstraints(textField,c);
add(textField);
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
gridBag.setConstraints(scrollPane,c);
add(scrollPane);
} // textField的事件服务方法
public void actionPerformed(ActionEvent evt) {
String text = textField.getText( );
textArea.append(text + newline);
textField.selectAll( );
}
public static void main(String[ ] args){
JFrame frame=new JFrame("GUIDemo5"); //主窗口关闭事件处理
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.getContentPane( ).add(new GUIDemo5( ));
frame.pack( );
frame.setVisible(true);
};
}
例 6-9的图形界面
JTabbedPane
? 标签面板组件 JTabbedPane也是一种中间层次的容
器组件,它将多个面板集成在一个组件中,每个面板
有一个标签(这里的标签是一种小标题,起到提示
面板内容的作用,与 JLabel的含义有区别)。当选
中某个标签时,组件显示对应的面板内容,而组件
中未被选中的面板则不予显示。当图形界面的功能
较多时,可以将这些功能分类,并使用标签面板将
实现某一类功能的组件安排到标签面板组件的某一
块面板上,使图形界面更加简洁清晰
常用的 JTabbedPane的方法
构造方法 说明
public JTabbedPane( ) 创建一个 JTabbedPane对象。
成员方法
void addTab(String title,Icon icon,
Component component,String tip)
将组件 component添加到标签面板对象的一个面板上,这
个面板的标签是字符串 title和 /或图标 icon,面板标签
的提示信息是 tip的内容。
演示 JTabbedPane的用法
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUIDemo6 extends JPanel {
public GUIDemo6( ) {
//建立标签面板
JTabbedPane tabbedPane = new JTabbedPane( );
Component panel1 = makeTextPanel("你选中了标签 1");
tabbedPane.addTab("标签 1",null,panel1,null);
tabbedPane.setSelectedIndex(0);
Component panel2 = makeTextPanel("你选中了标签 2");
tabbedPane.addTab("标签 2",null,panel2,null);
Component panel3 = makeTextPanel("你选中了标签 3");
tabbedPane.addTab("标签 3",null,panel3,null);
Component panel4 = makeTextPanel("你选中了标签 4");
tabbedPane.addTab("标签 4",null,panel4,null);
setLayout(new GridLayout(0,1));
add(tabbedPane);
}
// makeTextPanel方法,返回值类型为 Component
protected Component makeTextPanel(String text) {
JPanel panel = new JPanel( );
JLabel filler = new JLabel(text);
filler.setHorizontalAlignment(JLabel.CENTER);
panel.setLayout(new GridLayout(1,1));
panel.add(filler);
return panel;
}
public static void main(String[ ] args) {
JFrame frame = new JFrame("TabbedPaneDemo");
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.getContentPane( ).add(new GUIDemo6( ));
frame.setSize(400,125);
frame.setVisible(true);
}
}
例 6-10的图形界面
成绩处理程序
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ScoreSort extends JPanel {
class Student{
int SNumber=0,Score=0;
}
Student[ ] st=new Student[10];//设所能处理的成绩个数为 10
int i;
JTextField TNumberIn=new JTextField(8);//学号输入框
JTextField TScoreIn=new JTextField(8);//成绩输入框
JTextField TNumberQuery=new JTextField(8);//学号查询框
JTextField TScoreQuery=new JTextField(8);//成绩查询框
JTextArea textArea = new JTextArea(5,20);//显示排序结果
public ScoreSort( ) { //数组元素初始化
int i=0;
for(i=0;i<st.length;i++){
st[i]=new Student( );
};
JTabbedPane tabbedPane = new JTabbedPane( );
//建立输入面板
JPanel panel1 =new JPanel( );
panel1.setLayout(new BorderLayout( ));
JLabel LNumberIn=new JLabel("请输入学号,");
JPanel Panel11=new JPanel( );
Panel11.setLayout(new FlowLayout( ));
Panel11.add(LNumberIn);
Panel11.add(TNumberIn);
panel1.add(Panel11,BorderLayout.NORTH);
JLabel LScoreIn=new JLabel("请输入成绩,");
JPanel Panel12=new JPanel( );
Panel12.setLayout(new FlowLayout( ));
Panel12.add(LScoreIn);
Panel12.add(TScoreIn);
panel1.add(Panel12,BorderLayout.CENTER);
JButton BIn=new JButton("确 认 ");
panel1.add(BIn,BorderLayout.SOUTH);
BIn.addActionListener(new InActionListener( ));
tabbedPane.addTab("成绩输入 ",null,panel1,null);
tabbedPane.setSelectedIndex(0);//一开始选中“成绩输入”标签面板
//建立排序面板
JPanel panel2 =new JPanel( );
JButton BSort=new JButton(" 排 序 ");
BSort.addActionListener(new SortActionListener( ));
textArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(textArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
GridBagLayout gridBag = new GridBagLayout( );
panel2.setLayout(gridBag);
GridBagConstraints c = new GridBagConstraints( );
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
gridBag.setConstraints(scrollPane,c);
panel2.add(scrollPane);
c.fill = GridBagConstraints.HORIZONTAL;
gridBag.setConstraints(BSort,c);
panel2.add(BSort);
tabbedPane.addTab("成绩排序 ",null,panel2,null);
//建立查询面板
JPanel panel3 = new JPanel( );
panel3.setLayout(new BorderLayout( ));
JLabel LNumberQuery=new JLabel("请输入学号,");
JPanel Panel31=new JPanel( );
Panel31.setLayout(new FlowLayout( ));
Panel31.add(LNumberQuery);
Panel31.add(TNumberQuery);
panel3.add(Panel31,BorderLayout.NORTH);
TScoreQuery.setEditable(false);
JLabel LScoreQuery=new JLabel("您的成绩是,");
JPanel Panel32=new JPanel( );
Panel32.setLayout(new FlowLayout( ));
Panel32.add(LScoreQuery);
Panel32.add(TScoreQuery);
panel3.add(Panel32,BorderLayout.CENTER);
JButton BQuery=new JButton("查 询 ");
panel3.add(BQuery,BorderLayout.SOUTH);
BQuery.addActionListener(new QueryActionListener( ));
tabbedPane.addTab("成绩查询 ",null,panel3,null);
setLayout(new GridLayout(0,1));
add(tabbedPane);
}
class InActionListener implements ActionListener{ //事件处理 ------成绩输入事件服务
public void actionPerformed(ActionEvent event){
if(i<st.length){
st[i].SNumber=Integer.valueOf(TNumberIn.getText( )).intValue( );
st[i].Score=Integer.valueOf(TScoreIn.getText( )).intValue( );
};
i++;
}
}
class SortActionListener implements ActionListener{ //成绩排序事件服务
public void actionPerformed(ActionEvent event){
int i,j,temp;
String s=new String( );
for(i=0;i<st.length-1;i++)
for(j=i+1;j<st.length;j++){
if(st[i].Score<st[j].Score){
temp=st[i].Score;st[i].Score=st[j].Score;st[j].Score=temp;
temp=st[i].SNumber;st[i].SNumber=st[j].SNumber;st[j].SNumber=temp;
};};
textArea.setText("学号 成绩 \n");
for(i=0;i<st.length;i++){
if(st[i].SNumber!=0){
textArea.append(s.valueOf(st[i].SNumber)+ " "+s.valueOf(st[i].Score)+"\n");
};};
}
}
//成绩查询事件服务
class QueryActionListener implements ActionListener{
public void actionPerformed(ActionEvent event){
int keyWord,i=0;
String s=new String( );
keyWord=Integer.valueOf(TNumberQuery.getText( )).intValue( );
for(i=0;i<st.length;i++)
if(st[i].SNumber==keyWord){
TScoreQuery.setText(s.valueOf(st[i].Score));
break;
};
if(i>=st.length)
TScoreQuery.setText("未找到您的成绩 ");
}
}
//主方法
public static void main(String[ ] args) {
JFrame frame = new JFrame("成绩处理 ");
frame.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.getContentPane( ).add(new ScoreSort( ));
frame.setSize(300,160);
frame.setVisible(true);
}
}
例 6-10的图形界面
*GUI组件包与 JComponent
?Swing和 AWT包
?JComponent
Swing和 AWT包
?在于 Swing组件不含有任何与平台有关的本
地代码。 Swing组件的这个特点使得基于
Swing组件的图形界面程序具有良好的跨平
台性能
?此外,即使最简单的 Swing组件也提供了比
AWT组件更强的功能
一个基于 AWT的程序转换到基于
Swing的程序
? 为要被转换的程序保留一个备份
? 移去所有对 java.awt包的引用
? 对于 applet程序,还要移去装入 java.applet.*的语句和对 java.applet.Applet的引用
? 装入 Swing包
? 小心线程安全问题 —— AWT是线程安全的,但 Swing不是
? 将每个 AWT组件改成与它对应的或最接近的 Swing组件
? 相应地改变对 add和 setLayout方法的调用 —— 在使用 AWT组件时,可以直接向 frames、
dialogs、和 applets添加组件,并可以直接设置这些组件的布局管理器,但在使用 Swing
组件时则必须先添加一个 content pane
? 根据绘画( paint)的类型,将绘画代码移出其 paint 和 update方法并移入适当的组件
? 使用编译程序找出其它需要修改的地方作适当地修改
? 运行这个转换到 Swing的程序
? 比较程序的 Swing版本和 AWT版本,作出使用 Swing组件可能作出的进一步的改进
? 清理这个转换到 Swing的程序代码,确保这个程序代码正确地使用了 Swing的特色
AWT组件和与之对应或最接近的
Swing组件
AWT组件 对应或最接近的 Swing组件
java.applet.Applet JApplet
Button JButton
Canvas JPanel,JLabel,或其它合适的 Swing 组件
Checkbox JCheckBox 或 JRadioButton
CheckboxMenuItem JCheckBoxMenuItem
Choice JComboBox
Dialog Jdialog或 JOptionPane
FileDialog JFileChooser
Frame JFrame
Label JLabel
List JList
Menu JMenu
MenuBar JMenuBar
MenuItem JMenuItem
Panel JPanel
PopupMenu JPopupMenu
Scrollbar JScrollPane 或 JSlider或 JProgressBar
ScrollPane JScrollPane
TextArea JTextArea
TextField JTextField
Window Jwindow或 JToolTip
JComponent
?除了顶层容器组件,所有以,J”为开始字母
的 Swing组件都是 JComponent的子类
?JFrame不是 JComponent的子类,因为
JFrame实现了一个顶层容器。 JComponent
类继承了 Container类,而 Container类本身又
继承了 Component类
JComponent的继承层次图
java.lang.Object
|
+--java.awt.Component
|
+--java.awt.Container
|
+--javax.swing.JComponent
JComponent类为它的子类提供的常用功能
?提示信息条( Tool tips)
?边界设置( Borders)
?键盘动作生成( Keyboard-generated actions)
?属性存取( Properties)
?布局管理支持( Support for layout)
定制组件外形
成员方法 用途
void setBorder(Border)
Border getBorder( )
(in JComponent)
设置或得到组件的边界。
void setForeground(Color)
Color getForeground( )
void setBackground(Color)
Color getBackground( )
(in java.awt.Component)
设置或得到组件的前景或背景颜色。
void setOpaque(boolean) 设置组件是否为透明。
boolean isOpaque 得到组件是否为透明的设置值。
void setFont(Font)
Font getFont( )
(in java.awt.Component)
设置或得到组件的字体字形信息。
FontMetrics getFontMetrics(Font)
(in java.awt.Component)
得到组件字体的写法布局信息。
设置组件状态
成员方法 用途
void setToolTipText(String)
(in JComponent)
设置组件提示信息条的提示信息内容。
void setEnabled(boolean b)
boolean isEnabled( )
(in java.awt.Component)
设置或测试组件是否能够对用户的输入和产生的事件作
出响应。
void setLocale(Locale l)
Locale getLocale()
(in java.awt.Component)
设置或得到 Locale类的对象。
void setCursor(Cursor)
Cursor getCursor()
(in java.awt.Component)
设置或得到鼠标指针图象。
void setVisible(boolean)
boolean isVisible( )
(in java.awt.Component)
设置或测试组件是否可见。
处理事件
成员方法 用途
void addComponentListener(ComponentListener)
void removeComponentListener(ComponentListener)
(in java.awt.Component)
向组件添加组件监听器,或从组件移去其监听器。当被监听的组件
被隐藏、显示、移动或调整大小时,组件监听器被唤醒。
void addKeyListener(KeyListener)
void removeKeyListener(KeyListener l)
(in java.awt.Component)
向组件添加键监听器,或从组件移去键监听器。当用户操作键盘和
被监听的组件被键盘聚焦时,键监听器被唤醒。
addMouseListener(MouseListener l)
void removeMouseListener(MouseListener)
(in java.awt.Component)
向组件添加鼠标移动监听器,或从组件移去鼠标移动监听器。当用
户在被监听的组件边界范围内移动鼠标时,鼠标移动监听器被
唤醒。
void addContainerListener(ContainerListener)
void removeContainerListener(ContainerListener)
(in java.awt.Container)
向容器添加容器监听器,或从容器移去容器监听器。当向被监听的
容器添加组件,或从被监听的容器中移去组件时,容器监听器
被唤醒。
void addFocusListener(FocusListener)
void removeFocusListener(FocusListener)
(in java.awt.Component)
向组件添聚焦监听器,或从组件移去聚焦监听器。当被监听的组件
得到或失去键盘聚焦时,聚焦监听器被唤醒。
Component getNextFocusableComponent( )
void setNextFocusableComponent(Component)
(in JComponent)
得到或设置下一个可聚焦的组件。 null表示聚焦管理器将自动选择下
一个可聚焦的组件。
void requestFocus( )
boolean hasFocus( )
(in java.awt.Component)
组件请求得到键盘聚焦,或测试组件是否得到了键盘聚焦。
boolean contains(int,int)
boolean contains(Point p)
(in java.awt.Component)
测试指定的点是否在组件范围内。
Component getComponentAt(int,int)
(in java.awt.Container)
得到含有指定点的组件。
绘制组件
成员方法 用途
void repaint( )
void repaint(int,int,int,int)
(in java.awt.Component)
请求对组件重新绘制,或对组件的指定区域重新绘制。
void repaint(Rectangle)
(in JComponent)
请求对组件的指定区域重新绘制。
void revalidate()
(in JComponent)
请求对组件和组件所影响的容器组件重新布局。
void paintComponent(Graphics)
(in JComponent)
绘制组件。
设置组件层次
成员方法 用途
Component add(Component)
Component add(Component,int)
void add(Component,Object)
(in java.awt.Container)
将指定组件添加到容器组件上。
void remove(int)
void remove(Component comp)
void removeAll( )
(in java.awt.Container)
从容器组件中移去指定组件。
JRootPane getRootPane()
(in JComponent)
得到组件所在组件层次的最顶层组件。
Container getParent()
(in java.awt.Component)
得到组件所在组件层次的直接上层组件。
int getComponentCount()
(in java.awt.Container)
得到容器组件中包含的组件数。
Component getComponent(int)
Component[] getComponents()
(in java.awt.Container)
得到容器组件中包含的指定组件。
组件布局
成员方法 用途
void setPreferredSize(Dimension)
void setMaximumSize(Dimension)
void setMinimumSize(Dimension)
(in JComponent)
设置组件大小(单位是象素,下同)。
Dimension getPreferredSize( )
Dimension getMaximumSize( )
Dimension getMinimumSize( )
(in java.awt.Component)
得到组件大小尺寸。
void setAlignmentX(float)
void setAlignmentY(float)
(in JComponent)
将组件设置为沿 x轴或沿 y轴排列。
float getAlignmentX()
float getAlignmentY()
(in java.awt.Component)
得到组件沿 x轴或沿 y轴排列的参数。
void setLayout(LayoutManager)
LayoutManager getLayout()
(in java.awt.Container)
设置组件的布局管理器。
得到组件的大小和位置信息
成员方法 用途
int getWidth( )
int getHeight( )
(in java.awt.Component)
得到组件的宽度或高度 ( 单位是象素, 下同 ) 。
Dimension getSize( )
Dimension getSize(Dimension)
(in java.awt.Component)
得到组件当前的大小尺寸 。
int getX( )
int getY( )
(in java.awt.Component)
得到组件的从它直接上层组件左上角算起的 x坐标或 y坐标 。
Point getLocation( )
Point getLocation(Point)
Point getLocationOnScreen( )
(in java.awt.Component)
得到组件的从它直接上层组件左上角算起的当前位置 。
Insets getInsets( )
(in java.awt.Container)
得到组件的 Insets值 。 Insets值描述容器组件距它边界的边距 。
说明组件的绝对尺寸和位置
成员方法 用途
void setLocation(int,int)
void setLocation(Point)
(in java.awt.Component)
设置组件的位置, 单位是象素 ( 下同 ), 从该组
件的直接上层组件的左上角算起 ( 下同 ) 。
void setSize(int,int)
void setSize(Dimension)
(in java.awt.Component)
设置组件的大小 。
void setBounds(int,int,int,int)
void setBounds(Rectangle)
(in java.awt.Component)
设置组件的大小和位置 。