JavaFX HTMLEditor text change listener



我对JavaFX世界相当陌生,我似乎不知道如何在HTMLEditor组件中侦听文本修改事件。

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

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

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

此外,最好仅在文本修改事件(例如,而不是在 CTRL+A上)调用侦听器。你知道的。。。就像SWT文本的addModifyListener()一样。

在我的一个项目应用程序中使用 JavaFXHTMLEditor时,我也遇到了类似的情况。我最终添加了一个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覆盖范围并不准确。

这里有一个简单的

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

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

最新更新