Java 外壳键侦听器 1)目标

Java 外壳键侦听器 1)目标,java,javafx,swt,eclipse-rcp,jface,Java,Javafx,Swt,Eclipse Rcp,Jface,OSX的文件快速预览小部件。基本上,在Mac上,当您选择一个文件并按空格键时,您可以快速预览该文件。我正试图用SWT+JFace(可能是JavaFX)复制这一功能 这对我来说是一个Shell 2)具体情况 预览小部件将是一个应用程序_模式外壳附加到结构视图 我不想每次打开预览时都重新创建Shell。我只想把它藏起来。这应该是一个快速预览 我希望能够在ESC和SPACE上关闭此Shell 我处理许多类型的文件(PDF、JPEG、PNG、TXT等),因此每个文件都有自己的预览组件。Shell知

OSX的文件快速预览小部件。基本上,在Mac上,当您选择一个文件并按空格键时,您可以快速预览该文件。我正试图用SWT+JFace(可能是JavaFX)复制这一功能

这对我来说是一个
Shell


2)具体情况
  • 预览小部件将是一个
    应用程序_模式
    外壳
    附加到
    结构视图

  • 我不想每次打开预览时都重新创建
    Shell
    。我只想把它藏起来。这应该是一个快速预览

  • 我希望能够在ESC和SPACE上关闭此
    Shell

  • 我处理许多类型的文件(PDF、JPEG、PNG、TXT等),因此每个文件都有自己的预览组件。
    Shell
    知道如何在这些组件之间切换

  • 此组件可能不会修改任何文件,只是预览它们。我用来构建预览的组件是另一回事


3)问题
  • 由于
    Shell
    具有直接子对象,这些子对象可能会“窃取”焦点并获取
    KeyEvent
    s。因此,
    Shell
    不知道如何关闭键盘事件

  • 我不想添加
    显示
    过滤器。每次显示/隐藏
    Shell
    时,我都必须添加/删除它们。另外,这些都是非常危险的,因为它是一个巨大的RCP应用程序,并且可能会影响其他工作台部件(如果由于某种原因没有移除过滤器)


4)SSCCE 在下面的示例中,您可以观察到,一旦
文本
具有焦点,
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)TL;博士
在不使用过滤器的
外壳上添加
KeyListener

我有关于您的第一个问题的答案。你可以:

  • 使用方法
    which\u CHILD.setFocusable(false)移除shell子对象的聚焦能力

  • 通过添加focuslistener,使shell请求在每次丢失时保持焦点:
    YOUR_SHELL.addFocusListener(新FocusListener{
    公共无效焦点丢失(焦点事件e){
    您的_SHELL.requestFocusOnWindow();
    }
    });


我个人更喜欢第二种选择。

+1期待这里有一个好的答案(如果有的话)。这是一个huuuuge drop shadow btw…您找到解决方案了吗?
setFocusable(布尔值)
requestFocusOnWindow()
在SWT中不存在