IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Open source  >

基于 JFace Text Framework 构建全功能代码编辑器: 第 3 部分

Double Click 和 Triple Click

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

样例代码


级别: 中级

马 若劼 (maruojie@cn.ibm.com), 软件工程师, IBM 中国软件开发中心

2008 年 3 月 27 日

Double Click(双击)和 Triple Click(三击)是方便用户选择文本(当然不一定非得是选择文本)的辅助功能。本文介绍在 JTF 里面如何自定义双击行为,以及如何为 JTF 添加三击支持。

Double Click(双击)和 Triple Click(三击)是方便用户选择文本(当然不一定非得是选择文本)的辅助功能。本文介绍在 JTF 里面如何自定义双击行为,以及如何为 JTF 添加三击支持。

Double Click

在 Eclipse 的 Java 编辑器中,用户用鼠标在编辑区域双击时,可以看到双击处的单词会被选中,这就是 JTF 的 Double Click(双击)特性。双击时触发的动作是可以自定义的,不一定非要选择一段文本。

与双击相关的接口是 ITextDoubleClickStrategy,它只有一个方法叫做 doubleClicked,只要实现这个接口就可以了,在例子中,我添加了 ExprDoubleClickStrategy 类:


清单1. ExprDoubleClickStrategy 实现了 ITextDoubleClickStrategy 接口
                
public class ExprDoubleClickStrategy implements ITextDoubleClickStrategy {
public void doubleClicked(ITextViewer viewer) {
		// get doc
	IDocument doc = viewer.getDocument();
		
		// get token list
	TokenList tokenList = TokenManager.getTokenList(doc);
		
		// get double click position
	int offset = viewer.getSelectedRange().x;
		
		// get token in that offset
	CommonToken token = tokenList.getToken(offset);
		
		// select whole token if token is not null
	if(token != null && token.getType() != Token.EOF)
		{
			// select double clicked token
		viewer.setSelectedRange(
		token.getStartIndex(), token.getStopIndex() - token.getStartIndex() + 1);
		}
	}
}

这个流程非常直接,得到被点击的位置,通过位置得到相应的符号,然后选择整个符号。我们再次利用了 TokenList 来得到指定字符偏移处的符号。

和本系列第二部分一样,有了实现还得让 JTF 知道你的实现,我们再来修改 ExprConfiguation,覆盖一个 getDoubleClickStrategy 方法:


清单2. 让 JTF 知道你的 Double Click 实现
                
      public ITextDoubleClickStrategy getDoubleClickStrategy(
	        ISourceViewer sourceViewer, String contentType) 
{
    return new ExprDoubleClickStrategy();
}

只是简单的返回我们实现的 ITextDoubleClickStrategy 而已,这样 JTF 就知道我们的双击行为了,注意双击行为也是和文本类型绑定到一起的,但是我们只有一种类型,所以没有利用这个信息。

读者可以尝试本文的例子,双击某个变量,看看是否这个变量被全部选中了。





回页首


Triple Click

有了双击,可能自然就会想到三击。但是 JTF 本身是不支持三击行为的。我们需要自己实现,只要模仿双击的机制来做就可以了。

接口

模仿双击的处理方式,我们也添加一个 ITextTripleClickStrategy 接口,如下所示:


清单3. 模仿 Double Click,创建 ITextTripleClickStrategy 接口
                
      public interface ITextTripleClickStrategy {
	/**
	 * Invoked when triple clicking detected
	 */
	public void tripleClicked(ITextViewer viewer);
}

然后我定义了 ExprTripleClickStrategy,它实现了 ITextTripleClickStrategy 接口。为了简单起见,我不添加具体代码了,只是显示一个对话框表示三击事件被我们捕捉到了。三击的时候具体做什么,读者有兴趣可以自己完成。

配置

下一步就是让 JTF 知道我们的三击策略,不过 SourceViewerConfiguration 没有和三击有关的方法,我们可以模仿 getDoubleClickStrategy 的形式添加一个 getTripleClickStrategy 方法,然后修改 ExprViewer 的 configure 方法,把三击策略安装上去。其实就是一个哈希表,里面把文本类型和三击策略映射了起来。这些代码都是模仿 SourceViewer 中对双击策略的处理方式写的,所以就不一一列举了。

事件的触发

最后的一步是触发三击事件,不然你装多少个三击策略也没用。从原理上说,三击事件就是鼠标双击之后又点了一下,我们可以监听双击事件,然后在下一次鼠标单击时检查其和双击事件的时间间隔,如果小于一个阈值,就触发三击事件。所以为了触发三击事件,我们需要给 ExprViewer 安装一个鼠标事件监听器:


清单4. 给 ExprViewer 添加三击事件触发机制
                
      // How long we can wait for triple click after double click
public static final long TRIPLE_CLICK_THRESHOLD = 500;
	
private class TripleClickStrategyConnector extends MouseAdapter {
	private long doubleClickTime;

	public TripleClickStrategyConnector() {
		doubleClickTime = 0;
	}

	@Override
	public void mouseDoubleClick(MouseEvent e) {
		doubleClickTime = System.currentTimeMillis();
	}

	@Override
public void mouseDown(MouseEvent e) {
		// compare time interval with threshold
  if (System.currentTimeMillis() - doubleClickTime <= TRIPLE_CLICK_THRESHOLD) {
  ITextTripleClickStrategy strategy = (ITextTripleClickStrategy) selectContentTypePlugin(
				getSelectedRange().x, tripleClickStrategies);
			if (strategy != null) {
				strategy.tripleClicked(ExprViewer.this);
			}
		}

		// clear double click time to avoid trigger triple click more than once
		doubleClickTime = 0;
	}
}

上面的代码实现了我所描述的逻辑,如果检测到三击事件,我们通知 ITextTripleClickStrategy。

到这里为止,我们的三击流程就跑完了。当然不止是三击,四击五击以至 N 击,就都可以这样实现了。





回页首


结束语

运行本文的例子之后会发现,三击后对话框确实出来了,但是文本选择区域发生了变化。这是因为 StyledText 内部做了一些事情,处理了我们的鼠标事件,如果完整的实现 ITextTripleClickStrategy 接口并设置我们想要的选择范围,这样的情况就不会出现了。至于三击之后可以做什么,我可以提供一个建议:以语句”abcde = 12345;”为例,双击 abcde 会选中 abcde,三击 abcde 则可以选中这条语句,即到分号为止的地方。我们可以从三击位置做一个扫描,直到前后碰到分号为止,有兴趣的读者可以尝试完善这个功能。





回页首


声明

本文仅代表作者的个人观点,不代表 IBM 的立场。






回页首


下载

描述名字大小下载方法
第三小节示例代码jtf.tutorial.part3.zip1130KBHTTP
关于下载方法的信息


参考资料



关于作者

马若劼是 Lotus Forms 部门的一位软件工程师,主要从事电子表单技术的研发工作。他在 Eclipse 和 Java 方面有多年研发经验,同时也是国内著名开源项目 LumaQQ 的创立者




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?







回页首


第 1 段商标声明。 第 2 段商标声明。 其他公司、产品或服务的名称可能是其他公司的商标或服务标志。

IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款