swing自定义组件之BUTTON精.docx
《swing自定义组件之BUTTON精.docx》由会员分享,可在线阅读,更多相关《swing自定义组件之BUTTON精.docx(30页珍藏版)》请在冰点文库上搜索。
swing自定义组件之BUTTON精
Swing自定义组件之Button
GUI组件要完成的任务有2个,展现与业务。
对于按钮来说,文本、图标、边框、背景属于展现层,而这些元素在按钮不同状态下会不尽相同,一般来说至少有4种状态下的展现:
普通、鼠标放在其上、被按下、被禁用,也就是按钮应该具备这4种状态。
下面给出的示例是swing实现的自定义按钮。
通常swing自定义组件继承javax.swing.JComponent并重写protectedvoidpaintComponent(Graphicsg方法实现自定义绘制。
重写paintComponent方法时通常要先去掉super.paintComponent(g,因为父方法调用会绘制背景色。
不妨先看一下源代码中的调用过程。
在JComponent.java中paintComponent(Graphicsg方法定义如下:
protectedvoidpaintComponent(Graphicsg{
if(ui!
=null{
GraphicsscratchGraphics=(g==null?
null:
g.create(;
try{
ui.update(scratchGraphics,this;
}
finally{
scratchGraphics.dispose(;
}
}
}
其中ui的声明如下
protectedtransientComponentUIui;
然后转向ComponentUI的update(Graphicsg,JComponentc方法:
publicvoidupdate(Graphicsg,JComponentc{
if(c.isOpaque({
g.setColor(c.getBackground(;
g.fillRect(0,0,c.getWidth(,c.getHeight(;
}
paint(g,c;
}
可见如果发现组件是非透明的,就绘制背景,可以看出swing组件的setBackground方法如何绘制背景的。
一般简单的自定义组件,你可以只通过重写paintComponent方法来实现绘制,对于一般的组件这已经足够。
对于自定义按钮一般的原则是准备4张背景图对应上述4种状态,这4种状态都可通过鼠标****来感知,当状态改变时,调用repaint(使Button重绘。
除了背景,按钮文本、图标等的改变一样也必须调用repaint(来刷新。
然后重要的一点是你必须重写publicDimensiongetPreferredSize(来获得按钮的最佳尺寸。
getPreferredSize方法对于布局管理器来说至关重要,布局管理器会通过getPreferredSize的判断组件的最佳大小,并进行布局。
而对于本范例而言,getPreferredSize的大小只和背景图片大小有关。
对于业务,尽量做到前台界面与后来业务分离。
你可以自定义按钮动作****器来实现,本例是沿用swing的Action实现,当鼠标抬起时,构造一个ActionEvent对象,然后交给Action成员的actionPerformed(ActionEvente处理。
代码如下:
/*
*ImageButton.java
*
*Createdon2007年11月11日,下午6:
30
*
*Tochangethistemplate,chooseTools|TemplateManager
*andopenthetemplateintheeditor.
*/
packagedemo.swing;
importjava.awt.AlphaComposite;
importjava.awt.Color;
importjava.awt.Container;
importjava.awt.Dimension;
importjava.awt.Font;
importjava.awt.FontMetrics;
importjava.awt.Graphics;
importjava.awt.Graphics2D;
importjava.awt.RenderingHints;
importjava.awt.Shape;
importjava.awt.event.ActionEvent;
importjava.awt.event.MouseEvent;
importjava.awt.font.TextAttribute;
importjava.awt.font.TextLayout;
importjava.awt.geom.AffineTransform;
importjava.util.HashMap;
importjavax.swing.Action;
importjavax.swing.Icon;
importjavax.swing.JComponent;
importjavax.swing.SwingConstants;
importjavax.swing.SwingUtilities;
importjavax.swing.event.MouseInputListener;
/**
*为需要具备专业外观的按钮提供方便的实现。
通过此类提供的若干方法可轻松实现专业外观。
*@author电玩
*/
publicfinalclassImageButtonextendsJComponentimplements
MouseInputListener{
/**
*通常状态下的背景图片
*/
privateIconbackgroundImage;
/**
*通常状态下的最佳尺寸
*/
privateDimensionpreferredSize;
/**
*鼠标光标在上方时的背景图片
*/
privateIconrolloverBackgroundImage;
/**
*鼠标光标在上方时的最佳尺寸
*/
privateDimensionrolloverPreferredSize;
/**
*按钮被按下时的背景图片
*/
privateIconpressedBackgroundImage;
/**
*按钮被按下时的最佳尺寸
*/
privateDimensionpressedPreferredSize;
/**
*按钮被禁止时的背景图片
*/
privateIcondisabledBackgroundImage;
/**
*按钮被禁止时的最佳尺寸
*/
privateDimensiondisabledPreferredSize;
/**
*当前按钮的最佳尺寸
*/
privatevolatileDimensioncurrentSize;
/**
*通常状态下按钮的图标
*/
privateIconicon;
/**
*按钮被禁止时的图标
*/
privateIcondisabledIcon;
/**
*按钮图标出现的位置
*/
privateIconOrientationiconOrientation=IconOrientation.WEST;
/**
*按钮的默认尺寸
*/
privatestaticfinalDimensionDEFAULT_SIZE=newDimension(100,25;
/**
*水平偏移量
*/
privateinthorizontalOffset=DEFAULT_HORIZONTAL_OFFSET;
/**
*默认的水平偏移量
*/
privatestaticfinalintDEFAULT_HORIZONTAL_OFFSET=4;
/**
*垂直偏移量
*/
privateintverticalOffset=DEFALUT_VERTICAL_OFFSET;
/**
*默认的垂直偏移量
*/
privatestaticfinalintDEFALUT_VERTICAL_OFFSET=2;
/**
*显示在按钮上的文字
*/
privateStringtext;
/**
*按钮文本的字体
*/
privateFontfont;
/**
*按钮文本的默认字体
*/
privatestaticfinalFontDEFAULT_FONT=Font.decode("Dialog-Plain-14";
/**
*按钮被禁止时候文字的颜色
*/
privateColordisabledForeground;
/**
*默认的按钮被禁止时文本的颜色
*/
privatefinalColorDEFAULT_DISABLED_FOREGROUND=newColor(192,192,192;
/**
*按钮的状态
*/
privatevolatileStatusstatus=Status.DEFAULT;
/**
*按钮的颜色透明度
*/
privatevolatilefloatalpha=1.0f;
privatestaticHashMaprenderingHints;
/**
*按钮执行的动作
*/
privateActionaction;
static{
renderingHints=newHashMap(;
renderingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY;
renderingHints.put(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON;
renderingHints.put(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY;
renderingHints.put(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_DISABLE;
renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON;
renderingHints.put(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC;
renderingHints.put(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE;
renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON;
}
/**创建一个ImageButton按钮的实例*/
publicImageButton({
currentSize=DEFAULT_SIZE;
addMouseListener(this;
addMouseMotionListener(this;
}
/**
*设置常规状态下按钮的背景。
调用该方法会影响到按钮在常规状态下的最佳尺寸,
*由传入的图标参数对应的图标尺寸决定
*@parambackgroundImage常规状态下背景图标对象
*@throwsjava.lang.IllegalArgumentException如果传入的参数为null
*/
publicvoidsetBackgroundImage(IconbackgroundImagethrowsIllegalArgumentException{
if(backgroundImage==null{
thrownewIllegalArgumentException("backgroundImagecan'tbenull";
}
this.backgroundImage=backgroundImage;
preferredSize=newDimension(backgroundImage.getIconWidth(,
backgroundImage.getIconHeight(;
currentSize=preferredSize;
}
/**
*设置被禁用状态下按钮的背景。
调用该方法会影响到按钮在禁用状态下的最佳尺寸,
*由传入的图标参数对应的图标尺寸决定
*@paramdisabledBackgroundImage禁用状态下背景图标对象
*@throwsjava.lang.IllegalArgumentException如果传入的参数为null
*/
publicvoidsetDisabledBackgroundImage(IcondisabledBackgroundImagethrowsIllegalArgumentException{
if(disabledBackgroundImage==null{
thrownewIllegalArgumentException(
"disabledBackgroundImagecan'tbenull";
}
this.disabledBackgroundImage=disabledBackgroundImage;
disabledPreferredSize=newDimension(disabledBackgroundImage
.getIconWidth(,disabledBackgroundImage.getIconHeight(;
}
/**
*设置在被按下状态时按钮的背景。
调用该方法会影响到按钮在被按下状态时的最佳尺寸,
*由传入的图标参数对应的图标尺寸决定
*@parampressedBackgroundImage被按下时的背景图标对象
*@throwsjava.lang.IllegalArgumentException如果传入的参数为null
*/
publicvoidsetPressedBackgroundImage(IconpressedBackgroundImagethrowsIllegalArgumentException{
if(pressedBackgroundImage==null{
thrownewIllegalArgumentException(
"pressedBackgroundImagecan'tbenull";
}
this.pressedBackgroundImage=pressedBackgroundImage;
pressedPreferredSize=newDimension(pressedBackgroundImage
.getIconWidth(,pressedBackgroundImage.getIconHeight(;
}
/**
*设置鼠标指针在其上方时按钮的背景。
调用该方法会影响到按钮在鼠标指针在其上方
*时的最佳尺寸,由传入的图标参数对应的图标尺寸决定
*@paramrolloverBackgroundImage鼠标指针在其上方时的背景图标对象
*@throwsjava.lang.IllegalArgumentException如果传入的参数为null
*/
publicvoidsetRolloverBackgroundImage(IconrolloverBackgroundImagethrowsIllegalArgumentException{
if(rolloverBackgroundImage==null{
thrownewIllegalArgumentException(
"rolloverBackgroundImagecan'tbenull";
}
this.rolloverBackgroundImage=rolloverBackgroundImage;
rolloverPreferredSize=newDimension(rolloverBackgroundImage
.getIconWidth(,rolloverBackgroundImage.getIconHeight(;
}
/**
*设置水平偏移量。
*@paramhorizontalOffset水平偏移量
*@throwsjava.lang.IllegalArgumentException如果参数小于0,抛出此异常
*/
publicvoidsetHorizontalOffset(inthorizontalOffsetthrowsIllegalArgumentException{
if(horizontalOffset<0{
thrownewIllegalArgumentException("horizontalOffsetmust>=0";
}
this.horizontalOffset=horizontalOffset;
}
/**
*设置垂直偏移量
*@paramverticalOffset垂直偏移量
*@throwsjava.lang.IllegalArgumentException如果参数小于0,抛出此异常
*/
publicvoidsetVerticalOffset(intverticalOffsetthrowsIllegalArgumentException{
if(verticalOffset<0{
thrownewIllegalArgumentException("verticalOffsetmust>=0";
}
this.verticalOffset=verticalOffset;
}
/**
*设置按钮的图标
*@paramicon图标对象
*@throwsjava.lang.IllegalArgumentException如果传入的参数为null,抛出此异常
*/
publicsynchronizedvoidsetIcon(IconiconthrowsIllegalArgumentException{
if(icon==null{
thrownewIllegalArgumentException(
"iconcan'tbenull";
}
this.icon=icon;
}
/**
*设置按钮在被禁用时显示的图标
*@paramdisabledIcon图标对象
*@throwsjava.lang.IllegalArgumentException如果传入的参数为null,抛出此异常
*/
publicsynchronizedvoidsetDisabledIcon(IcondisabledIconthrowsIllegalArgumentException{
if(disabledIcon==null{
thrownewIllegalArgumentException(
"disabledIconcan'tbenull";
}
this.disabledIcon=disabledIcon;
}
publicvoidsetIconOrientation(IconOrientationiconOrientationthrowsIllegalArgumentException{
if(iconOrientation==null{
thrownewIllegalArgumentException(
"iconOrientationcan'tbenull";
}
this.iconOrientation=iconOrientation;
}
publicvoidsetDisabledForeground(ColordisabledForeground{
this.disabledForeground=disabledForeground;
}
/**
*设置按钮的透明度
*@paramalpha透明度。
范围在0.0f~1.0f之间。
0.0f为完全透明,1.0f为完全显示
*@throwsjava.lang.IllegalArgumentException如果不在0.0f~1.0f之间会抛出此异常
*/
publicsynchronizedvoidsetAlpha(floatalphathrowsIllegalArgumentException{
if(alpha<0f||alpha>1.0f{
thrownewIllegalArgumentException(
"alphavaluemustbetween0.0and1.0";
}
this.alpha=alpha;
repaint(;
}
/**
*设置按钮显示的文本
*@paramtext显示的文本字符串
*/
publicsynchronizedvoidsetText(Stringtext{
if(text!
=null{
this.text=text;
repaint(;
}
}
/**
*返回按钮的当前字体,如果之前没有设置字体,则返回默认字体
*@return按钮的当前字体
*/
publicFontgetFont({
if(font==null{
returnDEFAULT_FONT;
}
returnfont;
}
/**
*设置按钮的当前字体
*@paramfont字体实例
*/
publicvoidsetFont(Fontfont{
this.font=font;
super.setFont(font;
}
/**
*指定这个按钮的动作
*@paramaction按钮的动作
*/
publicvoidsetAction(Act