2023年10月7日17:21:38
parent
a982e15507
commit
f3fc26c724
|
|
@ -0,0 +1,567 @@
|
|||
package com.zhangmeng.tools.controller;
|
||||
|
||||
import com.zhangmeng.tools.editors.ace.AceEditor;
|
||||
import com.zhangmeng.tools.utils.ImagePath;
|
||||
import com.zhangmeng.tools.utils.ResourcesUtils;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.control.SplitPane;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.scene.web.WebView;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Callback;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Slf4j
|
||||
public class EditListController {
|
||||
|
||||
private SimpleDoubleProperty width = new SimpleDoubleProperty(0.0);
|
||||
private SimpleDoubleProperty height = new SimpleDoubleProperty(0.0);
|
||||
private AceEditor root;
|
||||
|
||||
private AceEditor acJsEditor;
|
||||
|
||||
public static final String color_cell = "#f4f4f4";
|
||||
|
||||
@FXML
|
||||
private ListView<ResourcesUtils.EditorList> listView;
|
||||
|
||||
@FXML
|
||||
private SplitPane splitPane;
|
||||
|
||||
@FXML
|
||||
public void date_query_menu_item(){
|
||||
load_small_tools(5);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void cron_menu_item(){
|
||||
load_small_tools(6);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void video_menu_item() {
|
||||
load_player(0);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void music_menu_item() {
|
||||
load_player(1);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void vip_parser_menu_item() {
|
||||
load_player(2);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void hex_16(){
|
||||
load_small_tools(0);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void hex_16_menu_item(){
|
||||
load_small_tools(0);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void unicode_menu_item(){
|
||||
load_small_tools(1);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void jwt_menu_item(){
|
||||
load_small_tools(2);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void color_choose_menu_item(){
|
||||
load_small_tools(3);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void qr_code_menu_item(){
|
||||
load_small_tools(4);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void base_62_menu_item(){
|
||||
load_codec_tools(0);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void base_64_menu_item(){
|
||||
load_codec_tools(1);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void base_32_menu_item(){
|
||||
load_codec_tools(2);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void morse_coder_menu_item(){
|
||||
load_codec_tools(3);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void sql_code_gen_menu_item(){
|
||||
load_sql_tools(0);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void netty_client_menu_item(){
|
||||
load_network_tools(0);
|
||||
}
|
||||
|
||||
public void load_network_tools(int index){
|
||||
AnchorPane fx = null;
|
||||
try {
|
||||
fx = FXMLLoader.load(ResourcesUtils.getResource("network-tools"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Scene scene = new Scene(fx);
|
||||
Stage stage = (Stage) splitPane.getScene().getWindow();
|
||||
stage.setScene(scene);
|
||||
|
||||
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
|
||||
listView.getSelectionModel().select(index);
|
||||
}
|
||||
|
||||
public void load_sql_tools(int index){
|
||||
AnchorPane fx = null;
|
||||
try {
|
||||
fx = FXMLLoader.load(ResourcesUtils.getResource("sql-tools"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Scene scene = new Scene(fx);
|
||||
Stage stage = (Stage) splitPane.getScene().getWindow();
|
||||
stage.setScene(scene);
|
||||
|
||||
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
|
||||
listView.getSelectionModel().select(index);
|
||||
}
|
||||
|
||||
public void load_codec_tools(int index){
|
||||
AnchorPane fx = null;
|
||||
try {
|
||||
fx = FXMLLoader.load(ResourcesUtils.getResource("codec-tools"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Scene scene = new Scene(fx);
|
||||
Stage stage = (Stage) splitPane.getScene().getWindow();
|
||||
stage.setScene(scene);
|
||||
|
||||
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
|
||||
listView.getSelectionModel().select(index);
|
||||
}
|
||||
|
||||
public void load_small_tools(int index){
|
||||
AnchorPane fx = null;
|
||||
try {
|
||||
fx = FXMLLoader.load(ResourcesUtils.getResource("small-tools"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Scene scene = new Scene(fx);
|
||||
Stage stage = (Stage) splitPane.getScene().getWindow();
|
||||
stage.setScene(scene);
|
||||
|
||||
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
|
||||
listView.getSelectionModel().select(index);
|
||||
}
|
||||
|
||||
public void load_player(int index) {
|
||||
AnchorPane fx = null;
|
||||
try {
|
||||
fx = FXMLLoader.load(ResourcesUtils.getResource("player"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Scene scene = new Scene(fx);
|
||||
Stage stage = (Stage) splitPane.getScene().getWindow();
|
||||
stage.setScene(scene);
|
||||
|
||||
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
|
||||
listView.getSelectionModel().select(index);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
init();
|
||||
listView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
boolean flag = false;
|
||||
|
||||
if (newValue.getIndex() == 0) {
|
||||
if (acJsEditor != null){
|
||||
flag = true;
|
||||
}
|
||||
acJsEditor(flag);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Image getImage(ResourcesUtils.EditorList player){
|
||||
return switch (player){
|
||||
case Ace_JS -> new Image(ImagePath.path(ImagePath.ImagePathType.MD5));
|
||||
};
|
||||
}
|
||||
|
||||
public void init() {
|
||||
ResourcesUtils.EditorList[] values = ResourcesUtils.EditorList.values();
|
||||
ObservableList<ResourcesUtils.EditorList> list = FXCollections.observableArrayList();
|
||||
list.addAll(Arrays.asList(values));
|
||||
listView.setItems(list);
|
||||
listView.setFixedCellSize(40);
|
||||
listView.setCellFactory(new Callback<>() {
|
||||
private int position;
|
||||
@Override
|
||||
public ListCell<ResourcesUtils.EditorList> call(ListView<ResourcesUtils.EditorList> playerListView) {
|
||||
Label label = new Label();
|
||||
label.setPrefWidth(200);
|
||||
ListCell<ResourcesUtils.EditorList> listCell = new ListCell<>() {
|
||||
@Override
|
||||
protected void updateItem(ResourcesUtils.EditorList player, boolean b) {
|
||||
super.updateItem(player, b);
|
||||
if (!b) {
|
||||
HBox hBox = new HBox(25);
|
||||
hBox.setAlignment(Pos.CENTER);
|
||||
label.setText(player.getTitle());
|
||||
label.setTextFill(Paint.valueOf("#000000"));
|
||||
Image im = getImage(player);
|
||||
ImageView iv = new ImageView(im);
|
||||
iv.setPreserveRatio(true);
|
||||
iv.setFitWidth(15);
|
||||
hBox.getChildren().add(iv);
|
||||
|
||||
hBox.getChildren().add(label);
|
||||
this.setGraphic(hBox);
|
||||
}
|
||||
this.setStyle("-fx-background-color: " + color_cell);
|
||||
}
|
||||
};
|
||||
|
||||
listCell.hoverProperty().addListener((observableValue, aBoolean, t1) -> {
|
||||
if (t1 && !label.getText().equals("")) {
|
||||
position = playerListView.getItems().indexOf(label.getText());
|
||||
label.setFont(new Font(16));
|
||||
playerListView.getFocusModel().focus(position);
|
||||
listCell.setStyle("-fx-background-color: #369e7d");
|
||||
} else {
|
||||
label.setPrefHeight(20);
|
||||
label.setFont(new Font(13));
|
||||
listCell.setStyle("-fx-background-color: " + color_cell);
|
||||
}
|
||||
});
|
||||
|
||||
return listCell;
|
||||
}
|
||||
});
|
||||
|
||||
acJsEditor(false);
|
||||
}
|
||||
|
||||
private void acJsEditor(boolean flag) {
|
||||
//默认选择第一个
|
||||
listView.getSelectionModel().select(0);
|
||||
|
||||
if (!flag){
|
||||
root = new AceEditor();
|
||||
WebView webView = root.getWebView();
|
||||
webView.prefWidthProperty().bind(root.widthProperty());
|
||||
webView.prefHeightProperty().bind(root.heightProperty());
|
||||
|
||||
acJsEditor = root;
|
||||
}else {
|
||||
root = acJsEditor;
|
||||
}
|
||||
common_method();
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
EditListController.this.width.set(width);
|
||||
log.info("home:--->width:{}", width);
|
||||
}
|
||||
});
|
||||
root.heightProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
double height = splitPane.getHeight();
|
||||
EditListController.this.height.set(height);
|
||||
log.info("home:--->height:{}", height);
|
||||
}
|
||||
});
|
||||
|
||||
this.width.addListener((observable, oldValue, newValue) -> {
|
||||
EditListController.this.root.setPrefWidth(newValue.doubleValue() - listView.getWidth());
|
||||
});
|
||||
|
||||
this.height.addListener((observable, oldValue, newValue) -> {
|
||||
EditListController.this.root.setPrefHeight(newValue.doubleValue() - listView.getHeight());
|
||||
});
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void http_request_menu_item(ActionEvent event) {
|
||||
load_http_tools(0);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void http_upload_menu_item(ActionEvent event) {
|
||||
load_http_tools(1);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void http_download_menu_item(ActionEvent event) {
|
||||
load_http_tools(2);
|
||||
}
|
||||
|
||||
public void load_http_tools(int index) {
|
||||
AnchorPane fx = null;
|
||||
try {
|
||||
fx = FXMLLoader.load(ResourcesUtils.getResource("http-tools"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Scene scene = new Scene(fx);
|
||||
Stage stage = (Stage) splitPane.getScene().getWindow();
|
||||
stage.setScene(scene);
|
||||
|
||||
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
|
||||
listView.getSelectionModel().select(index);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void mail_menu_item(ActionEvent event) {
|
||||
load_small_tools(7);
|
||||
}
|
||||
|
||||
public void http_server_menu_item(ActionEvent event) {
|
||||
load_server_tools(0);
|
||||
}
|
||||
|
||||
public void ftp_server_menu_item(ActionEvent event) {
|
||||
load_server_tools(1);
|
||||
}
|
||||
|
||||
public void load_server_tools(int index) {
|
||||
AnchorPane fx = null;
|
||||
try {
|
||||
fx = FXMLLoader.load(ResourcesUtils.getResource("server-tools"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Scene scene = new Scene(fx);
|
||||
Stage stage = (Stage) splitPane.getScene().getWindow();
|
||||
stage.setScene(scene);
|
||||
|
||||
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
|
||||
listView.getSelectionModel().select(index);
|
||||
}
|
||||
|
||||
public void ssh_client_menu_item(ActionEvent event) {
|
||||
load_server_tools(2);
|
||||
}
|
||||
|
||||
public void socket_server_menu_item(ActionEvent event) {
|
||||
load_server_tools(3);
|
||||
}
|
||||
|
||||
public void telephone_menu_item(ActionEvent event) {
|
||||
load_small_tools(8);
|
||||
}
|
||||
|
||||
public void mybatis_plus_gen_menu_item(ActionEvent event) {
|
||||
load_sql_tools(1);
|
||||
}
|
||||
|
||||
public void JsonView_menu_item(ActionEvent event) {
|
||||
|
||||
load_small_tools(9);
|
||||
}
|
||||
|
||||
public void maven_jar_install_menu_item(ActionEvent event) {
|
||||
load_small_tools(10);
|
||||
}
|
||||
|
||||
public void word_ocr_menu_item(ActionEvent event) {
|
||||
load_small_tools(11);
|
||||
}
|
||||
|
||||
public void bar_code_menu_item(ActionEvent event) {
|
||||
load_small_tools(12);
|
||||
}
|
||||
|
||||
public void pdf_menu_item(ActionEvent event) {
|
||||
load_small_tools(13);
|
||||
}
|
||||
|
||||
public void json_javabean_gen_menu_item(ActionEvent event) {
|
||||
load_sql_tools(2);
|
||||
}
|
||||
|
||||
public void music_parser_menu_item(ActionEvent event) {
|
||||
load_player(3);
|
||||
}
|
||||
|
||||
public void batch_update_file_name_menu_item(ActionEvent event) {
|
||||
load_small_tools(14);
|
||||
}
|
||||
|
||||
public void socket_client_aio_menu_item(ActionEvent event) {
|
||||
load_server_tools(4);
|
||||
}
|
||||
|
||||
public void socket_server_aio_menu_item(ActionEvent event) {
|
||||
load_server_tools(5);
|
||||
}
|
||||
|
||||
public void socket_server_nio_menu_item(ActionEvent event) {
|
||||
load_server_tools(6);
|
||||
}
|
||||
|
||||
public void socket_client_nio_menu_item(ActionEvent event) {
|
||||
load_server_tools(7);
|
||||
}
|
||||
|
||||
public void capter_screen_menu_item(ActionEvent event) {
|
||||
load_small_tools(15);
|
||||
}
|
||||
|
||||
public void sql_query_gen_menu_item(ActionEvent event) {
|
||||
load_sql_tools(3);
|
||||
}
|
||||
|
||||
public void video_transcoder_menu_item(ActionEvent event) {
|
||||
load_player(4);
|
||||
}
|
||||
|
||||
public void json_to_struct_menu_item(ActionEvent event) {
|
||||
load_go_tools(0);
|
||||
}
|
||||
|
||||
public void load_go_tools(int index){
|
||||
AnchorPane fx = null;
|
||||
try {
|
||||
fx = FXMLLoader.load(ResourcesUtils.getResource("go-tools"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Scene scene = new Scene(fx);
|
||||
Stage stage = (Stage) splitPane.getScene().getWindow();
|
||||
stage.setScene(scene);
|
||||
|
||||
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
|
||||
listView.getSelectionModel().select(index);
|
||||
}
|
||||
|
||||
public void file_edit_menu_item(ActionEvent event) {
|
||||
load_small_tools(16);
|
||||
}
|
||||
|
||||
public void web_socket_client_menu_item(ActionEvent event) {
|
||||
load_server_tools(8);
|
||||
}
|
||||
|
||||
public void layui_form_gen_menu_item(ActionEvent actionEvent) {
|
||||
load_small_tools(17);
|
||||
}
|
||||
|
||||
public void log_console_menu_item(ActionEvent actionEvent) {
|
||||
load_small_tools(18);
|
||||
}
|
||||
|
||||
public void edit_plus_code_menu_item(ActionEvent actionEvent) {
|
||||
load_small_tools(19);
|
||||
}
|
||||
|
||||
public void minio_upload_menu_item(ActionEvent actionEvent) {
|
||||
load_small_tools(20);
|
||||
}
|
||||
|
||||
public void ace_js_menu_item(ActionEvent actionEvent) {
|
||||
js_edit_list(0);
|
||||
}
|
||||
|
||||
public void js_edit_list(int index){
|
||||
AnchorPane fx = null;
|
||||
try {
|
||||
fx = FXMLLoader.load(ResourcesUtils.getResource("editor-list"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Scene scene = new Scene(fx);
|
||||
Stage stage = (Stage) splitPane.getScene().getWindow();
|
||||
stage.setScene(scene);
|
||||
|
||||
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
|
||||
listView.getSelectionModel().select(index);
|
||||
}
|
||||
|
||||
public void md5_menu_item(ActionEvent actionEvent) {
|
||||
|
||||
load_encrypt(0);
|
||||
}
|
||||
|
||||
public void spring_security_menu_item(ActionEvent actionEvent) {
|
||||
load_encrypt(1);
|
||||
}
|
||||
|
||||
public void jks_file_menu_item(ActionEvent actionEvent) {
|
||||
load_encrypt(2);
|
||||
}
|
||||
|
||||
public void load_encrypt(int index) {
|
||||
|
||||
Stage stage = (Stage) splitPane.getScene().getWindow();
|
||||
|
||||
AnchorPane fx = null;
|
||||
try {
|
||||
fx = FXMLLoader.load(ResourcesUtils.getResource("home"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Scene scene = new Scene(fx);
|
||||
stage.setScene(scene);
|
||||
|
||||
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
|
||||
listView.getSelectionModel().select(index);
|
||||
}
|
||||
}
|
||||
|
|
@ -616,4 +616,26 @@ public class HomeController implements Serializable {
|
|||
public void minio_upload_menu_item(ActionEvent actionEvent) {
|
||||
load_small_tools(20);
|
||||
}
|
||||
|
||||
public void ace_js_menu_item(ActionEvent actionEvent) {
|
||||
|
||||
js_edit_list(0);
|
||||
}
|
||||
|
||||
public void js_edit_list(int index){
|
||||
AnchorPane fx = null;
|
||||
try {
|
||||
fx = FXMLLoader.load(ResourcesUtils.getResource("editor-list"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Scene scene = new Scene(fx);
|
||||
Stage stage = (Stage) splitPane.getScene().getWindow();
|
||||
stage.setScene(scene);
|
||||
|
||||
ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
|
||||
listView.getSelectionModel().select(index);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
package com.zhangmeng.tools.editors.ace;
|
||||
|
||||
|
||||
import com.zhangmeng.tools.utils.AlertUtils;
|
||||
import com.zhangmeng.tools.utils.ClipboardUtils;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.concurrent.Worker;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.web.WebEngine;
|
||||
import javafx.scene.web.WebView;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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日09:12:41
|
||||
* @version 1.0
|
||||
* js 编辑器 ace 实现
|
||||
*/
|
||||
@Slf4j
|
||||
public class AceEditor extends AnchorPane {
|
||||
|
||||
private final WebView webView = new WebView();
|
||||
private WebEngine engine;
|
||||
private AceMode mode = AceMode.JAVA;
|
||||
private JSObject window;
|
||||
private JSObject editor;
|
||||
private File file;
|
||||
|
||||
public WebView getWebView() {
|
||||
return webView;
|
||||
}
|
||||
|
||||
public AceEditor() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
public AceEditor(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 AceEditor(String text) {
|
||||
setText(text);
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void setText(String text) {
|
||||
this.text.set(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置内容
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
private void setAceText(String value) {
|
||||
editor.call("setValue", value, 1);
|
||||
// 或者调用js中定义好的方法
|
||||
// JSObject editor = (JSObject) engine.executeScript("window");
|
||||
// editor.call("setEditorValue", value);
|
||||
}
|
||||
|
||||
private final StringProperty text = new SimpleStringProperty("");
|
||||
|
||||
public StringProperty textProperty() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改主题
|
||||
*/
|
||||
private void setAceTheme(AceTheme aceTheme) {
|
||||
editor.call("setTheme", aceTheme.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题
|
||||
*/
|
||||
private final ObjectProperty<AceTheme> theme = new SimpleObjectProperty<>(AceTheme.CHROME);
|
||||
|
||||
public ObjectProperty<AceTheme> themeProperty() {
|
||||
return theme;
|
||||
}
|
||||
|
||||
public AceTheme getTheme() {
|
||||
return theme.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模式
|
||||
*/
|
||||
private void setAceMode(AceMode mode) {
|
||||
window.call("setEditorMode", mode.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑器是否只读
|
||||
*
|
||||
* @param val
|
||||
*/
|
||||
private void setAceReadOnly(boolean val) {
|
||||
//editor.call("setReadOnly", !val);
|
||||
setAceOption("readOnly", !val);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置ace.js配置项
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
private void setAceOption(String key, Object value) {
|
||||
editor.call("setOption", key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否可编辑
|
||||
*/
|
||||
private final BooleanProperty editable = new SimpleBooleanProperty(true); // 可编辑
|
||||
|
||||
public boolean isEditable() {
|
||||
return editable.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选定文本
|
||||
*
|
||||
* @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");
|
||||
}
|
||||
|
||||
private final BooleanProperty showGutter = new SimpleBooleanProperty(true);
|
||||
|
||||
public void setShowGutter(boolean showGutter) {
|
||||
this.showGutter.set(showGutter);
|
||||
}
|
||||
|
||||
public boolean isShowGutter() {
|
||||
return showGutter.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听值变化,这个由js触发调用。
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void textChange(String text) {
|
||||
//log.info(text);
|
||||
setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否显示左侧内容(行号,折叠符号区域)
|
||||
*
|
||||
* @param val
|
||||
*/
|
||||
private void setAceShowGutter(boolean val) {
|
||||
setAceOption("showGutter", val);
|
||||
}
|
||||
|
||||
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("AceEditor", this);
|
||||
editor = (JSObject) engine.executeScript("window.editor");
|
||||
setAceText(getText());
|
||||
setAceTheme(getTheme());
|
||||
setAceMode(mode);
|
||||
setAceReadOnly(isEditable());
|
||||
// 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());
|
||||
if (isEditable()) {
|
||||
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);
|
||||
setAceText(getText());
|
||||
}
|
||||
|
||||
});
|
||||
// 主题监听
|
||||
themeProperty().addListener((observable, oldValue, newValue) -> setAceTheme(newValue));
|
||||
// 是否可编辑
|
||||
editable.addListener((observable, oldValue, newValue) -> setAceReadOnly(newValue));
|
||||
showGutter.addListener((observable, oldValue, newValue) -> setAceShowGutter(newValue));
|
||||
}
|
||||
});
|
||||
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(AceHelper.getHtml(this.mode,AceTheme.XCODE_JS)); // 加载html资源
|
||||
// engine.load(""); // 同一时间多个WebView访问同一个资源时engine.executeScript();会返回undefined。
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
package com.zhangmeng.tools.editors.ace;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
|
||||
public class AceHelper {
|
||||
|
||||
private static final String ace_js = "/static/editors/ace-builds/src-min/ace.js";
|
||||
private static final String ext_language_tools_js = "/static/editors/ace-builds/src-min/ext-language_tools.js";
|
||||
|
||||
public static String getHtml(AceMode aceMode,AceTheme aceTheme) {
|
||||
String model_js = "/static/editors/ace-builds/src-min/" + aceMode.getName();
|
||||
|
||||
String theme_js = "/static/editors/ace-builds/src-min/" + aceTheme.getName();
|
||||
|
||||
try (
|
||||
InputStream aceJsStream = AceHelper.class.getResourceAsStream(ace_js);
|
||||
InputStream ext_language_tools = AceHelper.class.getResourceAsStream(ext_language_tools_js);
|
||||
InputStream modelJsStream = AceHelper.class.getResourceAsStream(model_js);
|
||||
InputStream themeJsStream = AceHelper.class.getResourceAsStream(theme_js);
|
||||
) {
|
||||
String html = """
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>AceDemo</title>
|
||||
<style>
|
||||
*{
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
}
|
||||
html,body{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
#editor-container{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: white;
|
||||
}
|
||||
.ace_editor.ace_autocomplete {
|
||||
width: 415px;
|
||||
z-index: 200000;
|
||||
border: 1px lightgray solid;
|
||||
position: fixed;
|
||||
box-shadow: 2px 3px 5px rgb(0 0 0 / 20%);
|
||||
line-height: 1.4;
|
||||
background: #fefefe;
|
||||
color: #111;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="editor-container" ></div>
|
||||
|
||||
""";
|
||||
|
||||
html += "<script>" + new String(Objects.requireNonNull(aceJsStream).readAllBytes(), StandardCharsets.UTF_8) + "</script>\n" +
|
||||
"<!--要更改主题,只需包含主题的JavaScript文件-->\n" +
|
||||
"\n" +
|
||||
"<script>" + new String(Objects.requireNonNull(themeJsStream).readAllBytes(), StandardCharsets.UTF_8) + "</script>\n" +
|
||||
"<!--默认情况下,编辑器只支持纯文本模式;许多其他语言作为单独的模块可用。在包含该模式的JavaScript文件后:-->\n" +
|
||||
"<script>" + new String(Objects.requireNonNull(modelJsStream).readAllBytes(), StandardCharsets.UTF_8) + "</script>\n" +
|
||||
"<script>" + new String(Objects.requireNonNull(ext_language_tools).readAllBytes(), StandardCharsets.UTF_8) +"</script>\n";
|
||||
|
||||
html += """
|
||||
<script>
|
||||
var editor = ace.edit("editor-container");
|
||||
// 使用主题:
|
||||
editor.setTheme("ace/theme/xcode");
|
||||
// 使用模式
|
||||
editor.session.setMode("ace/mode/java");
|
||||
|
||||
//字体大小
|
||||
editor.setFontSize(20);
|
||||
//editor.setValue(Areacode);
|
||||
|
||||
//启动提示
|
||||
var langTools = ace.require("ace/ext/language_tools");
|
||||
|
||||
editor.setOptions({
|
||||
showGutter: true, // 显示左侧内容(行号和折叠内容)
|
||||
lanuage: "java",
|
||||
showFoldWidgets: true, // 显示折叠小部件
|
||||
showLineNumbers: true, // 是否显示行号
|
||||
readOnly: false, // 设置只读(true时只读,用于展示代码)
|
||||
wrap: 'off', // 自动换行,off:关闭 , free:开启
|
||||
enableBasicAutocompletion: true,
|
||||
enableSnippets: true,
|
||||
enableLiveAutocompletion: true,
|
||||
showPrintMargin: false, // 打印边距
|
||||
});
|
||||
|
||||
// 设置模式
|
||||
function setEditorMode(mode){
|
||||
editor.session.setMode(mode);
|
||||
}
|
||||
|
||||
// 设置内容
|
||||
function setEditorValue(value){
|
||||
editor.setValue(value,1);
|
||||
// editor.setValue("text2", -1); // set value and move cursor to the start of the text
|
||||
// editor.session.setValue("the new text here"); // set value and reset undo history
|
||||
}
|
||||
|
||||
// 获取内容
|
||||
function getEditorValue(value){
|
||||
return editor.getValue(); // or session.getValue
|
||||
}
|
||||
|
||||
// 删除选中的内容
|
||||
function removeSelectRange(){
|
||||
var range = editor.getSelectionRange();
|
||||
editor.remove(range);
|
||||
}
|
||||
|
||||
// 监听窗口大小变化
|
||||
window.addEventListener('resize', function() {
|
||||
// 在这里执行窗口大小变化后的操作
|
||||
editor.resize();
|
||||
});
|
||||
|
||||
// 监听内容变化
|
||||
editor.on('change', function(delta) {
|
||||
// delta.start, delta.end, delta.lines, delta.action
|
||||
try{
|
||||
window.AceEditor.textChange(editor.getValue()); // 通知javafx(AceView)程序内容发生变化。
|
||||
}catch(err){
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>""";
|
||||
|
||||
return html;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.zhangmeng.tools.editors.ace;
|
||||
|
||||
public enum AceMode {
|
||||
|
||||
CSS("mode-css.js", "ace/mode/css"),
|
||||
HTML("mode-html.js", "ace/mode/html"),
|
||||
JAVA("mode-java.js", "ace/mode/java"),
|
||||
JAVASCRIPT("mode-javascript.js", "ace/mode/javascript"),
|
||||
JSON("mode-json.js", "ace/mode/json"),
|
||||
NGINX("mode-nginx.js", "ace/mode/nginx"),
|
||||
PROPERTIES("mode-properties.js", "ace/mode/properties"),
|
||||
SQL("mode-sql.js", "ace/mode/sql"),
|
||||
TEXT("mode-text.js", "ace/mode/text"),
|
||||
XML("mode-xml.js", "ace/mode/xml"),
|
||||
YAML("mode-yaml.js", "ace/mode/yaml"),
|
||||
MARKDOWN("mode-markdown.js", "ace/mode/markdown");
|
||||
|
||||
AceMode(String name, String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private final String name;
|
||||
|
||||
private final String value;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.zhangmeng.tools.editors.ace;
|
||||
|
||||
public enum AceTheme {
|
||||
|
||||
CHROME("theme-chrome.js", "ace/theme/chrome"),
|
||||
XCODE_JS("theme-xcode.js", "ace/theme/theme-xcode"),
|
||||
TOMORROW_NIGHT("theme-tomorrow_night.js", "ace/theme/tomorrow_night");
|
||||
|
||||
AceTheme(String name, String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private final String name;
|
||||
|
||||
private final String value;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
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) {
|
||||
editor.call("setValue", value, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模式
|
||||
*/
|
||||
private void setMonacoMode(MonacoMode mode) {
|
||||
window.call("setEditorMode", mode.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选定文本
|
||||
*
|
||||
* @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("window.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。
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,350 @@
|
|||
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 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' +
|
||||
'}';
|
||||
|
||||
require.config({ paths: { 'vs': './monaco-editor/min/vs' } });
|
||||
require(['vs/editor/editor.main'], function () {
|
||||
|
||||
var defaultCode = [
|
||||
Areacode
|
||||
].join('\\n');
|
||||
|
||||
// 定义编辑器主题
|
||||
monaco.editor.defineTheme('myTheme', {
|
||||
base: 'vs',
|
||||
inherit: true,
|
||||
rules: [{ background: 'EDF9FA' }],
|
||||
});
|
||||
monaco.editor.setTheme('myTheme');
|
||||
addNewEditor(defaultCode, 'java');
|
||||
});
|
||||
|
||||
|
||||
// 新建一个编辑器
|
||||
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) => {
|
||||
Areacode = editor.getValue();
|
||||
});
|
||||
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(Areacode)
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<button type="button" onclick="getValue()">获取文本</button>
|
||||
<button type="button" onclick="setModelLanguage('javascript')">设置语言</button>
|
||||
</div>
|
||||
<div id="root" ></div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
""";
|
||||
|
||||
return html;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
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,35 @@
|
|||
package com.zhangmeng.tools.utils;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.SnapshotParameters;
|
||||
import javafx.scene.input.Clipboard;
|
||||
import javafx.scene.input.ClipboardContent;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
/**
|
||||
* 剪贴板工具
|
||||
*/
|
||||
public class ClipboardUtils {
|
||||
|
||||
private static final Clipboard SYSTEM_CLIPBOARD = Clipboard.getSystemClipboard();
|
||||
private static final ClipboardContent CLIPBOARD_CONTENT = new ClipboardContent();
|
||||
|
||||
public static void setString(String val) {
|
||||
CLIPBOARD_CONTENT.clear();
|
||||
CLIPBOARD_CONTENT.putString(val);
|
||||
SYSTEM_CLIPBOARD.setContent(CLIPBOARD_CONTENT);
|
||||
}
|
||||
|
||||
public static String getString() {
|
||||
return SYSTEM_CLIPBOARD.getString();
|
||||
}
|
||||
|
||||
public static void setSnapshotImage(Node node) {
|
||||
SnapshotParameters snapshotParameters = new SnapshotParameters();
|
||||
snapshotParameters.setFill(Color.TRANSPARENT); // 透明背景
|
||||
CLIPBOARD_CONTENT.clear();
|
||||
CLIPBOARD_CONTENT.putImage(node.snapshot(snapshotParameters, null)); // 设置剪贴板内容
|
||||
SYSTEM_CLIPBOARD.setContent(CLIPBOARD_CONTENT);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -358,4 +358,34 @@ public class ResourcesUtils {
|
|||
private String title;
|
||||
private int index;
|
||||
}
|
||||
|
||||
public enum EditorList {
|
||||
|
||||
Ace_JS("ace.js 编辑器", 0),
|
||||
;
|
||||
|
||||
EditorList(String title, int index) {
|
||||
this.title = title;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
private String title;
|
||||
private int index;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.Menu?>
|
||||
<?import javafx.scene.control.MenuBar?>
|
||||
<?import javafx.scene.control.MenuItem?>
|
||||
<?import javafx.scene.control.SplitPane?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
|
||||
<AnchorPane prefHeight="800.0"
|
||||
prefWidth="1661.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="com.zhangmeng.tools.controller.EditListController">
|
||||
<children>
|
||||
<MenuBar layoutX="14.0" layoutY="27.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
|
||||
AnchorPane.topAnchor="0.0">
|
||||
<menus>
|
||||
<Menu mnemonicParsing="false" text="加密工具">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" onAction="#md5_menu_item" text="md5 加密"/>
|
||||
<MenuItem mnemonicParsing="false" onAction="#spring_security_menu_item" text="spring security 加密"/>
|
||||
<MenuItem mnemonicParsing="false" onAction="#jks_file_menu_item" text="jkd 文件生成"/>
|
||||
|
||||
</items>
|
||||
</Menu>
|
||||
<Menu mnemonicParsing="false" text="影音工具">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="视频播放" onAction="#video_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="音乐播放" onAction="#music_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="vip 视频解析" onAction="#vip_parser_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="音乐解析" onAction="#music_parser_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="视频转码" onAction="#video_transcoder_menu_item"/>
|
||||
</items>
|
||||
</Menu>
|
||||
<Menu mnemonicParsing="false" text="常用小工具">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="16进制(Hex)" onAction="#hex_16_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="Unicode和字符串转换" onAction="#unicode_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="jwt工具" onAction="#jwt_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="颜色选择工具" onAction="#color_choose_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="二维码生成" onAction="#qr_code_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="时间工具" onAction="#date_query_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="cron表达式" onAction="#cron_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="邮件发送" onAction="#mail_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="手机号工具" onAction="#telephone_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="JsonView" onAction="#JsonView_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="maven-jar-install" onAction="#maven_jar_install_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="word-ocr" onAction="#word_ocr_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="条形码识别" onAction="#bar_code_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="pdf识别" onAction="#pdf_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="批量修改文件名" onAction="#batch_update_file_name_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="截图工具" onAction="#capter_screen_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="文件编辑器" onAction="#file_edit_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="LayUI表单代码生成" onAction="#layui_form_gen_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="日志输出" onAction="#log_console_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="EditPlus注册码生成" onAction="#edit_plus_code_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="minio文件上传" onAction="#minio_upload_menu_item"/>
|
||||
</items>
|
||||
</Menu>
|
||||
|
||||
<Menu mnemonicParsing="false" text="编解码工具">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="Base62编码解码" onAction="#base_62_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="Base64编码解码" onAction="#base_64_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="Base32编码解码" onAction="#base_32_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="摩尔斯电码" onAction="#morse_coder_menu_item"/>
|
||||
</items>
|
||||
</Menu>
|
||||
|
||||
<Menu mnemonicParsing="false" text="代码工具">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="mysql代码生成" onAction="#sql_code_gen_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="mybatis-plus 代码生成" onAction="#mybatis_plus_gen_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="json转javaBean 代码生成" onAction="#json_javabean_gen_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="sql 查询" onAction="#sql_query_gen_menu_item"/>
|
||||
</items>
|
||||
</Menu>
|
||||
|
||||
<Menu mnemonicParsing="false" text="http工具">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="http请求工具" onAction="#http_request_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="http上传工具" onAction="#http_upload_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="http下载工具" onAction="#http_download_menu_item"/>
|
||||
</items>
|
||||
</Menu>
|
||||
|
||||
<Menu mnemonicParsing="false" text="server 工具">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="http-server 请求工具" onAction="#http_server_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="ftp-server 请求工具" onAction="#ftp_server_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="ssh-client 请求工具" onAction="#ssh_client_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="socket-server 服务工具" onAction="#socket_server_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="socket-client-aio 客户端工具" onAction="#socket_client_aio_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="socket-server-aio 服务端工具" onAction="#socket_server_aio_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="socket-server-nio 服务端工具" onAction="#socket_server_nio_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="socket-client-nio 客户端工具" onAction="#socket_client_nio_menu_item"/>
|
||||
<MenuItem mnemonicParsing="false" text="web-socket-client 客户端工具" onAction="#web_socket_client_menu_item"/>
|
||||
</items>
|
||||
</Menu>
|
||||
|
||||
<Menu mnemonicParsing="false" text="go语言工具">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="json生成结构体" onAction="#json_to_struct_menu_item"/>
|
||||
</items>
|
||||
</Menu>
|
||||
|
||||
<Menu mnemonicParsing="false" text="编辑器工具">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="ace.js 编辑器" onAction="#ace_js_menu_item"/>
|
||||
</items>
|
||||
</Menu>
|
||||
</menus>
|
||||
</MenuBar>
|
||||
<SplitPane fx:id="splitPane" dividerPositions="0.5" layoutY="25.0" prefHeight="575.0" prefWidth="1200.0"
|
||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
|
||||
AnchorPane.topAnchor="25.0">
|
||||
<items>
|
||||
<ListView fx:id="listView" maxWidth="300.0" minWidth="200.0" prefHeight="200.0" prefWidth="200.0"/>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0"/>
|
||||
</items>
|
||||
</SplitPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
|
@ -102,6 +102,13 @@
|
|||
<MenuItem mnemonicParsing="false" text="json生成结构体" onAction="#json_to_struct_menu_item"/>
|
||||
</items>
|
||||
</Menu>
|
||||
|
||||
<Menu mnemonicParsing="false" text="编辑器工具">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="ace.js 编辑器" onAction="#ace_js_menu_item"/>
|
||||
</items>
|
||||
</Menu>
|
||||
|
||||
</menus>
|
||||
</MenuBar>
|
||||
<SplitPane fx:id="splitPane" dividerPositions="0.5" layoutY="25.0" prefHeight="575.0" prefWidth="1200.0"
|
||||
|
|
|
|||
|
|
@ -19,6 +19,17 @@
|
|||
width: 100%;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.ace_editor.ace_autocomplete {
|
||||
width: 415px;
|
||||
z-index: 200000;
|
||||
border: 1px lightgray solid;
|
||||
position: fixed;
|
||||
box-shadow: 2px 3px 5px rgb(0 0 0 / 20%);
|
||||
line-height: 1.4;
|
||||
background: #fefefe;
|
||||
color: #111;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -36,218 +47,6 @@
|
|||
<script src="./ace-builds/src-min/ext-language_tools.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script>
|
||||
|
||||
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 editor = ace.edit("editor-container");
|
||||
// 使用主题:
|
||||
editor.setTheme("ace/theme/xcode");
|
||||
|
|
|
|||
Loading…
Reference in New Issue