如何将 Tinymce 集成到 JavaFx webview 中?
How to integrate Tinymce into JavaFx webview?
我正在尝试在我们的 JavaFX 桌面应用程序中添加 Tinymce,因此我需要在 Tinymce 和 FX webview 之间进行双向通信。
到目前为止我做了什么:
在javaFX webview中集成Tinymce并显示,但是不知道Tinymce和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>
最后我让它按下面的方式工作,可能对其他人有帮助。任何好的建议或更好的解决方案将不胜感激..
在脚本中创建全局var tinyEditor;
。
在设置函数开始时启动它:tinyEditor = editor;
在 javaFx 中创建对此编辑器的引用
// JavaScript interface object
public class JavaFxApp {
private JSObject tinyEditor;
public void init(JSObject tinyEditor) {
this.tinyEditor = tinyEditor;
}
}
使用 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);" );
}
});
设置内容:javaFxApp.tinyEditor.call("setContent", "Your content here");
通过以下方式获取内容:String content = (String) javaFxApp.tinyEditor.call("getContent");
我正在尝试在我们的 JavaFX 桌面应用程序中添加 Tinymce,因此我需要在 Tinymce 和 FX webview 之间进行双向通信。
到目前为止我做了什么: 在javaFX webview中集成Tinymce并显示,但是不知道Tinymce和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>
最后我让它按下面的方式工作,可能对其他人有帮助。任何好的建议或更好的解决方案将不胜感激..
在脚本中创建全局
var tinyEditor;
。在设置函数开始时启动它:
tinyEditor = editor;
在 javaFx 中创建对此编辑器的引用
// JavaScript interface object public class JavaFxApp { private JSObject tinyEditor; public void init(JSObject tinyEditor) { this.tinyEditor = tinyEditor; } }
使用 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);" ); } });
设置内容:
javaFxApp.tinyEditor.call("setContent", "Your content here");
通过以下方式获取内容:
String content = (String) javaFxApp.tinyEditor.call("getContent");