学堂在线—Java程序设计—课程笔记(第7章 图形用户界面)

第7章 图形用户界面

    • 7.1 绘图
    • 7.2 Swing基础
    • 7.3 Swing的层次
    • 7.4 布局管理
    • 7.5 内部类
    • 7.6 事件处理的基本概念
    • 7.7 事件派发机制
    • 7.8 顶层容器
    • 7.9 中间层容器
    • 7.10 原子组件
    • 7.11 其他Swing特性

7.1 绘图

  1. 图形环境和图形对象:
    GUI组件左上角坐标默认为(0,0),从左上角到右下角坐标增加,坐标的单位是像素;
    Graphics对象,抽象类,专门管理图形环境,提供了一个与平台无关的绘图接口;
    各平台上实现的Java系统将创建Graphics类的一个子类来实现绘图功能,但是这个子类对程序员是透明的;
    执行paint方法时,系统会传递一个指向特定平台的Graphics子类的图形对象g;
  2. 颜色设置:Color类及Graphics类中相关方法;
    字体设置:Font类及Graphics类中相关方法;
  3. Graphics类:绘制字符串或各种图形;
    主窗口:继承JFrame;
    主程序:GraphicsTester application = new GraphicsTester();
    application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  4. Java2D API提供了高级的二维绘图功能,分布在java.awt、java.awt.image等多个包中,能够绘制各种形状、控制笔画、填充形状、变换图形、构建重叠文本和图形、剪切形状等;
    Graphics2D类,Graphics的抽象子类,使用Java2D API必须建立该类对象;
  5. 传递给paint方法的对象是Graphics2D的一个子类实例,被向上转型为Graphics类的实例,要访问Graphics2D功能,必须将传递给paint方法的Graphics引用强制转换为Graphics2D引用:Graphics2D g2d = (Graphics2D)g;

7.2 Swing基础

  1. JFC(Java Foundation Classes),关于GUI组件和服务的完整集合,作为Java Se的一个有机部分,主要包含AWT、Java2D、Accessibility、Drag&Drop、Swing共5个部分;
    Swing:JFC的一部分,提供按钮、窗口、表格等所有组件,纯Java组件;
    Swing出现之前:AWT包,大多重量级组件,含有本地代码;
    Swing组件名称是在原来AWT组件名称前加上J,如JButton、JCheckBox、JScrollbar等,是JComponent类的子类;
    架构在AWT之上,是AWT的扩展而不是取代;
    完全由Java语言编写,外观和功能不依赖于任何由宿主平台的窗口系统提供的代码,是轻量级组件;
    可以提供更丰富的视觉感受;
  2. 在Applet和Application中应用Swing:
    在Applet中应用Swing,要将Swing组件加载到Applet容器上(通常是JApplet),通常在init方法中完成;
    在Application中应用Swing,要将Swing组件加载到这个Application的顶层容器(通常是JFrame中);

7.3 Swing的层次

  1. 多数Swing组件的继承层次:
    java.lang.Object -> java.awt.Component -> java.awt.Container -> javax.swing.JComponent
    JComponent类是除了顶层容器以外所有Swing组件的超类;
  2. Component类:
    包含paint、repaint方法,可以在屏幕上绘制组件;
    大多数GUI组件直接或间接扩展Component;
  3. Container类:
    容器类,容纳相关组件;
    包括add方法,用来添加组件;
    包括setLayout方法,用来设置布局,帮助Container对象对组件定位和设置大小;
  4. JComponent类(多数Swing组件的超类)
    可定制的观感,即可根据需求定制观感;
    快捷键(通过键盘直接访问GUI组件);
    一般的事件处理功能;
  5. Swing的组件和容器层次:
    顶层容器JFrame(单个主窗口),JDialog(二级窗口(对话框)),JApplet(在浏览器窗口中实现一个applet显示区域),都是重量级组件(必须和操作系统打交道),分别从原来AWT组件的Frame、Dialog和Applet类继承而来,每个使用Swing组件的Java程序必须至少有一个顶层容器放置其他组件;
    中间层容器:一般用途的(JPanel、JScrollPane、JSplitPane、JTabbedPane、JToolBar),特殊用途的(JInternalFrame、JRootPane);
    原子组件:直接与用户交互的组件,显示不可编辑信息的(JLabel、JProgressBar、JToolTip等),有控制功能可用来输入信息的(JButton、JCheckBox、JRadioButton等),能提供格式化信息并允许用户选择的(JColorChooser、JFileChooser、JTable、JTree等);

