1.) 目标
OSX 的文件快速预览小部件。基本上,在 Mac 上,当您选择一个文件并按空格键时,您可以快速预览该文件。我正在尝试使用 SWT+JFace(可能是 JavaFX)复制该功能。
这对我来说就是一个Shell
。
2.) 细节
预览小部件将是附加到
StructuredViewer
的APPLICATION_MODAL
Shell
。我不想在每次打开预览时都重新创建
Shell
。我只想把它隐藏起来。这应该是一个快速预览。我希望能够在 ESC 和 SPACE 上关闭此
Shell
。我处理多种类型的文件(PDF、JPEG、PNG、TXT 等),因此每个文件都有自己的预览组件。
Shell
知道如何在这些组件之间切换。此组件不能修改任何文件,只能预览它们。我用来构建预览的组件是另一回事。
3.) 问题
由于
Shell
有直接子级,这些子级可能会“窃取”焦点并获取KeyEvent
。因此,Shell
不知道如何关闭键盘事件。我不想添加
Display
过滤器。每次显示/隐藏Shell
时,我都必须添加/删除它们。另外,这些非常危险,因为它是一个巨大的 RCP 应用程序,它可能会影响其他工作台部件(如果由于某种原因未删除过滤器)。
4.) 中南合作商会
在下面的示例中,您可以观察到一旦 Text
获得焦点,Shell
就无法夺回焦点,并且不会向其发送关键事件不再。
/**
*
* @author ggrec
*
*/
public class SSCCE_ShellWithShellParent
{
// ==================== 1. Static Fields ========================
private static final int CHILD_SHELL_STYLE = SWT.BORDER | SWT.RESIZE | SWT.TITLE | SWT.CLOSE | SWT.APPLICATION_MODAL;
// ==================== 3. Static Methods ====================
public static void main(final String[] args)
{
new SSCCE_ShellWithShellParent();
}
// ==================== 4. Constructors ====================
private SSCCE_ShellWithShellParent()
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final Shell childShell = new Shell(shell, CHILD_SHELL_STYLE);
childShell.setLayout(new FillLayout());
childShell.pack();
createChildContents(childShell);
final KeyAdapter keyListener = new KeyAdapter()
{
@Override public void keyPressed(final KeyEvent e)
{
final Object source = e.getSource();
if (source == shell)
System.out.println(e.keyCode);
else
System.err.println(e.keyCode);
// Escape
if (e.keyCode == 27)
shell.close();
// Spacebar
if (e.keyCode == 32 && e.getSource() == shell)
childShell.open();
}
};
childShell.addKeyListener(keyListener);
shell.addKeyListener(keyListener);
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
// ==================== 5. Creators ====================
private void createChildContents(final Shell childShell)
{
new Text(childShell, SWT.NULL);
}
}
5.) 长话短说
在不使用过滤器的情况下在 Shell
上添加 KeyListener
。
最佳答案
我有您第一个问题的答案。您可以:
使用
WHATEVER_CHILD.setFocusable(false);
方法从 shell 的子级移除焦点容量
通过添加 focuslistener,使 shell 请求在每次失去焦点时获得焦点:
YOUR_SHELL.addFocusListener(新的 FocusListener{ public void focusLost(FocusEvent e) { YOUR_SHELL.requestFocusOnWindow(); } });
我个人更喜欢第二种选择。
关于java - SWT Shell KeyListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24553010/