昨天晚上写完Swing的模型和渲染器之后,觉得对Swing的体系结构还是没有说清楚。Swing的基础体系结构中的四大基本对象Component、
Model、UI
Delegate以及Renderer都值得详细解释。Swing的树状组件结构(虽然这是用户界面工具通有的特征)也值得详细解释,因为这是完成某些复
杂Swing组件,尤其像JTable、JTree、JList和JComboBox这种复杂组件中编辑功能得关键。此外,Swing /
AWT的事件模型如Event
Dispatching和Propagation和事件处理线程模型也需要详细解释,理解这部份是编写高效率Swing界面的关键。
今天从Swing的四大基本对象Component说起。
====================================
Component在Swing的MVC模型中担任Controller的角色,同时它也是Swing
API中代表具体组件的对象。Component在Swing中对外负责提供API接口,对内负责协调控制Model和UI
Delegate(有时可能还包括Renderer)的操作,可以说是整个Swing结构的中心角色。为了方便你回忆Swing的MVC模型,特地将上一
篇文章中的Swing模型示意图引了过来:
Component代表Swing对应用程序提供了如下几类编程接口:
- 用户界面的组件树的创建和修改的方法。这包括组件的添加和删除等操作。
- 组件属性访问的方法,比如组件位置、组件前后背景色、组件字体等等。
- 组件状态及生命周期的管理的方法,比如隐藏和显示、创建和销毁等等。
- 组件位置、大小的管理,包括通过布局管理器的方法。
- 组件事件处理接口的管理,包括添加、删除等操作。
从开发者的角度来看,Component是组件树上的节点、是控制外观和行为的入口、是组件事件的发源地。从Swing组件实现者的角度来看,
Component是协调Model和UI
Delegate的操作的地方,是低层次事件处理的地方,是高层事件发生的地方,是同父组件和子组件交互的地方。掌握的这些角度,Swing程序员完全可
以实现自己的自定义简单组件,当然如需要实现类似于JTable和JTree等复杂的矢量组件,还需要进一步了解Swing的Model和UI
Delegate以及Renderer模型。
对于复合型(Composite)组件很简单,这儿要讲述的是如何实现自定义的组件,比如表盘,比如温度计这些没有标准组件可以使用的组件,那么如何自己实现这种自定义组件呢?
不考虑Model分隔和UI
Delegate皮肤分离问题,能够简化自定义Component的模型。总的来说自定义组件需要完成两样基本任务:第一侦听并处理低层事件,根据具体情
况改变组件状态,如需要还要发出高级事件;第二,根据当前组件的状态画出当前组件的外观。
侦听底层的事件是指侦听类似于mouse、keyboard、focus等事件,然后处理此事件,如果发现此事件带有特定语义,表达某种组件行为,则改变
当前的组件状态以记录,并触发某种事件通知应用程序进行处理。举例说明,想象你准备实现一个简单的按钮,你可以通过继承JComponent来完成。你可
以在按钮初始化时,注册此按钮的鼠标事件侦听器,以侦听发生自己组件上的鼠标事件。当按钮捕获到鼠标按下时,检查鼠标按下的点是否在按钮有效区域内。如果
是,则认为当前是一个按钮按下动作,那么改变按钮的状态为按下去,调用repaint方法通知按钮重画成按下去的状态,然后发出
ActionPerformed的事件,通知注册在此按钮上的应用程序的ActionListener处理这个动作。下面是一个简单示意代码:
public class MyButton extends Jcomponent implements MouseListener{
private String text;
private boolean pressed=false;
private ArrayList<ActionListener> listeners=new ArrayList<ActionListener>();
public MyButton(){
addMouseListener(this);//将自己注册为自己的鼠标事件侦听器,监听鼠标事件
}
....
public void mousePressed(MouseEvent evt){
Point p=evt.getPoint();
if(getBounds().contains(p)){//判断鼠标落点是否在有效区域内。
pressed=true; //鼠标点击的含义是按钮被按下!改表按钮状态。
repaint(); //通知按钮重画,由原来的抬起状态改变成按下状态。
fireActionPerformed(new ActionEvent(this)); //这是一个按钮动作事件,触发它。
}
}
public void addActionListener(ActionListener listener){
listeners.add(listener);
}
public void removeActionListener(ActionListener listener){
listeners.remove(listener);
}
protected fireActionPerformed(ActionEvent evt){
for(ActionListener listener:listeners){
listener.actionPerformed(evt);
}
}
...
//这儿你要覆盖paint方法,实现按钮状态的重画
public void paint(Graphics g){
if(pressed){
//画出按下的样子
}else{
//画出抬起的样子
}
}
}
上面要注意的是你要自己管理自定义组件的事件监听器,包括addListener和removeListener方法,以及如何触发。这个过程很简单,基本上就是上面的模板来实现添加删除和触发。
除了要负责事件的处理和新事件的触发,自定义组件第二个要完成的任务就是要根据组件当前的状态改变重画组件的外观。重画组件的外观只需要覆盖public
void paint(Graphics g)方法即可以,在这个方法里,你只需要根据当前的组件状态分别画出当前的组件即可。
当然除了上面两个基本准则外,不要忘了添加访问你的组件属性的方法,比如,如果上面的按钮是个二元按钮(相当于
JCheckbox/JToggleButton的那种按钮),你可能需要提供isPressed或者setPressed来获取和设置当前按钮的状态。
注意,在设置状态按钮变化的访问方法中,比如setPressed,你需要使用repaint方法通知按钮重新渲染(复杂的实现可能包括触发
propertyChange事件,这儿从简):
public void setPressed(boolean p){
pressed=p;
repaint();
}
到此为止,你已经能根据上面的两条准则简单的实现你想要的组件了。但是你发现没有,你的按钮状态和外观行为都被堆到了Component
(MyButton)中实现了,而且,对于各个平台都是一个样子,不能换皮肤。这对于比较简单、不想要皮肤的组件,可能没有什么,但是对于复杂的组件,比
如JTable或者甚至Excel类似的电子表格的那种组件,你把数据(组件状态)和外观堆在这儿实现就严重违反了MVC原则。
如何简化这种组件的实现呢?使你实现的此种组件容易维护、扩展以及重用,皮肤容易换呢?这就需要Swing结构中的另外三个元素:Model、UI
Delegate和Renderer,后面的几个文章将讲述Model、UI
Delegate和Renderer帮你逐步实现一个复杂、灵活、可扩展、高效的矢量组件。
=====================================================
今天这样讲,不知道讲明白没有。当初刚开始学习Swing的时候,还不了解Swing的这种MVC结构,因此当时自己做的自定义组件都是这样写的,没有单
独的Model和可以定制的UI
Delegate,更不用说Renderer了。但是我觉得自己的这个学习过程,恰恰是人们学习Swing的最佳途径,先简化模型,然后逐步扩展,直到了
解Swing模型的全部图像
相关推荐
### Swing框架定制Component详解 Swing作为Java图形用户界面(GUI)编程的重要组成部分,提供了丰富的组件库和灵活的自定义选项。本文旨在深入探讨Swing框架中Component的定制方法,特别是GUI的绘制机制以及Swing的...
11. **Swing框架之Component**:"Swing框架之Component.txt"可能深入讨论了Component类,它是所有Swing组件的基类,包含了一些基本的属性和方法,如可见性、尺寸、位置等。 以上就是基于给定的文件名和描述所推断出...
Swing框架是Java GUI开发中的一个重要部分,它是建立在AWT(Abstract Window Toolkit)之上,提供了更丰富的组件和更现代的用户界面。Swing使用Java2D API来绘制组件,确保了平台独立性,使得在不同操作系统上都能...
- **Swing概述**:Swing是Java中用于构建GUI应用程序的一个轻量级组件库,它是建立在AWT基础之上的一个高级框架。Swing组件不仅提供了更丰富的功能,而且在不同操作系统上具有一致的表现形式,这主要得益于Swing采用...
根据给定的信息,本文将详细解释如何在Java Swing框架中创建具有圆角效果的自定义按钮。这将涉及Swing的基本概念、自定义组件的方法以及如何实现特定的视觉效果。 ### Swing简介 Swing是Java平台的一个图形用户...
`JComponent`是Swing组件层次结构的基础,它扩展了AWT的`Component`类,添加了许多高级特性,如内置的事件处理、可定制的外观(LookAndFeel)以及丰富的组件属性。通过`JComponent`,开发者可以方便地自定义组件的...
2. **组件体系结构**: Swing组件基于JComponent类,它是AWT Component类的子类。JComponent类提供了事件处理、定制外观和行为的能力。例如,JButton、JLabel、JFrame、JPanel等都是JComponent的子类。 3. **布局...
基于SWing,聊天软件的框架。 可以重用,基本修改,是改变了所有的透明特性。
在Swing框架中,`JTable`是构建GUI应用程序中表格的主要组件。它继承自`JComponent`类,这使得`JTable`能够支持丰富的图形用户界面功能。下面展示了`JTable`的类层次结构: 1. `java.lang.Object` - `java.awt....
例如,可以使用JUnit或TestNG等单元测试框架,结合Swing提供的`Robot`类来模拟键盘和鼠标操作,配合窗体抓取技术,实现对GUI应用的自动化测试。 在这个项目中,"AmsSwing"可能是项目的源代码文件夹,包含了实现窗体...
本项目“Java Swing中使用Spring技术”展示了如何在Swing应用中集成Spring框架,以实现更加模块化和可维护的代码结构。通过这种方式,开发者可以在Swing界面中利用Spring的强大功能,如管理对象的生命周期、处理事务...
Java Swing是Java平台的一个图形用户界面(GUI)工具包,它构建于AWT之上,并提供了一系列更丰富、更强大的组件来帮助开发者创建美观且功能丰富的应用程序。Swing不仅支持基本的GUI组件如按钮、文本框等,还提供了更...
本项目通过Swing框架实现了一个动态演示排序过程的应用程序。主要目标是让用户能够直观地看到各种排序算法(例如冒泡排序、插入排序等)在数组上的执行过程。 #### 二、程序结构分析 ##### 1. `AlgorithmAnimation...
Swing则是在AWT之上构建的,它使用纯Java实现,因此提供了更好的跨平台一致性。Swing组件不仅比AWT更丰富,还支持自定义外观,这使得实现换肤成为可能。 Swing的外观(LookAndFeel)机制允许开发者通过更换不同的...
Swing的类层次结构非常丰富,从Java.awt.Component开始,到特定的Swing组件如JButton、JLabel等,这些组件都继承自Container类,进一步扩展了AWT的组件功能。Swing还包含多个辅助包,如javax.swing.table用于支持...
在Java Swing中,组件(Component)是GUI的基础,它们是用户可以看到和交互的对象。每个组件都有其特定的功能和行为。例如: 1. **JFrame**: 是Swing中最基本的容器,用于承载其他组件。它是大多数Swing应用程序的...
本文将深入探讨Swing框架中处理键盘事件的不同机制,并详细介绍如何实现这些功能。 #### 二、键盘事件处理的历史演变 在不同版本的Java Development Kit (JDK)中,处理Swing组件键盘事件的方式有所变化。从JDK 1.2...
本篇文章對 Java Swing 的目录进行了详细的介绍,為讀者提供了一个总体的了解 Java Swing 的框架结构。 第2篇 Java Swing大神必经之路2:啃透JDK源码-JCheckBox详解 本篇文章详细介绍了 JCheckBox 的继承体系和常用...
Swing用户界面设计是Java...总的来说,Swing用户界面设计提供了一个强大而灵活的框架,用于构建功能丰富的Java应用程序。通过深入理解和熟练掌握Swing,开发者可以创建出符合现代用户需求的、具有吸引力的图形界面。