7.4 布局管理

  1. 布局管理器:调用容器对象的setLayout方法,并以布局管理器对象为参数,例如
    Container contentPane = frame.getContentPane();
    contentPane.setLayout(new FlowLayout());
    使用布局管理器可以更容易地进行布局,且当改变窗口大小时,会自动更新版面配合窗口的大小,不需担心版面因此混乱;
  2. Java中有很多实现LayoutManager接口的类,常用的有
    BorderLayout:内容面板(content pane)默认使用,可将组件放到东西南北中五个区域;
    FlowLayout:JPanel默认,放在一行(宽度不足会自动换行);
    GridLayout:按指定行列数划分成等大的若干块;
    CardLayout:根据选择像卡片一样现实不同布局;
    GridBagLayout:灵活的网格,可以设置组件的位置和占多少行/列;
    BoxLayout:单一行或列,可以设置组件对齐方式,最大、最小、优选尺寸;
    SpringLayout;能够精确指定组件之间的距离;

7.5 内部类

  1. 内部类:
    在另一个类或方法的定义中定义的类;
    可访问其外部类中所有数据和方法成员;
    可对逻辑上相互联系的类进行分组;
    对于同一包中的其他类来说能够隐藏;
    可非常方便地编写事件驱动程序;
  2. 命名的内部类:可在类的内部多次使用;
    匿名内部类:可在new关键字后声明内部类,并立即创建一个对象;
  3. 假设外层类名为Myclass,该类的内部类名为:
    Myclass$c1.class(c1为命名的内部类名);
    Myclass$1.class(表示类中声明的第一个匿名内部类);
  4. 内部类实现接口、继承抽象类:
    可以完全不被看到,而且不能被调用;
    可以方便实现“隐藏实现细则”,外部能得到的是指向超类或接口的一个引用;
  5. 局部作用域中的内部类:
    实现某个接口,产生并返回一个引用;
    为解决一个复杂问题,需要建立一个类,而又不想它为外界所用;
  6. 匿名的内部类:
    public Contents cont() {
    return new Contents() {
    private int I = 11;
    public int value() { return I;}}}
    此处new了一个Contents的子类对象,匿名;

7.6 事件处理的基本概念

  1. 常见的事件包括:移动鼠标、单双击鼠标各个按钮、单击按钮、在文本字段输入、在菜单中选择菜单项、在组合框中选择、单选和多选、拖动滚动条、关闭窗口等;
    Swing通过事件对象来包装事件,程序可以通过事件对象获得事件的有关信息;
  2. 事件处理的几个要素:
    事件源:与用户进行交互的GUI组件,表示事件来自于哪个组件或对象;
    事件监听器:负责监听事件并做出响应的代码;
    事件对象:封装了有关已发生的事件的信息;
  3. 程序员应完成的两项任务:
    为事件源注册一个事件监听器;
    实现事件处理方法;
  4. 事件源:
    提供注册监听器或取消监听器的方法;
    如有事件发生,已注册的监听器就会被通知;
    一个事件源可以注册多个事件监听器,每个监听器可对多种事件进行响应;
  5. 事件监听器:
    是一个对象,通过事件源的add xxx Listener方法被注册到某个事件上;
    不同的Swing组件可以注册不同的事件监听器;
    一个事件监听器中可以包含有对多种具体事件的专用处理方法;
  6. 常用事件对象ActionEvent、ItemEvent、ChangeEvent、WindowEvent、MouseEvent;
  7. 接口与适配器:
    事件监听器接口(xxxListener规定了要响应某类事件必须实现的方法);
    事件监听器适配器类(xxxAdapter含有xxxListener中方法的默认实现,只需编写要处理的事件的方法);
  8. 事件处理方法:
    实现事件监听器接口(需实现接口所有方法,不处理的方法可用空花括号);
    继承事件监听器适配器类(只需重写感兴趣的事件);
    使用匿名内部类(特别适用于已经继承了某个父类(例如Applet程序,主类必须继承JApplet类或Applet类),则根据Java语法规则,就不能再继承适配器类的情况,而且使用这种方法程序看起来会比较清楚明了);
    lambda表达式(对于只有一个抽象方法的函数式监听器接口可使用);

7.7 事件派发机制

  1. Swing中的组件不是线程安全的(不能有多个程序段并发操作);
  2. 事件派发线程:
    Swing中的组件是非线程安全的,在Swing中专门提供了一个事件派发线程(EDT)用于对组件的安全访问;
    用来执行组件事件处理程序的线程(如按钮的点击事件),依次从系统事件队列取出事件并处理,一定要执行完上一个事件的处理程序后,才会处理下一个事件;
    事件监听器的方法都在事件派发线程中执行,如ActionListener的actionPerformed方法;
  3. 由事件派发线程启动GUI:
    可以调用invokeLater或invokeAndWait请事件分发线程以运行某段代码;
    要将这段代码放入一个Runnable对象run方法中,并将该对象作为参数传递给invokeLater;
    invokeLater是异步的,不用等代码执行完就返回;
    invokeAndWait是同步的,要等代码执行完才返回,调用时要避免死锁;

7.8 顶层容器

  1. Swing的3个顶层容器类:
    JFrame、JApplet、JDialog;
    都是重量级组件,分别继承了AWT组件的Frame、Applet、Dialog;
    每个顶层容器都有一个内容面板,通常直接或间接的容纳别的可视组件;
    可以有选择地为顶层容器添加菜单,菜单被放置在顶层容器上,但是在内容面板之外;
  2. 通过静态方法show xxx Dialog可以产生四种简单的对话框:它们的方法参数中绝大部分(除了输入对话框可以不指定父窗口)都需要提供一个父窗口组件ParentComponent,只有关闭这些简单的对话框后,才可以返回到其父窗口,也就是说它们绝大部分是模态的;

7.9 中间层容器

  1. 中间层容器:一般用途的JPanel、JScrollPane、JSplitPane、JTabbedPane、JToolBar,特殊用途的JInternalFrame、JRootPane(可以直接从顶层容器中获得)
  2. JRootPane的层次结构:
    glassPane:默认隐藏,可以使用glassPane截获所有要到达JRootPane别的部分的事件;
    layeredPane:分为很多层(layer),每层有一个代表层深度的整数值(Z-order),深度值高的组件覆盖在深度值低的组件上;一般将所有组件添加到contentPane上;JmenuBark可选,如果没有,contentPane会充满整个顶层容器;
  3. JPanel:
    默认状态下,除了背景色不绘制任何东西;
    可以很容易地为它设置边框和绘制特性,有效利用JPanel可使版面管理更容易;
    可以使用布局管理器规划它容纳的组件的位置和大小(可以通过setLayout方法改变布局;可以在创建JPanel对象时为它确定布局方式,默认使用FlowLayout布局(一行));
  4. JScrollPane:
    容器有滚动条,通过拖动滑块可以看到更多内容;
    由9个部分组成,包括一个中心显示地带、四个角和四条边;
  5. JSplitPane:
    可以把两个组件显示在两个显示区域内,且随着区域间分隔线的拖动,区域内组件大小随之变动;
    允许设置水平或垂直分割,允许设置动态拖曳功能;
    通常先把组件放到ScrollPane中,再把ScrollPane放到SplitPane中,实现每部分滚动条;
  6. JTabbedPane:
    如果一个窗口的功能有几项,可以给每项设置一个标签,标签下面包含若干专用组件;
  7. JToolBar:
    将常用功能以工具栏方式呈现;
  8. JInternalFrame:
    实现在一个主窗口中打开很多个文档,每个文档各自占用一个新窗口;
    JInternalFrame使用和JFrame几乎一样,可以最大化、最小化、关闭窗口、加入菜单;
    JInternalFrame是轻量级组件,只能是中间容器,必须依附于顶层容器上;
    通常将internal frame加入JDesktopPane类的对象来方便管理,JDesktopPane继承自JLayeredPane,用来建立虚拟桌面,可以显示并管理众多internal frame之间层次关系;

