第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 上的更多相关文章

  1. 20190821 On Java8 第十一章 内部类

    第十一章 内部类 一个定义在另一个类中的类,叫作内部类. 链接外部类 内部类是一种名字隐藏和组织代码的模式. 内部类拥有其外围类的所有元素的访问权. 内部类 .this 和 .new的使用 this: ...

  2. <构建之法>第十一章、十二章有感

    十一章:软件设计与实现 工作时要懂得平衡进度和质量.我一直有一个困扰:像我们团队这次做 男神女神配 社区交友网,我负责主页的设计及内容模块,有个队友负责网站的注册和登录模块,有个队友负责搜索模块,有个 ...

  3. sql 入门经典(第五版) Ryan Stephens 学习笔记 (第六,七,八,九,十章,十一章,十二章)

    第六章: 管理数据库事务 事务 是 由第五章 数据操作语言完成的  DML ,是对数据库锁做的一个操作或者修改. 所有事务都有开始和结束 事务可以被保存和撤销 如果事务在中途失败,事务中的任何部分都不 ...

  4. 第十一章 TClientDataSet

    第十一章 TClientDataSet 与TTable.TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端.TClientDataSet最大 ...

  5. 第十一章、认识与学习BASH

    第十一章.认识与学习 BASH 最近升级日期:2009/08/25 1. 认识 BASH 这个 Shell 1.1 硬件.核心与 Shell 1.2 为何要学文字接口的 shell 1.3 系统的合法 ...

  6. [Effective Java]第十一章 序列化

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  7. 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高

    第十一章 搭建云端服务器 该章主要介绍了移动后端服务的概念以及Bmob的使用,比较简单,所以略过不总结. 第十三章 Android实例提高 该章主要介绍了拼图游戏和2048的小项目实例,主要是代码,所 ...

  8. [CSAPP笔记][第十一章网络编程]

    第十一章 网络编程 我们需要理解基本的客户端-服务端编程模型,以及如何编写使用因特网提供的服务的客户端-服务端程序. 最后,我们将把所有这些概念结合起来,开发一个小的但功能齐全的Web服务器,能够为真 ...

  9. perl5 第十一章 文件系统

    第十一章  文件系统 by flamephoenix 一.文件输入/输出函数  1.基本I/O函数    1)open函数    2)用open重定向输入    3)文件重定向    4)指定读写权限 ...

随机推荐

  1. QT 调试时出现 During startup program exited with code 0xc0000135 错误

    我用的QT creator 5.70 出现上述原因是动态库加载不成功,但是QTcreator 不会提示什么动态库,具体缺乏什么动态库要用VS新建一个工程调用才可以看到,这也是QT Creator很大的 ...

  2. 使用jsonp跨域请求后可以获得数据,但是进入error方法,返回parseerror

    $.ajax({ url:url, dataType:'jsonp', jsonp: 'callback',//回调函数名字 jsonpCallback: 'success_jsonpCallback ...

  3. 选择App开发外包时,你该了解哪些法律常识?

    随着App需求的激增,选择App外包服务的客户也多了起来.然而客户和开发方对于其中的法律条款却不甚了解,导致在服务过程中,时常会发生一些分歧和纠纷,最终致使项目搁浅. 为了普及App外包的法律常识,移 ...

  4. TestNG测试报告美化buid.xml配置

    <?xml version="1.0" encoding="UTF-8"?> <project name="myproject&qu ...

  5. java 性能优化:35 个小细节,让你提升 java 代码的运行效率

    前言 代码 优化 ,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没 ...

  6. Python程序的首行

    >问题 >>在一些python程序中的首行往往能够看见下面这两行语句中的一句 >>>#!/usr/bin/Python >>>#!/usr/bin ...

  7. csuoj 1391: Boiling Vegetables

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1391 1391: Boiling Vegetables Time Limit: 1 Sec  Me ...

  8. IOS关于不同字体和不同颜色的选择

    在项目中,用到一个功能,就是不同文字和不同颜色字体选择, 界面如下:,效果如下: 这个功能主要用到了textview的几个代理办法,其中一个重要的问题就是,在英文下和英文下的不同判断方式,以及是否有追 ...

  9. Redis不同类型方法整合

    1     对value操作的命令 exists(key):确认一个key是否存在 del(key):删除一个key type(key):返回值的类型 keys(pattern):返回满足给定patt ...

  10. 箭头函数 Arrow Functions/////////////////////zzz

    箭头符号在JavaScript诞生时就已经存在,当初第一个JavaScript教程曾建议在HTML注释内包裹行内脚本,这样可以避免不支持JS的浏览器误将JS代码显示为文本.你会写这样的代码: < ...