Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function Undefined error in JavaFX application

The requirement was to embed a JSON editor in a javafx application. I tried embedding the json editor(powered by Ace) https://github.com/josdejong/jsoneditor into my javafx application with the help of webview. Everything is working except copy(CTRL+C) and paste(CTRL+V).

After a research, I came to know that javafx webkit is of safari. But I tried the same editor in web browsers like firefox, chrome and all. Even in latest version of safari it is working well, but I failed to get it working in javafx webview. Currently I am using the latest JDK(8), so having the latest javafx also. Is there any way by which I can get the copy paste shortcut keys to be working on my embedded editor in javafx webview? Please help.

like image 215
Nidhin Joseph Avatar asked Aug 23 '26 18:08

Nidhin Joseph


1 Answers

ace.js uses the clipboard, and in any regular browser it works fine, but inside a JavaFX webView, there's a problem. If you look for the function handleClipboardData in ace.js you can see that:

  • Copy works internally, but when it tries to setData it fails.
  • Paste doesn't work because getData fails.

Looking for a workaround I found this answer related to codemirror, that could be applied to ace.js as well.

Basically, you have to make a bridge in your JavaFX application (outside the ace editor) to deal with copy and paste events. Something like this:

 @Override
public void start(Stage primaryStage) {
    webView=new WebView();
    webEngine = webView.getEngine();

    webEngine.load(Utils.class.getResource("editor.html").toExternalForm());

    // Capture Ctrl+V event and process it
    webView.addEventHandler(KeyEvent.KEY_PRESSED, keyEvent -> {
        if (keyEvent.isControlDown() && keyEvent.getCode() == KeyCode.V){
            // PASTE
            final Clipboard clipboard = Clipboard.getSystemClipboard();
            String content = (String) clipboard.getContent(DataFormat.PLAIN_TEXT);
            webEngine.executeScript(" pasteContent(\""+content+"\") ");

        }
    });

    // retrieve copy event via javascript:alert
    webEngine.setOnAlert((WebEvent<String> we) -> {
        if(we.getData()!=null && we.getData().startsWith("copy: ")){
               // COPY
               final Clipboard clipboard = Clipboard.getSystemClipboard();
               final ClipboardContent content = new ClipboardContent();
               content.putString(we.getData().substring(6));
               clipboard.setContent(content);    
        }
    });
}   

Now in editor.html,you have to create the pasteContent function that will be called from the webEngine on a paste event:

<script>
var editor = ace.edit("editor");
...
function pasteContent(content){
    editor.onPaste(content);
}
</script> 

And finally in ace.js, in the function getCopyText, close to line 13071, you have to insert the alert, so the copied text in the editor can be sent to the webEngine. Note the use of the hardcoded string "copy: ", for simplicity.

this.getCopyText = function() {
    var text = this.getSelectedText();
    javascript:alert("copy: "+text);
    this._signal("copy", text);
    return text;
};

This will be all.

like image 175
José Pereda Avatar answered Aug 25 '26 08:08

José Pereda



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!