【问题标题】:JavaFX HTMLEditor text change listenerJavaFX HTMLEditor 文本更改监听器
【发布时间】:2014-03-02 13:27:08
【问题描述】:

我对 JavaFX 世界还很陌生,我似乎不知道如何在 HTMLEditor 组件中侦听 text-modify 事件。

我需要这个,因为我正在将此小部件连接到需要更新的模型。

带有KeyEvent.KEY_TYPED 事件类型的addEventFilter API 似乎无法正常工作。当调用它的处理程序时,getHTMLText() 还没有更新为最新的字符(如果有人不理解这一段,我将提供一个分步示例)。

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

另外,最好只在文本修改事件上调用监听器(而不是在 CTRL+A 上,例如)。你知道...就像 SWT Text 的 addModifyListener()

【问题讨论】:

    标签: java javafx javafx-2


    【解决方案1】:

    在我的一个项目应用程序中使用 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 处理程序的覆盖范围并不准确。

    【讨论】:

    • 复制粘贴怎么样? :-(
    • @GGrec:我已经更新了对剪切和粘贴事件做出反应的答案,我相信你足够聪明,可以根据自己的需要配置这个低级键监听器。跨度>
    • 天哪,这很明显。我要提出另一个快速问题,因为它在同一页上。 HTML 的变化呢?例如用鼠标选择了一些文本,然后变为粗体。模型应该改变,但它不是类型事件。
    • @GGrec:必须说这是一个很棒的问题。显然,您在 HTML 编辑器中看到的所有按钮和工具栏都是 HTMLEditorSkin 类的一部分,并且这些按钮都被声明为私有,因此无法访问它们。在这种情况下,我会从头开始构建自定义 HTML 编辑器,方法是复制粘贴 HTMLEditor 和相关类的 JavaFX 源代码,然后适当地调整它。我会采取的第二种方法是我会在另一个线程上运行一个计时器服务,它会每隔几秒检索一次 HTML 文本并相应地对其进行解析。
    【解决方案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));
        }
    }
    

    【讨论】:

      【解决方案3】:

      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;
                  }
      
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-06
        • 2021-08-25
        • 2015-11-01
        • 1970-01-01
        • 2013-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多