7.10 原子组件

  1. 原子组件可分为三类:
    显示不可编辑信息:JLabel、JProgressBar、JToolTip;
    有控制功能,可以用来输入信息:JButton、JCheckBox、JRadioButton、JComboBox、JList、JMenu、JSlider、JSpinner、JTextComponent;
    能提供格式化的信息并允许用户选择:JColorChooser、JFileChooser、JTable、JTree;
  2. 显示不可编辑信息的原子组件:
    JLabel可以显示文字和图像,并指定两者位置;
    JProgressBar进度条;
    JToolTip使用setToolTipText()方法为组件设置提示信息;有的组件如JTabbedPane由多个部分组成,需要鼠标在不同部分停留时显示不同提示信息,这时可以在其addTab()方法中设置提示信息参数,也可以通过setTooltipTextAt方法进行设置;
  3. 按钮类:AbstractButton抽象类是众多按钮类的超类,继承它的类包括:
    JButton;
    JToggleButton(有两个选择状态的按钮,CheckBox多选按钮,JRadioButton单选按钮);
    JMenuItem(在菜单中使用,JCheckBoxMenuItem多选按钮,JRadioButtonMenuItem单选按钮,JMenu一般菜单项);
  4. 列表框JList(可以选择一到多个选项)
    有几种各有特色的构造方法(选项是否可添加、删除);
    提供了很多API可以用来设置各选项的显示方式(在一列还是若干列)、选择模式(一次可选几项及是否可连续)等;
    因为JList通常含有很多选项,通常放在一个JScrollPane对象里;
    JList事件处理一般分为两类(取得用户选取的项目,事件监听器ListSelectionListener;对鼠标事件作出响应,事件监听器MouseListener);
  5. 组合框JComboBox:
    在许多选项中选其一,可以有两种非常不一样的格式(默认状态不可编辑,包括一个按钮和一个下拉列表,用户只能选择;可编辑模式,多了一个文本区域,用户可填写);
    组合框只需要很少的屏幕区域,而一组JRadioBox、JCheckBox、JList占据空间较大;
  6. 连续数值选择:
    JSlider占空间大,可设置最小、最大、初始刻度、方向、标上刻度或文本,移动滑动杆会产生ChangeEvent事件;
    JSpinner占空间小,类似于可编辑的JComboBox,复合组件由3个部分构成(向上按钮、向下按钮和文本编辑区),可通过按钮选择或直接输入;和JComboBox不同,待选项不会显示;
  7. 文本组件,都继承自JTextComponent抽象类,可分为三类
    JTextField、JPasswordField、JFormattedTextField单行文本,只能显示和编辑一行文本,像按钮一样可以产生ActionEvent事件,通常用来接受少量用户输入信息并在输入结束进行一些事件处理;
    JTextArea多行单一样式文本区域,通常用户输入任意长度无格式文本或显示无格式的帮助信息;
    JEditorPane、JTextPane多行风格化文本区域,嵌入图像或别的组件;
  8. JColorChooser颜色选择对话框:
    通常使用这个类的静态方法showDialog()输出标准颜色选择对话框,返回值为所选颜色;
    也可以通过静态方法createDialog()方式输出个性化颜色选择对话框,如为其添加菜单、定义事件处理程序,这个方法的返回值就是一个对话框;
  9. JFileChooser文件选择对话框:
    可以使用JFileChooser的showDialog、showOpenDialog或showSaveDialog()方法来打开文件对话框,但它仅返回用户选择的按钮(确认or取消)和文件名(如果确认),后续功能如存盘、打开文件等需要程序员进一步编写;
    提供了专门的方法用于设置可选择的文件类型,可指定每类文件使用的类型图标;
  10. JTable表格:
    可为表格设计显示外观(是否有滚动条、调整某一列宽其它列宽变化情形)、显示模式(根据数据类型的不同有不同的排列显示方式、为某一字段添加组合框JComboBox)、选择模式(单选、多选、连续选、任意选);
    JTable的事件都是针对表格内容的操作处理,称为TableModelEvent事件,通过addTableModelListener方法为表格添加此种事件监听器;
    和其相关的还有一些接口和类,包括TableModel、AbstractTableModel、DefaultTableModel、SelectionModel、TableColumnModel;
  11. JTree树状结构直观表现层次关系:
    构造方法有多种,参数可以是Hashtable,也可以是TreeNode或TreeModel对象;
    可以使用JComponent提供的putClientProperty方法设置JTree外观,也可以使用TreeCellRenderer个性化各类节点的显示样式;

