java - SWT Shell KeyListener

标签 java javafx swt eclipse-rcp jface

1.) 目标

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

这对我来说就是一个Shell

Mac screenshot of the quick preview


2.) 细节

  • 预览小部件将是附加到 StructuredViewerAPPLICATION_MODAL Shell

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

  • 我希望能够在 ESCSPACE 上关闭此 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/

相关文章:

JavaFX TextArea - 调整大小时不需要的滚动条

java - 显示 3 张随机卡 JavaFX

java - 将自定义对象绑定(bind)到 JMS MapMessage

java - Kotlin 如何将 val 作为 java 类的关键字

java - 理解 Play 2.4 依赖注入(inject)

java - 使用自定义标题栏管理 Windows Aero 震动功能

java - SWT.CHECK 上的交叉图像

swt - 如何确定 JFace TreeViewer 或 SWT Tree 的首选大小?

java - 如何配置 NatTable FilterComboBox 为每列使用不同的 DataProvider

java - 在 Hibernate 中映射 oracle 的 UserType 列