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(Compon