I'm fairly new to the JavaFX world, and I can't seem to figure out how to listen for events in the component. 组件中侦听事件。
I need this since I'm hooking this widget to a model, which needs updating.
The addEventFilter
API, with a KeyEvent.KEY_TYPED
event type doesn't seem to be working as it should. When its handler is called, the getHTMLText()
isn't updated yet with the most recent character (if someone doesn't understand this paragraph, I'll provide a step-by-step example).
The has a textProperty()
on which a listener can be attached. 具有textProperty()
,可以在其上附加侦听器。
Now what about the ? 呢?
Also, it would be nice to have the listener called ONLY on text modify events (and not on CTRL + A , for example). You know... like SWT Text's addModifyListener()
.
While using JavaFX HTMLEditor
in one of my project application, I also faced a similar situation. I ended up adding a button
, upon whose click the parsing of the HTML text would happen, and further tasks executed. With AnchorPane
, I was able to add the button
on the HTMLEditor seamlessly, and it looked like a part of it.
Anyways, here's a little example of how you can achieve what you want without any extra 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);
}
}
UPDATE: Upon a bit more of thinking, I found a way to get event handling done even on those button clicks. Here's how:
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);
}
If you see the HTMLEditor
, it has two ToolBars
.
What I'm doing in the code is looking up
for those two toolbars, and setting an onMouseExited
event handler. The analogy is that if the user enters and makes some changes on the HTML Text and exits the toolbar, an event will be fired, which can then be handled.
You can even set different kind of event handlers on these two toolbars, based on your needs, but in my opinion, these onMouseExited
event handlers provide a very wide coverage when used with the onKeyReleased
event handlers. The coverage based on onMouseExited
handler is not exact though.
here is a simple one
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 is based on Web view
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) {
}
});
Add Callback for tracking html changes.
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;
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.