簡體   English   中英

如何將 Tinymce 集成到 JavaFx webview 中?

[英]How to integrate Tinymce into JavaFx webview?

我正在嘗試在我們的 JavaFX 桌面應用程序中添加 Tinymce,因此我需要 Tinymce 和 FX Z5A98E2840FDD814608D 之間的雙向通信。

What I have done up to now: Integrated Tinymce in javaFX webview and displaying it, but don't know how to communicate between Tinymce and javaFx webview?

任何人都有經驗或可以回答以下問題嗎?

  • 如何從 Tinymce 到 javaFx 組件(例如 textarea)獲取內容?
  • 加載 fx 應用程序后,如何從 JavaFX 設置 Tinymce 內容?

下面是實現源代碼。

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Border;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.events.EventTarget;

import static javafx.concurrent.Worker.State;

public class TinymceInJavaFx extends Application {
    private static String URL_TINYMCE_PAGE = "/html/tinymcePage.html";
    private static String ID = "tinymceTextarea";
    private static String INITIAL_TEXT = "Initial text to be loaded in Tinymce.";

    private WebEngine webEngine;
    private Document document;
    private Element element;

    final TextArea fxTextArea = new TextArea(INITIAL_TEXT);
    public JavaFxApp javaFxApp;


    public static void main(String[] args) {
        launch(args);
    }

    public void start(Stage primaryStage) {
        primaryStage.setTitle("JavaFX HTML Editor Tinymce");

        WebView webView = new WebView();
        webEngine = webView.getEngine();
        webEngine.load(getClass().getResource(URL_TINYMCE_PAGE).toExternalForm());
        webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
            public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
                if (newState == State.SUCCEEDED) {
                    primaryStage.setTitle(webEngine.getLocation());
                    initJavaAndJavascriptObject();
                    element.setTextContent(fxTextArea.getText());
                }
            }
        });

        VBox vBox = new VBox(webView);
        vBox.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");
        fxTextArea.setBorder(Border.EMPTY);
        fxTextArea.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: red;");
        Button btnSave = new Button("Update FX TextArea");
        btnSave.setOnAction((ActionEvent t) -> {
            fxTextArea.setText(element.getTextContent());
        });
        // create the toolbar
        VBox toolBar = new VBox();
        toolBar.setMinHeight(200.0);
        toolBar.setAlignment(Pos.CENTER);
        toolBar.getStyleClass().add("browser-toolbar");
        toolBar.getChildren().addAll(btnSave, fxTextArea);
        Scene scene = new Scene(new VBox(vBox, toolBar), 1000, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void initJavaAndJavascriptObject() {
        document = webEngine.getDocument();
        element = document.getElementById(ID);
        addChangeListenerToTinymceEditorTextareaElement(element);

        //Mapping Java objects to JavaScript values, Calling back to Java from JavaScript
        JSObject window = (JSObject) webEngine.executeScript("window");
        // You can then refer to the object and the method from your HTML page: <a href="" onclick="fxApp.update()">Click here to exit application</a>
        window.setMember("fxApp", javaFxApp);
    }


    // JavaScript interface object
    public class JavaFxApp {

        public JavaFxApp() {
        }

        public void update(String content) {
            fxTextArea.setText(content);
        }

        public void reset() {
            fxTextArea.setText("");
        }
    }


    private void addChangeListenerToTinymceEditorTextareaElement(Element el) {
        ((EventTarget) el).addEventListener(
                "onchange",
                event -> fxTextArea.setText("Added by textarea change listener. ".concat(el.getTextContent())),
                false
        );
    }

}

html 頁面包含 Tinymce 和 javascript 代碼:

<!DOCTYPE html>
<html>
<head>
    <script src="../js/tinymce4/tinymce.min.js"></script>
    <script type="text/javascript">
        tinymce.init({
            selector: "#tinymceTextarea",
            width: '100%',
            height: 800,
            placeholder:'Typ of plak hier...',
            plugins: [
                "advlist autolink lists link image charmap print preview anchor",
                "searchreplace visualblocks code fullscreen",
                "insertdatetime media table paste",
            ],
            toolbar:
                "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | code openlocalfile",
            setup: function(editor) {

                function displayFile(contents) {
                    editor.insertContent(contents);
                }

                function openLocalFile() {
                    const readFile = function (e) {
                        let file = e.target.files[0];
                        if (!file) {
                            return;
                        }
                        let reader = new FileReader();
                        reader.onload = function (e) {
                            let contents = e.target.result;
                            fileInput.func(contents)
                            document.body.removeChild(fileInput)
                        }
                        reader.readAsText(file)
                    };
                    let fileInput = document.createElement("input")
                    fileInput.type='file'
                    fileInput.style.display='none'
                    fileInput.onchange=readFile
                    fileInput.func=displayFile
                    document.body.appendChild(fileInput)
                    fileInput.dispatchEvent(new MouseEvent('click', {shiftKey: true}));
                }

                editor.addButton('openlocalfile', {
                    text:"Open file",
                    icon: 'browse',
                    //image: 'https://cdn-icons.flaticon.com/png/512/5994/premium/5994754.png?token=exp=1643109307~hmac=6e7bf649b369f4936adba174205d9e5c',
                    tooltip: "Open a local File in the editor",
                    onclick: openLocalFile
                });
            }
        });

        function callJavaFx(){
            return tinymce.getContent();
        }


    </script>
</head>
<body>
<div>Tinymce <b>locally</b> hosted and <strong>Opensource</strong><br>
    <input type="button" onclick="fxApp.reset()" value="Reset FX Textarea from html page">
    <input type="button" onclick="fxApp.update(callJavaFx());" value="Save tinymce content to FX textarea">
    <hr>
</div>
<form method="post">
    <textarea id="tinymceTextarea" onchange="fxApp.update()" >I'm initial text value in opensource self-hosted HTML page.</textarea>
</form>
</body>
</html>

最后我讓它如下工作,可能對其他人有幫助。 任何好的建議或更好的解決方案將不勝感激..

  1. 創建一個全局var tinyEditor; 在腳本中。

  2. 在設置開始時啟動它 function: tinyEditor = editor;

  3. 在 javaFx 中創建對此編輯器的引用

    // JavaScript interface object public class JavaFxApp { private JSObject tinyEditor; public void init(JSObject tinyEditor) { this.tinyEditor = tinyEditor; } }
  4. 使用 webEngin 啟動對 tinymceEditor 的引用,如下所示。

     webEngine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> { if (newState == State.SUCCEEDED) { JSObject window = (JSObject) webEngine.executeScript("window"); window.setMember("fxApp", javaFxApp = new JavaFxApp()); webEngine.executeScript( "window.fxApp.init(window.tinyEditor);" ); } });
  5. 設置內容: javaFxApp.tinyEditor.call("setContent", "Your content here");

  6. 通過以下方式獲取內容: String content = (String) javaFxApp.tinyEditor.call("getContent");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM