JavaFX HTMLEditor文本更改侦听器

时间:2014-03-02 13:27:08

标签: java javafx javafx-2

我是JavaFX世界的新手,我似乎无法弄清楚如何在 HTMLEditor 组件中监听 text-modify 事件。< / p>

我需要这个,因为我将这个小部件挂钩到需要更新的模型。

具有addEventFilter事件类型的KeyEvent.KEY_TYPED API似乎无法正常工作。调用其处理程序时,getHTMLText()尚未使用最新字符进行更新(如果有人不理解本段,我将提供逐步示例)。

TextField 有一个textProperty(),可以附加一个侦听器。
那么 HTMLEditor 呢?

此外,让侦听器仅在文本修改事件上调用(而不是在 CTRL + A 上)是很好的。你知道......就像SWT Text的addModifyListener()

3 个答案:

答案 0 :(得分:3)

在我的一个项目应用程序中使用JavaFX HTMLEditor时,我也遇到了类似的情况。我最后添加了一个button,点击后会发生HTML文本的解析,并执行进一步的任务。使用AnchorPane,我能够无缝地在HTMLEditor上添加button,它看起来就像是它的一部分。

无论如何,这里有一个小例子,说明如何在没有任何额外按钮的情况下达到你想要的效果:

package application;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.web.HTMLEditor;
import javafx.stage.Stage;

public class Main extends Application
{
  @Override
  public void start(Stage primaryStage)
  {
    try
    {
      final HTMLEditor editor = new HTMLEditor();
      Scene scene = new Scene(editor);
      primaryStage.setScene(scene);

      editor.setOnKeyReleased(new EventHandler<KeyEvent>()
      {
        @Override
        public void handle(KeyEvent event)
        {
          if (isValidEvent(event))
          {
            System.out.println(editor.getHtmlText());
          }
        }

        private boolean isValidEvent(KeyEvent event)
        {
          return !isSelectAllEvent(event)
              && ((isPasteEvent(event)) || isCharacterKeyReleased(event));
        }

        private boolean isSelectAllEvent(KeyEvent event)
        {
          return event.isShortcutDown() && event.getCode() == KeyCode.A;
        }

        private boolean isPasteEvent(KeyEvent event)
        {
          return event.isShortcutDown() && event.getCode() == KeyCode.V;
        }

        private boolean isCharacterKeyReleased(KeyEvent event)
        {
          // Make custom changes here..
          switch (event.getCode())
          {
            case ALT:
            case COMMAND:
            case CONTROL:
            case SHIFT:
              return false;
            default:
              return true;
          }
        }
      });

      primaryStage.show();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }

  public static void main(String[] args)
  {
    launch(args);
  }
}

更新: 经过一番思考,我找到了一种方法,即使按下这些按钮,也可以完成事件处理。方法如下:

EventHandler<MouseEvent> onMouseExitedHandler = new EventHandler<MouseEvent>()
{
  @Override
  public void handle(MouseEvent event)
  {
    System.out.println(editor.getHtmlText());
  }
};

for (Node node : editor.lookupAll("ToolBar"))
{
  node.setOnMouseExited(onMouseExitedHandler);
}

如果您看到HTMLEditor,则会有两个ToolBars 对于这两个工具栏,我在代码中所做的是looking up,并设置了onMouseExited事件处理程序。类比是,如果用户输入并对HTML文本进行一些更改并退出工具栏,则会触发一个事件,然后可以对其进行处理。

您甚至可以根据需要在这两个工具栏上设置不同类型的事件处理程序,但在我看来,这些onMouseExited事件处理程序在与onKeyReleased事件一起使用时提供了非常广泛的覆盖范围处理程序。但是基于onMouseExited处理程序的覆盖范围并不确切。

答案 1 :(得分:2)

这是一个简单的

public class HtmlEditorListener {
    private final BooleanProperty editedProperty;

    private String htmlRef;

    public HtmlEditorListener(final HTMLEditor editor) {
        editedProperty = new SimpleBooleanProperty();
        editedProperty.addListener((ov, o, n) -> htmlRef = n? null: editor.getHtmlText());
        editedProperty.set(false);

        editor.setOnMouseClicked(e -> checkEdition(editor.getHtmlText()));
        editor.addEventFilter(KeyEvent.KEY_TYPED, e -> checkEdition(editor.getHtmlText()));
    }

    public BooleanProperty editedProperty() {
        return editedProperty;
    }

    private void checkEdition(final String html) {
        if (editedProperty.get()) {
            return;
        }
        editedProperty.set(htmlRef != null
                && html.length() != htmlRef.length()
                || !html.equals(htmlRef));
    }
}

答案 2 :(得分:0)

HtmlEditor基于Web视图

    HTMLEditor editor = getEditor();
    WebView webView = (WebView) getEditor().lookup("WebView");
    new WebViewEditorListener(webView, new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {

        }
    });

添加回调以跟踪HTML更改。

public static class WebViewEditorListener {

        private final ChangeListener<String> listener;

        private final WebPage webPage;

        private String htmlRef, innerText;

        public WebViewEditorListener(final WebView editor, ChangeListener<String> listener) {
            this.listener = listener;
            webPage = Accessor.getPageFor(editor.getEngine());

            editor.setOnMouseClicked(e -> onKeyTyped(webPage.getHtml(webPage.getMainFrame())));
            editor.addEventFilter(KeyEvent.KEY_TYPED, e -> onKeyTyped(webPage.getHtml(webPage.getMainFrame())));
        }

        public String getHtmlContent(){
            return htmlRef == null ? "" : htmlRef ;
        }

        private void onKeyTyped(final String html) {
            boolean isEqual = htmlRef != null ? htmlRef.length() == html.length() : html == null;
            if (!isEqual){
                String text = webPage.getInnerText(webPage.getMainFrame());
                listener.changed(null, innerText, text);
                innerText = text;
                htmlRef = html;
            }

        }
    }