一、GUI概述
GUI全称是Graphiacl User Interface,即图形用户界面。户名思议,就是应用程序提供给用户操作的图形界面,包括窗口、菜单、按钮、工具栏和其他各种图形界面元素。目前,图形用户界面已经成为一种趋势,几乎所有的程序设计语言都提供了GUI设计功能。Java中针对GUI设计提供了丰富的类库,这些类分别位于java.awt和javax.swing包中,简称AWT和Swing。其中,AWT是SUN公司最早推出的一套API,它需要利用本地操作系统所提供的图形库,属于重量级组件,不跨平台,它的组件种类有限,可以提供基本的GUI设计工具,却无法实现目前GUI设计所需的功能。随后,SUN公司对AWT进行改进,提供了Swing组件,Swing组件有纯java语言编写,属于轻量级组件,可跨平台,Swing不仅实现了AWT中的所有功能,而且还提供了更加丰富的组件和功能,足以满足GUI设计的一切需求。
二、AWT概述
AWT是用于创建图形用户界面的一个工具包,它提供了一系列用于实现图形界面的组件,如窗口、按钮、文本框、对话框等。在JDK中针对每个组件都提供了对应的Java类,这些类都位于java.awt包中。
AWT中组件分为两大类,这两大类基类分贝时Component和Menu Component。其中,Menu Component是所有与菜单相关组件的父类。Component则是除菜单外其他AWT组件的父类,它表示一个能以图形化方式显示出来,并可与用户交互的对象。
Compoment类通常被称为组件,根据Component的不同作用,可将其分为基本组件类和容器类。基本组件是诸如按钮、文本框之类的图形界面元素,而容器类则是通过Component的子类Container实例化的对象。Container类表示容器,是一种特殊的组件,可以用来容纳其他组件。Container容器又分为两种类型,分别是Window和Panel。
1.Window
Window类是不依赖其他容器而独立存在的容器,它有两个子类,分别是Frame类和Dialog类。Frame类用于创建一个具有标题栏的框架窗口,作为程序的主界面,Dialog类用于创建一个对话框,实现与用户的信息交互。
2.Panel
Panel也是一个容器,但是它不能单独存在,只能存在其他容器(Window或其子类)中,一个Panel对象代表了一个长方形的区域,在这个区域中可以容纳其他组件。在程序中通常会使用Panel来实现一些特殊的布局。
案例1:制作第一个窗体
public class Example01 {
public static void main(String[] args) {
//建立新窗体对象
Frame f = new Frame("我的第一个窗体!");
//设置窗体的宽度和高度
f.setSize(400,300);
//设置窗体在屏幕中所处位置(参数是窗口左上角的坐标)
f.setLocation(300,200);
//设置窗体可见
f.setVisible(true);
}
}
三、布局管理器
之前提到过,组件不能单独存在,必须放置于容器当中,而组件在容器中的位置和尺寸是由布局管理器来决定的,在java.awt包中提供了五种布局管理器,分别是:FlowLayout(流式布局管理器)、BorderLayout(边界布局管理器)、GridLayout(网络布局管理器)、GridBagLayout(网络包布局管理器)和CardLayout(卡片布局管理器)。每个容器在创建时都会使用一种默认的布局管理器,在程序中可以通过调用同期对象的setLayout()方法设置布局管理器。
例如把一个Frame窗体的布局管理器设置为FlowLayout,代码如下:
Frame frame = new Frame();
frame.setLayout(new FlowLayout());
1.FlowLayout
流式布局管理是最简单的布局管理,在这种布局下,容器会将组按照添加顺序从左向右放置。当达到容器的边界时,会自动将组建放到下一行的开始位置。这些组建可以左对齐、居中对齐(默认方式)或右对齐的方式排列。FlowLayout对象有三个构造方法。
方法声明 | 功能描述 |
---|---|
FlowLayout() | 组建默认居中对齐,水平,垂直间距默认为5个单位 |
FlowLayout(int align) | 指定组建相对于容器的对齐方式、水平、垂直间距默认为5个单位 |
FlowLayout(int align,int hgap,int vgap) | 指定组建的对齐方式,如水平,垂直间距 |
表中列出了FlowLayout的三个构造方法,其中,参数align决定组建在每行中相对于容器边界的对齐方式,可以使用该类中提供的常量作为参数传递给构造方法,其中FlowLayout用于表示左对齐、FlowLayout.RIGHT用于表示右对齐、FlowLayout.CENTER用于表示居中对齐。参数hgap和参数vgap分别设定组件之间的水平和垂直间隙,可以填入一个任意数值。
例:
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
public class example02 {
public static void main(String[] args) {
//创建一个FlowLayout的窗体
Frame f = new Frame("FlowLayout");
//设置窗体中的布局管理器FlowLayout,所有组件左对齐,水平间距为20,垂直间距为30
f.setLayout(new FlowLayout(FlowLayout.LEFT,20,30));
//设置窗体大小
f.setSize(220,300);
//设置窗体的位置(左上角)
f.setLocation(300,200);
//把按钮添加到f对应的窗口中
f.add(new Button("第一个按钮"));
f.add(new Button("第二个按钮"));
f.add(new Button("第三个按钮"));
f.add(new Button("第四个按钮"));
f.add(new Button("第五个按钮"));
f.add(new Button("第六个按钮"));
//设置窗体可见
f.setVisible(true);
}
}
2.BorderLayout
边界布局管理器是一种较为复杂的布局方式,它将容器划分为五个区域,分别是东(EAST)、南(SOUTH)、西(WEST)、北(NORTH)、中(CENTER)。组件可以被放置在这五个区域中的任意一个。
边界布局管理器将容器划分为五个区域,其中箭头是指改变容器大小时,各个区域需要改变的方向。也就是说,在改变容器是NORTH和SOUTH区域高度不变长度调整,WEST和EAST区域宽度不变高度调整增,CENTER会相应进行调整。
当向边界布局管理器中添加组件时,需要使用add(Component comp,Object constrains)方法。其中参数comp表示要添加的组件,constrains指定将组件添加到布局中的方式和对象,它是一个Object类型,在传参时可以使用BorderLayout提供的五个常量。
例:
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
public class example03 {
public static void main(String[] args) {
//创建一个名为BorderLayout对的窗体
Frame f = new Frame("BorderLayout");
f.setLayout(new BorderLayout());//设置窗体中的布局管理器BorderLayout
f.setSize(300,300);//设置大小
f.setLocation(300,200);
f.setVisible(true);
//下面代码是创建五个按钮,分别用于填充BorderLayout的五个区域
Button but1 = new Button("EAST");
Button but2 = new Button("SOUTH");
Button but3 = new Button("WEST");
Button but4 = new Button("NORTH");
Button but5 = new Button("CENTER");
//将创建好的按钮添加到窗体中,并且设置按钮所在的区域
f.add(but1,BorderLayout.EAST);
f.add(but2,BorderLayout.SOUTH);
f.add(but3,BorderLayout.WEST);
f.add(but4,BorderLayout.NORTH);
f.add(but5,BorderLayout.CENTER);
}
}
3.GridLayout
网格布局管理器使用纵横线将容器分成n行m列相等的网格,每个网格中放置一个组件。添加到容器中的组件首先放置在第一行第一列的网格中,然后在第1行的网格中从左向右一次放置其他组件,行满后,继续在下一行中从左到右放置组件。与FlowLayout不同的是,放置在GridLayout布局管理器中的组件将自动占据整个网格区域。
构造方法:
方法声明 | 功能描述 |
---|---|
GridLayout() | 默认只有一行,每个组件占一列 |
GridLayout(int rows,int cols) | 指定容器的行数和列数 |
GridLayout(int rows,int cols,int,hgap,int xgap) | 指定容器的行数和列数以及组件之间的水平、垂直间距 |
水平间隙指的是网格之间的水平距离,垂直间隙同理
import java.awt.Button;
import java.awt.Frame;
import java.awt.GridLayout;
public class example04 {
public static void main(String[] args) {
// 创建一个名为GridLayout的窗体
Frame f = new Frame("GridLayout");
f.setLayout(new GridLayout(3,3));//设置该窗体为3*3的网格
f.setSize(300,300);
f.setLocation(200,300);
//循环添加9个按钮到GridLayout中
for(int i=1;i<=9;i++) {
Button btn = new Button("btn"+i);
f.add(btn);//向窗体中添加按钮
}
f.setVisible(true);
}
}
4.GridBagLayout
网格包布局管理器是最灵活、最复杂的布局管理器。与GridLayout布局管理器类似,不同的是,它允许网格中的组件大小各不相同,而且允许一个组件跨越一个或多个网络。
使用GridBagLayout布局管理器的步骤如下:
- 创建GridBagLayout布局管理器,并使用容器采用该布局管理器
- 创建GridBagLayout对象(布局约束条件),并设置该对象的相关属性
- 调用GridBagLayout对象的setConstrains()方法建立GridBagConstrains对象和受控组件之间的并联
- 向容器中添加组件
GridBagConstraints对象可以重复使用,只需要改变它的属性即可。如果要向容器中添加多个组件,则重复(2)、(3)、(4)步骤。
import java.awt.Button;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
//网格包布局管理器
class Layout extends Frame{
public Layout(String title) {
GridBagLayout layout = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();//约束对象
this.setLayout(layout);//设置布局管理器
c.fill = GridBagConstraints.BOTH; //设置组件横向纵向可以拉伸
c.weightx = 1;//设置横向权重为1
c.weighty = 1;//设置纵向权重为1
//增加组件
this.addComponent("btn1",layout,c);
this.addComponent("btn2",layout,c);
this.addComponent("btn3",layout,c);
c.gridwidth = GridBagConstraints.REMAINDER;//添加的组件是本行的最后一个组件
this.addComponent("btn4",layout,c);
c.weightx = 0;//设置纵向权重为0
c.weighty = 0;//设置纵向权重为0
this.addComponent("btn5",layout,c);
c.gridwidth = 1;//设置组件跨一个网格(默认值)
this.addComponent("btn6",layout,c);
c.gridwidth = GridBagConstraints.REMAINDER;//添加的组件是本行的最后一个组件
this.addComponent("btn7",layout,c);
c.gridwidth = 1;//设置组件跨2个网格
c.gridheight = 2;////设置组件跨一个网格(默认值)
c.weightx = 2;//设置纵向权重为2
c.weighty = 2;//设置纵向权重为2
this.addComponent("btn8",layout,c);
c.gridwidth = GridBagConstraints.REMAINDER;//添加的组件是本行的最后一个组件
c.gridheight = 1;//设置组件跨1个网格
this.addComponent("btn9",layout,c);
this.addComponent("btn10",layout,c);
this.setTitle(title);//设置窗体的标题
this.pack();//设置自动窗体大小
this.setVisible(true);
}
//添加组件的方法,通过指定的约束,将组件添加到布局管理器中
public void addComponent(String name,GridBagLayout layout,GridBagConstraints c) {
Button bt = new Button(name);//创建一个名为name的按钮
layout.setConstraints(bt, c);//设置约束对象和按钮的关联
this.add(bt);
}
}
public class example05 {
public static void main(String[] args) {
new Layout("GridBagLayout");
}
}
从上面的步骤可以看出,使用GridBagLayout布局管理器关键在于GridBagConstraints对象,它才是控制容器中每个组件布局的核心类,在GridBagConstraints类中有很多表示约束的属性.
-
GridBagConstraints.gridwidth
、GridBagConstraints.gridheight
指定组件显示区域中一行中的单元格数(对于
gridwidth
)或列(对于gridheight
)。 默认值为1.使用GridBagConstraints.REMAINDER
指定组件的显示区域将从gridx
到行中的最后一个单元格(对于gridwidth
),或从gridy
到列中的最后一个单元格(对于gridheight
)。 使用GridBagConstraints.RELATIVE
来指定组件的显示区域将从gridx
到其行中最后一个单元格的下一个(对于gridwidth
或从其列中的最后一个单元格的gridy
到gridheight
)。 -
GridBagConstraints.fill
当组件的显示区域大于组件的请求大小时使用,以确定是否(以及如何)调整组件的大小。 可能的值为
GridBagConstraints.NONE
(默认值),GridBagConstraints.HORIZONTAL
(使组件足够宽,可以水平填充其显示区域,但不要更改其高度),GridBagConstraints.VERTICAL
(使组件足够高以垂直填充其显示区域,但不要更改其宽度)和GridBagConstraints.BOTH
(使组件完全填充其显示区域)。 -
GridBagConstraints.weightx、GridBagConstraints.weighty
用于确定如何分配空间,这对于指定调整大小的行为很重要。 除非您指定一行中至少一个组件(
weightx
)和列(weighty
)的权重,否则所有组件都将集中在其容器的中心。 这是因为当重量为零(默认值)时,GridBagLayout
对象在其单元格格栅和容器边缘之间放置任何额外的空格。
5.CardLayout
在操作程序时,经常会遇到通过选项卡按钮来切换程序中的界面,这些界面就相当于一张张卡片,而管理这些卡片的布局管理器就是卡片布局管理器。卡片布局管理器将界面看做是一系列卡片,在任何时候只有其中一张卡片是可见的,这张卡片占据容器的整个区域。
在CardLayout不倦利器中经常会用到下面几个方法:
方法声明 | 功能需求 |
---|---|
void first(Container parent) | 显示parent容器第一张卡片 |
void last(Container parent) | 显示parent容器的最后一张卡片 |
void previous(Container parent) | 显示parent容器的前一张卡片 |
void next(Container parent) | 显示parent容器的下一张卡片 |
void show(Container parent,String name) | 显示parent容器中名称为name的组件,如果不存在,则不会发生任何操作 |
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.CardLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
class cardLayout extends Frame implements ActionListener{
CardLayout cardlayout = new CardLayout();//定义卡片布局管理器
Panel cardPanel = new Panel();//定义面板,放置卡片内容
Panel controlPanel = new Panel();//定义面板,放置按钮
Button preButton;//声明切换到上一张卡片的按钮
Button nextButton;//声明切换到下一张卡片的按钮
public cardLayout() {
this.setSize(300,200);//设置窗体大小
cardPanel.setLayout(cardlayout);//设置布局为卡片布局管理器
//在cardPanel中添加三个文本标签
cardPanel.add(new Label("第一个界面",Label.CENTER));
cardPanel.add(new Label("第二个界面",Label.CENTER));
cardPanel.add(new Label("第三个界面",Label.CENTER));
//创建两个按钮
nextButton = new Button("下一张卡片");
preButton = new Button("上一张卡片");
//将按钮添加到controlButton面板中
controlPanel.add(preButton);
controlPanel.add(nextButton);
//把面板添加到窗体中显示
this.add(cardPanel,BorderLayout.CENTER);
this.add(controlPanel, BorderLayout.SOUTH);
this.setVisible(true);//设置窗体显示
//为按钮添加监听事件
nextButton.addActionListener(this);
preButton.addActionListener(this);
//为窗口添加关闭事件监听器
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
cardLayout.this.dispose();
}
});
}
//实现按钮的监听触发,并对触发实践做出相应的处理方式
@Override
public void actionPerformed(ActionEvent e) {
//如果用户点击nextButton,执行操作
if(e.getSource()== nextButton) {
//切换cardPanel面板当前卡片,向后切换一张
cardlayout.next(cardPanel);
}
if(e.getSource()== preButton) {
cardlayout.previous(cardPanel);
}
}
}
public class example06 {
public static void main(String[] args) {
cardLayout layout = new cardLayout();
}
}
6.不使用布局管理器
当一个容器被创建后,它们都会有一个默认的布局管理器。Window、Frame和Dialog的默认布局管理器是BorderLayout,Panel的默认布局管理器是FlowLayout。如果不希望通过布局管理器来对容器进行布局,也可以调用容器的setLayout(null)方法,将布局管理器取消。在这种情况下,程序必须调用容器中每个组件的setSize和setLocation方法或者是setBounds方法(这个方法接受四个参数,分别是左上角的x、y坐标和组件的长、宽)来为这些组件在容器中定位。
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class example07{
public static void main(String[] args) {
Frame f = new Frame("不使用布局管理器");
//取消当前窗体的不管理器
f.setLayout(null);
f.setSize(300,150);
Button bt1 = new Button("press");
Button bt2 = new Button("pop");
//设置按钮显示的位置与大小
bt1.setBounds(40, 60, 100, 30);
bt2.setBounds(140, 90, 100, 30);
f.add(bt1);
f.add(bt2);
f.setVisible(true);
//添加了关闭窗口监听事件
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
f.dispose();
}
});
}
}
四、AWT事件处理
1.事件处理机制
如果不设置任何东西,单机窗口右上角的关闭按钮会发现窗口无法关闭,这说明该按钮的单机功能没有实现。按理说Frame对象应该实现这个按钮的功能,之所以没有实现,是因为Frame的设计者无法确定用户关闭Frame窗口的方式,例如:是直接关闭窗口还是需要弹出对话框询问用户是否关闭。如果想要关闭窗口,就需要通过实践处理机制对窗口进行监听。
实践处理机制专门用于响应用户的操作。比如,想要响应用户的单机鼠标、按下键盘的操作,就需要使用AWT的时间处理机制。在学习如何使用awt事件处理机制之前,首先向读者介绍几个比较重要的概念,具体概念如下:
- 事件对象(Event):封装GUI组件上发生的特定时间(通常就是用户的一次操作)
- 事件源(组件):时间发生的场所,通常就是产生事件的组件
- 监听器(Listener):负责监听事件源上发生的事件,并对各种时间做出相应处理的对象(对象中包含事件处理器)
- 事件处理器,监听器对象接受的事件对象进行相应处理的方法
上面提到的事件对象、事件源、监听器、事件处理器在整个事件处理机制中都起着非常重要的作用,他们彼此之间有着非常紧密的联系。
程序中,如果想实现事件的监听机制,首先需要定义一个实现了事件监听器接口的类,例如Window类型的窗口需要实现WindowsListener。接着通过addWindowLinstener()方法为时间源注册时间监听器的对象,当事件源上发生事件时,便会触发时间监听对象,由时间监听器调用相应的方法来处理相应的事件。
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class example08 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建新窗体
Frame f = new Frame("我的窗体");
f.setSize(400,300);//设置窗体尺寸大小
f.setLocation(300,200);//设置窗口的位置
f.setVisible(true);//设置窗口的显示
//为窗口组件注册监听器
f.addWindowListener(new MyWindowListener());
}
}
//创建MyWindowLinstener类实现WindowListener接口
class MyWindowListener implements WindowListener{
@Override
public void windowOpened(WindowEvent e) {}
@Override
public void windowClosing(WindowEvent e) {
// 监听器监听事件对象作出处理
Window window = e.getWindow();
window.setVisible(false);
//窗口的释放
window.dispose();
}
@Override
public void windowClosed(WindowEvent e) {}
@Override
public void windowIconified(WindowEvent e) {}
@Override
public void windowDeiconified(WindowEvent e) {}
@Override
public void windowActivated(WindowEvent e) {}
@Override
public void windowDeactivated(WindowEvent e) {}
}
2.事件适配器
MyWindowLinstener类实现WindowLinstener接口后,需要实现接口中定义的七个方法,然而在程序中只需要windowClosing()一个方法,其他六个方法都是空实现,没有发挥任何作用,这样代码的编写明显是多余的但是右必需的工作。正对这样的问题,JDK提供了一些适配器,他们是监听接口的默认实现类,这些实现类中实现了接口的所有方法,但方法中没有任何代码,程序可以通过继承适配器来达到实现监听接口的目的。
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class example09 {
public static void main(String[] args) {
Frame f = new Frame("继承适配器");
f.setSize(400,300);
f.setLocation(200,300);
f.setVisible(true);
//为窗口组件注册监听器
f.addWindowListener(new MyWindowListener02());
}
}
class MyWindowListener02 extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
Window window = (Window) e.getComponent();
window.dispose();
}
}
3.匿名内部类实现事件处理
在实际开发中,为了代码的简洁,经常通过匿名内部类来创建监听器对象,正对所发生的事件进行处理。
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* 用匿名内部类实现事件处理
*/
public class example10 {
public static void main(String[] args) {
Frame f = new Frame("匿名内部类实现事件处理");
f.setSize(400,300);
f.setLocation(300,200);
f.setVisible(true);
Button bt1 = new Button("EXIT");
f.add(bt1);
//用匿名内部类的方法实现为按钮注册监听器
bt1.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
System.exit(0);
}
});
}
}
五、常用事件分类
1.窗口事件
大部分GUI应用程序都需要使用Window窗体对象作为最外层的容器,可以说窗体对象是所有GUI应用程序的基础,应用程序中通常都是将其他组件直接或者间接置于窗体中。
当对窗体进行操作时,比如窗体的打开、关闭、激活、停用等,这些冯作都属于窗体时间,JDK提供了一个类WindowEvent用于表示这些窗体事件。在应用程序中,当对窗体事件进行处理时,首先需要定义一个实现了WindowListener接口类作为窗体监听器,然后通过addWindowListener()方法将窗体对象与窗体监听器绑定。
import java.awt.Frame;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class example11 {
/**
* 窗口事件
*/
public static void main(String[] args) {
Frame f = new Frame("windowEvent");
f.setSize(400,300);
f.setLocation(300,200);
f.setVisible(true);
//使用内部类创建WindowListener对象,监听窗体事件
f.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
System.out.println("WindowOpened --- 窗体打开激活事件");
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println("windowClosing --- 窗体正在执行关闭时的操作");
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println("windowClosed --- 窗口关闭事件");
}
@Override
public void windowIconified(WindowEvent e) {
System.out.println("windowIconified --- 窗体图标化事件(最小化)");
}
@Override
public void windowDeiconified(WindowEvent e) {
System.out.println("windowDeiconified --- 窗体取消图标化事件");
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println("windowActivated --- 窗体激活事件");
}
@Override
public void windowDeactivated(WindowEvent e) {
System.out.println("windowDeactivated--窗体停用事件");
}
});
}
}
2.鼠标事件
在图形用户界面中,用户经常会使用鼠标来进行选择、切换界面操作,这些操作被定义为鼠标事件,其中包括鼠标按下、鼠标松开、鼠标单击等。JDK中提供了一个MouseEvent类用于表示鼠标事件,几乎所有的组件都可以产生鼠标事件。处理鼠标事件时,首先需要通过实现MouseListener接口定义监听器(也可以通过继承适配器MouseAdapter类来实现),然后调用addMouseListener()方法将监听器绑定到之间源对象。
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class example12 {
public static void main(String[] args) {
Frame f = new Frame("MouseEvent");
f.setLayout(new FlowLayout());
f.setSize(300,200);
f.setLocation(300,200);
f.setVisible(true);
Button btn = new Button("Button");
f.add(btn);//将按钮添加到窗体
//为按钮添加鼠标事件监听器
btn.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("mouseClicked---鼠标点击事件");
}
@Override
public void mousePressed(MouseEvent e) {
System.out.println("mousePressed---鼠标按下事件");
}
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("mouseReleased---鼠标放开事件");
}
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("mouseEntered---鼠标进入按钮区域的事件");
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("mouseExited---鼠标移出按钮区域的事件");
}
});
}
}
3.键盘事件
键盘操作也是最常用的用户交互方式,例如键盘按下、释放等,这些操作被定义为键盘事件。JDK中提供了一个KeyEvent类表示键盘事件,处理KeyEvent事件的监听器对象需要实现KeyListener接口或者KeyAdapter类。
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class example13 {
/**
* 键盘监听
*/
public static void main(String[] args) {
Frame f = new Frame("KeyEvent");
f.setLayout(new FlowLayout());
f.setSize(400,300);
f.setLocation(200,300);
f.setVisible(true);
TextField tf = new TextField(30);//创建一个文本框对象
f.add(tf);
tf.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();//返回所按按键对应的整数值
//返回按键的字符串描述
String s = KeyEvent.getKeyText(keyCode);
//输出相关信息
System.out.println("键盘输入的内容为"+s+",");
System.out.println("对应的keyCode值为:"+keyCode+",");
}
});
//用匿名内部类实现窗口关闭
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
4.动作事件
动作事件与前面三种事件有所不同,它不代表某个具体动作,只是表示一个动作发生了。例如,在关闭一个文件时,可以通过键盘关闭,也可以通过鼠标关闭。在这里不需要关心使用哪种方式对文件进行关闭,只要是对关闭按钮进行操作,即出发了动作事件。
在java中,董总事件用ActionEvent类表示,处理ActionEvent事件的监听器对象需要实现ActionListener接口。监听器对象在监听动作时,不会像鼠标事件一样处理鼠标的移动和单机的细节,而是去处理类似于“按钮按下”这样有意义的事件。
5.AWT绘图
很多GUI程序都需要在组件上绘制图形,比如说实现一个五子棋的小游戏,就需要在组件上绘制棋盘和妻子。在java.awt包中专门提供了一个Graphics类,它相当于一个抽象的画笔,其中提供了各种绘制图形的方法,使用Graphics类的方法就可以完成在组件上绘制图形。表中列出了Graphics类常用的方法。
方法声明 | 方法描述 |
---|---|
void setColor(Color c) |
将此图形上下文的当前颜色设置为指定的颜色。 |
void setFont(Font font) |
将此图形上下文的字体设置为指定的字体。 |
void drawLine(int x1, int y1, int x2, int y2) |
在该图形上下文的坐标系中的点 (x1, y1) 和 (x2, y2) 之间绘制一行,使用当前颜色。 |
void drawRect(int x, int y, int width, int height) |
绘制指定矩形的轮廓。 |
void drawOval(int x, int y, int width, int height) |
绘制椭圆形轮廓。 |
void fillRect(int x, int y, int width, int height) |
填写指定的矩形 |
void fillOval(int x, int y, int width, int height) |
用当前颜色填充由指定矩形界定的椭圆。 |
void drawString(String str,int x,int y) |
使用该图形上下文的当前字体和颜色绘制由指定字符串给出的文本。 |
例:利用awt写一个验证码生成器
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Panel;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;
public class example14 {
/**
* AWT绘图
*/
public static void main(String[] args) {
Frame frame = new Frame("验证码");
Panel panel = new MyPanel();
frame.add(panel);
frame.setSize(200,100);
//将frame窗口居中
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//利用匿名内部类实现关闭操作
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
class MyPanel extends Panel {
@Override
public void paint(Graphics g) {
int width = 160;//定义验证码所对应的图片宽度
int height = 40;//定义验证码图片的高度
g.setColor(Color.LIGHT_GRAY);//设置画笔颜色
//绘制验证码的背景
g.fillRect(0, 0, width-1, height-1);
//设置画笔颜色
g.setColor(Color.BLACK);
//设置边框
g.drawRect(0, 0, width, height);
//绘制干扰点
Random r = new Random();
for(int i=0;i<100;i++) {
int x = r.nextInt(width) -2;
int y = r.nextInt(height)-2;
g.drawOval(x, y, 2, 2);
}
//设置验证码字体
g.setFont(new Font("黑体",Font.BOLD,30));
//设置验证码文字颜色
g.setColor(Color.red);
//产生随机验证码操作
StringBuffer sb = new StringBuffer();
char[] chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
for (int i = 0; i < 4; i++) {
int pos = r.nextInt(chars.length);
char c = chars[pos];
sb.append(c+" ");
}
//绘制验证码字符串文字
g.drawString(sb.toString(), 20, 30);
}
}
六、Swing
一开始提到JDK中针对GUI提供的API包括AWT和Swing。前面的都是正对AWT的了解,接下来针对swing组件进行讲解。相对于awt来说,swing包提供了更加丰富、边界、强大的GUI组件,而且这些组件都是java语言编写而成的,因此,swing组件不依赖于本地平台,可以真正做到跨平台运行。通常来讲,把依赖与本地平台的awt称作重量级组件,而把不依赖本地平台的swing组件成为轻量级组件。
学习swing组件的过程和学习awt差不多,大部分swing组件都是JComponent类的直接或间接子类,而JComponent类是AWT中java.awt.Container的子类,说明swing组件和awt组件在继承树上形成了一定的关系。
1.JFrame
在Swing组件中,最常见的就是一个JFrame,它和Frame一样是一个独立存在的顶级窗口,不能放置在其他容器中,JFrame支持通用窗口的索引基本功能,例如窗口的最小化,设定窗口大小等。
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
/**
* JFrame的使用
*/
public class example01 extends JFrame{
public example01() {
this.setTitle("JFrameTest");
this.setSize(250, 300);
//设置居中显示
this.setLocationRelativeTo(null);
//定义一个按钮
JButton bt = new JButton("按钮");
//设置流式布局管理器
this.setLayout(new FlowLayout());
//添加按钮
this.add(bt);
//设置点击关闭按钮时,默认操作
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new example01();
}
}
2.JDialog
JDialog是另外一个顶级窗口,它和Dialog一样都表示对话框。JDialog对话框可分为两种:静态对话框和非静态对话框。所谓模式对话框是指用户需要等到处理完对话框后才能继续与其他窗口交互的对话框,而非模式对话框是允许用户在处理对话框的同时与其他窗口交互的对话框。
对话框是模式或者费模式,可以在创建JDialog对象是为构造方法传入参数来设置,也可以在创建JDialog对象后调用它的setModal()方法来进行设置。JDialog常见的构造方法如表所示。
方法声明 | 功能描述 |
---|---|
JDialog(Frame owner) |
创建一个无模式对话框,其中指定的是 Frame 作为其所有者,并且是一个空的标题。 |
JDialog(Frame owner, String title) |
使用指定的标题和指定的所有者框架创建无模式对话框 |
JDialog(Frame owner, boolean modal) |
创建一个具有空标题和指定模态的对话框,并以 Frame 作为其所有者。 |
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
/**
* JDialog对话框
*/
public class example02 {
public static void main(String[] args) {
//建立两个按钮
JButton btn1 = new JButton("模式对话框");
JButton btn2 = new JButton("非模式对话框");
JFrame f = new JFrame("JDialogDemo");
f.setSize(300, 250);
f.setLocationRelativeTo(null);//设置居中效果
f.setLayout(new FlowLayout());//设置布局管理模式
//添加按钮
f.add(btn1);
f.add(btn2);
//设置点击关闭按钮的默认操作
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
//创建JDialog
final JDialog dialog = new JDialog(f,"Dialog");
dialog.setSize(220, 150);
dialog.setLocation(350, 150);//设置对话框显示位置
dialog.setLayout(new FlowLayout());//设置对话框的布局管理器
JButton btn3 = new JButton("确定");
dialog.add(btn3);//在对话框中添加按钮
final Label label = new Label("标签");
dialog.add(label);
//为“模式对话框”按钮,添加点击事件
btn1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//设置对话框的状态设置为模式对话框
dialog.setModal(true);
//修改标签的内容
label.setText("模式对话框,点击确定按钮关闭");
//显示对话框
dialog.setVisible(true);
}
});
//为“非模式对话框”按钮,添加点击事件
btn2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//设置对话框的状态设置为模式对话框
dialog.setModal(false);
//修改标签的内容
label.setText("非模式对话框,点击确定按钮关闭");
//显示对话框
dialog.setVisible(true);
}
});
//为对话框中的按钮添加点击事件
btn3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
}
}
3.中间容器
Swing组件不仅具有JFrame和Dialog这样的顶级窗口,还提供了一些中间容器,这些容器不能单独存在,只能放置在顶级窗口中。最常见的中间容器有两种:JPanel和JScrollPane。
- JPanel:JPanel和AWT中的Panel组件使用方法一致,它是一个无边框,不能被移动、方法、缩小或者关闭的面板,它的默认布局管理器是流布局。当然也可以使用JPanel带参数的构造函数JPanel(LayoutManager layout)或者它的setLayout()方法为其制定布局管理器。
- JScrollPane:与JPanel不同的是,JScrollPanel是一个都带有滚动条的面板容器,而且这个面积只能添加一个组件,如果想在JScrollPane面板中添加多个组件,应该先将组件添加到JPanel中,然后将JPanel添加到JScrollPane中
import java.awt.Button;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
/**
* 中间容器添加按钮
*/
public class example03 extends JFrame{
public example03() {
this.setTitle("PanelDemo");
this.setLocationRelativeTo(null);
//定义一个JPanel面板
JPanel panel = new JPanel();
//在pannel面板添加四个按钮
panel.add(new Button("按钮1"));
panel.add(new Button("按钮2"));
panel.add(new Button("按钮3"));
panel.add(new Button("按钮4"));
//创建一个滚动面板
JScrollPane scrollpane = new JScrollPane();
//设置水平滚动条一直显示效果
scrollpane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
//设置垂直滚动条的显示效果,需要时显示
scrollpane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
//设置panel面板在滚动面板中显示
scrollpane.setViewportView(panel);
//将面板scrollpane添加到窗体中
this.add(scrollpane);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 250);
this.setVisible(true);
}
public static void main(String[] args) {
new example03();
}
}
4.文本组件
文本组件用于接收用户输入的信息或向用户展示信息,其中包括文板框(JTextField)、文本域(JTextArea)等。他们都有一个共同的父类JTextComponent。
import java.awt.BorderLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* 文本组件JTextField与JTextArea
*/
public class example04 extends JFrame{
public example04() {
//基本设定
this.setLayout(new BorderLayout());//设置窗口布局
this.setTitle("聊天窗口");//设置窗口标题
this.setLocation(500,300);
this.setSize(400, 300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//上面部分
final JTextArea chatContent = new JTextArea(12,34);//创建一个文本域
chatContent.setEditable(false);//设置文本域不可修改
//创建有一个滚动面板,并把文本域添加到滚动面板中
JScrollPane showPanel = new JScrollPane(chatContent);
//添加滚动面板到窗口中
this.add(showPanel,BorderLayout.CENTER);
//下面部分
Label label = new Label("聊天信息");//创建一个标签
final JTextField inputField = new JTextField(20);
JButton sendBt = new JButton("发送");//创建按钮
JPanel inputPanel = new JPanel();//创建一个面板,用来存储下面的组件
//添加组件到下面的面板中
inputPanel.add(label);
inputPanel.add(inputField);
inputPanel.add(sendBt);
//添加下面的面板到窗口中
this.add(inputPanel,BorderLayout.SOUTH);//添加下面的面板到窗口中
//为按钮添加事件
sendBt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String content = inputField.getText();//获取输入文本框内容
if(content != null && !content.trim().equals("")) {
//如果内容不为空,将输入的文本信息追加到聊天的从窗口中
chatContent.append("本人:"+content+"\n");
}else {
//如果内容为空,提示聊天信息不能为空
chatContent.append("聊天信息不能为空\n");
}
//将文本框的内容设置为空
inputField.setText("");
}
});
this.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new example04();
}
}
5.按钮组件
在Swing中,常见的按钮组件有JButton、JCheckBox、JRadioButton等,他们都是抽象类AbstractButton类的直接或间接子类。
1.JCheckBox
JCheckBox又称复选框,它有选中(是)/未选中(否)两种状态,如果用户想接收的输入只有“是”和“非”,则可以通过复选框来切换状态。如果复选框有多个,则用户可以选中其中一个或多个。
方法描述 | 功能说明 |
---|---|
JCheckBox() |
创建一个最初未选择的复选框按钮,没有文字,没有图标。 |
JCheckBox(String text) |
创建一个最初未选择的复选框与文本。 |
JCheckBox(String text, boolean selected) |
创建一个带有文本的复选框,并指定是否最初选择它。 |
表中,,列出了用于创建JCheckBox对象三个构造方法。其中,第一个构造方法没有指定复选框的文本信息以及状态,如果想设置文本信息,可以通过调用JCheckBox从父类继承的方法来进行设置。第二个和第三个构造方法都制定了复选框的文本信息,而且第三个构造方法还制定了复选框初始化状态是否被选中。
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* JCheckBox组件(复选框)
*/
public class example05 extends JFrame{
public example05() {
//创建一个标签,标签中的文本信息进行居中显示
JLabel label =new JLabel("李玺,你好",JLabel.CENTER);
label.setFont(new Font("宋体",Font.PLAIN,20));//设置标签文字的字体
this.add(label);//把标签添加到窗体中显示
this.setSize(300, 300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//下面的
JCheckBox italic = new JCheckBox("italic");//倾斜效果
JCheckBox bold = new JCheckBox("bold");//粗体效果
JPanel panel = new JPanel();//创建窗口显示
//添加复选框按钮到面板中
panel.add(bold);
panel.add(italic);
//把面板添加到窗体的下方
this.add(panel,BorderLayout.SOUTH);
//为复选框定义ActionListener监听器
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int mode = Font.PLAIN;//默认字体样式
if(italic.isSelected()) {
//选中倾斜的复选框
mode+=Font.ITALIC;
}
if(bold.isSelected()) {
mode+=Font.BOLD;
}
//设置当前标签文字的样式
label.setFont(new Font("宋体",mode,20));
}
};
//为两个复选框添加监听器
italic.addActionListener(listener);
bold.addActionListener(listener);
this.setVisible(true);//设置窗体显示
}
public static void main(String[] args) {
new example05();
}
}
2.JRadionButton
JRadioButton组件被成为单选按钮,与JCheckBox复选框不同的是,单选按钮只能选一个。就像随身听上的播放和快进按钮,当按下一个,先前按下的按钮就会自动弹起。对于JRadioButton按钮来说,当一个按钮被选中时,先前被选中的按钮就会自动取消选中。
由于JRadioButton组件本身并不具备这种功能,因此若想实现JRadioButton按钮之间的互斥,需要使用javax.swing.ButtonGroup类,它是一个不可见的组件,不需要将其增加到容器中显示,知识在逻辑上表示一个单选按钮组。将多个JRadioButton按钮添加到同一个单选按钮组对象中,就能实现按钮的单选功能。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
/**
* JRadioButton组件的使用
*
*/
public class example06 extends JFrame{
public example06() {
final JPanel pallet = new JPanel();//创建一个调色板
this.add(pallet,BorderLayout.CENTER);//将调色板添加到窗体的中间位置
ButtonGroup group = new ButtonGroup();//单选按钮组对象
JRadioButton btn1 = new JRadioButton("灰");
JRadioButton btn2 = new JRadioButton("粉");
JRadioButton btn3 = new JRadioButton("黄");
//添加按钮到按钮组中
group.add(btn1);
group.add(btn2);
group.add(btn3);
JPanel panel = new JPanel();//创建一个面板
panel.add(btn1);//按钮添加到面板中
panel.add(btn2);
panel.add(btn3);
//添加面板到窗体的下方
this.add(panel,BorderLayout.SOUTH);
this.setSize(300, 300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//创建单选按钮的ActionListener监听器
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Color color = null;
if(btn1.isSelected()) {
color = Color.GRAY;
}else if (btn2.isSelected()) {
color = Color.PINK;
}else if(btn3.isSelected()) {
color = Color.YELLOW;
}
//为调色板设置背景色
pallet.setBackground(color);
}
};
//为单选按钮添加监听器
btn1.addActionListener(listener);
btn2.addActionListener(listener);
btn3.addActionListener(listener);
this.setVisible(true);
}
public static void main(String[] args) {
new example06();
}
}
3.JComboBox
JComboBox组件被称为组合框还或者下拉列表框,它将所有选项折叠收藏在一起,默认显示的是第一个添加的选项。当用户单击组合框时,会出现下拉式的选择列表,用户可以从选择其中一项并显示。
JComboBox组合框组件分为可编辑和不可编辑的两种形式,对于不可编辑的组合框,用户只能在现有选项列表中选择,而对于可编辑的组合框,用户既可以在现有的选项中选择,也可以自己出入新的内容。需要注意的是,自己输入的内容只能作为当前项显示,并不会添加到组合框的选项中。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* JComboBox组件
*/
public class example07 extends JFrame{
public example07() {
//创建JPanel面板
JPanel panel = new JPanel();
//创建一个下拉列表框
final JComboBox<String> comboBox = new JComboBox<String>();
//为下拉列表框添加选择
comboBox.addItem("请选择城市");
comboBox.addItem("南阳");
comboBox.addItem("杭州");
comboBox.addItem("宁波");
comboBox.addItem("上海");
comboBox.addItem("广州");
//创建文本框
JTextField field = new JTextField(20);
//添加组件到面板中
panel.add(comboBox);
panel.add(field);
//为下拉列表框添加监听器
comboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String item = (String) comboBox.getSelectedItem();
if("请选择城市".equals(item)) {
field.setText("");
}else {
field.setText("您选择的城市是:"+item);
}
}
});
//把面板添加到窗体上
this.add(panel);
this.setSize(350,100);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new example07();
}
}
6.菜单组合
在GUI程序中,菜单式很常见的组件,利用Swing提供的菜单组件可以创建出多种样式的菜单。下面是下拉式菜单和弹出式菜单的介绍。
1.下拉式菜单
下拉式菜单,是计算机中很多文件的菜单的首选,如记事本的菜单。在GUI程序中,创建下拉式菜单需要使用三个组件“:JMenuBar(菜单栏)、JMenu(菜单)和JMenultem(菜单项)。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class example08 extends JFrame{
public example08() {
JMenuBar menuBar = new JMenuBar();//创建菜单栏
JMenu menu = new JMenu("操作");//创建菜单
JMenuItem item1 = new JMenuItem("弹出窗口");//创建两个菜单项
JMenuItem item2 = new JMenuItem("关闭");//创建两个菜单项
//组建下拉式菜单
menu.add(item1);
menu.addSeparator();//添加分隔符
menu.add(item2);
menuBar.add(menu);//菜单添加到菜单栏
this.setJMenuBar(menuBar);//菜单栏添加到窗体
this.setSize(300, 300);
this.setLocationRelativeTo(null);
this.setVisible(true);
//为菜单项添加事件的监听器
item1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JDialog dialog = new JDialog(example08.this,true);
dialog.setTitle("弹出对话框");
dialog.setSize(200, 200);
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
}
});
item2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) {
new example08();
}
}
2.弹出式菜单
弹出式菜单,在Windows桌面单机鼠标右键会出现一个菜单,那就是弹出式菜单。在Java的Swing组件中,弹出式菜单用JPopupMenu表示。
JPopupMenu弹出式菜单和下拉式菜单一样,都要通过调用add()方法添加JMenuItem菜单项,但他默认是不可见的。如果要显示出来,则必须调用他的show(Component invoker,int x,int y)方法,该方法中参数invoker表示JPopupMenu菜单显示位置的窗口组件,x和y表示invoker组件坐标空间中的一个坐标,显示的是JPopMenu菜单的左上角坐标。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
public class example09 extends JFrame{
public example09() {
//创建一个JPopopMenu菜单
JPopupMenu popupMenu = new JPopupMenu();
//创建三个菜单项
JMenuItem refreshItem = new JMenuItem("refresh");//刷新
JMenuItem createItem = new JMenuItem("create");//新建
JMenuItem exitItem = new JMenuItem("exit");//退出
//把菜单项添加到菜单中
popupMenu.add(refreshItem);
popupMenu.addSeparator();//添加菜单项分隔符
popupMenu.add(createItem);
popupMenu.addSeparator();//添加菜单项分隔符
popupMenu.add(exitItem);
//为当前窗体JFrame添加鼠标点击事件
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
//如果点击的是鼠标的右键 ,显示弹出菜单
if(e.getButton() == e.BUTTON3) {
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
});
this.setSize(300, 300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
//为菜单项添加事件监听器
exitItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) {
new example09();
}
}
7. JTable
表格也是GUI程序中常用的组件,表格是一个由多行、多列组成的而未显示区。Swing的JTable已经相关类提供了对这种表格的支持。使用了JTable以及相关类,程序既可以使用简单代码创建出表格来显示二维数据,也可以开发出功能丰富的表格,还可以为表格定制各种显示外观、编辑特性。
使用JTable来创建表格是非常容易的事情,它可以把一个二维数据包装成一个表格,这个二维数据既可以是一个二维数组,也可以是几何元素Vector对象。除此之外,为了给该表格的每一列指定列标题,还需要传入一个一维数据作为列标题,这个一维数据既可以是一维数据,也可以是Vector对象。
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
/**
* JTable
*/
public class example10 extends JFrame{
public example10() {
init();//使用JTable对象创建表格
}
//使用JTable对象创建表格
public void init() {
//定义一个一维数组,作为列的标题
Object[] columnTitle = {"姓名","年龄","性别"};
//定义一个二维数组,作为表格行对象的数据
Object[][] tableData = {
new Object[] {"李清照","29","女"},
new Object[] {"summer","20","男"},
new Object[] {"茉莉","20","女"},
new Object[] {"李白","38","男"},
};
//创建表格
JTable table = new JTable(tableData,columnTitle);
//添加表格组件到窗体上
this.add(new JScrollPane(table));
//设置自适应窗体大小
this.pack();
this.setTitle("简单的表格");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public static void main(String[] args) {
new example10();
}
}