第十一章 GUI 上
第11章 GUI程序设计
11.1 JFC简介
JFC(Java Foundation Class) 作为CUI(Graphic User Interface)设计的基础.JFC包含AWT(Abstract Window Toolkit),Swing和Java2D
Swing相对于AWT的优点:
1:Swing不在依赖于运行时的本地组件,它完全是用Java编写的,从而解决了AWT中存在的可移植的问题
2:Swing具有可拔插的外观风格,即通过在几种预先配置好的外观风格中进行选择,可以让GUI程序显示出不同的外观风格
3:Swing采用的是MVC模式.更灵活
11.2 Swing组件的结构
1:顶层容器:JApplet,JDialog,JFrame 和JWindow及其子类
2:MVC结构
11.3:顶层容器
11.3.1:JFrame
JFrame 是最常用的一种顶层容器,它的作用是创建一个顶层的Windows窗体.JFrame的外观就像平常的Windows系统下见到的窗体,有标题,边框,菜单.
public class JFrameDemo extends JFrame
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(300, 300);// 设置窗体大小
frame.setLocation(400, 400);// 设置窗体显示的位置
frame.setTitle("JFrameDemo");// 设置窗体的标题frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 设置关闭按键的默认操作
frame.setVisible(true);// 显示窗体
}}
11.3.2 JDialog,JWindow和JApplet
JDialog是创建对话框的顶层容器类,它与JFrame的不同之处在于对话框没有最大化和最小化按钮.JWindow 也可以创建一个窗体,没有标题栏,最大化和最小化,Applet是一种能够嵌入到网页执行的Java图形程序
11.4:布局管理
Swing采用了两种布局方式:无布局管理器布局和基于布局管理器的布局.后者是Swing为了实现跨平台的动态布局效果而提出的布局方式.在设置时,我们需要调用setLayout方法,布局管理器有:FlowLayout,BorderLayout,GridLayout等多种方式.
11.4.1:无布局管理器布局
Swing提供了setLocation(),setSize(),setBounds()等布局方法,但Swing的组件中存在一个默认的布局管理器,因此这些设置方法都会失效.如果需要设置组件大小或位置,则应取消该容器的布局管理器,方法为调用setLayout方法,并将布局管理器设置为null 举例代码如下:
public class AbsoluteLayout extends JFrame
{
public static void main(String[] args)
{
AbsoluteLayout aLayout = new AbsoluteLayout();
aLayout.setVisible(true);
}
private JButton button = new JButton("JButton");// 创建button
private JTextField textField = new JTextField("JTextField");// 创建输入字符段
public AbsoluteLayout()
{
setSize(300, 300);
setLocation(400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);// 设置布局管理null
this.button.setLocation(20, 20);
this.button.setSize(100, 20);
add(this.button);
this.textField.setBounds(20, 50, 200, 100);// 设置输入框的位置为(20,50),宽200高100
add(this.textField);
}}
11.4.2:FlowLayout 规律是从左到右,从上到下进行放置,变化规律是:组件的大小不变,但是其相对位置会发生改变
public class FlowLayoutDemo extends JFrame
{
public static void main(String[] args)
{
FlowLayoutDemo fLayoutDemo = new FlowLayoutDemo();
fLayoutDemo.setVisible(true);
}
private JButton button1 = new JButton("first button");
private JButton button2 = new JButton("second button");
private JButton button3 = new JButton("third button");
private JButton button4 = new JButton("fourth button");
public FlowLayoutDemo()
{
setSize(300, 300);
setLocation(400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
// 添加按键,注意设置布局方式后任何对组件进行设置的方法,都会失效
add(this.button1);
add(this.button2);
add(this.button3);
add(this.button4);
}}
11.4.3:BorderLayout 布局管理器把容器分成五个局域:North,South,East,West和Center每个局域只能放一个组件.变化规律是:组件的相对位置不变,大小发生改变.
11.4.4:GridLayout 布局管理器将整个容器划分为n行m列的网格,平均占据容器的空间,按照组件加入的顺序优先考虑按行布局,当一行布局满之后再布局下一行每行只能布局m个组件.只有昂行列不满足指定的数值时,才按行进行扩展, 举例如下
public class GirdLayoutDemo extends JFrame
{
public static void main(String[] args)
{
GirdLayoutDemo gLayoutDemo = new GirdLayoutDemo();
gLayoutDemo.setVisible(true);
}
private JButton button1 = new JButton("first button");
private JButton button2 = new JButton("second button");
private JButton button3 = new JButton("third button");
private JButton button4 = new JButton("fourth button");
public GirdLayoutDemo()
{
setSize(300, 300);
setLocation(400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置格式为两行两列
setLayout(new GridLayout(2, 2));
// 添加按键,注意设置布局方式后任何对组件进行设置的方法,都会失效
add(this.button1);
add(this.button2);
add(this.button3);
add(this.button4);
}}
11.4.5:复杂界面布局
为了实现该布局需要使用容器类,例如JPanel.JPanel是一种不可见的容器,其作用是对其他容器和组件进行组织.JPanel可以通过setLayout方法设置布局方式,也可以用add方法添加Swing组件或者其他容器.JPanel只有被布局在另外的容器上才可见.如果JPanel上没有任何Swing组件,则显示空白区域.除了JPanel,JScrollPane,和JTabbedPane也是Swing中常用的容器.JScrollPane是带有滚动条的容器,如果布局组件的大小超过了容器的大小,则可以显示水平和垂直方向的滚动条.JTabbedPane是用于产生选项卡界面的容器
public class ComplexLayout extends JFrame
{
public static void main(String[] args)
{
ComplexLayout complexLayout = new ComplexLayout();
complexLayout.setVisible(true);
}
private JPanel panel1 = new JPanel();
private JPanel panel2 = new JPanel();
private JPanel panel3 = new JPanel();
private JPanel panel4 = new JPanel();
// 构造方法
public ComplexLayout()
{
setSize(500, 500);
setLocation(400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 对panel1进行布局
layoutPanel1();
// 对panel2进行布局
layoutPanel2();
// 对panel3进行布局
layoutPanel3();
// 对panel4进行布局
layoutPanel4();
// 对顶层容器进行布局,采用的GridLayout,2行列
setLayout(new GridLayout(2, 2));
add(this.panel1);
add(this.panel2);
add(this.panel3);
add(this.panel4);
}
// Panel1布局 格式为BorderLayout
private void layoutPanel1()
{
JButton north = new JButton("north");
JButton south = new JButton("south");
JButton east = new JButton("East");
JButton west = new JButton("west");
JButton center = new JButton("Center");
this.panel1.setLayout(new BorderLayout());
this.panel1.add(north, BorderLayout.NORTH);
this.panel1.add(south, BorderLayout.SOUTH);
this.panel1.add(west, BorderLayout.WEST);
this.panel1.add(east, BorderLayout.EAST);
this.panel1.add(center, BorderLayout.CENTER);
}
// Panel2布局 格式为FlowLayout
private void layoutPanel2()
{
JButton button1 = new JButton("First button");
JButton button2 = new JButton("Second button");
JButton button3 = new JButton("Third button");
JButton button4 = new JButton("Fourth button");
this.panel2.setLayout(new FlowLayout());
this.panel2.add(button1);
this.panel2.add(button2);
this.panel2.add(button3);
this.panel2.add(button4);
}
// Panel3布局 格式为GridLayout 两行两列
private void layoutPanel3()
{
JButton button1 = new JButton("First button");
JButton button2 = new JButton("Second button");
JButton button3 = new JButton("Third button");
JButton button4 = new JButton("Fourth button");
this.panel3.setLayout(new GridLayout(2, 2));
this.panel3.add(button1);
this.panel3.add(button2);
this.panel3.add(button3);
this.panel3.add(button4);
}
private void layoutPanel4()
{
JButton button = new JButton("JButton");
JTextField textField = new JTextField("JTextField");
this.panel4.setLayout(null);
this.panel4.setLocation(20, 20);
button.setSize(100, 20);
textField.setBounds(20, 50, 200, 100);
this.panel4.add(button);
this.panel4.add(textField);
}}
11.5 事件处理
11.5.1事件处理模型
GUI程序都需要对环境中的发生的各种事件(鼠标的单击,值的改变,焦点的获取或丢失,键盘输入等)进行监控并根据事件的类型进行相应的处理.Swing采用了委托事件模型,也叫授权模型,该模型主要包含三个对象
1事件:发生在用户界面的用户交互行为所产生的一种效果
2 事件源:产生事件的对象
3 事件监听器:接受事件并对其进行处理的对象
组件作为事件源可以触发事件,一个事件源注册一个或者多个事件监听器.
委托事件模型的优点:
1:事件对象只传给注册的监听器,不会意外的被其他组件或上层容器捕获和处理
2:可以实现过滤器的功能,只监听和处理感兴趣的事件
3:实现了将事件源和事件监听器分开处理的功能
public class EventDemo extends JFrame
{
public static void main(String[] args)
{
EventDemo eventDemo = new EventDemo();
eventDemo.setVisible(true);
}
JButton button = new JButton("press me");
public EventDemo()
{
setSize(300, 300);
setLocation(400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置默认事件,使用了匿名类
this.button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
// 获取被单击的按钮
JButton clickButton = (JButton) e.getSource();
clickButton.setText("I have been pressed");
}
});
setLayout(new BorderLayout());
add(this.button, BorderLayout.NORTH);
}}
11.5.2:事件类
事件既是基础,又是联系各个部分的桥梁.首先,组件作为事件源产生事件,不同类型的组件会产生不同的类型的事件.事件发生后,事件被传递给对应的事件监听器实现的事件的处理方法.基类是java.util.EventObject,基类定义了getSource方法,该方法返回产生或触发事件的对象.AWTEvent定义方法getID,该方法的返回值用来区别用同一个事件类所代表的不同类型的事件.
11.5.3:事件监听器
接收事件并对事件作出相应反应的对象称为事件监听器.一个类可以实现监听器的一个或多个接口,这就需要把所实现的接口中的所定义的方法都得到实现,当对其中的方法不感兴趣时,也可以将方法体保持为空,而不给出具体的方法
事件类别/接口名字 接口中的方法 产生事件的用户操作
ComponentEvent事件 Component Listenter 接口 |
Moved |
移动组件时 |
Hidden |
隐藏事件时 |
|
Resized |
改变组建大小 |
|
Shown |
显示组件时 |
|
ContainerEvent 事件及接口 |
Added |
添加组件时 |
Removed |
移动组件时 |
|
WindowEvent 窗口事件及接口 |
Opened |
打开窗户时 |
Activated |
激活窗口时 |
|
Dactived |
窗口失去焦点时 |
|
Closing |
关闭窗口时 |
|
Closed |
关闭窗口后 |
|
Iconified |
窗口最小化时 |
|
Deiconifed |
当窗口从最小化恢复到正常大小时 |
|
MouseEvent 鼠标事件和接口 |
Dragged |
鼠标拖动时 |
Moved |
鼠标移动时 |
|
Action 事件和接口 |
Performed |
单击按钮,在文本行中按回车键,双击列表框选择菜单项时 |
Text 文本事件和接口 |
textValueChanged |
文本行或文本区中修改内容 |
Mouse鼠标事件和接口 |
Clicked |
单击 |
Entered |
进入 |
|
Exited |
离开 |
|
Pressed |
按下 |
|
Released |
释放 |
|
KeyEvent键盘事件和接口 |
Pressed |
按下键盘时 |
Released |
释放键盘时 |
|
Typed |
敲击键盘时 |
|
Focus焦点事件和接口 |
Gained |
获得焦点时 |
Lost |
失去焦点时 |
11.5.4:事件适配器
每个有多个方法的监听器接口都对应于一个适配器
ComponentAdapter:组件适配器
ContainerAdapter :容器适配器
FocusAdapter 焦点适配器
KeyAdapter 键盘适配器
MouseAdapter 鼠标适配器
WindowAdapter 窗口适配器
使用适配器,只需要重写需要实现的方法,不用实现无关的方法,与监听器不同的是,监听器是一个接口,而适配器是个类
public class WindowclosingDemo extends JFrame
{
public static void main(String[] args)
{
WindowclosingDemo windowclosingDemo = new WindowclosingDemo();
windowclosingDemo.setVisible(true);
}
public WindowclosingDemo()
{
setSize(300, 300);
setLocation(400, 400);
// 设置默认关闭操作作为:什么都不做
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
// 询问是否关闭窗口
int answer = JOptionPane.showConfirmDialog(null, "是否关闭窗口?",
"窗口信息", JOptionPane.YES_NO_CANCEL_OPTION);
if (answer == JOptionPane.YES_OPTION)
{
System.exit(0);
}
}
});}}
第十一章 GUI 上的更多相关文章
- 20190821 On Java8 第十一章 内部类
第十一章 内部类 一个定义在另一个类中的类,叫作内部类. 链接外部类 内部类是一种名字隐藏和组织代码的模式. 内部类拥有其外围类的所有元素的访问权. 内部类 .this 和 .new的使用 this: ...
- <构建之法>第十一章、十二章有感
十一章:软件设计与实现 工作时要懂得平衡进度和质量.我一直有一个困扰:像我们团队这次做 男神女神配 社区交友网,我负责主页的设计及内容模块,有个队友负责网站的注册和登录模块,有个队友负责搜索模块,有个 ...
- sql 入门经典(第五版) Ryan Stephens 学习笔记 (第六,七,八,九,十章,十一章,十二章)
第六章: 管理数据库事务 事务 是 由第五章 数据操作语言完成的 DML ,是对数据库锁做的一个操作或者修改. 所有事务都有开始和结束 事务可以被保存和撤销 如果事务在中途失败,事务中的任何部分都不 ...
- 第十一章 TClientDataSet
第十一章 TClientDataSet 与TTable.TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端.TClientDataSet最大 ...
- 第十一章、认识与学习BASH
第十一章.认识与学习 BASH 最近升级日期:2009/08/25 1. 认识 BASH 这个 Shell 1.1 硬件.核心与 Shell 1.2 为何要学文字接口的 shell 1.3 系统的合法 ...
- [Effective Java]第十一章 序列化
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高
第十一章 搭建云端服务器 该章主要介绍了移动后端服务的概念以及Bmob的使用,比较简单,所以略过不总结. 第十三章 Android实例提高 该章主要介绍了拼图游戏和2048的小项目实例,主要是代码,所 ...
- [CSAPP笔记][第十一章网络编程]
第十一章 网络编程 我们需要理解基本的客户端-服务端编程模型,以及如何编写使用因特网提供的服务的客户端-服务端程序. 最后,我们将把所有这些概念结合起来,开发一个小的但功能齐全的Web服务器,能够为真 ...
- perl5 第十一章 文件系统
第十一章 文件系统 by flamephoenix 一.文件输入/输出函数 1.基本I/O函数 1)open函数 2)用open重定向输入 3)文件重定向 4)指定读写权限 ...
随机推荐
- QT 调试时出现 During startup program exited with code 0xc0000135 错误
我用的QT creator 5.70 出现上述原因是动态库加载不成功,但是QTcreator 不会提示什么动态库,具体缺乏什么动态库要用VS新建一个工程调用才可以看到,这也是QT Creator很大的 ...
- 使用jsonp跨域请求后可以获得数据,但是进入error方法,返回parseerror
$.ajax({ url:url, dataType:'jsonp', jsonp: 'callback',//回调函数名字 jsonpCallback: 'success_jsonpCallback ...
- 选择App开发外包时,你该了解哪些法律常识?
随着App需求的激增,选择App外包服务的客户也多了起来.然而客户和开发方对于其中的法律条款却不甚了解,导致在服务过程中,时常会发生一些分歧和纠纷,最终致使项目搁浅. 为了普及App外包的法律常识,移 ...
- TestNG测试报告美化buid.xml配置
<?xml version="1.0" encoding="UTF-8"?> <project name="myproject&qu ...
- java 性能优化:35 个小细节,让你提升 java 代码的运行效率
前言 代码 优化 ,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没 ...
- Python程序的首行
>问题 >>在一些python程序中的首行往往能够看见下面这两行语句中的一句 >>>#!/usr/bin/Python >>>#!/usr/bin ...
- csuoj 1391: Boiling Vegetables
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1391 1391: Boiling Vegetables Time Limit: 1 Sec Me ...
- IOS关于不同字体和不同颜色的选择
在项目中,用到一个功能,就是不同文字和不同颜色字体选择, 界面如下:,效果如下: 这个功能主要用到了textview的几个代理办法,其中一个重要的问题就是,在英文下和英文下的不同判断方式,以及是否有追 ...
- Redis不同类型方法整合
1 对value操作的命令 exists(key):确认一个key是否存在 del(key):删除一个key type(key):返回值的类型 keys(pattern):返回满足给定patt ...
- 箭头函数 Arrow Functions/////////////////////zzz
箭头符号在JavaScript诞生时就已经存在,当初第一个JavaScript教程曾建议在HTML注释内包裹行内脚本,这样可以避免不支持JS的浏览器误将JS代码显示为文本.你会写这样的代码: < ...