From ec9eace48c42780ee3bf1bcf0671dda86f86743e Mon Sep 17 00:00:00 2001 From: zhangmeng <1334717033@qq.com> Date: Mon, 9 Oct 2023 18:19:15 +0800 Subject: [PATCH] =?UTF-8?q?2023=E5=B9=B410=E6=9C=889=E6=97=A518:19:01?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/EditorListImplController.java | 879 ++++++++++++++++++ .../tools/controller/HomeController.java | 36 + .../com/zhangmeng/tools/dto/FileTreeView.java | 406 ++++++++ .../tools/editors/ace/AceEditor.java | 16 +- .../tools/editors/ace/AceHelper.java | 36 +- src/main/resources/fxml/editor-list-impl.fxml | 135 +++ src/main/resources/fxml/home.fxml | 10 + 7 files changed, 1495 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/zhangmeng/tools/controller/EditorListImplController.java create mode 100644 src/main/java/com/zhangmeng/tools/dto/FileTreeView.java create mode 100644 src/main/resources/fxml/editor-list-impl.fxml diff --git a/src/main/java/com/zhangmeng/tools/controller/EditorListImplController.java b/src/main/java/com/zhangmeng/tools/controller/EditorListImplController.java new file mode 100644 index 0000000..cdef5dd --- /dev/null +++ b/src/main/java/com/zhangmeng/tools/controller/EditorListImplController.java @@ -0,0 +1,879 @@ +package com.zhangmeng.tools.controller; + +import com.zhangmeng.tools.dto.FileTreeView; +import com.zhangmeng.tools.editors.ace.AceEditor; +import com.zhangmeng.tools.editors.ace.AceMode; +import com.zhangmeng.tools.editors.codemirr.CodeMirrWebView; +import com.zhangmeng.tools.editors.monaco.*; +import com.zhangmeng.tools.editors.timifx.TimiFxEditor; +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.property.SimpleObjectProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +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.*; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseButton; +import javafx.scene.input.MouseEvent; +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 org.apache.commons.io.FilenameUtils; +import org.fxmisc.flowless.VirtualizedScrollPane; +import org.fxmisc.richtext.CodeArea; + +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.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; + +import static net.imyeyu.timifx.TimiFX.BORDER_EXLEFT; + +@Slf4j +public class EditorListImplController { + + public enum Type { + + JAVA, + HTML, + GO, + JS, + CSS, + SQL, + XML, + YML, + MARKDOWN + } + + private SimpleDoubleProperty width = new SimpleDoubleProperty(0.0); + private SimpleDoubleProperty height = new SimpleDoubleProperty(0.0); + private AnchorPane root; + + private AceEditor acJsEditor; + private MonacoWebView monacoEdit; + private CodeMirrWebView codemirror; + private AnchorPane timiFx; + + private SimpleObjectProperty choose_file = new SimpleObjectProperty<>(null); + + public static final String color_cell = "#f4f4f4"; + + @FXML + private ListView 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 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 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 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 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 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); + } + + if (newValue.getIndex() == 1) { + if (monacoEdit != null) { + flag = true; + } + monacoEdit(flag); + } + + if (newValue.getIndex() == 2) { + if (codemirror != null) { + flag = true; + } + codemirror(flag); + } + + if (newValue.getIndex() == 3) { + if (timiFx != null) { + flag = true; + } + timiFx(flag); + } + } + }); + } + + public static Image getImage(ResourcesUtils.EditorList player) { + return switch (player) { + case Ace_JS -> new Image(ImagePath.path(ImagePath.ImagePathType.MD5)); + case Monaco_JS -> new Image(ImagePath.path(ImagePath.ImagePathType.MD5)); + case CodeMirror_JS -> new Image(ImagePath.path(ImagePath.ImagePathType.MD5)); + case Timi_Fx -> new Image(ImagePath.path(ImagePath.ImagePathType.MD5)); + }; + } + + public void init() { + ResourcesUtils.EditorList[] values = ResourcesUtils.EditorList.values(); + ObservableList list = FXCollections.observableArrayList(); + list.addAll(Arrays.asList(values)); + listView.setItems(list); + listView.setFixedCellSize(40); + listView.setCellFactory(new Callback<>() { + private int position; + + @Override + public ListCell call(ListView playerListView) { + Label label = new Label(); + label.setPrefWidth(200); + ListCell 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) { + acJsEditor = new AceEditor(); + root = acJsEditor; + 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; + } + common_method(); + } + + private void monacoEdit(boolean flag) { + + //默认选择第一个 + listView.getSelectionModel().select(1); + if (!flag) { + monacoEdit = new MonacoWebView(); + root = monacoEdit; + } else { + root = monacoEdit; + } + common_method(); + } + + private void codemirror(boolean flag) { + + //默认选择第一个 + listView.getSelectionModel().select(2); + if (!flag) { + codemirror = new CodeMirrWebView(); + root = codemirror; + } else { + root = codemirror; + } + common_method(); + } + + private void timiFx(boolean flag) { + + //默认选择第一个 + listView.getSelectionModel().select(3); + if (!flag) { + root = new TimiFxEditor(); + timiFx = root; + } else { + root = timiFx; + } + common_method(); + } + + public void writer_file() { + + log.info("writer_file__path:" + choose_file.get().getName()); + + int index = listView.getSelectionModel().getSelectedIndex(); + String text = null; + switch (index) { + case 0 -> text = acJsEditor.getText(); + case 1 -> text = monacoEdit.text_code.getValue(); + case 2 -> text = codemirror.text_code.getValue(); + } + + try { + FileWriter writer = new FileWriter(choose_file.get()); + writer.write(text); + writer.flush(); + writer.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + AlertUtils.alert_warning("tab " + choose_file.get().getName() + "保存成功!"); + } + + public void file_checked(File file) { + String extension = FilenameUtils.getExtension(file.getName()); + boolean flag = true; + + if (extension.equals("mp4")) { + flag = false; + } + + if (extension.equals("jpg")) { + flag = false; + } + + if (extension.equals("png")) { + flag = false; + } + + if (extension.equals("avi")) { + flag = false; + } + + if (extension.equals("zip")) { + flag = false; + } + + if (extension.equals("ico")) { + flag = false; + } + + if (extension.equals("exe")) { + flag = false; + } + if (flag) { + Type type = null; + + if (extension.equals("java")) { + type = Type.JAVA; + } + + if (extension.equals("go")) { + type = Type.GO; + } + if (extension.equals("html")) { + type = Type.HTML; + } + if (extension.equals("sql")) { + type = Type.SQL; + } + if (extension.equals("xml")) { + type = Type.XML; + } + if (extension.equals("yml")) { + type = Type.YML; + } + if (type == null) { + type = Type.JAVA; + } + if (type == null) { + type = Type.MARKDOWN; + } + open_file(file, type); + } else { + AlertUtils.alert_warning("该文件不支持!"); + } + } + + public void open_file(File file, Type type) { + + String file_content = null; + try { + file_content = Files.readString(choose_file.get().toPath(), StandardCharsets.UTF_8); + } catch (IOException e) { + try { + file_content = Files.readString(choose_file.get().toPath(), Charset.forName("GBK")); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + int index = listView.getSelectionModel().getSelectedIndex(); + + switch (index) { + case 0 -> { + + switch (type){ + case JAVA -> acJsEditor.setAceMode(AceMode.JAVA); + case HTML -> acJsEditor.setAceMode(AceMode.HTML); + case XML -> acJsEditor.setAceMode(AceMode.XML); + case SQL -> acJsEditor.setAceMode(AceMode.SQL); + case MARKDOWN -> acJsEditor.setAceMode(AceMode.MARKDOWN); + } + + acJsEditor.setAceText(file_content); + } + case 1 -> monacoEdit.setText(file_content); + case 2 -> codemirror.setText(file_content); + } + } + + private void common_method() { + //splitPane.getItems().remove(1); + + splitPane.getItems().clear(); + //添加文件选择 + File file = new File("D:\\generate"); + + FileTreeView fileTreeView = new FileTreeView(file); + fileTreeView.setBorder(BORDER_EXLEFT); + //fileTreeView.addItemFilter(file -> file.isDirectory() || file.getName().endsWith(".txt")); + splitPane.getItems().add(0, fileTreeView); + splitPane.getItems().add(1, root); + splitPane.setDividerPosition(0, 0.2); + splitPane.setDividerPosition(1, 0.8); + + fileTreeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener>() { + @Override + public void changed(ObservableValue> observable, TreeItem oldValue, TreeItem newValue) { + if (newValue != null) { + File value = newValue.getValue(); + if (!value.isDirectory()) { + choose_file.setValue(value); + log.info("selectedItemProperty:------------>:" + value.getName()); + } + } + } + + }); + + + fileTreeView.setOnMouseClicked(event -> { + if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2) { + // 双击左键的操作 + log.info("open file:" + choose_file.get().getName()); + file_checked(choose_file.get()); + } + }); + + root.widthProperty().addListener((observable, oldValue, newValue) -> { + if (newValue != null) { + double width = splitPane.getWidth(); + EditorListImplController.this.width.set(width); + log.info("home:--->width:{}", width); + } + }); + root.heightProperty().addListener((observable, oldValue, newValue) -> { + if (newValue != null) { + double height = splitPane.getHeight(); + EditorListImplController.this.height.set(height); + log.info("home:--->height:{}", height); + } + }); + + this.width.addListener((observable, oldValue, newValue) -> { + EditorListImplController.this.root.setPrefWidth(newValue.doubleValue() - listView.getWidth()); + log.info("root:=====================>width:" + (newValue.doubleValue() - listView.getWidth())); + }); + + this.height.addListener((observable, oldValue, newValue) -> { + EditorListImplController.this.root.setPrefHeight(newValue.doubleValue() - listView.getHeight()); + log.info("root:=====================>:height" + (newValue.doubleValue() - listView.getWidth())); + }); + } + + @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 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 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 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 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 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 listView = (ListView) fx.lookup("#listView"); + listView.getSelectionModel().select(index); + } + + public void ace_js_menu_item(ActionEvent actionEvent) { + js_edit_list(0); + } + + public void monaco_js_menu_item(ActionEvent actionEvent) { + js_edit_list(1); + } + + public void codemirror_js_menu_item(ActionEvent actionEvent) { + js_edit_list(2); + } + + public void timeFx_fx_menu_item(ActionEvent actionEvent) { + js_edit_list(3); + } + + public void ace_menu_item(ActionEvent actionEvent) { + boolean flag = false; + if (acJsEditor != null) { + flag = true; + } + acJsEditor(flag); + } + + public void monaco_menu_item(ActionEvent actionEvent) { + boolean flag = false; + if (monacoEdit != null) { + flag = true; + } + monacoEdit(flag); + } + + public void codemirror_menu_item(ActionEvent actionEvent) { + boolean flag = false; + if (codemirror != null) { + flag = true; + } + codemirror(flag); + } + + public void timeFx_menu_item(ActionEvent actionEvent) { + boolean flag = false; + if (timiFx != null) { + flag = true; + } + timiFx(flag); + } +} diff --git a/src/main/java/com/zhangmeng/tools/controller/HomeController.java b/src/main/java/com/zhangmeng/tools/controller/HomeController.java index 4ee194a..0420897 100644 --- a/src/main/java/com/zhangmeng/tools/controller/HomeController.java +++ b/src/main/java/com/zhangmeng/tools/controller/HomeController.java @@ -645,4 +645,40 @@ public class HomeController implements Serializable { public void codemirror_js_menu_item(ActionEvent actionEvent) { js_edit_list(2); } + + public void ace_menu_item(ActionEvent actionEvent) { + js_edit_list_impl(0); + } + + public void monaco_menu_item(ActionEvent actionEvent) { + js_edit_list_impl(1); + } + + public void codemirror_menu_item(ActionEvent actionEvent) { + js_edit_list_impl(2); + } + + public void timeFx_menu_item(ActionEvent actionEvent) { + js_edit_list_impl(3); + } + + public void js_edit_list_impl(int index){ + AnchorPane fx = null; + try { + fx = FXMLLoader.load(ResourcesUtils.getResource("editor-list-impl")); + } catch (IOException e) { + e.printStackTrace(); + } + + Scene scene = new Scene(fx); + Stage stage = (Stage) splitPane.getScene().getWindow(); + stage.setScene(scene); + +// ListView listView = (ListView) fx.lookup("#listView"); +// listView.getSelectionModel().select(index); + } + + public void timeFx_fx_menu_item(ActionEvent actionEvent) { + js_edit_list(3); + } } \ No newline at end of file diff --git a/src/main/java/com/zhangmeng/tools/dto/FileTreeView.java b/src/main/java/com/zhangmeng/tools/dto/FileTreeView.java new file mode 100644 index 0000000..bf5b562 --- /dev/null +++ b/src/main/java/com/zhangmeng/tools/dto/FileTreeView.java @@ -0,0 +1,406 @@ +package com.zhangmeng.tools.dto; + +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by FernFlower decompiler) +// + + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javafx.application.Platform; +import javafx.beans.Observable; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.BooleanBinding; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.control.MenuItem; +import javafx.scene.control.TreeCell; +import javafx.scene.control.TreeItem; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.scene.text.Text; +import javax.naming.NoPermissionException; +import net.imyeyu.timifx.TimiFX; +import net.imyeyu.timifx.component.ContextMenu; +import net.imyeyu.timifx.component.XTreeView; +import net.imyeyu.timifx.component.alert.AlertConfirm; +import net.imyeyu.timifx.component.alert.AlertTextField; +import net.imyeyu.timifx.component.alert.AlertTips; +import net.imyeyu.timifx.component.alert.AlertButton.Action; +import net.imyeyu.timifx.icon.TimiFXIcon; +import net.imyeyu.timifx.service.RunAsync; +import net.imyeyu.timijava.IO; +import net.imyeyu.timijava.Lang; +import net.imyeyu.timijava.TimiJava; +import net.imyeyu.timijava.bean.CallbackReturn; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileTreeView extends XTreeView implements TimiFX { + private static final Logger log = LoggerFactory.getLogger(net.imyeyu.timifx.component.FileTreeView.class); + protected final BooleanBinding findingItem; + protected final BooleanProperty showHide = new SimpleBooleanProperty(false); + protected final ObservableList selectDeque = FXCollections.synchronizedObservableList(FXCollections.observableArrayList()); + protected final List> itemFilters = new ArrayList(); + + public FileTreeView(File root) { + this.findingItem = Bindings.isNotEmpty(this.selectDeque); + this.disableProperty().bind(this.findingItem); + this.setCellFactory((cell) -> { + return new TreeCell() { + final Label loading = new Label(Lang.text("public.loading")); + final Text iconFile = TimiFXIcon.fromName("FILE"); + final Text iconDirectory = TimiFXIcon.fromName("FOLDER"); + + { + this.iconFile.fillProperty().bind(Bindings.when(FileTreeView.this.focusedProperty().and(this.selectedProperty())).then(TimiFX.GRAY_WHITE).otherwise(TimiFX.GRAY)); + this.iconDirectory.fillProperty().bind(Bindings.when(FileTreeView.this.focusedProperty().and(this.selectedProperty())).then(TimiFX.GRAY_WHITE).otherwise(TimiFX.GRAY)); + } + + protected void updateItem(File file, boolean empty) { + super.updateItem(file, empty); + if (empty) { + this.setText(""); + this.setGraphic((Node)null); + } else if (file == null) { + this.setGraphic(this.loading); + } else { + if (TimiJava.isEmpty(file.getName())) { + this.setText(file.toString()); + } else { + this.setText(file.getName()); + } + + this.setGraphic(file.isFile() ? this.iconFile : this.iconDirectory); + } + + } + }; + }); + MenuItem menuMkdir = new MenuItem(Lang.text("timifx.file.mkdir"), TimiFXIcon.fromName("FOLDER_ADD")); + MenuItem menuRename = new MenuItem(Lang.text("public.rename")); + MenuItem menuRefresh = new MenuItem(Lang.text("public.refresh"), TimiFXIcon.fromName("REFRESH")); + MenuItem menuDestroy = new MenuItem(Lang.text("public.delete"), TimiFXIcon.fromName("FAIL", RED)); + this.setContextMenu(new ContextMenu(new MenuItem[]{menuMkdir, menuRename, menuRefresh, TimiFX.sep(), menuDestroy})); + menuMkdir.disableProperty().bind(menuRefresh.disableProperty()); + menuMkdir.setOnAction((e) -> { + this.mkdir((TreeItem)this.getSelectionModel().getSelectedItem()); + }); + menuRename.disableProperty().bind(TimiFX.onlyOnceInList(this.getSelectionModel().getSelectedItems()).not()); + menuRename.setOnAction((e) -> { + this.rename((TreeItem)this.getSelectionModel().getSelectedItem()); + }); + menuRefresh.disableProperty().bind(Bindings.createBooleanBinding(() -> { + List> items = this.getSelectionModel().getSelectedItems(); + return items == null || items.size() != 1 || ((File)((TreeItem)items.get(0)).getValue()).isFile(); + }, new Observable[]{this.getSelectionModel().selectedItemProperty()})); + menuRefresh.setOnAction((e) -> { + this.refreshItem((TreeItem)this.getSelectionModel().getSelectedItem()); + }); + + + List roots = new ArrayList<>(); + roots.add(root); + + + menuDestroy.disableProperty().bind(Bindings.createBooleanBinding(() -> { + ObservableList> items = this.getSelectionModel().getSelectedItems(); + if (items.isEmpty()) { + return true; + } else { + for(int i = 0; i < items.size(); ++i) { + if (roots.contains(((TreeItem)items.get(i)).getValue())) { + return true; + } + } + + return false; + } + }, new Observable[]{this.getSelectionModel().getSelectedItems()})); + menuDestroy.setOnAction((e) -> { + this.destroy(this.getSelectionModel().getSelectedItems()); + }); + this.addEventFilter(KeyEvent.KEY_RELEASED, (e) -> { + boolean control = e.isControlDown(); + boolean shift = e.isShiftDown(); + boolean alt = e.isAltDown(); + KeyCode code = e.getCode(); + if (!control && !shift && !alt) { + switch(code) { + case F2: + menuRename.fire(); + break; + case F5: + menuRefresh.fire(); + break; + case DELETE: + menuDestroy.fire(); + } + } + + if (control && shift && !alt && code == KeyCode.N) { + menuMkdir.fire(); + } + + }); + CallbackReturn filterHidden = (file) -> { + return !file.isHidden(); + }; + this.itemFilters.add(filterHidden); + this.showHide.addListener((obs, o, n) -> { + if (this.isShowHide()) { + this.itemFilters.remove(filterHidden); + } else { + this.itemFilters.add(filterHidden); + } + + }); + + for(int i = 0; i < roots.size(); ++i) { + this.getRoots().add(new FileItem((File)roots.get(i))); + } + + } + + public void mkdir(TreeItem base) { + if (base != null) { + AlertTextField alert = new AlertTextField(Lang.text("timifx.file.mkdir")); + alert.setTips(Lang.text("public.name")); + alert.setOnActionEvent((action) -> { + if (action == Action.CONFIRM) { + try { + String var10000 = IO.fitPath(((File)base.getValue()).getAbsolutePath()); + IO.dir(var10000 + alert.getText()); + this.refreshItem((TreeItem)this.getSelectionModel().getSelectedItem()); + } catch (NoPermissionException var5) { + var5.printStackTrace(); + } + } + + return true; + }); + alert.autoSize().showRelativeCenter(this.getScene().getWindow()); + } + } + + public void rename(TreeItem file) { + if (file != null) { + AlertTextField alert = new AlertTextField(Lang.text("timifx.file.rename")); + alert.setTips(Lang.text("public.name")); + alert.setOnActionEvent((action) -> { + if (action == Action.CONFIRM) { + IO.rename((File)((TreeItem)this.getSelectionModel().getSelectedItem()).getValue(), alert.getText()); + this.refreshItem(((TreeItem)this.getSelectionModel().getSelectedItem()).getParent()); + } + + return true; + }); + alert.autoSize().showRelativeCenter(this.getScene().getWindow()); + } + } + + public void destroy(final List> files) { + if (!TimiJava.isEmpty(files)) { + (new AlertConfirm(Lang.text("timifx.file.destroy")) { + protected void onConfirm() { + (new RunAsync>() { + protected TreeItem call() { + List items = files.stream().map(TreeItem::getValue).toList(); + + int l; + for(l = 0; l < items.size(); ++l) { + IO.destroy((File)items.get(l)); + } + + l = 2147483647; + TreeItem item = null; + + for(int i = 0; i < items.size(); ++i) { + int j = FileTreeView.this.getTreeItemLevel((TreeItem)files.get(i)); + if (j < l) { + l = j; + item = (TreeItem)files.get(i); + if (item.getParent() != null) { + item = item.getParent(); + } + } + } + + return item; + } + + protected void onFinish(TreeItem item) { + if (item != null) { + FileTreeView.this.refreshItem(item); + } + + } + + protected void onException(Throwable e) { + log.error("destroy fail", e); + AlertTips.error(getScene().getWindow(), Lang.text("timifx.file.destroy_fail")); + } + }).start(); + } + }).autoSize().showRelativeCenter(this.getScene().getWindow()); + } + } + + public void refreshItem(TreeItem treeItem) { + if (treeItem instanceof net.imyeyu.timifx.component.FileTreeView.FileItem) { + FileTreeView.FileItem fileItem = (FileTreeView.FileItem)treeItem; + fileItem.getChildren().clear(); + fileItem.getChildren().add(new FileTreeView.FileItem()); + fileItem.asyncLoadChildren(); + } + + } + + public void refreshItem(FileTreeView.FileItem fileItem) { + fileItem.getChildren().clear(); + fileItem.getChildren().add(new FileTreeView.FileItem()); + fileItem.asyncLoadChildren(); + } + + public void selectItem(String path) { + if (TimiJava.isEmpty(path)) { + path = "./"; + } + + this.selectItem(new File(path)); + } + + public void selectItem(File file) { + File parent = file.getAbsoluteFile(); + if (!parent.exists()) { + parent = (new File("./")).getAbsoluteFile(); + } + + do { + this.selectDeque.add(0, parent); + } while((parent = parent.getParentFile()) != null); + + if (TimiJava.isNotEmpty(this.selectDeque)) { + ObservableList> roots = this.getRoots(); + + for(int i = 0; i < roots.size(); ++i) { + ((TreeItem)roots.get(i)).setExpanded(false); + if (((File)((TreeItem)roots.get(i)).getValue()).equals(this.selectDeque.get(0))) { + this.selectDeque.remove(0); + ((TreeItem)roots.get(i)).setExpanded(true); + if (TimiJava.isEmpty(this.selectDeque)) { + break; + } + } + } + } + + } + + /** @deprecated */ + @Deprecated + public void setItemFactory(CallbackReturn itemFactory) { + this.itemFilters.clear(); + this.itemFilters.add(itemFactory); + } + + public void addItemFilter(CallbackReturn itemFilter) { + this.itemFilters.add(itemFilter); + } + + public void removeItemFilter(CallbackReturn itemFilter) { + this.itemFilters.remove(itemFilter); + } + + public void setShowHide(boolean showHide) { + this.showHide.set(showHide); + } + + public boolean isShowHide() { + return this.showHide.get(); + } + + public BooleanProperty showHideProperty() { + return this.showHide; + } + + public BooleanBinding findingItemProperty() { + return this.findingItem; + } + + public final class FileItem extends TreeItem { + FileItem() { + this((File)null); + } + + FileItem(File file) { + super(file); + if (file != null && file.isDirectory()) { + this.getChildren().add(FileTreeView.this.new FileItem((File)null)); + } + + this.expandedProperty().addListener((obs, o, isExpanded) -> { + if (isExpanded) { + FileTreeView.this.getSelectionModel().clearSelection(); + FileTreeView.this.getSelectionModel().select(this); + this.asyncLoadChildren(); + } else { + this.getChildren().add(FileTreeView.this.new FileItem()); + } + + }); + } + + void asyncLoadChildren() { + RunAsync.runback(() -> { + List fileItems = new ArrayList(); + File[] files = ((File)this.getValue()).listFiles(); + if (files != null) { + List fileList = Arrays.stream(files).sorted(TimiJava.COMPARATOR_FILE_NAME).toList(); + + label26: + for(int i = 0; i < fileList.size(); ++i) { + for(int j = 0; j < FileTreeView.this.itemFilters.size(); ++j) { + if (!(Boolean)((CallbackReturn) FileTreeView.this.itemFilters.get(j)).handler((File)fileList.get(i))) { + continue label26; + } + } + + fileItems.add(FileTreeView.this.new FileItem((File)fileList.get(i))); + } + } + + return fileItems; + }, (items) -> { + this.getChildren().setAll(items); + if (TimiJava.isNotEmpty(FileTreeView.this.selectDeque)) { + File file = (File) FileTreeView.this.selectDeque.remove(0); + + for(int i = 0; i < items.size(); ++i) { + if (((File)((FileTreeView.FileItem)items.get(i)).getValue()).equals(file)) { + if (((File)((FileTreeView.FileItem)items.get(i)).getValue()).isDirectory()) { + ((FileTreeView.FileItem)items.get(i)).setExpanded(true); + } + break; + } + } + + if (TimiJava.isEmpty(FileTreeView.this.selectDeque)) { + Platform.runLater(() -> { + FileTreeView.this.scrollTo(FileTreeView.this.getSelectionModel().getSelectedIndex() - 5); + }); + } + } + + }); + } + } +} + diff --git a/src/main/java/com/zhangmeng/tools/editors/ace/AceEditor.java b/src/main/java/com/zhangmeng/tools/editors/ace/AceEditor.java index 4014864..d11ff30 100644 --- a/src/main/java/com/zhangmeng/tools/editors/ace/AceEditor.java +++ b/src/main/java/com/zhangmeng/tools/editors/ace/AceEditor.java @@ -48,6 +48,14 @@ public class AceEditor extends AnchorPane { private JSObject editor; private File file; + public File getFile() { + return file; + } + + public void setFile(File file) { + this.file = file; + } + public WebView getWebView() { return webView; } @@ -77,7 +85,7 @@ public class AceEditor extends AnchorPane { initialize(); } - private void setText(String text) { + public void setText(String text) { this.text.set(text); } @@ -86,7 +94,7 @@ public class AceEditor extends AnchorPane { * * @param value */ - private void setAceText(String value) { + public void setAceText(String value) { editor.call("setValue", value, 1); // 或者调用js中定义好的方法 // JSObject editor = (JSObject) engine.executeScript("window"); @@ -106,7 +114,7 @@ public class AceEditor extends AnchorPane { /** * 修改主题 */ - private void setAceTheme(AceTheme aceTheme) { + public void setAceTheme(AceTheme aceTheme) { editor.call("setTheme", aceTheme.getValue()); } @@ -126,7 +134,7 @@ public class AceEditor extends AnchorPane { /** * 设置模式 */ - private void setAceMode(AceMode mode) { + public void setAceMode(AceMode mode) { window.call("setEditorMode", mode.getValue()); } diff --git a/src/main/java/com/zhangmeng/tools/editors/ace/AceHelper.java b/src/main/java/com/zhangmeng/tools/editors/ace/AceHelper.java index ed1450d..ae97d13 100644 --- a/src/main/java/com/zhangmeng/tools/editors/ace/AceHelper.java +++ b/src/main/java/com/zhangmeng/tools/editors/ace/AceHelper.java @@ -9,18 +9,15 @@ 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(); - + public static String getHtml(AceMode aceMode, AceTheme aceTheme) { 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 = """ + StringBuilder html = new StringBuilder(""" @@ -40,7 +37,7 @@ public class AceHelper { #editor-container{ height: 100%; width: 100%; - + } .ace_editor.ace_autocomplete { width: 415px; @@ -57,25 +54,26 @@ public class AceHelper {
- """; + """); - html += "\n" + - "\n" + - "\n" ; + html.append("\n").append("\n").append("\n"); - //加载所有主题 + //加载所有主题 for (AceTheme value : AceTheme.values()) { String theme_path = "/static/editors/ace-builds/src-min/" + value.getName(); InputStream themeStream = AceHelper.class.getResourceAsStream(theme_path); - html += "\n" ; + html.append("\n"); } - html+= - "\n" + - "\n" + - "\n"; + for (AceMode value : AceMode.values()) { + String model_js = "/static/editors/ace-builds/src-min/" + value.getName(); + InputStream modelJsStream = AceHelper.class.getResourceAsStream(model_js); + html.append("\n"); + } - html += """ + html.append("\n"); + + html.append(""" - """; + """); - return html; + return html.toString(); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/src/main/resources/fxml/editor-list-impl.fxml b/src/main/resources/fxml/editor-list-impl.fxml new file mode 100644 index 0000000..16d3498 --- /dev/null +++ b/src/main/resources/fxml/editor-list-impl.fxml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/fxml/home.fxml b/src/main/resources/fxml/home.fxml index f6ce65d..b24e307 100644 --- a/src/main/resources/fxml/home.fxml +++ b/src/main/resources/fxml/home.fxml @@ -108,6 +108,16 @@ + + + + + + + + + +