3

我试图用 JavaFX 的HTMLEditor组件做一些实验。我使用了以下代码(摘录):

    fxPanel=new JFXPanel();
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            Group group = new Group();
            scene = new Scene(group);               
            fxPanel.setScene(scene);
            view = VBoxBuilder.create().build();

            group.getChildren().add(view);


            edit = HTMLEditorBuilder.create().build();
           // toolPane = TabPaneBuilder.create().minHeight(60d).build();
            //toolPane.getTabs().add(new Tab("Allgemein"));

            view.getChildren().add(edit);

        }
    });

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            jPanel1.add(fxPanel);
        }
    });

到目前为止,它工作正常,但有一个重要的例外——我不能为 BR 使用返回键——它似乎只是被忽略了。这个键完全没有反应。据我所知,任何其他键都按预期工作。

4

4 回答 4

9

我注意到CTRL-在不M工作的地方工作。Enter所以我只是通过KeyListener在 JFXPanel 上放置一个来解决这个问题,将它KeyChar从 10 更改为 13 并将事件重新发布到系统事件队列。如果 HTMLEditor 开始同时响应两者ENTER,这可能会在稍后停止工作CTRLM尽管如此。

fxPanel.addKeyListener(new KeyListener() {

    public void keyTyped(KeyEvent e) {
        if (e.getKeyChar() == 10) {
            e.setKeyChar((char) 13);
            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e);
        }
    }

    public void keyPressed(KeyEvent e) {}

    public void keyReleased(KeyEvent e) {}
});

现在有人有更好的主意吗?

编辑:我发现另一种获得所需效果的方法是KeyEventDispatcher在当前键盘焦点管理器上安装自定义,如下所示:

KeyboardFocusManager kfm = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager();
kfm.addKeyEventDispatcher(new KeyEventDispatcher() {
    @Override
    public boolean dispatchKeyEvent(KeyEvent e) {
        if (DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == jfxPanel) {
            if (e.getID() == KeyEvent.KEY_TYPED && e.getKeyChar() == 10) {
                e.setKeyChar((char) 13);
            }
        }
        return false;
    }
});

这样做的好处是更改原始KeyEvent版本而不是之后发布新版本,因此如果HTMLEditor要开始响应Enter事件,我们就不会加倍。

于 2012-09-24T23:50:09.580 回答
4

我发现这是 JavaFX 中的一个已知错误。

https://javafx-jira.kenai.com/browse/RT-33354

http://javafx-jira.kenai.com/browse/RT-20887

但仅供参考,对于 JavaFX 2.2,它被解决为“不会修复”。JavaFX 8 中没有问题。

于 2012-07-04T12:14:11.167 回答
1

我仍然看到 Oracle JDK 10 的这个问题。窥视HTMLEditorSkin,有一个Command.INSERT_NEW_LINE,但按“Enter”时没有执行。原则上,有用于执行Command, 的 API 可以从关键事件过滤器中调用,但 API 是私有的。

以下是围绕此限制的破解。它“有效”,但它当然是一个 hack,可能会随着 JavaFX 的未来更新而中断:

HTMLEditor editor = /* .. somehow get the HTMLEditor .. */
editor.addEventFilter(KeyEvent.KEY_PRESSED, event ->
{
    if (event.getCode() == KeyCode.ENTER)
    {
        event.consume();
        final HTMLEditorSkin skin = (HTMLEditorSkin) htmlEditor.getSkin();
        try
        {
            // Use reflection to invoke the private method
            // executeCommand(Command.INSERT_NEW_LINE.getCommand(), null);
            final Method method = skin.getClass().getDeclaredMethod("executeCommand", String.class, String.class);
            method.setAccessible(true);
            method.invoke(skin, Command.INSERT_NEW_LINE.getCommand(), null);
        }
        catch (Throwable ex)
        {
            throw new RuntimeException("Cannot hack around ENTER", ex);
        }
    }
});
于 2018-07-24T16:23:42.627 回答
0

您可以通过过滤事件并将 <^m> 事件触发到 webview 来生成换行符

        // fix enter ignored on linux
    HTMLEditor editor = ...
    WebView editorView = (WebView) editor.lookup(".web-view");
    editor.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
        if (e.getCode() == KeyCode.ENTER) {
            e.consume();
            editorView.fireEvent(new KeyEvent(
                    e.getSource(),
                    editorView,
                    KeyEvent.KEY_TYPED,
                    "\r", "", KeyCode.ENTER,
                    false, true, false, false));
        }
    });
于 2019-12-18T22:32:21.610 回答