问题描述:
在Eclipse插件开发过程中,都会涉及到“弹出对话框”的问题,今天偶然发现了一个现象:弹出的对话框打开后,再按ESC键,对话框自动就关闭了。后来发现在Eclipse中也是一样的。比如创建一个类的时候,弹出对话框以后按ESC,对话框就直接关闭了。这样设计主要是为了方便用户,可是当我们不需要这样的效果的时候,应该怎么做呢?
问题分析:
在Eclipse中,在键盘上按下的每一个键,都会触发相应的事件,Eclipse拦截到事件后,再进行后续的处理。再回到我们上面提到的问题: 既然对话框是在按ESC键后关闭的,那我们很自然的想到:如果能够屏蔽按下ESC键触发的事件,对话框应该就不会关闭了。
解决方案:
经过上面的分析,问题已经清楚了:为了解决这个问题,我们需要搞定下面的两件事儿:
1、找到按ESC时触发的事件;
2、拦截这个事件,不让事件生效(相当于用户没按ESC)。
感谢万能的Google大神,我们找到了这个接口:TraverseListener。上源码:
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.events;
import org.eclipse.swt.internal.SWTEventListener;
/**
* Classes which implement this interface provide a method
* that deals with the events that are generated when a
* traverse event occurs in a control.
* <p>
* After creating an instance of a class that implements
* this interface it can be added to a control using the
* <code>addTraverseListener</code> method and removed using
* the <code>removeTraverseListener</code> method. When a
* traverse event occurs in a control, the keyTraversed method
* will be invoked.
* </p>
*
* @see TraverseEvent
*/
public interface TraverseListener extends SWTEventListener {
/**
* Sent when a traverse event occurs in a control.
* <p>
* A traverse event occurs when the user presses a traversal
* key. Traversal keys are typically tab and arrow keys, along
* with certain other keys on some platforms. Traversal key
* constants beginning with <code>TRAVERSE_</code> are defined
* in the <code>SWT</code> class.
* </p>
*
* @param e an event containing information about the traverse
*/
public void keyTraversed(TraverseEvent e);
}
从描述中可以看出,这个接口是专门用来监听特殊按键的。具体的信息大家可以自己去看SWT的源码。
第一个问题已经解决,我们看看怎么样拦截ESC:
public void keyTraversed(TraverseEvent e) {
if(e.detail == SWT.TRAVERSE_ESCAPE){
e.doit = false;
}
}
根据detai可以判断出来按下的是ESC,然后将doti设定为false就可以了。
拦截ESC的代码已经有了,还剩最后一个问题:监听器只有注册了之后才能生效,那这个监听器我们在哪里注册呢?
还是看源码,在面板类Composite以及Shell中,提供了接口addTraverseListener,通过这个借口,我们就可以注册监听器了。
总结:
1、在创建页面的时候,我们可以在将监听器注册到根面板(root composite)中;
2、如果页面是通过继承Dialog类来实现,可以在createDialogArea方法中注册监听;
3、如果页面作为向导页(继承WizardPage),可以在createControl方法中注册监听。
声明:
文章来自于ITeye,欢迎访问我的博客:xiaoyu1985ban.iteye.com
ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。若作者同意转载,必须以超链接形式标明文章原始出处和作者。