From 6152cf10e36d8a866be19d84f4e032fc0c48fd6a Mon Sep 17 00:00:00 2001 From: zhangmeng <1334717033@qq.com> Date: Thu, 1 Jun 2023 16:35:57 +0800 Subject: [PATCH] =?UTF-8?q?2023=E5=B9=B46=E6=9C=881=E6=97=A516:35:26=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=87=E6=9C=AC=E7=BC=96=E8=BE=91=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 +- .../tools/components/RecursiveFileList.java | 159 +++++++++++++++ .../tools/controller/FileEditController.java | 179 +++++++++++++++++ .../tools/controller/HomeController.java | 3 + .../controller/SmallToolsController.java | 133 ++++++++----- .../tools/languages/ProcessJava.java | 127 ++++++++++++ .../zhangmeng/tools/utils/ResourcesUtils.java | 1 + src/main/resources/css/code.css | 187 ++++++++++++++++++ src/main/resources/fxml/file-edit.fxml | 27 +++ src/main/resources/fxml/home.fxml | 1 + src/main/resources/image/dir.png | Bin 0 -> 4309 bytes src/main/resources/image/html.png | Bin 0 -> 6155 bytes src/main/resources/image/jar.png | Bin 0 -> 8518 bytes src/main/resources/image/java.png | Bin 0 -> 5484 bytes src/main/resources/image/jpg.png | Bin 0 -> 4910 bytes src/main/resources/image/json.png | Bin 0 -> 5382 bytes src/main/resources/image/png.png | Bin 0 -> 5815 bytes src/main/resources/image/向下.png | Bin 0 -> 3027 bytes src/main/resources/image/向右.png | Bin 0 -> 2879 bytes 19 files changed, 770 insertions(+), 53 deletions(-) create mode 100644 src/main/java/com/zhangmeng/tools/components/RecursiveFileList.java create mode 100644 src/main/java/com/zhangmeng/tools/controller/FileEditController.java create mode 100644 src/main/java/com/zhangmeng/tools/languages/ProcessJava.java create mode 100644 src/main/resources/css/code.css create mode 100644 src/main/resources/fxml/file-edit.fxml create mode 100644 src/main/resources/image/dir.png create mode 100644 src/main/resources/image/html.png create mode 100644 src/main/resources/image/jar.png create mode 100644 src/main/resources/image/java.png create mode 100644 src/main/resources/image/jpg.png create mode 100644 src/main/resources/image/json.png create mode 100644 src/main/resources/image/png.png create mode 100644 src/main/resources/image/向下.png create mode 100644 src/main/resources/image/向右.png diff --git a/pom.xml b/pom.xml index c96c1f9..e1dcbd9 100644 --- a/pom.xml +++ b/pom.xml @@ -406,7 +406,11 @@ bcprov-jdk16 1.46 - + + org.fxmisc.richtext + richtextfx + 0.10.0 + diff --git a/src/main/java/com/zhangmeng/tools/components/RecursiveFileList.java b/src/main/java/com/zhangmeng/tools/components/RecursiveFileList.java new file mode 100644 index 0000000..5b6f4c2 --- /dev/null +++ b/src/main/java/com/zhangmeng/tools/components/RecursiveFileList.java @@ -0,0 +1,159 @@ +package com.zhangmeng.tools.components; + +/** + * @author : 芊芊墨客 + * @version : 1.0 + * @date : 2023-05-08 11:41 + */ + +import com.zaxxer.hikari.util.FastList; +import javafx.application.Platform; +import javafx.beans.property.SimpleIntegerProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.scene.control.Label; +import javafx.scene.control.TreeCell; +import javafx.scene.control.TreeItem; +import javafx.scene.control.TreeView; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; +import javafx.scene.text.Font; +import javafx.scene.text.Text; +import javafx.util.Callback; +import org.apache.commons.io.FilenameUtils; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.*; + +public class RecursiveFileList extends TreeView { + + private final SimpleObjectProperty index_file = new SimpleObjectProperty<>(null); + + private final SimpleIntegerProperty text_size = new SimpleIntegerProperty(15); + private final SimpleIntegerProperty icon_size = new SimpleIntegerProperty(15); + + public RecursiveFileList(File root) { + super(new TreeItem<>(root)); + if (root != null){ + new Thread(()->{ + Platform.runLater(()->{ + setRoot(getTreeItem(root)); + }); + }).start(); + }else { + setRoot(null); + } + setShowRoot(true); + this.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { + if (newValue.getValue().isFile()) { + index_file.setValue(newValue.getValue()); + } + }); + this.setCellFactory(new Callback, TreeCell>() { + @Override + public TreeCell call(TreeView param) { + return new TreeCell(){ + @Override + protected void updateItem(File item, boolean empty) { + super.updateItem(item, empty); + if (!empty){ + HBox hBox = new HBox(10); + ImageView iv = null; + if (this.getTreeItem().isExpanded()){ + iv = new ImageView(new Image("image/向下.png")); + }else { + iv = new ImageView(new Image("image/向右.png")); + } + iv.setPreserveRatio(true); + iv.setFitWidth(icon_size.get()); + this.setDisclosureNode(iv); + + Label label = new Label(item.getName()); + label.setFont(new Font(text_size.get())); + + //判断是否是文件 + boolean directory = item.isDirectory(); + if (directory){ + ImageView dir = new ImageView(new Image("image/dir.png")); + dir.setPreserveRatio(true); + dir.setFitWidth(icon_size.get()); + hBox.getChildren().add(dir); + }else { + if (item.isFile()){ + ImageView file = null; + + String extension = FilenameUtils.getExtension(item.getName()); + if (extension.equals("java")){ + file = new ImageView(new Image("image/java.png")); + } + if (extension.equals("html")){ + file = new ImageView(new Image("image/html.png")); + } + if (extension.equals("jar")){ + file = new ImageView(new Image("image/jar.png")); + } + if (extension.equals("json")){ + file = new ImageView(new Image("image/json.png")); + } + + if (extension.equals("jpg")){ + file = new ImageView(new Image("image/jpg.png")); + } + + if (extension.equals("png")){ + file = new ImageView(new Image("image/png.png")); + } + + if (file != null){ + file.setPreserveRatio(true); + file.setFitWidth(icon_size.get()); + hBox.getChildren().add(file); + } + } + } + + hBox.getChildren().add(label); + this.setGraphic(hBox); + }else { + this.setGraphic(null); + this.setDisclosureNode(null); + } + } + }; + } + }); + } + + private TreeItem getTreeItem(File file) { + TreeItem item = new TreeItem<>(); + item.setGraphic(new Text(file.getName())); + item.setValue(file); + if (file.isDirectory()) { + if (file.listFiles()!= null){ + List fileList = new ArrayList<>(); + File[] dirs = file.listFiles(File::isDirectory); + if (dirs != null){ + Arrays.sort(dirs, Comparator.comparing(File::getName)); + fileList.addAll(List.of(dirs)); + } + File[] files = file.listFiles(File::isFile); + if (files != null){ + Arrays.sort(files, Comparator.comparing(File::getName)); + fileList.addAll(List.of(files)); + } + for (File child : fileList) { + item.getChildren().add(getTreeItem(child)); + } + } + } + return item; + } + + public File getValue() { + if (index_file.getValue() == null) { + return null; + } + return index_file.getValue(); + } +} diff --git a/src/main/java/com/zhangmeng/tools/controller/FileEditController.java b/src/main/java/com/zhangmeng/tools/controller/FileEditController.java new file mode 100644 index 0000000..3741a26 --- /dev/null +++ b/src/main/java/com/zhangmeng/tools/controller/FileEditController.java @@ -0,0 +1,179 @@ +package com.zhangmeng.tools.controller; + +import com.zhangmeng.tools.components.RecursiveFileList; +import com.zhangmeng.tools.languages.ProcessJava; +import com.zhangmeng.tools.utils.AlertUtils; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.SplitPane; +import javafx.scene.image.Image; +import javafx.stage.DirectoryChooser; +import javafx.stage.FileChooser; +import javafx.stage.Stage; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.fxmisc.flowless.VirtualizedScrollPane; +import org.fxmisc.richtext.CodeArea; +import org.fxmisc.richtext.LineNumberFactory; +import org.fxmisc.richtext.model.StyleSpans; +import org.fxmisc.richtext.model.StyleSpansBuilder; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Collection; +import java.util.Collections; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author : 芊芊墨客 + * @version : 1.0 + * @date : 2023-06-01 10:44 + * + * 文本编辑器 + */ +@Slf4j +public class FileEditController { + + + public SplitPane splitPane; + + private CodeArea codeArea; + private RecursiveFileList recursiveFileList = null; + + @FXML + public void initialize() { + recursiveFileList = new RecursiveFileList(null); + codeArea = new CodeArea(); + URL resource = this.getClass().getClassLoader().getResource("css/code.css"); + codeArea.setParagraphGraphicFactory(LineNumberFactory.get(codeArea)); + codeArea.textProperty().addListener((obs, oldText, newText) -> { + codeArea.setStyleSpans(0, computeHighlighting(newText)); + }); + codeArea.getStylesheets().add(resource.toExternalForm()); + splitPane.getItems().add(0,recursiveFileList); + splitPane.getItems().add(1,new VirtualizedScrollPane<>(codeArea)); + splitPane.setDividerPosition(0,0.20); + splitPane.setDividerPosition(1,0.80); + } + + @FXML + public void open_file_dir(ActionEvent event) { + open_file_dir(); + } + + public void open_file(File file){ + byte[] bytes = new byte[0]; + try { + bytes = Files.readAllBytes(file.toPath()); + } catch (IOException e) { + e.printStackTrace(); + } + String file_content = new String(bytes, StandardCharsets.UTF_8); + codeArea.clear(); + codeArea.replaceText(0, 0, file_content); + } + + public void open_file_dir(){ + + Stage stage = new Stage(); + DirectoryChooser dc = new DirectoryChooser(); + dc.setTitle("文件夹选择"); + File file = dc.showDialog(stage); + if (file != null) { + if (file.isDirectory()){ + splitPane.getItems().clear(); + recursiveFileList = new RecursiveFileList(file) ; + recursiveFileList.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { + if (newValue.getValue().isFile()) { + String extension = FilenameUtils.getExtension(newValue.getValue().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("json")){ +// flag = true; +// } +// +// if (extension.equals("go")){ +// flag = true; +// } +// +// if (extension.equals("js")){ +// flag = true; +// } +// +// if (extension.equals("css")){ +// flag = true; +// } +// +// if (extension.equals(".xml")){ +// flag = true; +// } + if (flag){ + open_file(newValue.getValue()); + }else { + AlertUtils.alert_warning("该文件不支持!"); + } + } + }); + + splitPane.getItems().add(0,recursiveFileList); + splitPane.getItems().add(1,new VirtualizedScrollPane<>(codeArea)); + splitPane.setDividerPosition(0,0.20); + splitPane.setDividerPosition(1,0.80); + } + } + } + + public static StyleSpans> computeHighlighting(String text) { + Matcher matcher = ProcessJava.PATTERN.matcher(text); + int lastKwEnd = 0; + StyleSpansBuilder> spansBuilder = new StyleSpansBuilder<>(); + while(matcher.find()) { + String styleClass = + matcher.group("KEYWORD") != null ? "keyword" : + matcher.group("PAREN") != null ? "paren" : + matcher.group("BRACE") != null ? "brace" : + matcher.group("BRACKET") != null ? "bracket" : + matcher.group("SEMICOLON") != null ? "semicolon" : + matcher.group("STRING") != null ? "string" : + matcher.group("COMMENT") != null ? "comment" : + matcher.group("ANNOTATION") != null ? "annotation" : + matcher.group("PARAMS") != null ? "parameter" : + null; /* never happens */ + assert styleClass != null; + spansBuilder.add(Collections.emptyList(), matcher.start() - lastKwEnd); + spansBuilder.add(Collections.singleton(styleClass), matcher.end() - matcher.start()); + lastKwEnd = matcher.end(); + } + spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd); + return spansBuilder.create(); + } + +} diff --git a/src/main/java/com/zhangmeng/tools/controller/HomeController.java b/src/main/java/com/zhangmeng/tools/controller/HomeController.java index 8ed041a..33230ab 100644 --- a/src/main/java/com/zhangmeng/tools/controller/HomeController.java +++ b/src/main/java/com/zhangmeng/tools/controller/HomeController.java @@ -595,4 +595,7 @@ public class HomeController implements Serializable { listView.getSelectionModel().select(index); } + public void file_edit_menu_item(ActionEvent event) { + load_small_tools(16); + } } \ No newline at end of file diff --git a/src/main/java/com/zhangmeng/tools/controller/SmallToolsController.java b/src/main/java/com/zhangmeng/tools/controller/SmallToolsController.java index 6387832..2f58af4 100644 --- a/src/main/java/com/zhangmeng/tools/controller/SmallToolsController.java +++ b/src/main/java/com/zhangmeng/tools/controller/SmallToolsController.java @@ -83,6 +83,7 @@ public class SmallToolsController { private AnchorPane pdf_ocr; private AnchorPane batch_update_file_name; private AnchorPane capter_screen; + private AnchorPane file_edit; @FXML private ListView listView; @@ -118,9 +119,9 @@ public class SmallToolsController { } @FXML - public void cron_menu_item(){ + public void cron_menu_item() { boolean flag = false; - if (cron != null){ + if (cron != null) { flag = true; } @@ -128,10 +129,10 @@ public class SmallToolsController { } @FXML - public void unicode_menu_item(){ + public void unicode_menu_item() { boolean flag = false; - if (unicode != null){ + if (unicode != null) { flag = true; } @@ -139,9 +140,9 @@ public class SmallToolsController { } @FXML - public void jwt_menu_item(){ + public void jwt_menu_item() { boolean flag = false; - if (jwt_web != null){ + if (jwt_web != null) { flag = true; } @@ -149,69 +150,69 @@ public class SmallToolsController { } @FXML - public void hex_16_menu_item(){ + public void hex_16_menu_item() { boolean flag = false; - if (hex_16 != null){ + if (hex_16 != null) { flag = true; } hex_16(flag); } @FXML - public void color_choose_menu_item(){ + public void color_choose_menu_item() { boolean flag = false; - if (color_choose != null){ + if (color_choose != null) { flag = true; } color_choose(flag); } @FXML - public void qr_code_menu_item(){ + public void qr_code_menu_item() { boolean flag = false; - if (qr_code != null){ + if (qr_code != null) { flag = true; } qr_code(flag); } @FXML - public void date_query_menu_item(){ + public void date_query_menu_item() { boolean flag = false; - if (date_query != null){ + if (date_query != null) { flag = true; } date_query(flag); } @FXML - public void base_62_menu_item(){ + public void base_62_menu_item() { load_codec_tools(0); } @FXML - public void base_64_menu_item(){ + public void base_64_menu_item() { load_codec_tools(1); } @FXML - public void base_32_menu_item(){ + public void base_32_menu_item() { load_codec_tools(2); } @FXML - public void sql_code_gen_menu_item(){ + public void sql_code_gen_menu_item() { load_mysql_tools(0); } @FXML - public void netty_client_menu_item(){ + public void netty_client_menu_item() { load_network_tools(0); } - public void load_network_tools(int index){ + public void load_network_tools(int index) { AnchorPane fx = null; try { fx = FXMLLoader.load(ResourcesUtils.getResource("network-tools")); @@ -228,7 +229,7 @@ public class SmallToolsController { } @FXML - public void morse_coder_menu_item(){ + public void morse_coder_menu_item() { load_codec_tools(3); } @@ -409,11 +410,33 @@ public class SmallToolsController { } capter_screen(flag); } + + if (newValue.getIndex() == 16) { + if (file_edit != null) { + flag = true; + } + file_edit(flag); + } } }); } + private void file_edit(boolean flag) { + //默认选择第一个 + listView.getSelectionModel().select(0); + if (!flag) { + try { + root = FXMLLoader.load(ResourcesUtils.getResource("file-edit")); + } catch (IOException e) { + e.printStackTrace(); + } + file_edit = root; + } else { + root = file_edit; + } + common_method(); + } public static Image getImage(ResourcesUtils.SmallTools SmallTools) { @@ -429,11 +452,12 @@ public class SmallToolsController { case TelePhone -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); case JSONView -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); case Maven_Install_Jar -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); - case Word_ocr -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); - case Bar_Code -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); - case Pdf_Ocr -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); - case BatchUpdateFileName -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); - case Capter_Screent -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); + case Word_ocr -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); + case Bar_Code -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); + case Pdf_Ocr -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); + case BatchUpdateFileName -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); + case Capter_Screent -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); + case File_Edit -> new Image(ImagePath.path(ImagePath.ImagePathType.Qr_CODE)); }; } @@ -496,7 +520,6 @@ public class SmallToolsController { } - private void hex_16(boolean flag) { //默认选择第一个 listView.getSelectionModel().select(0); @@ -531,7 +554,7 @@ public class SmallToolsController { common_method(); } - public void jwt_web(boolean flag){ + public void jwt_web(boolean flag) { //默认选择第一个 listView.getSelectionModel().select(2); @@ -548,7 +571,7 @@ public class SmallToolsController { common_method(); } - public void color_choose(boolean flag){ + public void color_choose(boolean flag) { //默认选择第一个 listView.getSelectionModel().select(3); @@ -565,7 +588,7 @@ public class SmallToolsController { common_method(); } - public void qr_code(boolean flag){ + public void qr_code(boolean flag) { //默认选择第一个 listView.getSelectionModel().select(4); @@ -582,7 +605,7 @@ public class SmallToolsController { common_method(); } - public void date_query(boolean flag){ + public void date_query(boolean flag) { //默认选择第一个 listView.getSelectionModel().select(4); @@ -599,7 +622,7 @@ public class SmallToolsController { common_method(); } - public void cron(boolean flag){ + public void cron(boolean flag) { //默认选择第一个 listView.getSelectionModel().select(6); @@ -616,7 +639,7 @@ public class SmallToolsController { common_method(); } - public void telephone(boolean flag){ + public void telephone(boolean flag) { //默认选择第一个 listView.getSelectionModel().select(8); @@ -705,9 +728,9 @@ public class SmallToolsController { } @FXML - public void batch_update_file_name_menu_item(){ + public void batch_update_file_name_menu_item() { boolean flag = false; - if (batch_update_file_name != null){ + if (batch_update_file_name != null) { flag = true; } @@ -750,7 +773,7 @@ public class SmallToolsController { common_method(); } - public void capter_screen(boolean flag){ + public void capter_screen(boolean flag) { //默认选择第一个 listView.getSelectionModel().select(15); @@ -799,13 +822,13 @@ public class SmallToolsController { @FXML public void mail_menu_item(ActionEvent event) { boolean flag = false; - if (mail != null){ + if (mail != null) { flag = true; } mail(flag); } - private void mail(boolean flag ){ + private void mail(boolean flag) { //默认选择第一个 listView.getSelectionModel().select(7); @@ -837,7 +860,7 @@ public class SmallToolsController { load_http_tools(2); } - public void load_http_tools(int index){ + public void load_http_tools(int index) { AnchorPane fx = null; try { fx = FXMLLoader.load(ResourcesUtils.getResource("http-tools")); @@ -868,7 +891,7 @@ public class SmallToolsController { load_server_tools(2); } - public void load_server_tools(int index){ + public void load_server_tools(int index) { AnchorPane fx = null; try { fx = FXMLLoader.load(ResourcesUtils.getResource("server-tools")); @@ -883,35 +906,40 @@ public class SmallToolsController { ListView listView = (ListView) fx.lookup("#listView"); listView.getSelectionModel().select(index); } + @FXML public void socket_server_menu_item(ActionEvent event) { load_server_tools(3); } + @FXML public void telephone_menu_item(ActionEvent event) { boolean flag = false; - if (telephone != null){ + if (telephone != null) { flag = true; } telephone(flag); } + @FXML public void mybatis_plus_gen_menu_item(ActionEvent event) { load_mysql_tools(1); } + @FXML public void JsonView_menu_item(ActionEvent event) { - boolean flag =false; - if (json_view != null){ + boolean flag = false; + if (json_view != null) { flag = true; } json_view(flag); } + @FXML public void maven_jar_install_menu_item(ActionEvent event) { - boolean flag =false; - if (maven_install_jar != null){ + boolean flag = false; + if (maven_install_jar != null) { flag = true; } maven_install_jar(flag); @@ -919,16 +947,17 @@ public class SmallToolsController { @FXML public void word_ocr_menu_item(ActionEvent event) { - boolean flag =false; - if (word_ocr != null){ + boolean flag = false; + if (word_ocr != null) { flag = true; } word_ocr(flag); } + @FXML public void bar_code_menu_item(ActionEvent event) { - boolean flag =false; - if (bar_code != null){ + boolean flag = false; + if (bar_code != null) { flag = true; } bar_code(flag); @@ -936,8 +965,8 @@ public class SmallToolsController { @FXML public void pdf_menu_item(ActionEvent event) { - boolean flag =false; - if (pdf_ocr != null){ + boolean flag = false; + if (pdf_ocr != null) { flag = true; } pdf_ocr(flag); @@ -945,7 +974,7 @@ public class SmallToolsController { public void capter_screen_menu_item(ActionEvent event) { boolean flag = false; - if (capter_screen != null){ + if (capter_screen != null) { flag = true; } capter_screen(flag); diff --git a/src/main/java/com/zhangmeng/tools/languages/ProcessJava.java b/src/main/java/com/zhangmeng/tools/languages/ProcessJava.java new file mode 100644 index 0000000..2b31356 --- /dev/null +++ b/src/main/java/com/zhangmeng/tools/languages/ProcessJava.java @@ -0,0 +1,127 @@ +package com.zhangmeng.tools.languages; + +import java.util.regex.Pattern; + +/** + * @author : 芊芊墨客 + * @version : 1.0 + * @date : 2023-06-01 11:01 + */ +public class ProcessJava { + + public static final String[] KEYWORDS = new String[] { + "abstract", "assert", "boolean", "break", "byte", + "case", "catch", "char", "class", "const", + "continue", "default", "do", "double", "else", + "enum", "extends", "final", "finally", "float", + "for", "if", "goto", "implements", "import", + "instanceof", "int", "interface", "long", "native", + "new", "package", "private", "protected", "public", + "return", "short", "static", "strictfp", "super", + "switch", "synchronized", "this", "throw", "throws", + "transient", "try", "void", "volatile", "while" + }; + + public static final String KEYWORD_PATTERN = "\\b(" + String.join("|", KEYWORDS) + ")\\b"; + public static final String PAREN_PATTERN = "\\(|\\)"; + public static final String BRACE_PATTERN = "\\{|\\}"; + public static final String BRACKET_PATTERN = "\\[|\\]"; + public static final String SEMICOLON_PATTERN = "\\;"; + public static final String STRING_PATTERN = "\"([^\"\\\\]|\\\\.)*\""; + public static final String COMMENT_PATTERN = "//[^\n]*" + "|" + "/\\*(.|\\R)*?\\*/"; + public static final String ANNOTATION_PATTERN = "@[a-zA-Z]+"; + public static final String PARAMS_PATTERN = "\\\\b([a-zA-Z]+)\\\\s*=\\\\s*([a-zA-Z0-9]+)\\\\b"; + + public static final Pattern PATTERN = Pattern.compile( + "(?" + KEYWORD_PATTERN + ")" + + "|(?" + PAREN_PATTERN + ")" + + "|(?" + BRACE_PATTERN + ")" + + "|(?" + BRACKET_PATTERN + ")" + + "|(?" + SEMICOLON_PATTERN + ")" + + "|(?" + STRING_PATTERN + ")" + + "|(?" + COMMENT_PATTERN + ")" + + "|(?" + ANNOTATION_PATTERN + ")" + + "|(?" + PARAMS_PATTERN + ")" + + ); + + public static String SAMPLE_CODE = "package com.dashidao.server.model;\n" + + "\n" + + "import java.util.Date;\n" + + "\n" + + "public class PosterGroupCouponCode extends BaseEntity {\n" + + "\n" + + "\tprivate Date addTime;\n" + + "\tprivate Boolean deleteStatus;\n" + + "\tprivate String groupCouponCode;\n" + + "\tprivate Integer groupCouponStatus;\n" + + "\tprivate Date writeOffTime;\n" + + "\tprivate Long orderFormId;\n" + + "\tprivate Long posterGoodsCartId;\n" + + "\tprivate Long tuiKuanShouHouId;\n" + + "\tprivate Long orderMealUserId;\n" + + "\tprivate String groupSkusJson;\n" + + "\n" + + "\tpublic Date getAddTime() {\n" + + "\t\treturn addTime;\n" + + "\t}\n" + + "\tpublic void setAddTime(Date addTime) {\n" + + "\t\tthis.addTime = addTime;\n" + + "\t}\n" + + "\tpublic Boolean getDeleteStatus() {\n" + + "\t\treturn deleteStatus;\n" + + "\t}\n" + + "\tpublic void setDeleteStatus(Boolean deleteStatus) {\n" + + "\t\tthis.deleteStatus = deleteStatus;\n" + + "\t}\n" + + "\tpublic String getGroupCouponCode() {\n" + + "\t\treturn groupCouponCode;\n" + + "\t}\n" + + "\tpublic void setGroupCouponCode(String groupCouponCode) {\n" + + "\t\tthis.groupCouponCode = groupCouponCode;\n" + + "\t}\n" + + "\tpublic Integer getGroupCouponStatus() {\n" + + "\t\treturn groupCouponStatus;\n" + + "\t}\n" + + "\tpublic void setGroupCouponStatus(Integer groupCouponStatus) {\n" + + "\t\tthis.groupCouponStatus = groupCouponStatus;\n" + + "\t}\n" + + "\tpublic Date getWriteOffTime() {\n" + + "\t\treturn writeOffTime;\n" + + "\t}\n" + + "\tpublic void setWriteOffTime(Date writeOffTime) {\n" + + "\t\tthis.writeOffTime = writeOffTime;\n" + + "\t}\n" + + "\tpublic Long getOrderFormId() {\n" + + "\t\treturn orderFormId;\n" + + "\t}\n" + + "\tpublic void setOrderFormId(Long orderFormId) {\n" + + "\t\tthis.orderFormId = orderFormId;\n" + + "\t}\n" + + "\tpublic Long getPosterGoodsCartId() {\n" + + "\t\treturn posterGoodsCartId;\n" + + "\t}\n" + + "\tpublic void setPosterGoodsCartId(Long posterGoodsCartId) {\n" + + "\t\tthis.posterGoodsCartId = posterGoodsCartId;\n" + + "\t}\n" + + "\tpublic Long getTuiKuanShouHouId() {\n" + + "\t\treturn tuiKuanShouHouId;\n" + + "\t}\n" + + "\tpublic void setTuiKuanShouHouId(Long tuiKuanShouHouId) {\n" + + "\t\tthis.tuiKuanShouHouId = tuiKuanShouHouId;\n" + + "\t}\n" + + "\tpublic Long getOrderMealUserId() {\n" + + "\t\treturn orderMealUserId;\n" + + "\t}\n" + + "\tpublic void setOrderMealUserId(Long orderMealUserId) {\n" + + "\t\tthis.orderMealUserId = orderMealUserId;\n" + + "\t}\n" + + "\tpublic String getGroupSkusJson() {\n" + + "\t\treturn groupSkusJson;\n" + + "\t}\n" + + "\tpublic void setGroupSkusJson(String groupSkusJson) {\n" + + "\t\tthis.groupSkusJson = groupSkusJson;\n" + + "\t}\n" + + "\n" + + "}\n"; +} diff --git a/src/main/java/com/zhangmeng/tools/utils/ResourcesUtils.java b/src/main/java/com/zhangmeng/tools/utils/ResourcesUtils.java index 4c856c0..70d38dd 100644 --- a/src/main/java/com/zhangmeng/tools/utils/ResourcesUtils.java +++ b/src/main/java/com/zhangmeng/tools/utils/ResourcesUtils.java @@ -132,6 +132,7 @@ public class ResourcesUtils { Pdf_Ocr("pdf识别", 13), BatchUpdateFileName("批量修改文件名", 14), Capter_Screent("截图", 15), + File_Edit("文件编辑器", 16), ; SmallTools(String title, int index) { diff --git a/src/main/resources/css/code.css b/src/main/resources/css/code.css new file mode 100644 index 0000000..9379b12 --- /dev/null +++ b/src/main/resources/css/code.css @@ -0,0 +1,187 @@ +/*- CodeArea的根节点样式*/ +.code-area { + -fx-font-family: "Consolas"; + -fx-font-size: 16px; + -fx-text-fill: #1d171e; + -fx-background-color: #ffffff; +} + +/** - 行号的样式*/ +.code-area .line-number { + -fx-background-color: #f4f4f4; + -fx-text-fill: #999999; + -fx-fill: #f4f; + -fx-font-size: 18px; + -fx-padding: 5 5 5 5px +} + +/*- 光标的样式*/ +.code-area .caret { + +} + +.code-area .selection { + -fx-fill: #cbcacb; +} + +/*-*/ +/*选中文本的样式*/ +.code-area .highlight { + +} + +/*-*/ +/*高亮文本的样式*/ +.code-area .folded { + +} + +/*-*/ +/*折叠代码的样式*/ +.code-area .folded-indicator { + +} + +/*-*/ +/*折叠代码指示器的样式*/ +.code-area .folded-indicator:hover { + +} + +/*-*/ +/*折叠代码指示器的鼠标悬停样式*/ +.code-area .error { + +} + +/*-*/ +/*错误文本的样式*/ +.code-area .warning { + +} + +/*-*/ +/*警告文本的样式*/ +.code-area .info { + +} + +/*-*/ +/*信息文本的样式*/ +.code-area .keyword { + -fx-fill: #10ADEBFF +} + +/*-*/ +/*关键字的样式*/ +.code-area .operator { + -fx-fill: #d12746; +} + +/*-*/ +/*运算符的样式*/ +.code-area .number { + -fx-fill: #27c5d1; +} + +/*-*/ +/*数字的样式*/ +.code-area .string { + +} + +/*-*/ +/*字符串的样式*/ +.code-area .comment { + -fx-fill: #cbcacb; +} + +/*-*/ +/*注释的样式*/ +.code-area .type { + -fx-fill: red; + -fx-text-fill: #ffff55; +} + +/*-*/ +/*类型的样式*/ +.code-area .function { + -fx-fill: red; + -fx-text-fill: #ffff55; +} + +/*-*/ +/*函数的样式*/ +.code-area .parameter { + -fx-fill: #d56b6b; +} + +/*-*/ +/*参数的样式*/ +.code-area .annotation { + -fx-fill: #eeee07; +} + +/*-*/ +/*注解的样式*/ +.code-area .class { + -fx-fill: red; + -fx-text-fill: red; +} + +/*-*/ +/*类的样式*/ +.code-area .interface { + -fx-fill: red; + -fx-text-fill: red; +} + +/*-*/ +/*接口的样式*/ +.code-area .enum { + +} + +/*-*/ +/*枚举的样式*/ +.code-area .field { + +} + +/*-*/ +/*字段的样式*/ +.code-area .method { + -fx-fill: red; + -fx-text-fill: red; +} + +/*-*/ +/*方法的样式*/ +.code-area .constructor { + +} + +/*-*/ +/*构造函数的样式*/ +.code-area .static { + +} + +/*-*/ +/*静态的样式*/ +.code-area .final { + +} + +/*-*/ +/*最终的样式*/ +.code-area .abstract { + -fx-fill: red; + +} + +/*-*/ +/*抽象的样式*/ +.code-area .deprecated { + -fx-fill: #d12746; +} diff --git a/src/main/resources/fxml/file-edit.fxml b/src/main/resources/fxml/file-edit.fxml new file mode 100644 index 0000000..2367e7a --- /dev/null +++ b/src/main/resources/fxml/file-edit.fxml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/fxml/home.fxml b/src/main/resources/fxml/home.fxml index 61dfe56..2afb18e 100644 --- a/src/main/resources/fxml/home.fxml +++ b/src/main/resources/fxml/home.fxml @@ -49,6 +49,7 @@ + diff --git a/src/main/resources/image/dir.png b/src/main/resources/image/dir.png new file mode 100644 index 0000000000000000000000000000000000000000..15c29b7d09235a4bd231b9a4d00fe9e3a6cd05f9 GIT binary patch literal 4309 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/image/jar.png b/src/main/resources/image/jar.png new file mode 100644 index 0000000000000000000000000000000000000000..1d7cfede3ce8c704eaaa8296cf243432ea63601b GIT binary patch literal 8518 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/image/java.png b/src/main/resources/image/java.png new file mode 100644 index 0000000000000000000000000000000000000000..4dc7435956acc9a3119fd7a8b5df7e9178417954 GIT binary patch literal 5484 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/image/jpg.png b/src/main/resources/image/jpg.png new file mode 100644 index 0000000000000000000000000000000000000000..960aefd0935a35222ea43d0567cf46f5a5749931 GIT binary patch literal 4910 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 h&Vu0kzg^|$%{av?p+R5rYpB8|fY;DhFITmX_C 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 Htwa6?K4p@a literal 0 HcmV?d00001 diff --git a/src/main/resources/image/向下.png b/src/main/resources/image/向下.png new file mode 100644 index 0000000000000000000000000000000000000000..bce1d60d50d3eea016094261f5706da3f5ad9637 GIT binary patch literal 3027 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 literal 0 HcmV?d00001