Java GUI编程中AWT、Swing和SWT的区别:
AWT:
AWT(Abstarct Window Toolkit)抽象窗口工具包。是SUN专门针对Java GUI编程提供的最早的开发工具包。用来建立和设置Java图形用户界面,这个工具包提供了一套与本地图形界面交互的接口。AWT 中的图形函数与操作系统所提供的图形函数之间有着一一对应的关系(peers)。也就是说,当我们利用 AWT 来构件图形用户界面的时候,实际上是在利用操作系统所提供的图形库。不过由于不同操作系统的图形库所提供的功能是不完全一样,所以在一个平台上存在的功能在另外一个平台上则可能不存在。这就导致一些应用程序在测试时界面非常美观,而一旦移植到其他的操作系统平台上后就可能变得“惨不忍睹”。为了实现Java语言”一次编译,到处运行”,AWT 不得不通过牺牲功能来实现其平台无关性,其所提供的图形功能被定格为各种通用型操作系统所提供的图形功能的交集。由于AWT 是依靠本地方法来实现其功能的,所以通常把AWT组件称为重量级组件。
AWT的优势:
虽然AWT是Sun不推荐使用的工具集,但是它在许多非桌面坏境中有着自己的优势:
- 更少的内存:对运行在有限环境中的GUI程序的开发,是合适的。
- 更少的启动事件:由于AWT组件是本地由操作系统实现的。绝大多数的二进制代码已经在如系统启动的时候被预装载了,这降低了它的启动事件。
- 更好的响应:由于本地组件由操作系统渲染。
- 成熟稳定的:能够正常工作并很少使你的程序崩溃。
AWT的缺点:
- 更少组件类型:表和树这些重要的组件缺失了。它们是桌面应用程序中普遍使用的。
- 缺乏丰富的组件特征:按钮不支持图片。
- 无扩展性:AWT的组件是本地组件。JVM中的AWT类实例实际只是包含本地组件的引用。唯一的扩展点是AWT的Canvas组件,可以从零开始创建自定义组件。然而无法继承和重用一个已有的AWT组件
Swing:
Swing 是在AWT的基础上构建的一套新的图形界面系统,是JFC(Java Foundation Class)的一部分,是试图解决AWT缺点的一个尝试。它提供了AWT 所能够提供的所有功能,并且用纯粹的Java代码对AWT 的功能进行了大幅度的扩充。所有的swing组件实际上也是AWT的一部分。Swing 对基于对等体的组件使用的术语是重量级,对于模拟的组件使用的术语是轻量级。实际上,Swing 可以支持在一个 GUI 中混合使用重量级组件和轻量级组件,不过一般将其称之为轻量级组件。
Swing是三者中最强大的GUI工具集,同时它也是SUN推荐使用的GUI工具集
Swing的优点:
- 丰富的组件类型:Swing提供了非常广泛的标准组件。这些组件和SWT一样丰富。基于它良好的可扩展性,除了标准组件,Swing还提供了大量的第三方组件。许多商业或开源的Swing组件库在开发多年后都已经可以方便地获取了。
- 丰富的组件特性:Swing不仅包含了所有平台上的特性,它还支持根据程序所运行的平台来添加额外特性。Swing组件特性遵循特定原则,易于扩展,因此能够提供较SWT和AWT更多的功能。
- 好的组件API模型支持:Swing遵循MVC模式,这是一种非常成功的设计模式。它的API成熟并设计良好。经过多年的演化,Swing组件APIs变得越来越强大,灵活和可扩展。它的API设计被认为是最成功的GUI API之一。较之SWT和AWT更面向对象,也更灵活而可扩展。MVC结构:Model View Control ,模型+视图+控制。
- 标准的GUI库:Swing和AWT一样是JRE中的标准库。因此,你不用单独地将它们随你的应用程序一起分发。它们是平台无关的,不用担心平台兼容性。
- 成熟稳定:由于它是纯Java实现的,不会有SWT的兼容性问题。Swing在每个平台上都有相同的性能,不会有明显的性能差异。
- 可扩展和灵活性。Swing完全由Java代码实现。Swing基于MVC的结构使得它可以发挥Java作为一门面向对象语言的优势。它提供了许总体上良好的性能。
- 可编程的外观,呈现器与编辑器。
- 支持以任意顺序构建GUI。
- 可访问性和支持自动销毁。是标准Java的一部分。
Swing的缺点:
Swing比AWT和SWT更多的消耗内存。Swing自己实现了所有组件。因此,它在运行时装载了大量的类。而在运行时Java在堆上创建小的对象导致了额外的堆空间消耗。而许多小的对象难以有效地被垃圾回收机制回收。因此,Swing应用程序通常会因无法及时回收冗余的对象而导致性能下降。
SWT:
SWT是Standard WidgetToolkit的缩写。是由IBM构建的一个新的GUI库,其目的在于尝试彻底解决AWT和swing带来的诸多问题,提供比AWT更为丰富的组件集。SWT和swing一样通过Java代码模拟了一些平台缺失的组件,不过与 AWT 的概念相比,SWT 是一个低级的 GUI 工具包,在构建SWT的过程中,构建者从 AWT 和 Swing 实现中学习了很多经验,他们试图构建一个集二者优点于一体而没有二者的缺点的系统。因此SWT可以说是AWT与swing的融合体。
SWT的优点:
- 丰富的组件类型:SWT提供了种类繁多的组件,从基础组件如按钮和标签到高级的表格和树。
- 相对的丰富组件特性:尽管SWT也遵循最大公倍数原则,它采用模拟的方式重新设计了对更多组件特性的支持。所以同AWT相比,它有着相对丰富的组件特性。
- 更快的响应时间:基于和AWT同样的原因,SWT组件包装了本地组件,由操作系统实现渲染。操作系统通常对渲染处理做了优化,保存GUI二进制代码为标准库,减少了内存的使用,提高了响应性能。
- 更少的内存消耗。
SWT的缺点:
- 不在JRE的标准库中。因此必须将它和程序捆绑在一起,并为所要支持的每个操作系统创建单独的安装程序。
- 不够成熟和稳定。SWT因其设计上的一些缺陷,如资源管理,Windows友好等,被认为是不稳定的。它可以在Windows上表现得很好,但在其他操作系统上,它经常是不稳定且容易崩溃的。这很大程度上是因为它把资源管理交给开发者来处理,而并不是所有的开发人员能够正确地处理这些。
- 在非Windows平台下的性能不高,无Look AndFeel 支持。和AWT同样的原因。
- 不可扩展。
- 不支持GUI的自动销毁。
- 仅支持自顶而下构建GUI。
- 对JAVA2D支持不够完善。
- 不属于标准Java的一部分。
三者在使用上的选择:
综上所述,在对GUI编程时的工具包选择得根据具体项目决定:若是需要用低内存来运行GUI程序,使用AWT会是一个不错的选择,而如果只考虑平台的移植性可优先考虑SWT/swing。
Swing是最灵活、最强的工具包,在界面开发中,首选Swing,它可以胜任绝大多数开发工作。是有一种场合不是用于Swing:在使用SWT开发的程序上继续编写界面,比如为Eclipse开发插件,因为Eclipse是基于SWT构建的。SWT与Swing不兼容,所以不能混合使用。
Swing基本组件:
Swing组件简介:
在Java语言提供的GUI构建工具中,可以分为“组件”(component)和“容器”(Container)两类。
在Java语言中,提供了以下组件:按钮、标签、复选框、单选按钮、选择框、列表框、文本框、滚动、条画布、菜单。
容器有:窗体(Form)、对话框(Dialog)。
Java语言是通过AWT(抽象窗口化工具包)和Java基础类(JFC或更常用的Swing)来提供这些GUI组件的。
其中Java.awt是最原始的GUI工具包,存放在java.awt包中。现在有许多功能被已被Swing取代并得到了很大的增加与提高,因此一般我们很少再使用Java.awt,但是AWT中还是包含了最核心的功能,通常,一个Java的GUI程序至少还要使用下面几个类:
- java.awt.Color:基本颜色定义
- java.awt.Font:基本字体定义
- java.awt.Cursor:光标操作定义
而Swing是JAVA提供的一组丰富的与平台无关的方式来创建图形用户界面的库。
组件与容器:
Jcomponent
Swing的整个可是组件库的基础构造块是Jcomponent,它是所有组件的父类,所以不能直接创建Jcomponent对象。组件都是矩形形状,组件本身有一个默认的坐标系,组件左上角的坐标值是(0,0)。然后向右向下延伸。最大值由组件的宽和高决定。组件默认的边框是一个黑色的矩形。可以通过方法设置组件的参数:
//设置颜色
setBackground(Color c); //设置组件的背景色。
setForeground(Color c);//设置组件的前景色。
getBackground(Color c);//获取组件的背景色。
getForeground(Color c);//获取组件的前景色。
Color(int red,int green,ing blue);//创建一个颜色对象,其中red、green、blue的取值在0到255之间。
//---------------------------------------
//字体
setFont(Font f);//组件调用该方法设置组件上的字体。
getFont(Font f;//组件调用该方法获取组件上的字体。
public void setSize(int width,int height):设置组件的大小。
//------------------------------------------
setLocation(int x,int y);//设置组件在容器中的位置,组件距容器的左、上边界 x、y 个像素。
getSize(); //返回当前组件的宽度和高度。
getLocation(int x,int y);//返回组件的左上角在容器的坐标系中的x坐标和y坐标。
psetBounds(int x,int y,int width,int height)://设置组件在容器中的位置和组件的大小。
getBounds();//返回当前组件左上角在容器坐标系中的x坐标和y坐标,宽度和高度。
//----------------------------------------------
setEnabled(boolean b);//设置组件是否可被激活。
//当参数b取值true时,组件可以被激活。
//当参数b取值false 时,组件不可激活。
setVisible(boolean b);//设置组件在该容器中的可见性。
//-------------------------------------------------
add( );//将组件添加到该容器中。
removeAll() ;//移掉容器中的全部组件。
remove(Component c) ;//移掉容器中参数指定的组件。
validate();//每当容器添加新的组件或移掉组件时,调用该方法以保证容器中的组件能正确显示出来。
JFrame(窗体):
JFrame类是一个顶层窗口,也是一个容器,允许将其他组件添加到它里面。
JFrame实际上不仅仅让您把组件放入其中并呈现给用户。比起它表面上的简单性,它实际上是 Swing 包中最复杂的组件。为了最大程度地简化组件,在独立于操作系统的Swing组件与实际运行这些组件的操作系统之间,JFrame起着桥梁的作用。JFrame在本机操作系统中是以窗口的形式注册的,这么做之后,就可以得到许多熟悉的操作系统窗口的特性:最小化/最大化、改变大小、移动。
JFrame常用构造方法:
JFrame();//可以创建一个无标题的窗口
JFrame(String title);//创建一个有标题的窗口
JFrame常用方法:
getTitle(); setTitle(); //获取/设置窗口标题
getState(); setState(); //获取和设置窗口的最小化、最大化等状态。
isVisible(); setVisible();//获取和设置窗口是否可见
getLocation(); setLoaction();//获取和设置窗口在屏幕上出现的位置
getSize(); setSize();//获取和设置窗口的大小
setBounds(); //获取和设置窗口出现在屏幕上时初始位置的大小
setResizable();//设置是否可调节大小
add();//添加组件到窗口中
setDefaultCloseOperation();//设置单击窗体右上角的关闭图标后,程序作出的处理。
JDialog(对话框):
对话框可分为无模式和有模式两种。
如果一个对话框是有模式的对话框,那么当这个对话框处于激活状态时,只让程序响应对话框内部的事件,程序不能再激活它所依赖的窗口或组件,而且它将堵塞当前线程的执行,直到该对话框消失不可见。
无模式对话框处于激活状态时,程序仍能激活它所依赖的窗口或组件,它也不堵塞线程的执行。
JMenu(菜单组件):
Swing菜单由菜单条(JMenuBar)、菜单(JMenu)和菜单项(JMenuItem)构成。菜单条是所有菜单和菜单项的根(容器)。
一、JMenuBar是Jcomponent类的子类,负责创建菜单条。
二、Jmenu是Jcomponent类的间接子类,负责创建菜单。
常用构造方法:
- pulbic JMenu():建立一个没有标题的菜单。
- pulbic JMenu(String title):建立一个指定标题菜单,标题由参数title确定
常用方法:
- add(MenuItem item):向菜单增加由参数item指定的菜单选项对象。
- add(String s):向菜单增加指定的选项。
- getItem(int n):得到指定索引处的菜单选项。
- getItemCount():得到菜单选项数目。
三、JMenultem是Jcomponent的间接子类,负责创建菜单项。
常用构造方法:
- public JMenuItem(String s):构造有标题的菜单项。
- public JMenuItem(String text, Icon icon):构造有标题和图标的菜单项。
创建图标对象 Icon icon=new ImageIcon(“图标文件名”);
常用方法:
- public void setEnabled(boolean b):设置当前菜单项是否可被选择。
- public String getLabel():得到菜单选项的名字。
- public void setAccelerator(KeyStroke keystroke):为菜单项设置快捷键。
- KeyStroke类静态方法:
keyCode一般取值范围:KeyEvent.VK_A~KeyEvent.VK_Z
modifiers一般取值:InputEvent.ALT_MASK,InputEvent.CTRL_MASK,InputEvent.SHIFT_MASK
中间容器:
用来添加组件的轻容器,称为中间容器。
JPanel(面板对象):
JPanel类用来创建一个面板对象,可以向这个面板添加组件(直接使用add方法)。
使用时需要把这个面板添加到底层容器或其他中间容器中。
JPanel面板的默认布局是FlowLayout布局。
JScrollPane(可滑动宽格):
滚动窗格,把一个组件放到一个滚动窗格中,然后通过滚动条来观察这个组件。
例如,JTextArea不自带滚动条,如果希望使用带滚动条的多行文本框,可把JTextArea放到一个滚动窗格中。
JSplitPane(拆分窗格):
拆分窗格,将容器拆分成两部分,拆分窗格有两种类型:
- 水平拆分:用一条拆分线把容器分成左右两部分,拆分线可以水平移动。
- 垂直拆分:用一条拆分线分成上下两部分,拆分线可以垂直移动。
JLayeredPane(分层窗格):
分层窗格,如果添加到容器中的组件经常需要处理重叠问题,就可以将组件添加到JLayeredPane容器中。
JLayeredPane将容器分成5个层,容器使用add(Jcomponent component, int layer)方法添加组件component,并指定component所在的层layer。
layer取值:
- DEFAULT_LAYER:最底层
- PALETTE_LAYER
- MODAL_LAYER
- POPUP_LAYER
- DRAG_LAYER:最上面的层
JTextFIeld(单行文本框):
单行文本框,用来建立文本框的组件,用户可以在文本框中输入单行的文本。
常用构造方法:
- JTextField(int x):创建文本框对象,可以在文本框中输入若干个字符,文本框的可见字符个数由参数x指定。
- JTextField(String s):创建文本框对象,则文本框的初始字符串为s,可以在文本框中输入若干个字符。
常用方法:
- public void setText(String text):设置文本框中的文本为参数text指定的文本。
- public String getText():获取文本框中的文本。
- public void setEditable(boolean b):指定文本框的可编辑性(默认为true-可编辑的)。
- public void setHorizontalAlignment(int alignment):设文本在文本框中的对齐方式,其中alignment的有效值确定对齐方式,如:LEFT、CENTER、RIGHT。
JPasswordField(密码框):
密码框,用于接收密码信息,输入的文本不会以明文形式显示出来。
常用方法:
- setEchoChar(char echoChar):设置回显字符(默认的回显字符是‘*’)。
- char[] getPassword():获取密码框中的密码。
JTextArea(多行文本框):
多行文本框,用户可以在文本区输入多行的文本。
常用构造方法:
- JTextArea(int rows, int columns):构造一个可见行和可见列分别是rows、columns的文本区。
常用方法:
- setLineWrap(boolean b):决定输入的文本能否在文本区的右边界自动换行。
- setWrapStyleWord(boolean b):决定是以单词为界(b取true时)或以字符为界(b取false时)进行换行。
- getText():获取文本区的文本。
- setText(String text):设置文本内容。
- append(String text):尾部加文本。
- insert(String text,int index):在文本区的指定位置处插入文本。
- public void copy():拷贝选定的区域。
- public void cut():剪切选定的区域。
- public void paste():在指定的区域粘贴。
JButton(按钮组件):
按钮组件,常用构造方法:
- public JButton(String text):创建名字是text的按钮。
- public JButton(Icon icon):创建带有图标icon的按钮。
- public JButton(String text, Icon icon):创建名字是text且带有图标icon的按钮。
常用方法:
- public String getText():获取当前按钮上的名字。
- public void setText(String text):重新设置当前按钮的名字,名字由参数text指定。
- public Icon getIcon():获取当前按钮上的图标。
- public void setIcon(Icon icon):重新设置当前按钮上的图标。
- public void setHorizontalTextPosition(int textPosition):设置按钮名字相对按钮上图标的水平位置。
textPosition取值:
SwingConstants.RIGHT
SwingConstants.LEFT
SwingConstants.CENTER
SwingConstants.LEADING
SwingConstants.TRAILING - public void setVerticalTextPosition(int textPosition):设置按钮上名字相对按钮上图标的垂直位置。
- public void addActionListener(ActionListener):按钮对象调用该方法可以向按钮增加动作监视器。
- public void removeActionListener(ActionListener):按钮对象调用该方法可以移去按钮上的动作监视器。
JLable(标签组件):
标签组件,一般用来显示信息,但没有编辑功能。
常用构造方法:
- public JLabel():创建空标签对象。
- public JLabel(String text):创建带文本的标签对象。
- public JLabel(String text, int aligment):创建带文本的标签对象,并设置文本对齐方式
常用方法:
- String getText():获取标签的名字。
- void setText(String s):设置标签的名字。
JCheckBox(复选框):
复选框,提供两种状态,一种是选中,另一种是未选中,用户通过单击该组件切换状态。如果不对复选框进行初始化设置,默认的初始化设置均为未选中。
常用构造方法:
- public JCheckBox():创建一个没有名字的复选框。
- public JCheckBox(String text):创建一个名字是text的复选框。
常用方法:
- public void setSelected(boolean b):设置按钮状态–是否选中
- public boolean isSelected():如果复选框处于选中状态该方法返回true,否则返回false。
JRadioButton(单选按钮):
单选按钮,一组单选按钮同一时刻只能有一个被选中。
当创建了若干个单选按钮后,应使用ButtonGroup再创建一个对象,然后利用这个对象把这若干个单选按钮归组。归到同一组的单选按钮每一时刻只能选一。
JTable(表格对象):
表格对象。
常用构造方法:
public JTable(Object[][] data , Object[] columnName)
- 表格的视图将以行和列的形式显示数组data每个单元中对象的字符串表示。
- 参数columnName用来指定表格的列名。
- 用户在表格单元中输入的数据都被认为是一个Object对象。
- 用户通过表格视图对表格单元中的数据进行编辑,以达到修改二维数组data中对应的数据。
JPopupMenu(弹出式菜单):
弹出式菜单,由JPopupMenu类负责创建,通常用于右键菜单。
常用构造方法:- public JPopupMenu():构造无标题弹出式菜单。- public JPopupMenu(String label):构造由参数label指定标题的弹出式菜单。
常用方法:
- public void show(Component invoker, int x, int y):设置弹出式菜单在组件invoker上的弹出的位置。
Swing布局管理器:
布局管理器:
用于指定各个视图组件在窗口中的分布位置,实现动态布局。有助于创建复合式的复杂界面,一个复合式的界面由一些简单的基本界面组成。
使用方法 setLayout(LayoutManager) 可以设置布局。
Absolute Layout(绝对布局):
1) 可以不借助布局管理器由用户直接精确定义组件的位置以及大小;
2) 直接使用Component的方法setSize、setLocation、setBounds即可;
3) 但是绝对布局不仅费神,需要提前精确计算,而其会丧失跨平台特性,在Java图形界面编程中绝对不推荐绝对定位的方式;
4) 如果一定要使用绝对布局,那么就先调用容器的setLayout,传递null参数,就表示启用绝对定位,然后就调用组件的set三方法定位后add进容器即可:c.setLayout(null);
BorderLayout(边界布局):
边界布局管理器,是Window型容器的默认布局,比如Jframe类,JDialog类。每个被BorderLayout管理的容器均被划分为五个区域:东(East)、南(South)、西(West)、北(North)、中(Center)。容器的每个区域,只能加入一个组件,如果加入多个组件,其中只有一个是可见的。
对于东南西北四个边界区域,如果其中的某个区域没有用,它的大小将边为0,中间区域将扩展并占用整个区域。
在BorderLayout布局管理器的管理下,组件必须通过add()方法加入到容器的去个命名区域之一,否则他们是不可见的。方法:add(组件,区域)。
FlowLayout(流式布局):
流式布局管理器,将组件按照加入的顺序逐个地放在容器中的一行上,一行放满后再另起一个新行。
每一行中的组件按布局指定的方式对齐方,默认情况下是居中对齐。
FlowLayout布局管理器不强行设定组件的大小,而是允许组件拥有自己希望的大小。
每个组件都有一个getPreferredSize()方法,容器布局管理器会调用此方法取得每个组件希望的大小。
FlowLayout布局管理器是JPanle容器的默认布局管理器。
GridLayout(网格式布局):
网格式的布局管理器,它将容器空间划分成若干行乘若干列的网格,每个格放一个组件。
各组件按照从上到下,从左至右的顺序排列。
使用GridLayout布局设计的一般步骤:
- 使用GridLayout的构造方法创建布局对象,指定划分网格的行数和列数。
- 使用GridLayout布局容器调用方发add将组件加入容器。
GridLayout布局中每个网格都是相同大小并且强制组件与网格相同大小。
BoxLayout(卡式布局):
卡式布局管理器,可以容纳多个组件,但是同一时刻容器只能从这些组件中选出一个来显示,被显示的组件占据容器的整个空间。
选项卡窗格(JTabbedPane)的默认布局是CardLayout。
BoxLayout(盒式布局):
盒式布局管理器。Box类创建的容器称作一个盒式容器,盒式容器的的默认布局是盒式布局,而且不允许更改盒式容器的布局。
行型盒式布局,特点:
- 容器中组件的上沿在同一水平线上。
- Box类的类方法createHorizontalBox()可以获得一个具有行型盒式布局的盒式容器。
- 行型盒式容器中组件间的间距:Box类调用静态方法createHorizontalStrut(int width)可以得到一个不可见的水平Struct类型对象,称做水平支撑。
列型盒式布局,特点:
- 容器中组件的左沿在同一垂直线上。
- Box类的类方法createVerticalBox()可以获得一个具有列型盒式布局的盒式容器。
- 列型盒式容器中组件间的间距:Box类调用静态方法createVertialStrut(int height)可以得到一个不可见的垂直Struct类型对象,称做垂直支撑。
GroupLayout(组布局):
分组布局管理器。它将组建按层次分组,以决定它们在 Container 中的位置。GroupLayout 主要供生成器使用(生成 并行组 和 串行组)。分组由GroupLayout.Group
类的实例来完成,每个组可以包含任意数量的元素(Group、Component 或 Gap)。
GroupLayout
支持两种组:
- 串行组 (sequential group):按顺序沿指定方向(水平/垂直)逐个放置元素。
- 并行组 (parallel group):沿指定方向(水平/垂直)并行排列元素,能够以四种不同方式对齐其子元素。
界面消息提示
JOptionPane.showConfirmDialog(确认提示框):
JPanel panel = new JPanel();
contentPane.add(panel, BorderLayout.CENTER);
JButton button = new JButton("确认提示框按钮");
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
//确认会话框,(父级容器,消息,标题,选择按钮的类型,提示消息的类型,图标);
//JOptionPane.showConfirmDialog(parentComponent, message, title, optionType, messageType, icon);
//确认框返回值类型为整型。
int value = JOptionPane.showConfirmDialog(NewFrame.this, "确认退出吗?", "请确认", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null);
//如果选择了确认,则系统退出,否则返回软件界面
if(value == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
});
JOptionPane.showMessageDialog(消息提示框):
JButton button_1 = new JButton("\u6D88\u606F\u63D0\u793A\u6846");
button_1.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
//消息提示框,可指定(父级容器,消息内容,标题,消息类型,图标)
JOptionPane.showMessageDialog(NewFrame.this, "警告!","提示框",JOptionPane.WARNING_MESSAGE,null);
}
});
JOptionPane.showInputDialog(输入框):
JButton button_2 = new JButton("\u8F93\u5165\u6846");
button_2.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
//输入框,可以指定(父级容器,提示消息,标题,消息类型,图标,数组,默认选项)
JOptionPane.showInputDialog(NewFrame.this, "请输入密码", "输入框", JOptionPane.INFORMATION_MESSAGE);
}
});
JOptionPane.showOptionDialog( 选择框):
JButton button_3 = new JButton("\u9009\u62E9\u6846");
button_3.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
//选择框,可以指定(父级容器,提示消息,标题,消息类型,图标,数组,默认选项)
String options[] = {"a","b","c","d"};
JOptionPane.showOptionDialog(NewFrame.this,"选择正确答案", "请选择",JOptionPane.OK_OPTION, JOptionPane.INFORMATION_MESSAGE, null,options, "a");
}
});
Java文件选择器
文件选择器:
JButton btnNewButton = new JButton("打开文件或文件夹");
btnNewButton.addMouseListener(new MouseAdapter() {
JFileChooser chooser = new JFileChooser();
public void mouseClicked(MouseEvent e) {
//设置文件选择模式,可选择,文件,文件夹,或文件和文件夹
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
//设置多选是否开启
chooser.setMultiSelectionEnabled(true);
//设置文件过滤器,指定可选择文件类型
FileNameExtensionFilter filter = new FileNameExtensionFilter("可选择文件类型", "txt","jar","js");
chooser.setFileFilter(filter);
//设置打开文件会话框
int value = chooser.showOpenDialog(OpenSaveFile.this);
//如果选择文件,则获取所有选择文件的路径
if (value == JFileChooser.APPROVE_OPTION) {
File file[] = chooser.getSelectedFiles();
/进行循环,把所有选择文档路径,输出到文本框
for(int i = 0; i < file.length; i++) { textArea.append("\n"+file[i].getAbsolutePath());
}
}
}
});
//文本显示框
textArea = new JTextArea(); textArea.setText("\u6587\u4EF6\u8DEF\u5F84\uFF1A");
保存文件:
button = new JButton("\u4FDD\u5B58\u6587\u4EF6");
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JFileChooser chooser1 = new JFileChooser();
int value = chooser1.showSaveDialog(OpenSaveFile.this);
if (value == JFileChooser.APPROVE_OPTION) {
File newFile = chooser1.getSelectedFile();
if (newFile.exists() == false) {
try {
newFile.createNewFile();
textArea.setText("文件已经保存,文件路径:"+newFile.getAbsolutePath());
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
});
Java 事件处理机制
Java事件驱动模型:
驱动模型的三大要素:
- 事件源:能够接收外部事件的源体。
- 监听器:能够接收事件源通知的对象。
- 事件处理程序:用于处理事件的对象。
窗口事件:
WindowListener接口
JFrame类是Window类的子类,Window型对象都能触发WindowEvent事件。当一个JFrame窗口被激活、撤消激活、打开、关闭、图标化或撤消图标化时,就引发了窗口事件。通过调用 addWindowlistener()来注册监听器。
WindowListener接口中有7个不同的方法,分别是:
- public void windowActivated(WindowEvent e):当窗口从非激活状态到激活时,窗口的监视器调用该方法。
- public void windowDeactivated(WindowEvent e):当窗口激活状态到非激活状态时调用该方法。
- public void windowClosing(WindowEvent e):当窗口正在被关闭时调用该方法。
- public void windowClosed(WindowEvent e):当窗口关闭时调用该方法。
- public void windowIconified(WindowEvent e):当窗口图标化时调用该方法。
- public void windowDeiconified(WindowEvent e):当窗口撤消图标化时调用该方法。
- public void windowOpened(WindowEvent e):当窗口打开时调用该方法。
鼠标事件:
鼠标事件是鼠标的移动、点击、拖放等行为。鼠标在组件上的操作(如点击按钮、菜单),不需要处理为鼠标事件,该组件会进行相应的处理。
用户的下列7种操作都可以使得组件触发鼠标事件:
- 鼠标指针从组件之外进入
- 鼠标指针从组件内退出
- 鼠标指针停留在组件上时,按下鼠标
- 鼠标指针停留在组件上时,释放鼠标
- 鼠标指针停留在组件上时,单击鼠标
- 在组件上拖动鼠标指针
- 在组件上运动鼠标指针
MouseListener接口与MouseMotionListener接口:
MouseListener、MouseMotionListener都是处理MouseEvent的接口。
MouseListener处理对象对于鼠标的进入、离开、下压、释放及敲击事件,使用addMouseMotionListener (MouseListener listener) 注册监听器。
MouseListener接口中的5个方法:
- mousePressed(MouseEvent):负责处理鼠标按下触发的鼠标事件。
- mouseReleased(MouseEvent e):负责处理鼠标释放触发的鼠标事件。
- mouseEntered(MouseEvent e):负责处理鼠标进入组件触发的鼠标事件。
- mouseExited(MouseEvent e):负责处理鼠标退出组件触发的鼠标事件。
- mouseClicked(MouseEvent e):负责处理鼠标单击或连击触发的鼠标事件。
MouseMotionListener用于处理鼠标的移动及拖曳,使用addMouseMotionListener(MouseListener listener)方法注册监听器
MouseMotionListener接口中的两个方法:
- mouseDragged(MouseEvent e):负责处理鼠标拖动事件
- mouseMoved(MouseEvent e):负责处理鼠标移动事件
MouseEvent类:
MouseEvent类的重要方法:
- getX():返回触发当前鼠标事件时,鼠标指针在事件源坐标系中的x-坐标。
- getY():返回触发当前鼠标事件时,鼠标指针在事件源坐标系中的y-坐标。
- getClickCount():返回鼠标被连续单击的次数。
- getModifiers():返回一个整数值。左键返回的值是常量BUTTON1_MASK,右键返回的值是常量BUTTON3_MASK。
- getSource():返回触发当前鼠标事件的事件源。
鼠标位置的坐标变换:
程序可能需要知道鼠标指针在容器坐标系中的坐标,这就需要进行坐标变换。
- public static Point convertPoint(Component source, int x, int y,Component destination):该方法返回一个Point对象。
根据鼠标指针在当前事件源source坐标系中的坐标(x,y),得到鼠标在容器 destination坐标系中的坐标。该对象再调用getX()和getY()方法就可以获取鼠标在容器destination坐标系中的坐标。
鼠标事件的转移:
假如正监视一个容器上的鼠标事件,而容器中添加了一些组件,则当在组件上鼠标操作时,容器将不知道这些操作的发生。
- MouseEvent convertMouseEvent(Component source, MouseEvent sourceEvent, Component destination):使鼠标事件从一个事件源转移到另一个事件源上。该方法是javax.swing包中的SwingUtilities类的静态方法。
获取鼠标在系统桌面上的坐标:
PointerInfo类
是JDK1.5在java.awt包中新增的一个类,可以帮助程序获取鼠标指针在系统图形设备中的位置坐标。使用MouseInfo的方法:getPointerInfo(),可以实例化一个PointerInfo对象。
方法:
- GraphicsDevice getDevice():返回在创建此 PointerInfo 时鼠标指针所在的 GraphicsDevice。
- Point getLocation():返回在屏幕上表示指针坐标的 Point。
键盘事件:
在具有键盘焦点的组件中按下或者释放按键时,将会激发键盘事件。键盘事件由接口KeyListener的方法来处理,组件使用addKeyListener()注册监听器。
接口KeyListener中有3个方法:
- public void keyPressed(KeyEvent e):按下键盘上某个键时,方法keyPressed方法会自动执行。
- public void keyTyped(KeyEvent e):当键被按下又释放时,keyTyped方法被调用
- public void KeyReleased(KeyEvent e):当键被释放时,KeyReleased方法被调用。
KeyEvent的重要方法:
- public int getKeyCode():返回一个整形值,常用于在keyPressed方法中获取用户敲击的键的虚拟键代码。
- public char getKeyChar():返回与此事件中的键关联的字符。
- public int getModifiers():返回此事件的修饰符掩码。以指出所按住的修改键(例如 shift、ctrl、alt、meta),该动作被定义为 InputEvent 的一部分。
java对字符和虚拟键代码进行了明确区分,虚拟键代码和键盘的扫描码类似,没有单独的小写虚拟键代码。虚拟键代码以VK_开头,是定义在KeyEvent类中的int型类变量,比如:VK_0, VK_A, VK_SHIFT, VK_RIGHT。在使用keyPressed()和keyReleased()方法时,需要进行虚拟键代码的检查,在使用keyTyped()方法时需要进行字符进行检查
Swing界面响应与线程安全
Swing界面响应与线程安全:
Java程序的主线程:
当Java程序启动时,一个线程立刻运行,该线程通常叫做程序的主线程(main thread),因为它是程序开始时就执行的。一般来说,某个类中会有一个main函数,当程序启动时,该函数就会有第一个自动得到执行,并成为程序的主线程。主线程的特征如下:
- 它是产生其他子线程的线程。
- 主线程中执行程序的控制。
- 通常它必须最后完成执行,因为他执行各种关闭动作。
Swing的UI线程:
Swing API的设计目标是强大、灵活和易用。但是Swing组件不支持多线程访问,程序要操作或改变界面内容,必须向单一线程执行请求,我们把这个单一个线程称为事件的派发线程。(可简称为UI线程)。这也意味着Swing是线程不安全的,所有对于UI元素的修改必须都提交给UI线程执行,不能再主线程或其他任何线程中直接操作UI的内容。
如果需要从UI线程或绘制代码以外的地方访问UI,那么需要使用SwingUtilities类的invokeLater()或invokerAndWait()方法、
如果需要处理一些耗费大量计算能力或受I/O能力限制的工作,可以使用一个线程工具类,如SwingWorker或Timer。