2023年10月8日14:35:33
parent
80b8f262f2
commit
c96026b85c
|
|
@ -1,11 +1,16 @@
|
|||
package com.zhangmeng.tools.controller;
|
||||
|
||||
import com.zhangmeng.tools.editors.ace.AceEditor;
|
||||
import com.zhangmeng.tools.editors.monaco.MonacoEdit;
|
||||
import com.zhangmeng.tools.editors.monaco.*;
|
||||
import com.zhangmeng.tools.utils.AlertUtils;
|
||||
import com.zhangmeng.tools.utils.ClipboardUtils;
|
||||
import com.zhangmeng.tools.utils.ImagePath;
|
||||
import com.zhangmeng.tools.utils.ResourcesUtils;
|
||||
import eu.mihosoft.monacofx.Editor;
|
||||
import eu.mihosoft.monacofx.MonacoFX;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
|
|
@ -19,21 +24,33 @@ import javafx.scene.control.ListView;
|
|||
import javafx.scene.control.SplitPane;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.scene.web.WebEngine;
|
||||
import javafx.scene.web.WebView;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Callback;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Slf4j
|
||||
public class EditListController {
|
||||
|
||||
@FXML
|
||||
public AnchorPane parent_root;
|
||||
|
||||
private SimpleDoubleProperty width = new SimpleDoubleProperty(0.0);
|
||||
private SimpleDoubleProperty height = new SimpleDoubleProperty(0.0);
|
||||
private AnchorPane root;
|
||||
|
|
@ -306,9 +323,13 @@ public class EditListController {
|
|||
if (!flag){
|
||||
acJsEditor = new AceEditor();
|
||||
root = acJsEditor;
|
||||
WebView webView = acJsEditor.getWebView();
|
||||
webView.prefWidthProperty().bind(root.widthProperty());
|
||||
webView.prefHeightProperty().bind(root.heightProperty());
|
||||
WebView view = acJsEditor.getWebView();
|
||||
|
||||
AnchorPane.setTopAnchor(view,0.0);
|
||||
AnchorPane.setBottomAnchor(view,0.0);
|
||||
AnchorPane.setLeftAnchor(view,0.0);
|
||||
AnchorPane.setRightAnchor(view,0.0);
|
||||
|
||||
}else {
|
||||
root = acJsEditor;
|
||||
}
|
||||
|
|
@ -317,27 +338,10 @@ public class EditListController {
|
|||
|
||||
private void monacoEdit(boolean flag) {
|
||||
|
||||
MonacoFX monacoFX = new MonacoFX();
|
||||
// set initial text
|
||||
monacoFX.getEditor().getDocument().setText(
|
||||
"#include <stdio.h>\n" +
|
||||
"int main() {\n" +
|
||||
" // printf() displays the string inside quotation\n" +
|
||||
" printf(\"Hello, World!\");\n" +
|
||||
" return 0;\n" +
|
||||
"}");
|
||||
|
||||
// use a predefined language like 'c'
|
||||
monacoFX.getEditor().setCurrentLanguage("c");
|
||||
monacoFX.getEditor().setCurrentTheme("vs-dark");
|
||||
|
||||
//默认选择第一个
|
||||
listView.getSelectionModel().select(1);
|
||||
if (!flag){
|
||||
root = new AnchorPane(monacoFX);
|
||||
WebView webView = monacoFX.getView();
|
||||
webView.prefWidthProperty().bind(root.widthProperty());
|
||||
webView.prefHeightProperty().bind(root.heightProperty());
|
||||
root = new MonacoWebView();
|
||||
monacoEdit = root;
|
||||
}else {
|
||||
root = monacoEdit;
|
||||
|
|
@ -349,6 +353,7 @@ public class EditListController {
|
|||
private void common_method() {
|
||||
splitPane.getItems().remove(1);
|
||||
splitPane.getItems().add(1, root);
|
||||
|
||||
root.widthProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
double width = splitPane.getWidth();
|
||||
|
|
@ -366,10 +371,12 @@ public class EditListController {
|
|||
|
||||
this.width.addListener((observable, oldValue, newValue) -> {
|
||||
EditListController.this.root.setPrefWidth(newValue.doubleValue() - listView.getWidth());
|
||||
log.info("root:=====================>width:" + (newValue.doubleValue() - listView.getWidth()));
|
||||
});
|
||||
|
||||
this.height.addListener((observable, oldValue, newValue) -> {
|
||||
EditListController.this.root.setPrefHeight(newValue.doubleValue() - listView.getHeight());
|
||||
log.info("root:=====================>:height" + (newValue.doubleValue() - listView.getWidth()));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,200 +0,0 @@
|
|||
package com.zhangmeng.tools.editors.monaco;
|
||||
|
||||
import com.zhangmeng.tools.editors.ace.AceHelper;
|
||||
import com.zhangmeng.tools.editors.ace.AceMode;
|
||||
import com.zhangmeng.tools.editors.ace.AceTheme;
|
||||
import com.zhangmeng.tools.utils.AlertUtils;
|
||||
import com.zhangmeng.tools.utils.ClipboardUtils;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.concurrent.Worker;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.web.WebEngine;
|
||||
import javafx.scene.web.WebView;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import netscape.javascript.JSObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
|
||||
|
||||
/**
|
||||
* @author zhangmeng
|
||||
* @date 2023年10月7日16:02:39
|
||||
* @version 1.0
|
||||
*/
|
||||
public class MonacoEdit extends AnchorPane {
|
||||
|
||||
private final WebView webView = new WebView();
|
||||
private WebEngine engine;
|
||||
private MonacoMode mode = MonacoMode.JAVA;
|
||||
private JSObject window;
|
||||
private JSObject editor;
|
||||
private File file;
|
||||
|
||||
|
||||
public WebView getWebView() {
|
||||
return webView;
|
||||
}
|
||||
|
||||
public MonacoEdit() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
public MonacoEdit(File file) {
|
||||
String file_content = null;
|
||||
try {
|
||||
file_content = Files.readString(file.toPath(), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
file_content = Files.readString(file.toPath(), Charset.forName("GBK"));
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
this.file = file;
|
||||
setText(file_content);
|
||||
initialize();
|
||||
}
|
||||
|
||||
public MonacoEdit(String text) {
|
||||
setText(text);
|
||||
initialize();
|
||||
}
|
||||
|
||||
private final StringProperty text = new SimpleStringProperty("");
|
||||
|
||||
public StringProperty textProperty() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text.get();
|
||||
}
|
||||
|
||||
private void setText(String text) {
|
||||
this.text.set(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置内容
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
private void setMonacoText(String value) {
|
||||
engine.executeScript("setValue()");
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模式
|
||||
*/
|
||||
private void setMonacoMode(MonacoMode mode) {
|
||||
engine.executeScript("setModelLanguage()");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选定文本
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String selectedText() {
|
||||
// 一下两个方法都可以获取到选中的文本
|
||||
// String selectedText = (String) engine.executeScript("window.getSelection().toString()"); // 有些问题
|
||||
return (String) editor.call("getSelectedText");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除选中的内容
|
||||
*/
|
||||
private void removeSelectText() {
|
||||
window.call("removeSelectRange"); // 或者:editor.call("remove", "right");
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
getChildren().addAll(webView);
|
||||
webView.setContextMenuEnabled(false);
|
||||
engine = webView.getEngine();
|
||||
// 界面加载完成执行的方法
|
||||
engine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> {
|
||||
if (newState == Worker.State.SUCCEEDED) {
|
||||
//
|
||||
window = (JSObject) engine.executeScript("window");
|
||||
window.setMember("MonacoEdit", this);
|
||||
// editor = (JSObject) engine.executeScript("monaco.editor");
|
||||
setMonacoText(getText());
|
||||
setMonacoMode(mode);
|
||||
// WebView 整合 Ace.js 后 Ctrl+C 和 Ctrl+X 有问题,重新处理下。
|
||||
webView.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||
if (event.isControlDown() && event.getCode() == KeyCode.C) {
|
||||
event.consume();
|
||||
ClipboardUtils.setString(selectedText());
|
||||
}
|
||||
if (event.isControlDown() && event.getCode() == KeyCode.X) {
|
||||
event.consume();
|
||||
ClipboardUtils.setString(selectedText());
|
||||
removeSelectText(); // 删除选中的内容
|
||||
}
|
||||
|
||||
if (event.isControlDown() && event.getCode() == KeyCode.S){//保存
|
||||
event.consume();
|
||||
|
||||
if (file != null){
|
||||
try {
|
||||
FileWriter writer = new FileWriter(file);
|
||||
writer.write(getText());
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}else {
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
AlertUtils.alert_warning("保存成功!");
|
||||
}
|
||||
|
||||
if (event.isControlDown() && event.getCode() == KeyCode.O){//保存
|
||||
event.consume();
|
||||
//打开文件
|
||||
Stage stage = new Stage();
|
||||
FileChooser dc = new FileChooser();
|
||||
dc.setTitle("文件选择");
|
||||
dc.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("文件类型", "*.java", "*.go", "*.txt", "*.json", "*.sql"));
|
||||
File file = dc.showOpenDialog(stage);
|
||||
String file_content = null;
|
||||
try {
|
||||
file_content = Files.readString(file.toPath(), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
file_content = Files.readString(file.toPath(), Charset.forName("GBK"));
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
this.file = file;
|
||||
setText(file_content);
|
||||
setMonacoText(getText());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
engine.setJavaScriptEnabled(true);
|
||||
// message print
|
||||
engine.getLoadWorker().messageProperty().addListener((observable, oldValue, newValue) -> System.out.printf("engine message : %s%n", newValue));
|
||||
// exception print
|
||||
engine.getLoadWorker().exceptionProperty().addListener((observable, oldValue, newValue) -> newValue.printStackTrace());
|
||||
engine.loadContent(MonacoHelper.getHtml(this.mode, MonacoThem.VS)); // 加载html资源
|
||||
// engine.load(""); // 同一时间多个WebView访问同一个资源时engine.executeScript();会返回undefined。
|
||||
}
|
||||
}
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
package com.zhangmeng.tools.editors.monaco;
|
||||
|
||||
import com.zhangmeng.tools.editors.ace.AceHelper;
|
||||
import com.zhangmeng.tools.editors.ace.AceMode;
|
||||
import com.zhangmeng.tools.editors.ace.AceTheme;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MonacoHelper {
|
||||
|
||||
private static final String loader_js_path = "/static/editors/monaco-editor/min/vs/loader.js";
|
||||
|
||||
public static String getHtml(MonacoMode aceMode, MonacoThem aceTheme) {
|
||||
|
||||
String model_js = aceMode.getName();
|
||||
String theme_js = aceTheme.getName();
|
||||
|
||||
try (
|
||||
InputStream loader_JS = AceHelper.class.getResourceAsStream(loader_js_path);
|
||||
) {
|
||||
String html = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Monaco Editor Demo</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
""";
|
||||
html += " <script>" + new String(Objects.requireNonNull(loader_JS).readAllBytes(), StandardCharsets.UTF_8) + "</script>";
|
||||
html += """
|
||||
<style>
|
||||
body {
|
||||
font-family: "Source Han Sans", "San Francisco", "PingFang SC", "Hiragino Sans GB", "Droid Sans Fallback", "Microsoft YaHei", sans-serif;
|
||||
transition: background-color .2s;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
right: 0;
|
||||
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
|
||||
transition: 0.2s;
|
||||
overflow: hidden;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var edit_content = "";
|
||||
|
||||
require.config({paths: {'vs': './monaco-editor/min/vs'}});
|
||||
require(['vs/editor/editor.main'], function () {
|
||||
|
||||
var defaultCode = [
|
||||
edit_content
|
||||
].join('\\n');
|
||||
|
||||
// 定义编辑器主题
|
||||
monaco.editor.defineTheme('myTheme', {
|
||||
base: 'vs',
|
||||
inherit: true,
|
||||
rules: [{background: 'EDF9FA'}],
|
||||
});
|
||||
monaco.editor.setTheme('myTheme');
|
||||
addNewEditor(defaultCode, 'java');
|
||||
});
|
||||
|
||||
var code_edit;
|
||||
|
||||
// 新建一个编辑器
|
||||
function newEditor(container_id, code, language) {
|
||||
var model = monaco.editor.createModel(code, language);
|
||||
var editor = monaco.editor.create(document.getElementById(container_id), {
|
||||
model: model,
|
||||
automaticLayout: true,
|
||||
tabSize: 4,
|
||||
minimap: {
|
||||
enabled: false, // 不要小地图
|
||||
},
|
||||
fontSize: 20,
|
||||
lineNumbers: true,
|
||||
});
|
||||
editor.onDidChangeCursorPosition((e) => {
|
||||
edit_content = editor.getValue();
|
||||
});
|
||||
code_edit = editor;
|
||||
return editor;
|
||||
}
|
||||
|
||||
// 新建一个 div
|
||||
function addNewEditor(code, language) {
|
||||
var new_container = document.getElementById("root")
|
||||
new_container.className = "container";
|
||||
newEditor(new_container.id, code, language);
|
||||
}
|
||||
|
||||
//设置语言
|
||||
function setModelLanguage(language) {
|
||||
monaco.editor.setModelLanguage(window.monaco.editor.getModels()[0], language)
|
||||
}
|
||||
|
||||
//获取值
|
||||
function getValue() {
|
||||
alert(edit_content)
|
||||
}
|
||||
|
||||
function setThem() {
|
||||
monaco.editor.setTheme('vs-dark');
|
||||
}
|
||||
|
||||
//获取所选文本
|
||||
function getSelected() {
|
||||
var text = code_edit.getModel().getValueInRange(code_edit.getSelection())
|
||||
}
|
||||
|
||||
function setValue(){
|
||||
// 销毁当前的编辑器实例
|
||||
code_edit.dispose();
|
||||
addNewEditor("defaultCode", 'java');
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div style="width: 100%">
|
||||
<button type="button" onclick="getValue()">获取文本</button>
|
||||
<button type="button" onclick="setModelLanguage('javascript')">设置语言</button>
|
||||
<button type="button" onclick="setThem('javascript')">设置主题</button>
|
||||
<button type="button" onclick="getSelected()">获取所选文本</button>
|
||||
<button type="button" onclick="setValue()">色值文本</button>
|
||||
</div>
|
||||
<div id="root"></div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
""";
|
||||
|
||||
return html;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package com.zhangmeng.tools.editors.monaco;
|
||||
|
||||
public enum MonacoMode {
|
||||
|
||||
JAVA("java"),
|
||||
JAVA_SCRIPT("javascript");
|
||||
private String name;
|
||||
|
||||
MonacoMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
package com.zhangmeng.tools.editors.monaco;
|
||||
|
||||
|
||||
/**
|
||||
* vs、vs-dark、hc-black
|
||||
*/
|
||||
|
||||
public enum MonacoThem {
|
||||
|
||||
VS("vs"),
|
||||
VS_DARK("va-dark"),
|
||||
HC_BLACK("hc-black");
|
||||
|
||||
private String name;
|
||||
|
||||
MonacoThem(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
package com.zhangmeng.tools.editors.monaco;
|
||||
|
||||
import com.zhangmeng.tools.utils.AlertUtils;
|
||||
import com.zhangmeng.tools.utils.ClipboardUtils;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.web.WebEngine;
|
||||
import javafx.scene.web.WebView;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import netscape.javascript.JSObject;
|
||||
|
||||
public class MonacoWebView extends AnchorPane {
|
||||
|
||||
|
||||
public MonacoWebView() {
|
||||
init();
|
||||
}
|
||||
|
||||
private File file;
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public WebView getView() {
|
||||
return view;
|
||||
}
|
||||
|
||||
public void setView(WebView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
private WebView view = new WebView();
|
||||
|
||||
public void init() {
|
||||
|
||||
WebEngine engine = view.getEngine();
|
||||
|
||||
String url = this.getClass().getResource("/static/editors/index2.html").toExternalForm();
|
||||
engine.load(url);
|
||||
AnchorPane.setTopAnchor(view, 0.0);
|
||||
AnchorPane.setBottomAnchor(view, 0.0);
|
||||
AnchorPane.setLeftAnchor(view, 0.0);
|
||||
AnchorPane.setRightAnchor(view, 0.0);
|
||||
getChildren().add(view);
|
||||
|
||||
view.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||
|
||||
if (event.isControlDown() && event.getCode() == KeyCode.C) {
|
||||
event.consume();
|
||||
JSObject editor = (JSObject) engine.executeScript("window");
|
||||
//获取所选文本
|
||||
String text= editor.call("getSelected").toString();
|
||||
ClipboardUtils.setString(text);
|
||||
}
|
||||
if (event.isControlDown() && event.getCode() == KeyCode.X) {
|
||||
event.consume();
|
||||
JSObject editor = (JSObject) engine.executeScript("window");
|
||||
//获取所选文本
|
||||
String text= editor.call("getSelected").toString();
|
||||
ClipboardUtils.setString(text);
|
||||
//删除所选文本
|
||||
editor.call("removeSelectText"); // 删除选中的内容
|
||||
}
|
||||
|
||||
|
||||
if (event.isControlDown() && event.getCode() == KeyCode.S) {//保存
|
||||
event.consume();
|
||||
AlertUtils.alert_warning("保存成功!");
|
||||
}
|
||||
|
||||
if (event.isControlDown() && event.getCode() == KeyCode.O) {
|
||||
event.consume();
|
||||
//打开文件
|
||||
Stage stage = new Stage();
|
||||
FileChooser dc = new FileChooser();
|
||||
dc.setTitle("文件选择");
|
||||
dc.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("文件类型", "*.java", "*.go", "*.txt", "*.json", "*.sql"));
|
||||
File file = dc.showOpenDialog(stage);
|
||||
String file_content = null;
|
||||
try {
|
||||
file_content = Files.readString(file.toPath(), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
file_content = Files.readString(file.toPath(), Charset.forName("GBK"));
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
this.file = file;
|
||||
JSObject editor = (JSObject) engine.executeScript("window");
|
||||
editor.call("setValue",file_content);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public static String getText() {
|
||||
return """
|
||||
package com.zhangmeng.tools.editors.monaco;
|
||||
|
||||
import com.zhangmeng.tools.utils.AlertUtils;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.web.WebEngine;
|
||||
import javafx.scene.web.WebView;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
|
||||
public class MonacoWebView extends AnchorPane {
|
||||
\s
|
||||
private File file;
|
||||
|
||||
private WebView view = new WebView();
|
||||
|
||||
public void init(){
|
||||
\s
|
||||
WebEngine engine = view.getEngine();
|
||||
|
||||
String url = this.getClass().getResource("/static/editors/index2.html").toExternalForm();
|
||||
engine.load(url);
|
||||
AnchorPane.setTopAnchor(view,0.0);
|
||||
AnchorPane.setBottomAnchor(view,0.0);
|
||||
AnchorPane.setLeftAnchor(view,0.0);
|
||||
AnchorPane.setRightAnchor(view,0.0);
|
||||
getChildren().add(view);
|
||||
|
||||
view.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||
if (event.isControlDown() && event.getCode() == KeyCode.S){//保存
|
||||
event.consume();
|
||||
AlertUtils.alert_warning("保存成功!");
|
||||
}
|
||||
|
||||
if (event.isControlDown() && event.getCode() == KeyCode.O){
|
||||
event.consume();
|
||||
//打开文件
|
||||
Stage stage = new Stage();
|
||||
FileChooser dc = new FileChooser();
|
||||
dc.setTitle("文件选择");
|
||||
dc.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("文件类型", "*.java", "*.go", "*.txt", "*.json", "*.sql"));
|
||||
File file = dc.showOpenDialog(stage);
|
||||
String file_content = null;
|
||||
try {
|
||||
file_content = Files.readString(file.toPath(), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
file_content = Files.readString(file.toPath(), Charset.forName("GBK"));
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
this.file = file;
|
||||
engine.executeScript("setValue('" + getText() +"')");
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
\s
|
||||
public static String getText(){
|
||||
return ""\"
|
||||
""\";
|
||||
}
|
||||
}
|
||||
|
||||
""";
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
<head>
|
||||
<title>Monaco Editor Demo</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<script src="./monaco-editor/min/vs/loader.js"></script>
|
||||
|
||||
<style>
|
||||
|
|
@ -26,239 +27,30 @@
|
|||
}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var Areacode = 'public class RichTextArea extends Control {\n' +
|
||||
' public static final String STYLE_CLASS = "rich-text-area";\n' +
|
||||
' public static final DataFormat RTA_DATA_FORMAT = new DataFormat(new String[]{"text/rich-text-area"});\n' +
|
||||
' private static final PseudoClass PSEUDO_CLASS_READONLY = PseudoClass.getPseudoClass("readonly");\n' +
|
||||
' private final ActionFactory actionFactory = new ActionFactory(this);\n' +
|
||||
' private final ObjectProperty<Document> documentProperty = new SimpleObjectProperty(this, "document", new Document());\n' +
|
||||
' private final BooleanProperty autoSaveProperty = new SimpleBooleanProperty(this, "autoSave");\n' +
|
||||
' final ReadOnlyBooleanWrapper modifiedProperty = new ReadOnlyBooleanWrapper(this, "modified");\n' +
|
||||
' private final BooleanProperty editableProperty = new SimpleBooleanProperty(this, "editable", true) {\n' +
|
||||
' protected void invalidated() {\n' +
|
||||
' RichTextArea.this.pseudoClassStateChanged(RichTextArea.PSEUDO_CLASS_READONLY, !this.get());\n' +
|
||||
' }\n' +
|
||||
' };\n' +
|
||||
' private final ReadOnlyObjectWrapper<Selection> selectionProperty;\n' +
|
||||
' final ReadOnlyIntegerWrapper textLengthProperty;\n' +
|
||||
' private final DoubleProperty contentAreaWidthProperty;\n' +
|
||||
' private final ObjectProperty<BiFunction<Integer, GraphicType, Node>> paragraphGraphicFactoryProperty;\n' +
|
||||
' private final ObjectProperty<Function<Node, Consumer<String>>> linkCallbackFactoryProperty;\n' +
|
||||
' private final ObjectProperty<EventHandler<ActionEvent>> onAction;\n' +
|
||||
' private final ObjectProperty<EmojiSkinTone> skinToneProperty;\n' +
|
||||
' final ReadOnlyIntegerWrapper caretPosition;\n' +
|
||||
' private final BooleanProperty tableAllowedProperty;\n' +
|
||||
' private StringProperty promptText;\n' +
|
||||
'\n' +
|
||||
' public RichTextArea() {\n' +
|
||||
' this.selectionProperty = new ReadOnlyObjectWrapper(this, "selection", Selection.UNDEFINED);\n' +
|
||||
' this.textLengthProperty = new ReadOnlyIntegerWrapper(this, "textLength");\n' +
|
||||
' this.contentAreaWidthProperty = new SimpleDoubleProperty(this, "contentAreaWidth", 0.0D);\n' +
|
||||
' this.paragraphGraphicFactoryProperty = new SimpleObjectProperty(this, "paragraphGraphicFactory", DefaultParagraphGraphicFactory.getFactory());\n' +
|
||||
' this.linkCallbackFactoryProperty = new SimpleObjectProperty(this, "linkCallbackFactory", DefaultLinkCallbackFactory.getFactory());\n' +
|
||||
' this.onAction = new SimpleObjectProperty(this, "onAction");\n' +
|
||||
' this.skinToneProperty = new SimpleObjectProperty(this, "skinTone", EmojiSkinTone.NO_SKIN_TONE);\n' +
|
||||
' this.caretPosition = new ReadOnlyIntegerWrapper(this, "caretPosition", 0);\n' +
|
||||
' this.tableAllowedProperty = new SimpleBooleanProperty(this, "tableAllowed", true);\n' +
|
||||
' this.promptText = new SimpleStringProperty(this, "promptText", "") {\n' +
|
||||
' protected void invalidated() {\n' +
|
||||
' String txt = this.get();\n' +
|
||||
' if (txt != null && txt.contains("\\n")) {\n' +
|
||||
' txt = txt.replace("\\n", "");\n' +
|
||||
' this.set(txt);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' }\n' +
|
||||
' };\n' +
|
||||
' this.getStyleClass().add("rich-text-area");\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final ObjectProperty<Document> documentProperty() {\n' +
|
||||
' return this.documentProperty;\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final Document getDocument() {\n' +
|
||||
' return (Document)this.documentProperty.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final void setDocument(Document value) {\n' +
|
||||
' this.documentProperty.set(value);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final BooleanProperty autoSaveProperty() {\n' +
|
||||
' return this.autoSaveProperty;\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final boolean isAutoSave() {\n' +
|
||||
' return this.autoSaveProperty.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final void setAutoSave(boolean value) {\n' +
|
||||
' this.autoSaveProperty.set(value);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final ReadOnlyBooleanProperty modifiedProperty() {\n' +
|
||||
' return this.modifiedProperty.getReadOnlyProperty();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final boolean isModified() {\n' +
|
||||
' return this.modifiedProperty.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final BooleanProperty editableProperty() {\n' +
|
||||
' return this.editableProperty;\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final boolean isEditable() {\n' +
|
||||
' return this.editableProperty.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final void setEditable(boolean value) {\n' +
|
||||
' this.editableProperty.set(value);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final ReadOnlyObjectProperty<Selection> selectionProperty() {\n' +
|
||||
' return this.selectionProperty.getReadOnlyProperty();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final Selection getSelection() {\n' +
|
||||
' return (Selection)this.selectionProperty.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final ReadOnlyIntegerProperty textLengthProperty() {\n' +
|
||||
' return this.textLengthProperty.getReadOnlyProperty();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final int getTextLength() {\n' +
|
||||
' return this.textLengthProperty.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final DoubleProperty contentAreaWidthProperty() {\n' +
|
||||
' return this.contentAreaWidthProperty;\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final double getContentAreaWidth() {\n' +
|
||||
' return this.contentAreaWidthProperty.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final void setContentAreaWidth(double value) {\n' +
|
||||
' this.contentAreaWidthProperty.set(value);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final ObjectProperty<BiFunction<Integer, GraphicType, Node>> paragraphGraphicFactoryProperty() {\n' +
|
||||
' return this.paragraphGraphicFactoryProperty;\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final BiFunction<Integer, GraphicType, Node> getParagraphGraphicFactory() {\n' +
|
||||
' return (BiFunction)this.paragraphGraphicFactoryProperty.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final void setParagraphGraphicFactory(BiFunction<Integer, GraphicType, Node> value) {\n' +
|
||||
' this.paragraphGraphicFactoryProperty.set(value);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final ObjectProperty<Function<Node, Consumer<String>>> linkCallbackFactoryProperty() {\n' +
|
||||
' return this.linkCallbackFactoryProperty;\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final Function<Node, Consumer<String>> getLinkCallbackFactory() {\n' +
|
||||
' return (Function)this.linkCallbackFactoryProperty.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final void setLinkCallbackFactory(Function<Node, Consumer<String>> value) {\n' +
|
||||
' this.linkCallbackFactoryProperty.set(value);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final ObjectProperty<EventHandler<ActionEvent>> onActionProperty() {\n' +
|
||||
' return this.onAction;\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final EventHandler<ActionEvent> getOnAction() {\n' +
|
||||
' return (EventHandler)this.onAction.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final void setOnAction(EventHandler<ActionEvent> value) {\n' +
|
||||
' this.onAction.set(value);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final ObjectProperty<EmojiSkinTone> skinToneProperty() {\n' +
|
||||
' return this.skinToneProperty;\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final EmojiSkinTone getSkinTone() {\n' +
|
||||
' return (EmojiSkinTone)this.skinToneProperty.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final void setSkinTone(EmojiSkinTone value) {\n' +
|
||||
' this.skinToneProperty.set(value);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final int getCaretPosition() {\n' +
|
||||
' return this.caretPosition.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final ReadOnlyIntegerProperty caretPositionProperty() {\n' +
|
||||
' return this.caretPosition.getReadOnlyProperty();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final BooleanProperty tableAllowedProperty() {\n' +
|
||||
' return this.tableAllowedProperty;\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final boolean isTableAllowed() {\n' +
|
||||
' return this.tableAllowedProperty.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final void setTableAllowed(boolean value) {\n' +
|
||||
' this.tableAllowedProperty.set(value);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final StringProperty promptTextProperty() {\n' +
|
||||
' return this.promptText;\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final String getPromptText() {\n' +
|
||||
' return (String)this.promptText.get();\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final void setPromptText(String value) {\n' +
|
||||
' this.promptText.set(value);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public final ActionFactory getActionFactory() {\n' +
|
||||
' return this.actionFactory;\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' protected SkinBase<RichTextArea> createDefaultSkin() {\n' +
|
||||
' return new RichTextAreaSkin(this);\n' +
|
||||
' }\n' +
|
||||
'\n' +
|
||||
' public String getUserAgentStylesheet() {\n' +
|
||||
' return this.getClass().getResource("rich-text-area.css").toExternalForm();\n' +
|
||||
' }\n' +
|
||||
'}';
|
||||
var edit_content = "";
|
||||
|
||||
var setModelLanguage;
|
||||
|
||||
require.config({ paths: { 'vs': './monaco-editor/min/vs' } });
|
||||
require.config({paths: {'vs': './monaco-editor/min/vs'}});
|
||||
require(['vs/editor/editor.main'], function () {
|
||||
var editorArray = [];
|
||||
|
||||
var defaultCode = [
|
||||
Areacode
|
||||
edit_content
|
||||
].join('\n');
|
||||
|
||||
// 定义编辑器主题
|
||||
monaco.editor.defineTheme('myTheme', {
|
||||
base: 'vs',
|
||||
inherit: true,
|
||||
rules: [{ background: 'EDF9FA' }],
|
||||
rules: [{background: 'EDF9FA'}],
|
||||
});
|
||||
monaco.editor.setTheme('myTheme');
|
||||
addNewEditor(defaultCode, 'java');
|
||||
});
|
||||
|
||||
var code_edit;
|
||||
|
||||
// 新建一个编辑器
|
||||
function newEditor(container_id, code, language) {
|
||||
|
|
@ -270,15 +62,13 @@
|
|||
minimap: {
|
||||
enabled: false, // 不要小地图
|
||||
},
|
||||
fontSize:20,
|
||||
fontSize: 18,
|
||||
lineNumbers: true,
|
||||
});
|
||||
|
||||
editor.onDidChangeCursorPosition((e) => {
|
||||
Areacode = editor.getValue();
|
||||
edit_content = editor.getValue();
|
||||
});
|
||||
|
||||
editorArray.push(editor);
|
||||
code_edit = editor;
|
||||
return editor;
|
||||
}
|
||||
|
||||
|
|
@ -289,27 +79,54 @@
|
|||
newEditor(new_container.id, code, language);
|
||||
}
|
||||
|
||||
addNewEditor(defaultCode, 'java');
|
||||
setModelLanguage = function setModelLanguage (language) {
|
||||
//设置语言
|
||||
function setModelLanguage(language) {
|
||||
monaco.editor.setModelLanguage(window.monaco.editor.getModels()[0], language)
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//设置语言
|
||||
setModelLanguag()
|
||||
|
||||
//获取值
|
||||
function getValue(){
|
||||
function getValue() {
|
||||
alert(edit_content)
|
||||
}
|
||||
|
||||
alert(Areacode)
|
||||
function setThem() {
|
||||
monaco.editor.setTheme('vs-dark');
|
||||
}
|
||||
|
||||
//获取所选文本
|
||||
function getSelected() {
|
||||
return code_edit.getModel().getValueInRange(code_edit.getSelection())
|
||||
}
|
||||
|
||||
//删除所选文本
|
||||
function removeSelectText(){
|
||||
// 触发查找操作
|
||||
getActionToTrigger('editor.action.deleteLines')
|
||||
}
|
||||
|
||||
function getActionToTrigger(id){
|
||||
code_edit.getAction(id).run().then(() => {
|
||||
console.log('运行成功')
|
||||
})
|
||||
}
|
||||
|
||||
function setValue(content){
|
||||
// 销毁当前的编辑器实例
|
||||
code_edit.dispose();
|
||||
addNewEditor(content, 'java');
|
||||
}
|
||||
|
||||
function setFont(){
|
||||
code_edit.updateOptions({
|
||||
fontSize:30
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root" ></div>
|
||||
<div id="root"></div>
|
||||
|
||||
</body>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue