Java桌面技术

Java Desktop Technology

常用链接

统计

友情连接

最新评论

自定义组件之Button

前面已经向大家介绍过《用SWT实现MSN风格的下拉框》、《SWT自定义组件之Slider》,现在再编写一个最常用的自定义组件——Button。

GUI组件要完成的任务有2个,展现与业务。对于按钮来说,文本、图标、边框、背景属于展现层,而这些元素在按钮不同状态下会不尽相同,一般来说至少有4种状态下的展现:普通、鼠标放在其上、被按下、被禁用,也就是按钮应该具备这4种状态。
下面给出的示例是swing实现的自定义按钮。
通常swing自定义组件继承javax.swing.JComponent并重写protected void paintComponent(Graphics g)方法实现自定义绘制。重写paintComponent方法时通常要先去掉super.paintComponent(g),因为父方法调用会绘制背景色。不妨先看一下源代码中的调用过程。
在JComponent.java中paintComponent(Graphics g)方法定义如下:
protected void paintComponent(Graphics g) {
        if (ui != null) {
            Graphics scratchGraphics = (g == null) ? null : g.create();
            try {
                ui.update(scratchGraphics, this);
            }
            finally {
                scratchGraphics.dispose();
            }
        }
    }
其中ui的声明如下
protected transient ComponentUI ui;
然后转向ComponentUI的update(Graphics g, JComponent c)方法:
 public void update(Graphics g, JComponent c) {
 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()来刷新。
然后重要的一点是你必须重写public Dimension getPreferredSize()来获得按钮的最佳尺寸。getPreferredSize方法对于布局管理器来说至关重要,布局管理器会通过getPreferredSize的判断组件的最佳大小,并进行布局。而对于本范例而言,getPreferredSize的大小只和背景图片大小有关。

对于业务,尽量做到前台界面与后来业务分离。你可以自定义按钮动作监听器来实现,本例是沿用swing的Action实现,当鼠标抬起时,构造一个ActionEvent对象,然后交给Action成员的actionPerformed(ActionEvent e)处理。

范例源代码这里下载

posted on 2007-11-11 15:33 sun_java_studio@yahoo.com.cn(电玩) 阅读(5467) 评论(4)  编辑  收藏 所属分类: Swing

评论

# re: 自定义组件之Button 2007-11-13 11:32 Matthew Chen

有个问题请教楼主,如何实现jtree针对不同节点的组件有不同的行高度,我现在被这个问题困扰了很久,想用拖拽来改变节点的行高,在DefaultTreeCellRenderer里处理重绘出来,但是在里面用setSize()怎么改都不行,网上没搜到这样的例子。  回复  更多评论   

# re: 自定义组件之Button 2007-11-13 13:38 sun_java_studio@yahoo.com.cn(电玩)

hehe,你在http://blogs.sun.com/Swing/entry/that_s_almost_what_i也提问了啊。  回复  更多评论   

# re: 自定义组件之Button 2007-11-13 13:49 Matthew Chen

是啊,TreeCellRenderer提供组件只用来实现节点本身的绘制,但节点所占的空间大小却不知用什么设置,我试过tree的getPathBounds()方法,好像也不是,哎。  回复  更多评论   

# re: 自定义组件之Button 2007-11-13 14:03 sun_java_studio@yahoo.com.cn(电玩)

@Matthew Chen
我在http://blogs.sun.com/Swing/entry/that_s_almost_what_i
上面回复了。  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
TWaver中文社区