2014-03-02 17 views
2

我是相當新的JavaFX的世界,我似乎無法弄清楚如何聽在HTML編輯成分爲文本修改事件。JavaFX的HTML編輯文本變化監聽

我需要這個,因爲我把這個小部件掛接到需要更新的模型。

addEventFilter API與KeyEvent.KEY_TYPED事件類型似乎沒有像它應該那樣工作。當它的處理程序被調用時,getHTMLText()沒有用最新的字符更新(如果有人不理解這一段,我將提供一個循序漸進的例子)。

TextField有一個textProperty(),可以在其上附加偵聽器。
現在HTMLEditor怎麼辦?

而且,這將是不錯的呼籲只是文本監聽修改事件(而不是CTRL +一個,例如)。你知道...像SWT文本的addModifyListener()

回答

2

在我的一個項目應用程序中使用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); 
    } 
} 

UPDATE: 在更多的思考了一下,我發現了一個辦法讓事件處理甚至做在這些按鈕點擊。具體方法如下:

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文本進行了一些更改並退出工具欄,則會觸發事件,然後可以處理該事件。

您甚至可以根據您的需要在這兩個工具欄上設置不同類型的事件處理程序,但在我看來,這些事件處理程序與onKeyReleased事件處理程序一起使用時提供了非常廣泛的覆蓋範圍。但基於onMouseExited處理程序的覆蓋率並不準確。

+0

什麼複製粘貼? :-( – GGrec

+0

@GGrec:我已經更新了答案,以對剪切和粘貼事件做出反應,我相信您足夠聰明,可以根據自己的需要配置此低級別密鑰偵聽器。 –

+0

哦,這是很明顯,我會再提一個簡單的問題,因爲它在同一個頁面上,關於HTML的改變呢?例如,用鼠標選擇一些文本,然後改變爲粗體,模型應該改變,但它不是一個類型事件 – GGrec

1

這裏是一個簡單的

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