Swing学习笔记(1)拖-放:基本原理

来源:互联网 发布:ubuntu 终端打不开 编辑:程序博客网 时间:2024/05/22 10:31

Swing对于拖放的支持是内置的,功能很强大,很多控件都内置了拖放操作的支持,包括:JColorChooser、JEditorPane、JFileChooser、JFormattedTextField、JList、JTable、JTextArea、JTextField、JTextPane、JTree。而copy-paste在Swing中也属于拖放操作的范畴。不过,默认情况下,Swing组件的拖放功能是被关闭的,需要调用组件的setDragEnabled(true)函数才能够启用。拖放功能被启用之后,对于多数Swing控件(包括JEditorPane、JFormattedTextField、JPasswordField、JTextArea、JTextField、JTextPane、JColorChooser)来说,程序员不需要做什么事情了,因为Swing已经为程序员做掉了通常该做的事情。但是对于诸如JList、JTree、JTable这三个组件来说,程序员还得写一点点代码才行。按照Swing文档里面的说法,这是因为这三个控件的拖放操作缺乏统一的操作标准,导致Swing设计者在为这三个控件设计Drop操作支持的时候感觉无所适从。我觉得其实并不是测三个控件缺乏统一的操作标准,而是因为这三种控件可处理的对象太过复杂,从字符串到图像到文件列表到数据库字段等等,而对于每一种对象,处理的代码都会千差万别,所以没办法用单一的代码提供支持也是很正常的。

不过,即便如此,Swing也为JList、JTree、JTable这三个组件的拖放操作提供了公共的框架,程序员无需关心拖放的操作细节,只需要编写拖放操作完成后该如何处理这些业务对象的代码即可。Swing的框架其实只有一个类:javax.swing.TransferHandler。程序员只需要重写这个类的几个方法即可。同样,倘若程序员觉得Swing内置的拖放支持不符合自己的需求,那么也可以继承javax.swing.TransferHandler类,并重写相应的方法,然后调用组件的setTransferHandler方法设置新的“传输处理器”即可。

在开始定义自己的TransferHandler之前,必须得弄明白Swing的拖放操作的原理。

下图取自Swing的教程,是一个从列表控件向文本框拖放的例子。


当用户选择列表框中的一个(或多个)条目,按下鼠标键,并开始拖动时,JList控件会将被选中的条目封装起来以备传送(Transfer),同时,还要向Swing的拖放框架指明自己支持何种拖放操作(称之为Source Action),诸如COPY、MOVE等。倘若用户在拖动鼠标的同时按下了CTRL键、ALT键或SHIFT键(或者这三者的组合),则这种组合(称之为User Action)亦被Swing记录下来。

在用户拖动鼠标的过程中,Swing连续计算鼠标指针拖动的位置,并且在屏幕上绘制拖放光标。

当鼠标光标拖过文本框的时候,文本框组件就不断查询判断是否可以接受对自己的“放”操作。同时,文本框组件还向用户提供某种反馈以指示当前的drop位置,例如,可能会出现一个“插入”光标,或者某些内容被自动选中。

当用户在文本框上方松开鼠标键时,文本框控件获取“source action”和“user action”,并决定如何处理这种actions。文本框控件的标准行为是将拖放过来的内容插入到当前光标所在位置。

最后,文本框将Swing拖放框架中封装的数据“导入”进来,并显示出来。

原创粉丝点击