7.11 其他Swing特性

  1. Action对象功能(封装对不同组件(如菜单项和工具栏按钮)同样的响应功能,封装属性设置等,再讲Action对象添加到需要响应的各个位置):
    Action接口是对ActionListener接口的一个有用的扩展,继承关系public interface Action extends ActionListener;
    在很多既有菜单又有工具栏的应用程序中,可以通过Action对象封装事件响应代码和相关设置,并添加到不同的事件源;
    对不同组件的显示文字、图标、快捷键、提示文字、是否可用等属性统一设置;
  2. 创建Action对象:
    AbstractAction类实现了Action接口中除了actionPerformed方法以外的其他方法,而且还提供了一些获取和设置Action域属性的方法;
    首先创建一个继承抽象类AbstractAction类的子类,再实例化子类(设置需要的属性值,定义actionPerformed方法);
  3. 使用Action对象:
    通过GUI组件的setAction方法将Action对象关联到组件(每个具有addActionListener方法的组件都具有setAction方法;Action是一个事件监听器,如果需要添加多个监听器,应使用addActionListener方法,一个GUI组件可以调用setAction不止一次,但组件和前一个Action对象的关联会被删除);
    通过setAction方法把Action对象关联到GUI组件后,此组件属性会被设置为符合这个Action对象的属性,这个Action对象会被注册为此组件的一个事件监听器对象,如果改变了Action对象的属性或方法则关联的组件会自动变更;
  4. 边框:
    每个继承自JComponent的Swing组件都可以有边框;
    使用组件的setBorder方法为组件添加边框,需提供一个Border类型对象(可以使用BorderFactory类提供的很多静态方法产生一个常用Border对象;如果不能满足要求,可以直接使用javax.swing.border包里的API来定义边框);
  5. 设置组件的观感:
    在产生任何可视组件前需使用UIManager类提供的setLookAndFeel()静态方法设置观感;
    Java提供跨平台观感,可利用UIManager类提供的getCrossPlatformLookAndFeelClassName()静态方法获得类名;
    程序所属系统观感,可利用UIManager类提供的getSystemLookAndFeel()静态方法获得目前操作平台的Look and Feel类名称字符串;
  6. 设置顶层容器观感:
    顶层容器JFrame和JDialog是重量级组件,依赖于操作系统,当使用不同操作系统时,所显示的顶层容器就会有所不同;
    针对这两个顶层容器,有一个静态方法专门设置观感:static void setDefaultLookAndFeelDecorated(Boolean) (参数true选用默认观感,参数false选用操作平台观感);
  7. 桌面API:
    从Java6开始,对于特定文件类型,Java程序可以和关联该文件类型的主机应用程序进行交互;这种交互通过java.awt.DeskTop类进行,因此java.awt.DeskTop API叫做桌面API;
  8. 桌面API允许Java应用程序完成3件事:
    启用主机平台上默认的浏览器打开URL,由DeskTop的browse方法完成;
    启用主机平台上默认的邮件客户端,由DeskTop的mail方法完成;
    对特定的文件,启用主机平台上与之关联的应用程序,对该文件进行打开、编辑、打印操作,分别由DeskTop的open、edit、print方法完成;

你可能感兴趣的:(基础学习)