1.01k likes | 1.2k Views
第 9 章 创建用户界面. Java 程序设计 教程. 本章主要内容. 图形用户界面的特点 创建图形用户界面的应用程序或 Applet Swing 包中的 GUI 组件 事件处理的方法 布局管理器. 图形用户界面 的组成. GUI 图形用户界面. 由组件、布局管理和事件委托处理组成。 创建一个图形用户界面的方法 创建一个顶级的容器组件 按指定的布局管理器向容器添加组件 设计事件处理程序 显示图形用户界面. 窗口示例. GUI 图形用户界面. ex9.1.txt. 组件. 窗口. 建立了一个窗口,窗口中添加了一个文本框,一个按钮,
E N D
第9章 创建用户界面 Java程序设计教程
本章主要内容 • 图形用户界面的特点 • 创建图形用户界面的应用程序或Applet • Swing包中的GUI组件 • 事件处理的方法 • 布局管理器
图形用户界面的组成 GUI图形用户界面 • 由组件、布局管理和事件委托处理组成。 • 创建一个图形用户界面的方法 • 创建一个顶级的容器组件 • 按指定的布局管理器向容器添加组件 • 设计事件处理程序 • 显示图形用户界面
窗口示例 GUI图形用户界面 ex9.1.txt 组件 窗口 建立了一个窗口,窗口中添加了一个文本框,一个按钮, 并对按钮添加了事件监听,当单次点击按钮时,文本框 显示“aaaaa”字样,当双击按钮时,文本框显示“bbbbb”。 程序见ex9.1.txt
事件处理模型 事 件 处 理 事件的发生是由于用户对程序(组件)的操作(如 鼠标点击按钮、由键盘输入数据到文本框等),而 这些事件会被Java的运行环境所监控并分配给对应 的事件处理方法进行处理。
事件和事件源 事 件 处 理 • 事件(event):点击了某个按钮,或组件的状态发生了某种变化,或按下了某个键盘键等,被认为产生了某个事件 。 • 事件源:产生事件的组件称事件源。 • 例如,按钮是点击按钮事件的事件源。
事件注册、监听和处理 事 件 处 理 • Java处理事件: • 在源对象上的外部用户行为引发事件。一个关心事件的对象如果接收事件,则称该对象为监听器(listener)。一个对象要成为监听器,必须由源对象注册为监听器。 • 事件处理方法也称为处理器(handler)。源对象和监听器对象可以是同一个对象。一个源对象可以有许多监听器,它拥有一个所有监听器构成的队列。对象要成为一个监听器,必须实现标准处理方法
例9.2 事件处理的简单例子 事 件 处 理 • 例中建立两个按钮和一个文本框,这两个按钮会产生动作,而加在这两个按钮的监听器接口会监听到所产生的动作,并交于事件处理程序进行处理. • 源程序见 ex9.2.txt
事件处理 事 件 处 理 • 本节主要讲解如何编写和指定各组件的事件处理方法 • 定义接口法 • 适配器法 • 匿名类法
定义接口法 例9.3以发出声音来响应按钮点击事件 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Beep implements ActionListener //实现动作事件监听接口 { public Beep( ) { JFrame f=new JFrame("voice"); Container c= f.getContentPane( ); c.setLayout(new GridLayout(2,1)); c.setFont(new Font("宋体",Font.PLAIN,16)); JPanel p1=new JPanel( ); //创建面板p1 c.add("Center",p1);
JButton btn=new JButton("按钮"); p1.add(btn); btn.addActionListener(this); //注册事件源的动作监听者 JPanel p2=new JPanel( ); //创建面板p2 c.add(p2); p2.setBackground(Color. yellow); p2.add(new JLabel("按一下按钮可听到响声!",JLabel.CENTER)); f.setSize(200,100); f.show( ); }
public void actionPerformed(ActionEvent e) { //动作事件发生时要作出的反应 Toolkit.getDefaultToolkit( ).beep( ); } public static void main(String args[]) { new Beep(); } }
采用定义接口法的步骤 • 引入系统事件类包,如import java.awt.event.*; • 在定义类的同时声明实现动作事件监听器接口,如implements ActionListener。 • 在方法中调用事件源对象的addActionListener,注册事件源对象的事件监听者,如btn.addActionListener(this)。 • 实现actionPerformed方法,这个方法是接口中的方法,应该实现这个方法,加入代码以响应事件的发生。如单击按钮时,系统将产生ActionEvent事件,动作事件监听者就调用actionPerformed方法处理这个事件。
定义接口法 例9.4 在窗口中用鼠标拖动画线 本例实现了多个事件接口。功能是按住 鼠标左键画线。
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class DrawLine extends JApplet implements MouseListener,MouseMotionListener { int x1,y1,x2,y2; public void init() { addMouseListener(this);//注意参数为this addMouseMotionListener(this); } public void paint(Graphics g) { g.drawLine(x1,y1,x2,y2); }
public void mousePressed(MouseEvent e) { x1=e.getX(); //获得鼠标按下时的横坐标 y1=e.getY(); //获得鼠标按下时的纵坐标 } public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} public void mouseReleased(MouseEvent e){} public void mouseDragged(MouseEvent e) { x2=e.getX();//获得放开鼠标时,鼠标此时的横坐标 y2=e.getY(); //获得放开鼠标时,鼠标此时的纵坐标 repaint(); } public void mouseMoved(MouseEvent e){} }
总结: 例9.4这个程序中使用了两个接口,并实现了这两个接口中的所有方法,不管是否用得到它们。程序中是将这些用不到的方法以空方法的形式给出的,即只给出方法的声明,方法体为空。
适配器法 • 定义接口法处理事件是在定义事件处理方法接口时必须实现所有的事件处理方法列出来,用不到的方法以空方法的形式给出。 • 适配器法:通过继承Java所提供的各事件处理方法接口对应的Adapter类来解决定义接口法这种缺点的好方法 。 • Adapter类的目的就是在使用这些具有很多方法的的监听器接口,集合成为一个抽象类。可以不需要在程序中将每个方法都写出来 。
例9.5 在窗口中用鼠标拖动画线 适配器法 import javax.swing.*; import java.awt.*; import java.awt.event.*; public class DrawLine1 extends JApplet { int x1,y1,x2,y2; public void init() { addMouseListener(new M1());//参数定义为M1的对象 addMouseMotionListener(new M2());//参数定义为M2类的对象 } public void paint(Graphics g) { g.drawLine(x1,y1,x2,y2); }
public void paint(Graphics g) { g.drawLine(x1,y1,x2,y2); } class M1 extends MouseAdapter //创建MouseAdapter的子类M1 { public void mousePressed(MouseEvent e) { x1=e.getX(); y1=e.getY(); } }
class M2 extends MouseMotionAdapter //创建MouseMotionAdapter的子类M2 { public void mouseDragged(MouseEvent e) { x2=e.getX(); y2=e.getY(); repaint(); } } } 注意:本例的init方法中注册监听器的参数与定义接口法不同,是适配器的子类。接下来介绍的匿名类中,仍要注意这个位置的参数。
匿名类法 • 匿名类法是指声明一个类时不给它命名。 • 匿名类法可说是类继承法的扩展,其主要目的是解决某些“变量存取”的问题,基本上说匿名类法非常好用,也不复杂
匿名类法 import javax.swing.*; import java.awt.*; import java.awt.event.*; public class DrawLine2 extends Japplet { int x1,y1,x2,y2; public void init() { addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { x1=e.getX(); y1=e.getY(); } }); //括号内是参数,参数为对象
addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent e) { x2=e.getX(); y2=e.getY(); repaint(); } }); //括号内是参数,参数为对象 } public void paint(Graphics g) { g.drawLine(x1,y1,x2,y2); } } 通过例子可以发现括号内实现了子类的继承和实例化。这与适配器法不同,三种方法比较而言,匿名类这种处理方 式最简单。
大多数事件处理接口中若有两个以上的处理方法的接口才可能拥有适配器,即Adapter类。大多数事件处理接口中若有两个以上的处理方法的接口才可能拥有适配器,即Adapter类。 表9-2 事件与Adapter类
组件 窗 口 与 组 件 • 组件(Component:是专门用建立图形用户界面的Java类,是构成GUI的基本要素 。 • 分类: • 控制组件:一般作为一个对象放置在容器(Container)内。 • 容器组件:就是能容纳和排列组件的对象,如JApplet、JPanel、JFrame等
窗口——JFrame类 窗 口 与 组 件 • JFrame是在Swing中经常使用到的组件, 是最底层的容器,可称之为“窗口”。 • JFrame窗口允许指定关闭窗口的默认模式 。 • JFrame对象的布局管理器默认为边界布局管理器。
窗口——JFrame类 窗 口 与 组 件
面板——JPanel类 窗 口 与 组 件 • 面板也是Java中常用到的容器之一 • 面板默认使用流式布局管理器 。 • JPanel除了可以让组件加入外,还可以将JPanel作为组件加入到JFrame中去
标签——JLabel类 窗 口 与 组 件 • 标签(JLabel)类是专门用于显示输出,它的功能为显示一串“只读文字”。 • 常用于在屏幕上显示一些提示性,说明性的文字。 • 标签不会产生事件
JLabel的对齐方式有三种: 分别用Label类的三个变量JLabel.LEFT,JLabel.CENTER和JLabel.RIGHT来 表示左对齐、居中对齐和右对齐
按钮——JButton类 窗 口 与 组 件 • 主要功能是用来获得用户的输入 。 • JButton类可产生ActionEvent事件。 • 在某些情况下也可以当做输出组件,这是因为按钮组件包含了一个“标签” 。
构造方法 JButton() 创建一个没有标题的按钮 JButton(String label) 创建一个有显示标题的按钮 JButton(Icon image) 创建指定显示于按钮上的图标的按钮 JButton(String label, Icon image) 创建有标题、有图标的按钮 类方法 String getLabel() 返回按钮的显示标题 void setLabel(String label) 设置按钮上的显示标题 表9-6 JButton类的构造方法及类方法
文本框—JTextField类与JPasswordField类 窗 口 与 组 件 • 单行文本框JTextField用来接收用户从键盘上的输入,也可用来显示输出单行文本信息。 • JPasswordField类是继承JTextField类而来,是一个专门用来输入“密码”的单行文本框。即对用户输入的字符采用密文的形式进行显示,如“****”。 • JTextField类与JPasswordField类均可产生ActionEvent事件。
构造方法 JTextField() 创建一个默认长度的文本框 JTextField(int columns) 创建一个指定长度的文本框 JTextField(String text) 创建一个带有初始文本内容的文本框 JTextField(String text,int columns) 创建一个带有初始文本内容并具有指定长度的文本框 类方法 int getColumns() 获得文本框的可见部分宽度 void setColumns(int columns) 设置文本框的可见部分宽度 void setText(String str) 设置文本框中的文本内容 void setFont(Font f) 设置文本框所使用的字体 表9-7 JTextField的构造方法及类方法
构造方法 JPasswordField(String str,int columns) 创建密码文本框组件 类方法 void copy() 将被选取的文字复制到剪贴板中 void cut() 将被选取的文字移动到剪贴板中 boolean echoCharIsSet() 测试是否已经设置响应字符 char getEchoChar() 获得响应字符 void setEchoChar(char c) 设置响应字符 表9-8 JPasswordField构造方法及类方法
文本区——JTextArea类 窗 口 与 组 件 • 文本区(JTextArea)允许用户编辑具有多行的文本,可以用于输出信息,也可以用于接收信息。 • 文本区不会产生ActionEvent事件,通常用一个外部事件(即事件由另外的GUI组件触发)来处理中JTextArea的文本。 • 当JTextArea的内容装满时不会产生滚动条,而是自动加大文本区的大小。
例9.7 综合例子 • 用以上介绍的六个GUI组件,创建一个窗口,实现当在文本框中输入内容完毕后,点击回车键或点击“OK”按钮,使得文本框内的字符串添加到文本区中。
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class example extends JFrame implements ActionListener { JLabel lb=new JLabel("组件和事件处理:"); JButton bt=new JButton("OK"); JTextField tf= new JTextField(20); JTextArea ta=new JTextArea(10,20); public example() { super("综合例子1"); Container c=getContentPane(); c.setLayout(new FlowLayout()); //指定布局方式为顺序布局
c.add(lb); //将组件添加到容器中 c.add(ta); c.add(bt); c.add(tf); bt.addActionListener(this); tf.addActionListener(this); setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE); setSize(200,100); setVisible(true); } public void actionPerformed(ActionEvent e) { if(e.getSource()==bt) ta.append("现在按下按钮引发的事件"+"\n"); else { ta.append(tf.getText()+"\n"); ta.append("现在因在文本框里回车而引发的事件"+"\n"); } }
public static void main(String args[]) { new example(); } } 使用了以JFrame建立窗口,采用顺序布局方式,将JLabel、JButton、JTextField和JTextArea组件顺序添加到窗口中,并对JButton、JTextField引发的ActionEvent事件进行了处理。
列表组件—JComboBox类和JList类 窗 口 与 组 件 • JComboBox组件具有一个下拉式列表,可用来存放多个文字选项,在显示方式上,使用“弹出式菜单”动态地显示选项,并且只会将被选择的选项显示出来 。 • JList类的作用是将所有选项都显示出来 ,列表组件没有滚动条 。 • JComboBox组件可引发ActionEvent事件与ItemEvent事件。 • JList组件可引发ListSeclectionEvent事件。
例9.8 使用JList和JComboBox组件 • 本例创建了下拉列表框JComboBox组件及列表框JList组件,并对列表框list进行了ListSelectionEvent事件的处理。
import java.awt.*; import javax.swing.*; import java.awt.event.*; import javax.swing.event.*;//ListSelectionListener属于这个包 public class ChoiceDemo extends JFrame implements ListSelectionListener { String str[]={"Java 语言","C语言","PowerBuilder", "SQl Sever","JBuilder"}; JComboBox cb=new JComboBox(str); JList list=new JList(str); JPanel jp1=new JPanel(); JPanel jp2=new JPanel(); JLabel lb=new JLabel();
public ChoiceDemo() { super("这是关于列表框的例子"); Container c=getContentPane(); cb.insertItemAt("选项"+cb.getItemCount()+"个",0); cb.setEditable(true); jp1.add(cb); c.add(jp1,BorderLayout.CENTER); list.setBackground(Color.yellow); list.setSelectionBackground(Color.red);//设置选项的背景色 list.setSelectionForeground(Color.white); list.setSelectionMode(1); //设置列表可以按住shift键后多选 list.addListSelectionListener(this); jp2.add(lb); jp2.add(list); c.add(jp2,BorderLayout.SOUTH); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300,200); setVisible(true); }
public void valueChanged(ListSelectionEvent e) { int[] index=list.getSelectedIndices(); for(int i=0;i<index.length;i++) { lb.setText("你选择学习的语言是:"+str[index[i]]+" "); } } public static void main(String args[]) { new ChoiceDemo(); } } 当选中列表框中的某一选项时,标签会显示出“你选择学习的 语言是:“*****”(“***”即你选择的那一选项)。 另外,list.setSelectionMode(1)语句可使列表框list中的选项可 多选。