Insets/Border/Icon/Action

在比较AWT、SWING的不同之处时,InSets和Border是个有趣的话题。

 

InSets是AWT时代就有的概念,多译为“边衬”,是指容器的边衬部分,布局管理器在安置容器的组件时,不会占用inSets部分。而且,AWT不提供动态改变inSets大小的方法,只提供getInsets()供子类型重载,即如想改变容器的inSets,只能继承该类,并重载该方法。

而Border是Swing引入的概念。Border绘制在inSets内——可以简单的理解成Border会占据整个InSets空间,事实上getInsets已经被重载以返回其Border的“边衬”(即返回Border接口的getBorderInsets方法的返回值)。通过动态的为Component设置Border(通过setBorder方法),就可以改变Component的inSets的大小。因此,Swing时代,基本上已经不再重载getInsets方法了——如果使用空Border(EmptyBorder),就可以得到“传统意义”上的InSets。

只所以会有如此奇怪的设置,我猜测原因是这样的。

AWT中的容器多是重量的,即有其相应的同位体。容器本身的绘制是由其同位体完成的,同位体有自身的Border,而inSets的引入也是为了腾出绘制Border位置。AWT其实是不鼓励改变InSets大小的,因为如果设置太小的InSets,组件有可能占据组件Border的位置。又由于Border的绘制是由同位体负责的,AWT就没有理由引入Border的概念了。

Swing的情况完全不同。所有的Swing组件(Swing组件都是容器)都是轻量的,它们由Swing负责绘制——包括容器的Border。因此,Swing可控制Border的绘制,Border类的引入就顺理成章了。

Border不是组件,只是组件用来委托绘制“边框”而已,所以不同的组件当然可以共享一个Border对象作为委托对象。BorderFactory被引入,尽量应该使用“工厂”来生产Border对象——对于能够共享的Border对象,“工厂”被实现成singleton模式——我们只管为每个Component创建Border即可,优化的工作就交给工厂来完成吧。

Border接口有3个方法:

(1)         isBorderOpaque();

(2)         paintBorder(Component , Graphics, int, int, int, int );

(3)         getBorderInsets(Component)

AbstractBorder是顶层的Border类实现,正如它名字所示,它是个Abstract类。如要实现自己的Border,则需要继承AbstractBorder类——通常需要重载paintBorder和getBorderInsets——AbstractBorder不绘制边框,会返回一个(0,0,0,0)的Insets。

需要注意的是,某些组件拥有默认的Border,有些Border还帮助组件实现特定的界面样式。当更改这些组件的Border时,需要特别小心。

Icon

Icon的概念与Border及其相似,它们都不是Component,但都被Component用来委托绘制一些东西——不同的是,Border绘制在Insets中,而Icon绘制在Component的非Insets部分。

同Border不同,Component并没有类似setIcon方法——支持Icon的Component通常会添加一个使用Icon作为参数的构造函数。

所有的Icon都实现Icon接口:

int

getIconHeight()
          返回图标的高度。

int

getIconWidth()
          返回图标的宽度。

void

paintIcon(Component c,Graphics g, int x, int y)
          在指定位置上绘制图标。

最常用的Icon实现是IamgeIcon类,IamgeIcon内部使用MediaTracker的一个实例来完全装载image。如果装载失败,其后调用paintIcon()将不会有任何操作,而getIconHeight()、getIconWidth()会返回-1。

有大量的Swing组件支持Icon——这很容易理解,因为Swing完全控制Component的绘制,它当然可以在Component上绘制一个Icon。

Action

与Icon相比,Action不太好理解,JDK帮助文档对Action接口的描述如下:

Action 接口提供 ActionListener 接口的一个有用扩展,以便若干控件访问相同的功能。

除了 ActionListener 接口定义的 actionPerformed 方法之外,此接口还允许应用程序在一个位置定义:

  • 描述函数的一个或多个文本字符串。这些字符串可用于显示按钮的立体文本、在菜单项中设置文本等等。
  • 描述函数的一个或多个图标。这些图标可用于菜单控件中的图像,或者用于更复杂用户界面中的合成项。
  • 功能的启用/禁用状态。应用程序可以禁用实现此接口的函数,而不必分别禁用菜单项和工具栏按钮。所有为侦听状态更改而注册为侦听器的组件都将禁止为该项生成事件,并相应地修改显示。

而AbstractAction是Swing提供的实现了Action接口的抽象基类,供用户继承——你必须自行实现actionPerformed方法。

我们看一个例子:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class Test extends JApplet {
          public void init() {
                    JMenuBar mb = new JMenuBar();
                    JMenu fileMenu = new JMenu("File");
 
                    fileMenu.add(new ExitAction());
                    mb.add(fileMenu);
                    setJMenuBar(mb);
          }
}
class ExitAction extends AbstractAction {
          public ExitAction() {
                    super("exit");
          }
          public void actionPerformed(ActionEvent e) {
                    System.exit(0);
          }
}

显然,我们并没有为菜单项设置String(我们甚至没有去创建菜单项)——菜单项自动获取了Action的String;如果Action带有Icon,菜单项还可以获取这个Icon。

除了String、Icon之外,Action还有一个状态值,当带有状态特征的Component使用该Action后,也会以此状态作为自己的状态(如按钮就带有状态),以下方法用于设置、获取Action的状态。

boolean

isEnabled()
          返回 Action 的启用状态。

void

setEnabled(boolean b)
          设置 Action 的启用状态。

Action还定义了一些列的常量作为Key值,可以通过这些常量进行获取、设置,如:

static String

NAME
          用来存储动作的 String 名称的键,用于菜单或按钮。

(即上例中,显示在菜单上的“String”)

static String

SMALL_ICON

即可以显示在菜单上的“Icon”

Object

getValue(String key)
          使用关联的键获取此对象的一个属性。

void

putValue(String key,Object value)
          使用关联的键设置此对象的一个属性。

这样,就可以动态的修改Action的这些信息——事实上,Component也是通过这些方法来获取自己需要的信息的。

还有一点需要注意的是,任何Action的属性修改后,都会激发属性修改事件,当然Action接口提供了相应的方法来添加、去除Listener:

void

addPropertyChangeListener(PropertyChangeListener listener)
          添加一个 PropertyChange 侦听器。

void

removePropertyChangeListener(PropertyChangeListener listener)
          移除一个 PropertyChange 侦听器。

同Icon、Border一样,Action也能被多个组件共享,共享Action的Component会具有同样的属性——来自Action。

总结

Border、Icon和Action都有两个共同特点:

(1)         它们都不是组件;

(2)         多个组件可以共享它们。

为多个组件共享不近节省了资源,还提供了一致性。对Action而言,还为GUI提供了控制中心点。

(swing读书笔记)Insets/Border/Icon/Action相关推荐

  1. (swing读书笔记)Swing Look And Feel(2)

    (swing读书笔记)Swing Look And Feel(2) By cszhao1980 三.      UI defaults UIDefaults内部维护了一张巨大的Hashtable, 记 ...

  2. (swing读书笔记)Swing Look And Feel(3)

    (swing读书笔记)Swing Look And Feel(3) By cszhao1980 六.UIResource UIResource是个空接口,它的目的是为标识一种身份,即是否为UI Res ...

  3. (swing读书笔记)Swing Look And Feel(4)

    (swing读书笔记)Swing Look And Feel(4) By cszhao1980 八.MetalLookAndFeel的功能增强 Swing对它默认的跨平台L&F提供了功能的增强 ...

  4. (swing读书笔记)JTree简介(下)

    (swing读书笔记)JTree简介(下) By cszhao1980 六.TreeCellRenderer 通过JTable一样,JTree也使用一个接口定义它的单元绘制器,该接口仅有一个方法: C ...

  5. (swing读书笔记)Swing Look And Feel(1)

    (swing读书笔记)Swing Look And Feel(1) By cszhao1980 Swing出现之初,就提供一种非常前卫的功能,即PLAF--可拔插的Look And Feel,我们可以 ...

  6. (swing读书笔记)Undo/Redo(下)

    (swing读书笔记)Undo/Redo(下) By cszhao1980 四.更好的集成--StateEdit 现在,实现Undo功能已经比较简单了: (1)         建立一个"普 ...

  7. (swing读书笔记)JTable简介(下)

    (swing读书笔记)JTable简介(下) by cszhao1980 六.Row 最初,JTable没有提供任何"Row"相关的类来控制Row,与Row相关的大量操作直接坐落在 ...

  8. swing读书笔记转载

    (swing读书笔记)Swing Look And Feel(1) http://blog.csdn.net/cszhao1980/article/details/7343524 (swing读书笔记 ...

  9. (swing读书笔记)JTree简介(中)

    (swing读书笔记)JTree简介(中) By cszhao1980 三.TreeModel(树模型) 同JTable相比,TreeModel接口显得不那么重要.这是Tree的特殊性造成的--Tre ...

最新文章

  1. Centos6/7下静默安装oracle10g
  2. matlab中bitget函数用法_MATLAB中SVM的用法
  3. Error: pgraster_wkb_reader: grayscale band type 10 unsupported
  4. android中组件获取焦点
  5. C++学习之路 | PTA乙级—— 1086 就不告诉你 (15 分)(精简)
  6. java outofmerroy_Tomcat中的Out Of Memory错误
  7. File Converter——万能格式转化神器
  8. Nsight软件简介
  9. Xshell6与Xftp6教育版下载(免费)
  10. 目标检测(一)目标检测算法综述
  11. Macbookpro键盘没有delete键怎么办
  12. 学而思pythonlevel3_【学而思网校语言学习】学而思网校【2019-寒】AE英语直播班 Level 3上【报价 价格 评测 怎么样】 -什么值得买...
  13. 跨越OpenGL和D3D的鸿沟[转]
  14. 《Python编程快速上手——让繁琐的工作自动化》读书笔记2
  15. 白话空间统计二十五:空间权重矩阵外篇:功能地理学
  16. python数据分析:商品数据化运营(上)——知识点
  17. 基因组选择的几个概念
  18. 导出datatable到excel然后让web客户端下载到本地
  19. 笔记本上建立WIFI供安卓手机使用
  20. python unicode码转换_python实现unicode转中文及转换默认编码的方法

热门文章

  1. 问题 D: 生理周期
  2. 中南大学计算机转专业介绍,中南大学转专业条件
  3. ps游戏在什么系统下开发_引擎级防沉迷! Unity携手腾讯游戏推出防沉迷系统开发工具...
  4. 10.26如何用C语言计算圆的周长与面积
  5. 孤儿助养助学基金逾千万 汶川孤儿牵动上海住德的心
  6. PDM图纸文档管理系统还可以实现哪些功能?
  7. python爬虫知网实例-33个Python爬虫项目实战(推荐)
  8. Cortex-M3 内核架构粗总结
  9. javaSE 数字处理类
  10. Matlab图像处理app(截图暂时只能截取原图或灰度图)