9.1 Java Swing概述
javax.Swing包(Java Swing框架)
1.通过图形用户界面(Graphics User Interface,GUI),用户和程序之间方便地进行交互
2.容器类(Container)和组件类(Component),学习GUI编程主要是学习掌握使用Component类的一些重要的子类
3.JFrame(窗口)和JDialog(对话框)是底层容器
javax.Swing包中JComponent类是javax.awt包中Container类的一个直接子类、是java.awt包中Component类的一个间接子类
GUI编程经常提到的基本知识点:
1.Java把Component类的子类或间接子类创建的对象称为一个组件
2.Java把Container的子类或间接子类创建的对象称为一个容器
3.可以向容器添加组件,Container类提供了一个public方法:add(),一个容器可以调用这个方法将组件添加到该容器中
4.容器调用removeAll()方法可以移掉容器中的全部组件;调用remove(Component c)方法可以移掉容器中参数c指定的组件
5.注意到容器本身也是一个组件,因此可以把一个容器添加到另一个容器中实现容器的嵌套
6.每当容器添加新的组件或移掉组件时,应当让容器调用validate()方法,以保证容器中的组件能正确显示出来如:下图所示
9.2 窗口
Java提供的JFrame类的实例是一个底层容器,即通常所称的窗口,其他组件必须添加到底层容器中,以便借助这个底层容器和操作系统进行信息交互
JFrame类是Container类的间接子类,当需要一个窗口时,可使用JFrame或其子类创建一个对象
窗口也是一容器,可以向窗口添加组件,需要注意的是窗口默认地被系统添加到显示器屏幕上,隐藏不允许将一个窗口添加到另一个容器中
JFrame构造方法:
——JFrame() 创建一个无标题的窗口
——JFrame(String s)创建标题为s的窗口
常用方法:
1.public void setBounds(int a,int b,int width,int height)设置窗口的初始位置是(a,b),即距屏幕左面a个像素、即距屏幕上方b个像素;窗口的宽width,高是height
2.Public void setSize(int width,int height) 设置窗口大小
3.Public void setLocation(int x,int y)
设置窗口位置,默认位置是(0,0)
4.public void setVisible(boolean b)设置窗口是否可见,窗口默认不可见
5.Public void setResizable(boolean b)设置窗口是否可调整大小,默认可调整大小
6.Public void dispose()撤销当前窗口,并释放当前窗口所使用的资源
7.Public void setExtendedState(int state)设置窗口的扩展状态
8.Public void setDefaultCloseOperation(int operation)该方法用来设置单击窗口右上角的关闭图标后,程序会做出怎样的处理,如:EXIT_ON_CLOSE
9.Public void setLayout(LayoutManager mgr)设置此容器的布局管理器
10.public Component add(Component comp)将指定组件追加到此容器的尾部
11.Public void setMenuBar(MenuBar mb)将此frame的菜单栏设置为指定的菜单栏
12.Public void validate()使用validate方法会使容器再次布置其子组件,在修改此容器的子组件的时候(在容器中添加或移除组件,或者更改与布局相关的信息),应该调用上述方法
菜单条、菜单、菜单项(如下图所示)
9.3常用组件与布局
1.常用组件(JComponent的子类)
(1)文本框JTextField
——构造函数:JTextField();JTextField(int columns);
——常用方法 public String getText();
Public void setText(String t);
(2)文本区JTextArea
——构造函数:JTextArea();JTextArea(int rows,int columns)
——常用方法:public String getText();
Public void setText(String t);
(3)按钮JButton
——构造函数:JButton();JButton(String text);
——常用方法:public void addActionListener(ActionListener l);
(4)标签JLabel
——构造函数:JLabel();JLabel(String text);JLabel(Icon image);
——常用方法:public String getText();
Public void setText(String t);
(5)选择框JCheckBox
——构造函数:JCheckBox();JCheckBox(String text);
——常用方法:public void addItemListener(ItemListener l);
Public void addActionListener(ActionListener l);
(6)单选按钮JRadioButton
——构造函数:JRadioButton();JRadioButton(String text);
——常用方法:public void addItemListener(ItemListener l);
(7)下拉列表JComboBOx
——构造函数:JComboBOx();JComboBOx(Object [ ] items);
——常用方法:public void addItemListener(ItemListener l);
Public Object getSelectedItem();
Public int getSelectedIndex();
(8)密码框JPasswordField
——构造函数:JPasswordField();JPasswordField(int columns);
——常用方法:public String getText();
Public void setText(String t);
——public void setEchoChar(char c)使用该方法重新设置回显字符
——public char [ ] getPassword()方法可以返回实际的密码
2.常用容器
(1)JPanel面板
——构造方法:JPanel();
——常用方法:public void add();
(2)JTabbedPane选项卡窗格:可以使用JTabbedPane容器作为中间容器,当用户向JTabbedPane容器添加一个 中间时,JTabbedPane容器就会自动指定给该组件一个选项卡,各个选项卡对应的组件层叠式放入JTabbedPane容器,当用户单击选项卡时,JTabbedPane容器显示该选项卡对应的组件,选项卡默认地在JTabbedPane容器的顶部,从左向右依次排列; JTabbedPane容器可以使用add(String text,Component c);方法将组件c添加到JTabbedPane容器中,并指定和组件c对应的选项卡的文本提示是text
(3)滚动窗格JScrollPane
(4)拆分窗格JSplitPane
(5)JLayeredPane分层窗格
3.常用布局
(1)FlowLayout布局
(2)BorderLayout布局
(3)CardLayout布局
(4)GridLayout布局
(5)null布局
(6)BoxLayout布局
具体内容如图所示:
9.4 处理事件
1.事件处理模式
(1)事件源:能触发事件的对象
(2)监视器:负责监视事件源对象
事件源.add???ActionEvent(监视器);
(3)处理事件的接口:监视器必须实现相应的接口
处理事件示意图如下
代码示例如图所示
2.ActionEvent事件:在文本框里输入文本回车,程序输出文本框中文本的长度(具体内容如下图所示)
3.ItemEvent事件
(1)ItemEvent事件源:选择框、下拉列
(2)注册监视器:addItemListener(ItemListener listen)
代码如下:
AA a = new AA( );
box.addItemListener(a);
Class AA implements ItemListener {
public void itemStateChanged(ItemEvent e) {
}
}
(3)ItemListener接口:接口只有一个方法public void itemStateChanged(ItemEvent e)
(4)ItemEvent类中的方法:
——getSource()方法返回发生ItemEvent事件的事件源外
——getItemSelectable()方法返回发生Itemevent事件的事件源
4.DocumentEvent事件
(1)DocumentEvent事件源
(2)注册监听器:addDucumentListener(DocumentListener listen);
Ducument doc = text。getDucument();
Doc.addDucumentListener(new A ( ));
Class A implements DocumentListener{
}
(3)DocumentListener接口:该接口有三个方法
——public void changedUpdate(DocumentEvent e)
——public void removeUpdate(DocumentEvent e)
——public void insertUpdate(DocumentEvent e)
5.MouseEvent事件
(1)事件源:任何组件上都可以发生鼠标事件
——鼠标进入组件退出组件、在组件上方按下,松开,击鼠标
——拖动鼠标、运动鼠标等触发鼠标事件
(2)监听器
——addMouseListener(MouseListener listener)
——addMouseMotionListener(MouseMotionListener listener)
(3)处理事件接口:MouseListener接口有五个方法
——mousePressed(MouseEvent)负责处理在组件上按下鼠标键触发的鼠标事件
——mouseReleased(MouseEvent)负责处理在组件上释放鼠标键触发的鼠标事件
——mouseEntered(MouseEvent)负责处理鼠标进入组件触发的鼠标事件
——mouseExited(MouseEvent)负责处理鼠标离开组件触发的鼠标事件
——mouseClicked(MouseEvent)负责处理在组件上单击鼠标键触发的鼠标事件
MouseMotionListener接口有2个方法
——mouseDragged(MouseEvent)
——mouseMoved(MouseEvent)
MouseEvent中有下列几个重要的方法:
——getX()获取鼠标指针在事件源坐标系中的X坐标
——getY()获取鼠标指针在事件源坐标系中的Y坐标
——getModifiers()获取鼠标的左键或右键
——getClickCount()获取鼠标被单击的次数
——getSource()获取发生鼠标事件的事件源
6.焦点事件及键盘事件
(1)事件源:任何组件都可以发生焦点事件,当组件获得焦点监视器后,如果组件从无输入焦点变成有输入焦点或从有输入焦点变成无输入焦点都会触发FocusEvent事件
(2)监视器:addFocusListener(FocusListener listener)
(3)处理事件的接口FocusListener有2个方法
——public void focusGained(FocusEvent e)
——public void focusLost(FocusEvent e)
(4)组件也可调用:public boolean requestFocusInWindow()方法获得输入焦点
7.键盘事件
(1)事件源:当一个组件处于激活状态时,敲击键盘上一个键就导致这个组件触发键盘事件
(2)监视器:addKeyListener(KeyListener listener)
(3)处理事件接口KeyListener有3个方法
——public void keyPressed(KeyEvent e)
——public void keyTyped(KeyEvent e)
——public void KeyReleased(KeyEvent e)
KeyEvent类的public int getKeyCode()方法,可以判断哪个键被按下、敲击或释放,getKeyCode方法返回一个键码值,也可以用KeyEvent类的public char getKeyChar()判断哪个键被按下、敲击或释放,getKeyChar()方法返回键上的字符
8.窗口事件
JFrame及子类创建的窗口可以调用setDefaultCloseOperation(int operation)方法设置窗口的关闭方式
参数Operation取JFrame的static常量:
——DO_NOTHING_ON_CLOSE(什么也不做)
——HIDE_ON_CLOSE(隐藏当前窗口)
——DISPOSE_ON_CLOSE(隐藏当前窗口,并解释窗体占有的其他资源)
——EXIT_ON_CLOSE(结束窗口所在的应用程序)
窗口事件,通过处理事件来满足程序的要求,需要注意的是,如果准备处理窗口事件,必须事先保证窗口的默认关闭方式为DO_NOTHING_ON_CLOSE(什么也不做)
(1)事件源:JFrame是Window(java.awt)的子类,凡是Window子类创建的对象可以发生WindowEvent事件,即窗口事件
(2)监视器:addWindowlistener(WindowListener listener);
(3)处理事件的接口WindowListener(有7个方法)
——windowActivated(WindowEvent e)当窗口从非激活状态到激活时,窗口的监视器调用该方法
——windowDeactivate(WindowEvent e)当窗口激活状态到非激活状态时,窗口的监视器调用该方法
——windowClosing(WindowEvent e)当窗口正在被关闭时,窗口的监视器调用该方法
——windowClosed(WindowEvent e)当窗口关闭后,窗口的监视器调用该方法
——windowIconified(WindowEvent e)当窗口图标化时,窗口的监视器调用该方法
——windowDeiconified(WindowEvent e)当窗口撤销图标化时,窗口的监视器调用该方法
——windowOpened(WindowEvent e)当窗口打开时,窗口的监视器调用该方法
注 :当单击窗口右上角的关闭图标时,监视器首先调用windowClosing方法,如果在该方法中,使用System.exit(0);退出程序的运行,那么监视器就没有机会再调用windowClosed方法
WindowAdapter适配器(具体内容如下图所示)
9事件总结
1.授权模式:Java的事件处理是基于授权模式,即事件源调用方法将某个对象注册为自己的监视器
2.接口回调:addXXXListener(XXXListener listener)方法中的参数是一个接口,listener可以引用任何实现了该接口的类所创建的对象,当事件源发生事件时,接口listener立刻回调被类实现的接口中的某个方法
3.方法绑定:当事件源触发事件发生后,监视器准确知道去调用哪个方法
4.保持松耦合:当事件源触发事件发生后,系统知道某个方法会被执行,但无须关心到底是哪个对象去调用了这个方法,因为任何实现接口的类的实例(做为监视器)都可以调用这个方法来处理事件
9.5 使用MVC结构
模型—视图—控制器(Model-View-Controller),简称为MVC,它是一种通过三个不同部分构造一个软件或组件的理想办法:
——模型(model):用于存储数据对象
——视图(view):为模型提供数据显示的对象
——控制器(controller):处理用户的交互操作,对于用户的操作作出响应,让模型和视图进行必要的交互,即通过视图修改、获取模型中的数据;当模型中的数据变化时,让视图更新显示
在设计程序时:可以将某个对象看作“模型”,然后为“模型”提供恰当的显示组件,即“视图”
为了对用户的操作作出响应,可以选择某个组件做“控制器”,当触发事件时,通过“视图”修改或得到“模型”中维护着的数据,并让“视图”更新显示
9.6 对话框
对话框分为有模式和无模式
——有模式:如果有模式的对话框处于激活状态时,只让程序响应对话框内部的事件,而且将堵塞其他线程的执行,用户不能再激活对话框所在存储中的其他窗口,直到对话框消失不见
——无模式:无模式对话框处于激活状态时,能再激活其他窗口,也不堵塞其他线程的执行
主要内容:1.消息对话框(有模式对话框)
——用javax.swing包中的JOptionPane类的静态方法创建一个消息对话框
静态方法如图所示
2.输入对话框(有模式对话框)
静态方法如图所示
3.确认对话框(有模式对话框)
静态方法如图所示
4.颜色对话框(有模式对话框)
静态方法如图所示
5.自定义对话框
常用构造方法如图所示
9.7 树组件与表格组件
1.树组件
(1)DefaultMutableTreeNode节点
DefaultMutableTreeNode类的两个常用的构造方法是:
——DefaultMutableTreeNode(Object userObject)
——DefaultMutableTreeNode(Object userObject,boolean allowChildren)
(2)树上的TreeSelectionEvent事件使用addTreeSelectionListener(TreeSelectionListener listener)方法获得一个监视器
2.表格组件
表格组件以行和列的形式显示数据,允许对表格中的数据进行编辑
(1)JTable有7个构造方法,这里介绍常用的三个
——JTable()创建默认的表格模型
——JTable(int a,int b)创建a行,b列的默认模型表格
——JTable(Object data[ ][ ],Object columnName[ ])创建默认表格模型对象,并且显示由data指定的二维数组的值,其列名由数组columnName指定
通过对表格中的数据进行编辑,可以修改表格中二维数组data中对应的数据。在表格中输入或修改数据后,需按回车或用鼠标单击表格的单元格确定所输入或修改的结果。当表格需要刷新显示时,让表格调用repaint方法
9.8 按钮绑定到键盘
将按钮绑定到键盘某个键的具体步骤
(1)获取输入映射
按钮首先调用:public final InputMap getInputMap(int condition)返回一个InputMap对象。
——InputMap inputmap = button.getInputMap(JCompent.WHEN_IN_FOCUSED_WINDOW);
参数condition取值JCompent类的下列static常量
——WHEN_FOCUSED
——WHEN_IN_FOCUSED_WINDOW
——WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
(2)绑定按钮的键盘操作
输入映射首先调用方法指定按钮的键盘操作:public void put(KeyStroke keyStroke,Object actionMapKey);
inputmap.put(KeyStroke.getKeyStroke(“A”),“dog”);
(3)为按钮的键盘操作指定监视器
按钮调用方法:public final ActionMap getActionMap()返回一个ActionMap对象:ActionMap actionmap = button.getActionMap();然后,该对象actionmap调用方法:public void put(Object key,Action action)为按钮的键盘操作指定监视器(实现单击键盘上的键通知监视器的过程)
9.9 打印组件
应用程序可以使用PrintJob对象完成打印组件的工作
步骤如下:
(1)去ToolKit对象:组件调用getToolkit()方法返回系统提供的Toolkit对象的引用
(2)获得PrintJob对象:步骤1得到的Toolkit对象调用getPrintJob()方法返回一个PrintJob对象
(3)获取Graphics对象:PrintJob对象使用getGraphics()方法获得一个Graphics对象
(4)打印组件:步骤3获得的Graphics对象,——button.paintAll(g)将打印出该组件及子组件。
——pain(g)将打印出该组件本身,但不打印子组件,注意如果调用方法pain(g)将打印出该组件本身的形状,但不打组件上的其他信息,比如文字图形等
打印位置:打印机总是从打印页的左上角开始打印组件,如果程序中有如下两条语句:按钮_1.painAll(g);按钮_2.painAll(g); “按钮_2”就会被打印在“按钮_1”的上面,盖住按钮_1,为了避免这种情况的发生,Gaphics对象g可以使用Graphics类中的方法:
Translate(int x,int y)改变组件在打印页中打印的位置