图形用户界面或图形用户接口(Graphical User Interface,GUI)是指采用图形方式,借助菜单、按钮等标准界面元素,用户可以通过鼠标等外设向计算机系统发出指令、启动操作,并将系统运行的结果同样以图形方式显示给用户的技术。
GUI是事件驱动的,常见交互包括移动鼠标、单击鼠标按钮、在文字段输入、从菜单选择一个选项以及关闭一个窗口等。
从Java 1.2版开始,Sun公司推出了新的图形界面工具包:Swing。相应的工具包都以Swing来命名,例如javax.swing、javax .swing.event。相对AWT而言,Swing更为轻便,更容易编程,而且功能也更为灵活、强大,是Java基础类(Java Foundation Classes, JFC)的主要组成部分.
Java绘图
Java在图形处理方面有丰富的类库和方法,使用这些方法可以便捷的绘图,基本的绘图方法包括点、线、矩形和圆等。绘制这些图形要用到Graphics类。
Java中的任何一个图形组件,小到文本框、标签,大到一个框架,一个对话框,都有一个专门负责显示其界面的方法,这个方法名称是固定的:paint(),它的原型为:
public void paint(Graphics g)
{
……
}
- 画直线
void drawLine(int startX,int startY,int endX,int endY);
四个参数分别为:起始点的x坐标和y坐标以及终点的x坐标和y坐标,该方法用于在起点(startX,startY)和终点(endX,endY)之间画一条直线。坐标参数是相对的,他们相对于左上角的坐标为(0,0),以像素为单位,向右向下延伸,直线如果超出窗口,则超出的部分不会显示。
- 画矩形
void drawRect(int x,int y,int width,int height);
绘制一个左上角坐标为(x,y),宽为width,高为height的直角矩形。void fillRect(int x,int y,int width,int height);
绘制一个左上角坐标为(x,y),宽为width,高为height的有填充效果的直角矩形。void drawRoundRect(int x,int y,int width,int height,int arcWidth,int arcHeight);
绘制一个左上角坐标为(x,y),宽为width,高为height,在x轴方向上圆边半径为arcWidth,在y轴方向上圆边半径为arcHeight的圆角矩形。void fillRoundRect(int x,int y,int width,int height,int arcWidth,int arcHeight);
绘制一个左上角坐标为(x,y),宽为width,高为height,在x轴方向上圆边半径为arcWidth,在y轴方向上圆边半径为arcHeight的,有填充效果的圆角矩形。
- 画多边形:多边形是不限边数的图形,而这些边实际上是由一组点连接而成的,所以绘制多边形需要一组x,y坐标对。绘图的原理是从第一个x,y坐标对开始,向第二坐标对画一条直线,然后向第三个x,y坐标对画一条直线,依次类推,可以画出多边形。下面有方法绘制和填充多边形:
void drawPloygon(int []xPoints,int []yPoints,int numPoints);
void fillPloygon(int []xPoints,int []yPoints,int numPoints);
xPoints代表x坐标的整形数组,yPoints代表y坐标的整形数组,numPoints代表所有点数的整数,当然,x数组和y数组应该具有相同数目的元素。通过规定Polygon对象或者x,y数组值来设置多边形的点。
Java字体颜色
任何颜色都是三原色组成(RGB),Java中支持24位彩色,即红绿蓝色分量取值介于0…255之间。
Color的构造函数: public Color(int r,int g,int b);
使用举例:如果想构造一个灰色对象,则用下面的句子:
Color gray=new Color(205,205,205);
设置画笔颜色语法
g.setColor(color); //color是一个Color对象
每修改一次颜色它影响的就是下面所有的绘图语句,一直影响到再次碰到setColor函数才以新的颜色代替。
框架和面板
框架
框架是GUI应用程序的主窗口,是顶层容器。所谓容器是指能够容纳其他组件的特殊组件,由于容器也是组件的一种,因此容器中也能容纳容器。框架可重定义尺寸大小,能最大化最小化,带边框,可以指定标题、图标和窗口光标。框架可包菜单,使用对话框。在Java中每个GUI程序至少要有一个框架,Applet有时也会使用框架。
Frame的构造方法:
Frame();
构造一个框架,标题为空,使用缺省布局管理器;Frame(GraphicsConfiguration gc)
构造一个使用特定图形配置的框架;Frame(string title)
构造一个带标题的框架Frame(string title , GraphicsConfiguration gc)
构造一个使用特定图形配置带标题的框架
package 实验九;import java.awt.*;
import javax.swing.*;
public class Test extends JFrame
{public Test (){ super("演示字体、颜色、绘图"); //调用基类构造方法 setVisible( true ); //显示窗口setSize( 480, 250 ); //设置窗口大小 }public void paint( Graphics g ) {super.paint( g ); // call superclass's paint methodg.setFont( new Font( "SansSerif", Font.BOLD, 12 ) ); g.setColor(Color.blue); //设置颜色g.drawString("字体ScanSerif,粗体,12号,蓝色",20,50); g.setFont( new Font( "Serif", Font.ITALIC, 14 ) );g.setColor(new Color(255,0,0));g.drawString( " 字体Serif,斜体,14号,红色", 250, 50 );g.drawLine(20,60,460,60); //绘制直线g.setColor(Color.green);g.drawRect(20,70,100,50); //绘制空心矩形g.fillRect(130,70,100,50); //绘制实心矩形g.setColor(Color.yellow);g.drawRoundRect(240,70,100,50,50,50); //绘制空心圆角矩形g.fillRoundRect(350,70,100,50,50,50); //绘制实心圆角矩形g.setColor(Color.cyan);g.draw3DRect(20,130,100,50,true); //绘制突起效果空心矩形g.fill3DRect(130,130,100,50,false); //绘制凹陷效果实心矩形g.setColor(Color.pink);g.drawOval(240,130,100,50); //绘制空心椭圆g.fillOval(350,130,100,50); //绘制实心椭圆g.setColor(new Color(0,120,20));g.drawArc(20,190,100,50,0,90); //绘制一段圆弧 g.fillArc(130,190,100,50,0,90); //绘制扇形g.setColor(Color.black);int xValues[]={250,280,290,300,330,310,320,290,260,270};int yValues[]={210,210,190,210,210,220,230,220,230,220};g.drawPolygon(xValues,yValues,10); //绘制空心多边形int xValues2[]={360,390,400,410,440,420,430,400,370,380};g.fillPolygon(xValues2,yValues,10); //绘制实心多边形}public static void main( String args[] ) { Test application = new Test (); application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );}
}
Swing基础
前面介绍了如何在屏幕上绘制普通的图形,但如果需要绘制一个按钮,并使其可以对点击事件作出响应,就需要使用java Swing提供的组件
其实前面我们已经用到的JFrame、JApplet都是Swing组件,它们分别代表窗口组件和Applet容器组件
JFC
Java Foundation Classes(Java基础类)的缩写
是关于组件和服务的完整集合
Swing
JFC 的一部分
提供按钮、窗口、表格等所有的组件
纯Java组件(完全用Java写的)
- 文本标签(label)显示静态文本,用于提示和说明
- 文本框(text box)接收单行字符串输入
- 文本区域(text area)接收多行字符串输入
- 组合框(combo box)用于选择单个值,也可直接输入值
- 复选框(check box)接收yes/no值的数据,可选择多个
- 单选按钮(radio button)从一组选项中选择单个选项
- 按钮(button)触发一个操作
容器:存放上述组件的窗口称为容器(Container)。每个组件都可以继承其父容器的性质,如字体和颜色。同时,容器也可以控制放置其中的组件位置。
容器包含在框架窗口(frame window)中。框架窗口是顶层窗口,没有父容器。
按钮 JButton
构造方法:
JButton()
创建不带有设置文本或图标的按钮JButton(Icon icon)
创建一个带图标的按钮JButton(String text)
创建一个带文本的按钮JButton(String text, Icon icon)
创建一个带初始文本和图标的按钮
package 实验九;
import java.awt.*;
import javax.swing.*;
public class Test extends JFrame //创建一个框架窗体
{ public Test(String str){super(str);}public static void main(String args[]){ Test f=new Test("框架");JPanel panelObject=new JPanel(); //创建一个面板f.getContentPane().add(panelObject); //添加面板到框架上JButton b=new JButton("login");panelObject.add(b); //在面板上添加按钮f.setSize(200,200); f.setBackground(Color.red);f.setVisible(true);}
}
从本例来看,创建的用户界面可以理解为实际上由三层内容组成:框架Frame为基层,面板Panel为第二层,按钮Button为第三层。
JPanel是一个构件,是JComponent类的子类,也是一个简单的容器类。
JPanel类的对象必须放在JFrame中才能可见,提供了添加其他组件的空间,即使添加另一个面板也可以。
标签JLabel
构造方法:
JLabel():
创建无图像并且其标题为空字符串的 JLabelJLabel(Icon image)
创建具有指定图像的 JLabel 实例Label(Icon image, int horizontalAlignment)
创建具有指定图像和水平对齐方式的 JLabel 实例。JLabel(String text)
创建具有指定文本的 JLabel 实例JLabel(String text, Icon icon, int horizontalAlignment)
创建具有指定文本、图像和水平对齐方式的 JLabel 实例。
package 实验九;import java.awt.*;
import javax.swing.*;
public class Test extends JFrame
{public Test(String str){ super(str); }public static void main(String args[]){ Test f=new Test("框架");JPanel panelObject=new JPanel();f.getContentPane().add(panelObject);JButton b1=new JButton("login");JButton b2=new JButton("exit");JLabel CustomerName=new JLabel("Customer Name"); panelObject.add(b1);panelObject.add(b2);panelObject.add(CustomerName); //添加标签到面板上panelObject.setBackground(Color.red);f.setSize(200,200); f.setVisible(true);}
}
文本字段 JTextField
构造方法:
JTextField()
构造一个新的 TextField。创建一个默认的模型,初始字符串为 null,列数设置为 0。JTextField(int columns)
构造一个具有指定列数的新的空 TextField。JTextField(String text)
构造一个用指定文本初始化的新 TextField。JTextField(String text, int columns)
构造一个用指定文本和列初始化的新 TextField。
package 实验九;import java.awt.*;
import javax.swing.*;
public class Test extends JFrame
{public Test(String str){super(str);}public static void main(String args[]){ Test f=new Test("框架");JPanel panelObject=new JPanel();f.getContentPane().add(panelObject);JButton b=new JButton("login");JButton b2=new JButton("exit");JLabel CustomerName=new JLabel("Customer Name"); JTextField CustNameText=new JTextField(10); //创建文本框,长度为10 panelObject.add(b);panelObject.add(b2);panelObject.add(CustomerName);panelObject.add(CustNameText); //添加文本框到面板上f.setSize(200,200); f.setVisible(true);}
}
文本列表框 JList
构造方法:
JList()
构造一个具有空的、只读模型的JList。JList(Object[] listData)
构造一个 JList,使其显示指定数组中的元素。
package 实验九;import java.awt.*;
import javax.swing.*;
public class Test extends JFrame
{public Test(String str){ super(str); }public static void main(String args[]){ JFrame f=new JFrame("List Demo");JPanel p=new JPanel();String listArray[]={"The first list", "The second list","The three list","The four list"};JList list=new JList(listArray); list.setFixedCellWidth(100);list.setVisibleRowCount(4);p.add(list);f.getContentPane().add(p);f.setSize(200,200); f.setVisible(true); }
}
菜单
创建一个菜单系统由JMenuBar,JMenu,JMenuItem三个类共同实现。位于窗口的菜单栏包括下拉菜单的名字,当点击该名字时就能打开包含菜单项及子菜单项的菜单。
JmenuBar:菜单栏的实现。将 JMenu 对象添加到菜单栏以构造菜单。当用户选择 JMenu 对象时,就会显示其关联的 JPopupMenu,允许用户选择其上的某一个 JMenuItem。构造方法 JMenuBar() 用于创建新的菜单栏。
JMenu:菜单的实现,是一个包含 JMenuItem 的弹出窗口,用户选择 JMenuBar 上的项时会显示该 JMenuItem。除 JMenuItem 之外,JMenu 还可以包含 JSeparator。 菜单本质上是带有关联 JPopupMenu 的按钮。当按下“按钮”时,就会显示 JPopupMenu。
其构造方法有:
JMenu():构造没有文本的新 JMenu。
JMenu(String s):构造一个新 JMenu,用提供的字符串作为其文本。
JMenuItem:菜单中的项的实现。菜单项本质上是位于列表中的按钮。当用户选择“按钮”时,则执行与菜单项关联的操作。JPopupMenu 中包含的 JMenuItem 正好执行该功能。
构造方法有:
JMenuItem():创建不带有设置文本或图标的 JMenuItem。
JMenuItem(Icon icon):创建带有指定图标的 JMenuItem。
JMenuItem(String text):创建带有指定文本的 JMenuItem。
JMenuItem(String text, Icon icon):创建带有指定文本和图标的 JMenuItem。
事件处理
基于窗口的,事件驱动程序的流程:
在事件处理的过程中,主要涉及三类对象:
- 事件源: 能够接收外部事件的源体, 产生事件的地方(单击鼠标, 按按钮, 选择项目等产生动作的对象)。
- 监听器: 能够接收事件源通知的对象。监听程序必须注册一个事件源, 才能接收这个事件, 这个过程是自动的, 监听程序必须实现接受和处理这个事件的方法。
- 事件处理方法: 用于处理事件的对象, 事件源产生一个事件, 并把这个事件发送到一个或多个监听程序, 监听程序只是等待这个事件并处理它, 然后返回. 即程序把事件的处理“委托”给一段“代码”。这段代码就是事件处理方法, 也叫事件处理程序。
Java中事件模型处理机制:
- 监听器对象是一个实现了专门监听接口的类的实例;
- 可以向事件源注册相应事件的监听器;
- 当事件发生时, 事件源能够把事件对象发给已注册的相应监听器;
- 监听器对象中的事件处理方法会使用事件中的信息决定对事情的反应;
授权处理模型处理时间的一般方法:
- 对于某种类型的事件XXXEvent, 要想接收并处理这类事件,必须定义相应的事件监听器类,该类需要实现与该事件相对应的接口XXXListener;
- 事件源实例化以后,必须进行授权,注册该类事件的监听器,使用addXXXListener(XXXListener ) 方法来注册监听器。
例如:按钮单击改变页面背景颜色的界面
package 实验九;import java.awt.*;
import java.awt.event.*;
public class Test extends Frame implements ActionListener
{static Test frm=new Test(); static Button btn=new Button("Click Me");public static void main(String args[]){ btn.addActionListener(frm); // 把frm向btn注册frm.setLayout(new FlowLayout());frm.setTitle("Action Event");frm.setSize(200,150);frm.add(btn);frm.setVisible(true);}public void actionPerformed(ActionEvent e) // 事件发生的处理操作{ frm.setBackground(Color.red); }
}
运行结果:
事件类
与AWT有关的所有事件类都由java.awt.AWTEvent类派生,它也是EventObject类的子类。AWT事件共有10类。
低级事件
ComponentEvent
( 组件事件:组件尺寸的变化,移动)ContainerEvent
( 容器事件:组件增加,移动)WindowEvent
( 窗口事件:关闭窗口,窗口闭合)FocusEvent
( 焦点事件:焦点的获得和丢失)KeyEvent
( 键盘事件:键按下、释放)MouseEvent
( 鼠标事件:鼠标单击,移动)
高级事件(语义事件)ActionEvent
(动作事件:按钮按下,按Enter键)AdjustmentEvent
(调节事件:在滚动条上移动滑块)ItemEvent
(项目事件:选择项目,不选择"项目改变")TextEvent
(文本事件,文本对象改变)
事件监听器
每类时间都有相应的事件监听器,根据动作来定义相应的方法。
如与键盘事件KeyEvent相对应的接口是:
public interface KeyListener extends EventListener
{public void keyPressed(KeyEvent ev);//键盘刚按下public void keyReleased(KeyEvent ev);//键盘抬起来public void keyTyped(KeyEvent ev);//键盘敲击一次
}
常用的事件监听器:
AcionListener
Button,List,MenuItem,TextField接收Acion_Event事件。ItemLisener
Choice,ChectBox接收Acion_Event事件,接收所有的List_事件FocusListener
接收Got_focus和Lost_Focus事件KeyListener
接收所有的Key_事件MouseMotionLisener
接收Mouse_Drag和Mouse_Move事件AdjustmentLisener
接收所有的Scroll_事件
实现事件处理的方法:
- 实现事件监听器接口:需要实现接口中的所有方法。不需要进行处理的事件方法也要列出来,可以用一堆空的花括号
- 继承事件监听器类:只需要重写我们感兴趣的事件
例:创建一窗口,当鼠标在窗口中点击时,在窗口标题栏中显示点击位置坐标
package 实验九;import java.awt.event.*; //载入MouseListener类所在的包
import javax.swing.*; //载入JFrame所在的包
public class Test implements MouseListener
{JFrame f; public Test () {f=new JFrame(); //新建一窗口f.setSize(300,150);f.show();f.addMouseListener(this); //为窗口增加鼠标事件监听器f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }public void mousePressed(MouseEvent e){} public void mouseReleased(MouseEvent e){}public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){}public void mouseClicked(MouseEvent e){f.setTitle("点击坐标为 ("+e.getX()+", "+e.getY());}public static void main(String[] args){ new Test ();}
}
运行结果: