第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. ui-grid

    html代码: <html ng-app="myApp">       <head>         <meta charset="utf- ...

  2. eclipse下导入jdk源码

    一直想好好看看jdk的源码,虽然可以直接解压jdk下的src看,但是终究不方便!后来发现可以导入到eclipse中,就在网上找了一些方法,下面就和大家分共享: step1:打开eclipse选择Win ...

  3. logstash插件

    codec 插件   goeip插件 input { file { path => ["/data/nginx/logs/access.log"] type =>&qu ...

  4. visio任意角度精确旋转图形

    visio 2013 步骤: 选中图形 点击"视图->显示->任务窗格->大小和位置" 然后会出现一个小窗口,里面可以输入图形的旋转角度

  5. c++中vector的用法详解

    c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...

  6. simple mail example for smtp debug

    vim /etc/mail.rc head /etc/rc.local | mail -s "test_email" pyz_sub1@mailtest.com

  7. mySql 注入攻击

    注入攻击 1.原理: a.只要是带有参数的动态网页且此网页访问了数据库,那么就有可能存在SQL注入; b.字符串拼接和没有判断用户输入是否合法------>导致用户可以玩填字游戏-----> ...

  8. cssSelector定位笔记1

    cssSelector定位方法:1.使用class属性定位元素:driver.findElement(By.cssSelector("input.login"));即可以先指定一个 ...

  9. [转]Google Guava官方教程(中文版)

    Google Guava官方教程(中文版) http://ifeve.com/google-guava/

  10. Qt qml listview 列表视图控件(下拉刷新、上拉分页、滚动轴)

    Qt qml listview下拉刷新和上拉分页主要根据contentY来判断.但要加上顶部下拉指示器.滚动条,并封装成可简单调用的组件,着实花了我不少精力:) [先看效果]    [功能] 下拉刷新 ...