第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. python_excel

    1. xlrd, xlwt, xlutils的关系 Python中一般使用xlrd(excel read)来读取Excel文件,使用xlwt(excel write)来生成Excel文件(可以控制Ex ...

  2. hadoop 性能调优与运维

    hadoop 性能调优与运维 . 硬件选择 . 操作系统调优与jvm调优 . hadoop运维 硬件选择 1) hadoop运行环境 2)  原则一: 主节点可靠性要好于从节点 原则二:多路多核,高频 ...

  3. [Android Tips] 21. Regex Named Groups in Android

    Android SDK 并没有包含 Java 7 新增加的命名捕获组功能,需要使用第三方库 https://github.com/tony19/named-regexp import com.goog ...

  4. python知识点总结

    此知识要点,是根据学习廖雪峰phthon3.0教程总结的,所以结构基本和这个教程的结构相同. 背景知识 python是什么?(1)python是一门编程语言,意味着可以用python编写程序,完成一定 ...

  5. url传参中文乱码

    当使用url重定向传参的时候,比如: javascript:window.location.href='modifyBook.jsp?BName=<%=URLEncoder.encode(&qu ...

  6. PHP 使用编码树,生成easyui中的tree样式

    生成树的时候,数据库中一般设计的都为无级数,即为:父子节点的树,例如:基本的数据表设计为: nodecode 节点编码 parentnodecode 父节点编码 nodename  节点名称 这样的形 ...

  7. 【Lua学习笔记之:Lua环境搭建 Windows 不用 visual studio】

    Lua 环境搭建 Windows 不用 visual studio 系统环境:Win7 64bit 联系方式:yexiaopeng1992@126.com 前言: 最近需要学习Unity3d游戏中的热 ...

  8. Spring透过ApplicationListener来触发contextrefreshedevent事件

    Spring通过ApplicationListener接口来触发contextrefreshedevent事件在开发时有时候需要在整个应用开始运行时执行一些特定代码,比如初始化环境,准备测试数据.加载 ...

  9. 将webservice封装成dll

    生成dll文件的步骤如下:1.发布完成后,在浏览器中打开WebService文件,如:http://localhost/WebSer/WebService1.asmx,可以看到WebService1. ...

  10. Oracle数据访问组件ODAC的安装方法

    Oracle数据访问组件ODAC(Oracle Data Access Components)顾名思义就是用来访问Oracle数据库的小程序.我们可以编程调用这些组件来实现在没有安装Oracle数据库 ...