From 8b0d686d0f89a63a82b361530a33e47dd3977e33 Mon Sep 17 00:00:00 2001 From: xufeng <1277032935@qq.com> Date: Mon, 17 Aug 2020 23:24:55 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=99=A8=E7=94=9F=E6=88=90pom=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xJavaFxTool/utils/PluginProgectPomBuildTool.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/javaFxTools/x-JavaFxXmlToObjectCode/src/main/java/com/xwintop/xJavaFxTool/utils/PluginProgectPomBuildTool.java b/javaFxTools/x-JavaFxXmlToObjectCode/src/main/java/com/xwintop/xJavaFxTool/utils/PluginProgectPomBuildTool.java index fe94a8b..1fba2e4 100644 --- a/javaFxTools/x-JavaFxXmlToObjectCode/src/main/java/com/xwintop/xJavaFxTool/utils/PluginProgectPomBuildTool.java +++ b/javaFxTools/x-JavaFxXmlToObjectCode/src/main/java/com/xwintop/xJavaFxTool/utils/PluginProgectPomBuildTool.java @@ -55,9 +55,15 @@ public class PluginProgectPomBuildTool { "\t\t\n" + "\t\t\tcom.xwintop\n" + "\t\t\txcore\n" + - "\t\t\t0.0.4-SNAPSHOT\n" + - "\t\t\tprovided\n" + + "\t\t\t0.0.6\n" + + "\n" + "\t\t\n" + + "\t\t\n" + + "\t\t\torg.projectlombok\n" + + "\t\t\tlombok\n" + + "\t\t\t1.18.12\n" + + "\t\t\tprovided\n" + + "\t\t\n"+ "\n" + "\t\n" + "\t\n" + -- Gitee From acd85df04342fafe7f504f54baeb348f06d4d885 Mon Sep 17 00:00:00 2001 From: "XUFENG-PC\\xufeng" <1277032935@qq.com> Date: Fri, 21 Aug 2020 12:24:51 +0800 Subject: [PATCH 2/9] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9javafx=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=94=9F=E6=88=90=E5=99=A8=EF=BC=9B2.=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0Luyten=E5=8F=8D=E7=BC=96=E8=AF=91=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- developTools/x-LuytenTool/.gitignore | 5 + developTools/x-LuytenTool/README.md | 1 + developTools/x-LuytenTool/README_EN.md | 1 + developTools/x-LuytenTool/pom.xml | 119 ++ .../xwintop/xJavaFxTool/LuytenToolMain.java | 51 + .../developTools/LuytenToolController.java | 48 + .../developTools/LuytenToolService.java | 14 + .../view/developTools/LuytenToolView.java | 14 + .../us/deathmarine/luyten/CellRenderer.java | 52 + .../java/us/deathmarine/luyten/Closer.java | 22 + .../us/deathmarine/luyten/ConfigSaver.java | 223 ++++ .../luyten/DecompilerLinkProvider.java | 384 ++++++ .../us/deathmarine/luyten/DirPreferences.java | 62 + .../us/deathmarine/luyten/DropListener.java | 108 ++ .../us/deathmarine/luyten/FileDialog.java | 135 +++ .../luyten/FileEntryNotFoundException.java | 6 + .../luyten/FileIsBinaryException.java | 6 + .../java/us/deathmarine/luyten/FileSaver.java | 334 ++++++ .../us/deathmarine/luyten/FindAllBox.java | 369 ++++++ .../java/us/deathmarine/luyten/FindBox.java | 232 ++++ .../us/deathmarine/luyten/JFontChooser.java | 772 ++++++++++++ .../us/deathmarine/luyten/JarEntryFilter.java | 82 ++ .../java/us/deathmarine/luyten/Keymap.java | 14 + .../us/deathmarine/luyten/LinkProvider.java | 22 + .../java/us/deathmarine/luyten/Luyten.java | 224 ++++ .../java/us/deathmarine/luyten/LuytenOsx.java | 30 + .../deathmarine/luyten/LuytenPreferences.java | 87 ++ .../deathmarine/luyten/LuytenTypeLoader.java | 34 + .../us/deathmarine/luyten/MainMenuBar.java | 677 +++++++++++ .../us/deathmarine/luyten/MainWindow.java | 440 +++++++ .../java/us/deathmarine/luyten/Model.java | 1057 +++++++++++++++++ .../java/us/deathmarine/luyten/OpenFile.java | 844 +++++++++++++ .../us/deathmarine/luyten/RecentFiles.java | 66 + .../java/us/deathmarine/luyten/Selection.java | 41 + .../us/deathmarine/luyten/SystemInfo.java | 10 + .../luyten/TooLargeFileException.java | 20 + .../luyten/TreeNodeUserObject.java | 37 + .../java/us/deathmarine/luyten/TreeUtil.java | 81 ++ .../us/deathmarine/luyten/WindowPosition.java | 93 ++ .../fxmlView/developTools/LuytenTool.fxml | 12 + .../config/toolFxmlLoaderConfiguration.xml | 14 + .../resources/locale/LuytenTool.properties | 3 + .../locale/LuytenTool_en_US.properties | 3 + .../src/main/resources/resources/Luyten.icns | Bin 0 -> 283742 bytes .../src/main/resources/resources/Luyten.png | Bin 0 -> 221391 bytes .../src/main/resources/resources/file.png | Bin 0 -> 414 bytes .../main/resources/resources/icon_close.png | Bin 0 -> 675 bytes .../src/main/resources/resources/java.png | Bin 0 -> 517 bytes .../main/resources/resources/package_obj.png | Bin 0 -> 345 bytes .../src/main/resources/resources/yml.png | Bin 0 -> 599 bytes .../JavaFxXmlToObjectCodeService.java | 10 +- 51 files changed, 6854 insertions(+), 5 deletions(-) create mode 100644 developTools/x-LuytenTool/.gitignore create mode 100644 developTools/x-LuytenTool/README.md create mode 100644 developTools/x-LuytenTool/README_EN.md create mode 100644 developTools/x-LuytenTool/pom.xml create mode 100644 developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/LuytenToolMain.java create mode 100644 developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/controller/developTools/LuytenToolController.java create mode 100644 developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/services/developTools/LuytenToolService.java create mode 100644 developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/view/developTools/LuytenToolView.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/CellRenderer.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Closer.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/ConfigSaver.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DecompilerLinkProvider.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DirPreferences.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DropListener.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileDialog.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileEntryNotFoundException.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileIsBinaryException.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileSaver.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FindAllBox.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FindBox.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/JFontChooser.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/JarEntryFilter.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Keymap.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LinkProvider.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Luyten.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenOsx.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenPreferences.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenTypeLoader.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/MainMenuBar.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/MainWindow.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Model.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/OpenFile.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/RecentFiles.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Selection.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/SystemInfo.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TooLargeFileException.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TreeNodeUserObject.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TreeUtil.java create mode 100644 developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/WindowPosition.java create mode 100644 developTools/x-LuytenTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/developTools/LuytenTool.fxml create mode 100644 developTools/x-LuytenTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml create mode 100644 developTools/x-LuytenTool/src/main/resources/locale/LuytenTool.properties create mode 100644 developTools/x-LuytenTool/src/main/resources/locale/LuytenTool_en_US.properties create mode 100644 developTools/x-LuytenTool/src/main/resources/resources/Luyten.icns create mode 100644 developTools/x-LuytenTool/src/main/resources/resources/Luyten.png create mode 100644 developTools/x-LuytenTool/src/main/resources/resources/file.png create mode 100644 developTools/x-LuytenTool/src/main/resources/resources/icon_close.png create mode 100644 developTools/x-LuytenTool/src/main/resources/resources/java.png create mode 100644 developTools/x-LuytenTool/src/main/resources/resources/package_obj.png create mode 100644 developTools/x-LuytenTool/src/main/resources/resources/yml.png diff --git a/developTools/x-LuytenTool/.gitignore b/developTools/x-LuytenTool/.gitignore new file mode 100644 index 0000000..0ffe365 --- /dev/null +++ b/developTools/x-LuytenTool/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +#/.gitignore +/x-LuytenTool.iml +/log/ +/target/ \ No newline at end of file diff --git a/developTools/x-LuytenTool/README.md b/developTools/x-LuytenTool/README.md new file mode 100644 index 0000000..af248a1 --- /dev/null +++ b/developTools/x-LuytenTool/README.md @@ -0,0 +1 @@ +LuytenTool 反编译工具 \ No newline at end of file diff --git a/developTools/x-LuytenTool/README_EN.md b/developTools/x-LuytenTool/README_EN.md new file mode 100644 index 0000000..9354927 --- /dev/null +++ b/developTools/x-LuytenTool/README_EN.md @@ -0,0 +1 @@ +LuytenTool \ No newline at end of file diff --git a/developTools/x-LuytenTool/pom.xml b/developTools/x-LuytenTool/pom.xml new file mode 100644 index 0000000..384e2ce --- /dev/null +++ b/developTools/x-LuytenTool/pom.xml @@ -0,0 +1,119 @@ + + 4.0.0 + + com.xwintop + x-LuytenTool + 0.0.1 + jar + x-LuytenTool + + + UTF-8 + + + + + aliyunmaven + http://maven.aliyun.com/nexus/content/groups/public/ + + + xwintop-maven + https://864381832.github.io/maven/repository + + + spring-snapshots + http://repo.spring.io/snapshot + + true + + + + spring-milestones + http://repo.spring.io/milestone + + + + + + junit + junit + 4.12 + test + + + com.xwintop + xcore + 0.0.6 + + + + org.projectlombok + lombok + 1.18.6 + provided + + + + com.fifesoft + rsyntaxtextarea + 3.0.2 + + + com.apple + AppleJavaExtensions + 1.4 + + + org.bitbucket.mstrobel + procyon-core + 0.5.36 + + + org.bitbucket.mstrobel + procyon-expressions + 0.5.36 + + + org.bitbucket.mstrobel + procyon-reflection + 0.5.36 + + + org.bitbucket.mstrobel + procyon-compilertools + 0.5.36 + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.5.5 + + false + utf-8 + + + + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + diff --git a/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/LuytenToolMain.java b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/LuytenToolMain.java new file mode 100644 index 0000000..541dbcf --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/LuytenToolMain.java @@ -0,0 +1,51 @@ +package com.xwintop.xJavaFxTool; + +import com.xwintop.xcore.util.javafx.JavaFxSystemUtil; +import javafx.application.Application; +import javafx.event.EventHandler; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; +import javafx.stage.WindowEvent; +import lombok.extern.slf4j.Slf4j; + +import java.net.URL; +import java.util.ResourceBundle; + +@Slf4j +public class LuytenToolMain extends Application { + public static void main(String[] args) { + try { + launch(args); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void start(Stage primaryStage) throws Exception { + FXMLLoader fXMLLoader = LuytenToolMain.getFXMLLoader(); + ResourceBundle resourceBundle = fXMLLoader.getResources(); + Parent root = fXMLLoader.load(); + primaryStage.setResizable(true); + primaryStage.setTitle(resourceBundle.getString("Title")); +// primaryStage.getIcons().add(new Image("/images/icon.jpg")); + double[] screenSize = JavaFxSystemUtil.getScreenSizeByScale(0.74, 0.8); + primaryStage.setScene(new Scene(root, screenSize[0], screenSize[1])); + primaryStage.show(); + primaryStage.setOnCloseRequest(new EventHandler() { + @Override + public void handle(WindowEvent event) { + System.exit(0); + } + }); + } + + public static FXMLLoader getFXMLLoader() { + ResourceBundle resourceBundle = ResourceBundle.getBundle("locale.LuytenTool"); + URL url = Object.class.getResource("/com/xwintop/xJavaFxTool/fxmlView/developTools/LuytenTool.fxml"); + FXMLLoader fXMLLoader = new FXMLLoader(url, resourceBundle); + return fXMLLoader; + } +} \ No newline at end of file diff --git a/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/controller/developTools/LuytenToolController.java b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/controller/developTools/LuytenToolController.java new file mode 100644 index 0000000..16ce3eb --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/controller/developTools/LuytenToolController.java @@ -0,0 +1,48 @@ +package com.xwintop.xJavaFxTool.controller.developTools; + +import com.xwintop.xJavaFxTool.services.developTools.LuytenToolService; +import com.xwintop.xJavaFxTool.view.developTools.LuytenToolView; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import us.deathmarine.luyten.Luyten; +import us.deathmarine.luyten.MainWindow; + +import javax.swing.*; +import java.net.URL; +import java.util.ResourceBundle; + +@Getter +@Setter +@Slf4j +public class LuytenToolController extends LuytenToolView { + private LuytenToolService luytenToolService = new LuytenToolService(this); + + @Override + public void initialize(URL location, ResourceBundle resources) { + initView(); + initEvent(); + initService(); + } + + private void initView() { +// SwingUtilities.invokeLater(new Runnable() { +// @Override +// public void run() { +// try { +// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// luytenSwingNode.setContent(new MainWindow(null).getRootPane()); +// } +// }); + } + + private void initEvent() { + Luyten.main(new String[]{}); + } + + private void initService() { + } +} \ No newline at end of file diff --git a/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/services/developTools/LuytenToolService.java b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/services/developTools/LuytenToolService.java new file mode 100644 index 0000000..9c8fc7a --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/services/developTools/LuytenToolService.java @@ -0,0 +1,14 @@ +package com.xwintop.xJavaFxTool.services.developTools; +import com.xwintop.xJavaFxTool.controller.developTools.LuytenToolController; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +@Getter +@Setter +@Slf4j +public class LuytenToolService{ +private LuytenToolController luytenToolController; +public LuytenToolService(LuytenToolController luytenToolController) { +this.luytenToolController = luytenToolController; +} +} \ No newline at end of file diff --git a/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/view/developTools/LuytenToolView.java b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/view/developTools/LuytenToolView.java new file mode 100644 index 0000000..f96b2b9 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/view/developTools/LuytenToolView.java @@ -0,0 +1,14 @@ +package com.xwintop.xJavaFxTool.view.developTools; + +import javafx.embed.swing.SwingNode; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public abstract class LuytenToolView implements Initializable { + @FXML + protected SwingNode luytenSwingNode; +} \ No newline at end of file diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/CellRenderer.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/CellRenderer.java new file mode 100644 index 0000000..b0fe32d --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/CellRenderer.java @@ -0,0 +1,52 @@ +package us.deathmarine.luyten; + +import java.awt.Component; +import java.awt.Toolkit; + +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; + +public class CellRenderer extends DefaultTreeCellRenderer { + private static final long serialVersionUID = -5691181006363313993L; + Icon pack; + Icon java_image; + Icon yml_image; + Icon file_image; + + public CellRenderer() { + this.pack = new ImageIcon( + Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/resources/package_obj.png"))); + this.java_image = new ImageIcon( + Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/resources/java.png"))); + this.yml_image = new ImageIcon( + Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/resources/yml.png"))); + this.file_image = new ImageIcon( + Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/resources/file.png"))); + } + + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, + int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + if (node.getChildCount() > 0) { + setIcon(this.pack); + } else if (getFileName(node).endsWith(".class") || getFileName(node).endsWith(".java")) { + setIcon(this.java_image); + } else if (getFileName(node).endsWith(".yml") || getFileName(node).endsWith(".yaml")) { + setIcon(this.yml_image); + } else { + setIcon(this.file_image); + } + + return this; + } + + public String getFileName(DefaultMutableTreeNode node) { + return ((TreeNodeUserObject) node.getUserObject()).getOriginalName(); + } + +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Closer.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Closer.java new file mode 100644 index 0000000..31dcc15 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Closer.java @@ -0,0 +1,22 @@ +package us.deathmarine.luyten; + +public final class Closer { + public static void tryClose(final AutoCloseable c) { + if (c == null) { + return; + } + try { + c.close(); + } catch (Throwable ignored) { + } + } + + public static void tryClose(final AutoCloseable... items) { + if (items == null) { + return; + } + for (AutoCloseable c : items) { + tryClose(c); + } + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/ConfigSaver.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/ConfigSaver.java new file mode 100644 index 0000000..6d53758 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/ConfigSaver.java @@ -0,0 +1,223 @@ +package us.deathmarine.luyten; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.prefs.Preferences; +import com.strobel.decompiler.DecompilerSettings; +import com.strobel.decompiler.languages.Language; +import com.strobel.decompiler.languages.Languages; +import com.strobel.decompiler.languages.java.JavaFormattingOptions; + +public class ConfigSaver { + + private static final String FLATTEN_SWITCH_BLOCKS_ID = "flattenSwitchBlocks"; + private static final String FORCE_EXPLICIT_IMPORTS_ID = "forceExplicitImports"; + private static final String SHOW_SYNTHETIC_MEMBERS_ID = "showSyntheticMembers"; + private static final String EXCLUDE_NESTED_TYPES_ID = "excludeNestedTypes"; + private static final String FORCE_EXPLICIT_TYPE_ARGUMENTS_ID = "forceExplicitTypeArguments"; + private static final String RETAIN_REDUNDANT_CASTS_ID = "retainRedundantCasts"; + private static final String INCLUDE_ERROR_DIAGNOSTICS_ID = "includeErrorDiagnostics"; + private static final String UNICODE_REPLACE_ENABLED_ID = "unicodeReplaceEnabled"; + private static final String LANGUAGE_NAME_ID = "languageName"; + + private static final String MAIN_WINDOW_ID_PREFIX = "main"; + private static final String FIND_WINDOW_ID_PREFIX = "find"; + private static final String WINDOW_IS_FULL_SCREEN_ID = "WindowIsFullScreen"; + private static final String WINDOW_WIDTH_ID = "WindowWidth"; + private static final String WINDOW_HEIGHT_ID = "WindowHeight"; + private static final String WINDOW_X_ID = "WindowX"; + private static final String WINDOW_Y_ID = "WindowY"; + + private DecompilerSettings decompilerSettings; + private WindowPosition mainWindowPosition; + private WindowPosition findWindowPosition; + private LuytenPreferences luytenPreferences; + + private static ConfigSaver theLoadedInstance; + + /** + * Do not instantiate, get the loaded instance + */ + private ConfigSaver() { + } + + public static ConfigSaver getLoadedInstance() { + if (theLoadedInstance == null) { + synchronized (ConfigSaver.class) { + if (theLoadedInstance == null) { + theLoadedInstance = new ConfigSaver(); + theLoadedInstance.loadConfig(); + } + } + } + return theLoadedInstance; + } + + /** + * Do not load, get the loaded instance + */ + private void loadConfig() { + decompilerSettings = new DecompilerSettings(); + if (decompilerSettings.getJavaFormattingOptions() == null) { + decompilerSettings.setJavaFormattingOptions(JavaFormattingOptions.createDefault()); + } + luytenPreferences = new LuytenPreferences(); + mainWindowPosition = new WindowPosition(); + findWindowPosition = new WindowPosition(); + try { + Preferences prefs = Preferences.userNodeForPackage(ConfigSaver.class); + if (!prefs.get(LANGUAGE_NAME_ID, decompilerSettings.getLanguage().getName()) + .equals(decompilerSettings.getLanguage().getName())) + prefs.put(LANGUAGE_NAME_ID, decompilerSettings.getLanguage().getName()); + + decompilerSettings.setFlattenSwitchBlocks( + prefs.getBoolean(FLATTEN_SWITCH_BLOCKS_ID, decompilerSettings.getFlattenSwitchBlocks())); + decompilerSettings.setForceExplicitImports( + prefs.getBoolean(FORCE_EXPLICIT_IMPORTS_ID, decompilerSettings.getForceExplicitImports())); + decompilerSettings.setShowSyntheticMembers( + prefs.getBoolean(SHOW_SYNTHETIC_MEMBERS_ID, decompilerSettings.getShowSyntheticMembers())); + decompilerSettings.setExcludeNestedTypes( + prefs.getBoolean(EXCLUDE_NESTED_TYPES_ID, decompilerSettings.getExcludeNestedTypes())); + decompilerSettings.setForceExplicitTypeArguments(prefs.getBoolean(FORCE_EXPLICIT_TYPE_ARGUMENTS_ID, + decompilerSettings.getForceExplicitTypeArguments())); + decompilerSettings.setRetainRedundantCasts( + prefs.getBoolean(RETAIN_REDUNDANT_CASTS_ID, decompilerSettings.getRetainRedundantCasts())); + decompilerSettings.setIncludeErrorDiagnostics( + prefs.getBoolean(INCLUDE_ERROR_DIAGNOSTICS_ID, decompilerSettings.getIncludeErrorDiagnostics())); + decompilerSettings.setLanguage( + findLanguageByName(prefs.get(LANGUAGE_NAME_ID, decompilerSettings.getLanguage().getName()))); + decompilerSettings.setUnicodeOutputEnabled(prefs.getBoolean(UNICODE_REPLACE_ENABLED_ID, false)); + + mainWindowPosition = loadWindowPosition(prefs, MAIN_WINDOW_ID_PREFIX); + findWindowPosition = loadWindowPosition(prefs, FIND_WINDOW_ID_PREFIX); + luytenPreferences = loadLuytenPreferences(prefs); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + private WindowPosition loadWindowPosition(Preferences prefs, String windowIdPrefix) { + WindowPosition windowPosition = new WindowPosition(); + windowPosition.setFullScreen(prefs.getBoolean(windowIdPrefix + WINDOW_IS_FULL_SCREEN_ID, false)); + windowPosition.setWindowWidth(prefs.getInt(windowIdPrefix + WINDOW_WIDTH_ID, 0)); + windowPosition.setWindowHeight(prefs.getInt(windowIdPrefix + WINDOW_HEIGHT_ID, 0)); + windowPosition.setWindowX(prefs.getInt(windowIdPrefix + WINDOW_X_ID, 0)); + windowPosition.setWindowY(prefs.getInt(windowIdPrefix + WINDOW_Y_ID, 0)); + return windowPosition; + } + + // load preferences by their java variable names + private LuytenPreferences loadLuytenPreferences(Preferences prefs) throws Exception { + LuytenPreferences newLuytenPrefs = new LuytenPreferences(); + for (Field field : LuytenPreferences.class.getDeclaredFields()) { + if (Modifier.isStatic(field.getModifiers())) + continue; + field.setAccessible(true); + String prefId = field.getName(); + Object defaultVal = field.get(newLuytenPrefs); + + if (field.getType() == String.class) { + String defaultStr = (String) (defaultVal == null ? "" : defaultVal); + field.set(newLuytenPrefs, prefs.get(prefId, defaultStr)); + + } else if (field.getType() == Boolean.class || field.getType() == boolean.class) { + Boolean defaultBool = (Boolean) (defaultVal == null ? new Boolean(false) : defaultVal); + field.setBoolean(newLuytenPrefs, prefs.getBoolean(prefId, defaultBool)); + + } else if (field.getType() == Integer.class || field.getType() == int.class) { + Integer defaultInt = (Integer) (defaultVal == null ? new Integer(0) : defaultVal); + field.setInt(newLuytenPrefs, prefs.getInt(prefId, defaultInt)); + } + } + return newLuytenPrefs; + } + + public void saveConfig() { + // Registry path on Windows Xp: + // HKEY_CURRENT_USER/Software/JavaSoft/Prefs/us/deathmarine/luyten + try { + Preferences prefs = Preferences.userNodeForPackage(ConfigSaver.class); + + prefs.putBoolean(FLATTEN_SWITCH_BLOCKS_ID, decompilerSettings.getFlattenSwitchBlocks()); + prefs.putBoolean(FORCE_EXPLICIT_IMPORTS_ID, decompilerSettings.getForceExplicitImports()); + prefs.putBoolean(SHOW_SYNTHETIC_MEMBERS_ID, decompilerSettings.getShowSyntheticMembers()); + prefs.putBoolean(EXCLUDE_NESTED_TYPES_ID, decompilerSettings.getExcludeNestedTypes()); + prefs.putBoolean(FORCE_EXPLICIT_TYPE_ARGUMENTS_ID, decompilerSettings.getForceExplicitTypeArguments()); + prefs.putBoolean(RETAIN_REDUNDANT_CASTS_ID, decompilerSettings.getRetainRedundantCasts()); + prefs.putBoolean(INCLUDE_ERROR_DIAGNOSTICS_ID, decompilerSettings.getIncludeErrorDiagnostics()); + prefs.putBoolean(UNICODE_REPLACE_ENABLED_ID, decompilerSettings.isUnicodeOutputEnabled()); + prefs.put(LANGUAGE_NAME_ID, decompilerSettings.getLanguage().getName()); + + saveWindowPosition(prefs, MAIN_WINDOW_ID_PREFIX, mainWindowPosition); + saveWindowPosition(prefs, FIND_WINDOW_ID_PREFIX, findWindowPosition); + saveLuytenPreferences(prefs); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + private void saveWindowPosition(Preferences prefs, String windowIdPrefix, WindowPosition windowPosition) { + prefs.putBoolean(windowIdPrefix + WINDOW_IS_FULL_SCREEN_ID, windowPosition.isFullScreen()); + prefs.putInt(windowIdPrefix + WINDOW_WIDTH_ID, windowPosition.getWindowWidth()); + prefs.putInt(windowIdPrefix + WINDOW_HEIGHT_ID, windowPosition.getWindowHeight()); + prefs.putInt(windowIdPrefix + WINDOW_X_ID, windowPosition.getWindowX()); + prefs.putInt(windowIdPrefix + WINDOW_Y_ID, windowPosition.getWindowY()); + } + + // save preferences by their java variable names + private void saveLuytenPreferences(Preferences prefs) throws Exception { + for (Field field : LuytenPreferences.class.getDeclaredFields()) { + if (Modifier.isStatic(field.getModifiers())) + continue; + field.setAccessible(true); + String prefId = field.getName(); + Object value = field.get(luytenPreferences); + + if (field.getType() == String.class) { + prefs.put(prefId, (String) (value == null ? "" : value)); + + } else if (field.getType() == Boolean.class || field.getType() == boolean.class) { + prefs.putBoolean(prefId, (Boolean) (value == null ? new Boolean(false) : value)); + + } else if (field.getType() == Integer.class || field.getType() == int.class) { + prefs.putInt(prefId, (Integer) (value == null ? new Integer(0) : value)); + } + } + } + + private Language findLanguageByName(String languageName) { + if (languageName != null) { + + if (languageName.equals(Languages.java().getName())) { + return Languages.java(); + } else if (languageName.equals(Languages.bytecode().getName())) { + return Languages.bytecode(); + } else if (languageName.equals(Languages.bytecodeAst().getName())) { + return Languages.bytecodeAst(); + } + + for (Language language : Languages.debug()) { + if (languageName.equals(language.getName())) { + return language; + } + } + } + return Languages.java(); + } + + public DecompilerSettings getDecompilerSettings() { + return decompilerSettings; + } + + public WindowPosition getMainWindowPosition() { + return mainWindowPosition; + } + + public WindowPosition getFindWindowPosition() { + return findWindowPosition; + } + + public LuytenPreferences getLuytenPreferences() { + return luytenPreferences; + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DecompilerLinkProvider.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DecompilerLinkProvider.java new file mode 100644 index 0000000..b63d9ad --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DecompilerLinkProvider.java @@ -0,0 +1,384 @@ +package us.deathmarine.luyten; + +import java.io.StringWriter; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import com.strobel.assembler.metadata.FieldDefinition; +import com.strobel.assembler.metadata.FieldReference; +import com.strobel.assembler.metadata.MetadataSystem; +import com.strobel.assembler.metadata.MethodDefinition; +import com.strobel.assembler.metadata.MethodReference; +import com.strobel.assembler.metadata.TypeDefinition; +import com.strobel.assembler.metadata.TypeReference; +import com.strobel.core.StringUtilities; +import com.strobel.decompiler.DecompilationOptions; +import com.strobel.decompiler.DecompilerSettings; +import com.strobel.decompiler.PlainTextOutput; + +public class DecompilerLinkProvider implements LinkProvider { + + private Map definitionToSelectionMap = new HashMap<>(); + private Map> referenceToSelectionsMap = new HashMap<>(); + private boolean isSelectionMapsPopulated = false; + + private MetadataSystem metadataSystem; + private DecompilerSettings settings; + private DecompilationOptions decompilationOptions; + private TypeDefinition type; + + private String currentTypeQualifiedName; + private String textContent = ""; + + @Override + public void generateContent() { + definitionToSelectionMap = new HashMap<>(); + referenceToSelectionsMap = new HashMap<>(); + currentTypeQualifiedName = type.getPackageName() + "." + type.getName(); + final StringWriter stringwriter = new StringWriter(); + PlainTextOutput plainTextOutput = new PlainTextOutput(stringwriter) { + @Override + public void writeDefinition(String text, Object definition, boolean isLocal) { + super.writeDefinition(text, definition, isLocal); + try { + if (text != null && definition != null) { + String uniqueStr = createUniqueStrForReference(definition); + if (uniqueStr != null) { + // fix link's underline length: _java.util.HashSet_ + // -> _HashSet_ + text = text.replaceAll("[^\\.]*\\.", ""); + int from = stringwriter.getBuffer().length() - text.length(); + int to = stringwriter.getBuffer().length(); + definitionToSelectionMap.put(uniqueStr, new Selection(from, to)); + } + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + @Override + public void writeReference(String text, Object reference, boolean isLocal) { + super.writeReference(text, reference, isLocal); + try { + if (text != null && reference != null) { + String uniqueStr = createUniqueStrForReference(reference); + if (uniqueStr != null) { + text = text.replaceAll("[^\\.]*\\.", ""); + int from = stringwriter.getBuffer().length() - text.length(); + int to = stringwriter.getBuffer().length(); + if (reference instanceof FieldReference) { + // fix enum definition links (note: could not fix enum reference links) + if (((FieldReference) reference).isDefinition()) { + definitionToSelectionMap.put(uniqueStr, new Selection(from, to)); + return; + } + } + if (referenceToSelectionsMap.containsKey(uniqueStr)) { + Set selectionsSet = referenceToSelectionsMap.get(uniqueStr); + if (selectionsSet != null) { + selectionsSet.add(new Selection(from, to)); + } + } else { + Set selectionsSet = new HashSet<>(); + selectionsSet.add(new Selection(from, to)); + referenceToSelectionsMap.put(uniqueStr, selectionsSet); + } + } + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + }; + plainTextOutput.setUnicodeOutputEnabled(decompilationOptions.getSettings().isUnicodeOutputEnabled()); + settings.getLanguage().decompileType(type, plainTextOutput, decompilationOptions); + textContent = stringwriter.toString(); + isSelectionMapsPopulated = true; + } + + private String createUniqueStrForReference(Object reference) { + String uniqueStr = null; + if (reference instanceof TypeReference) { + TypeReference type = (TypeReference) reference; + String pathAndTypeStr = getPathAndTypeStr(type); + if (pathAndTypeStr != null) { + uniqueStr = "type|" + pathAndTypeStr; + } + } else if (reference instanceof MethodReference) { + MethodReference method = (MethodReference) reference; + String pathAndTypeStr = getPathAndTypeStr(method.getDeclaringType()); + if (pathAndTypeStr != null) { + uniqueStr = "method|" + pathAndTypeStr + "|" + method.getName() + "|" + method.getErasedSignature(); + } + } else if (reference instanceof FieldReference) { + FieldReference field = (FieldReference) reference; + String pathAndTypeStr = getPathAndTypeStr(field.getDeclaringType()); + if (pathAndTypeStr != null) { + uniqueStr = "field|" + pathAndTypeStr + "|" + field.getName(); + } + } + return uniqueStr; + } + + private String getPathAndTypeStr(TypeReference typeRef) { + String name = typeRef.getName(); + String packageStr = typeRef.getPackageName(); + TypeReference mostOuterTypeRef = getMostOuterTypeRef(typeRef); + String mostOuterTypeName = mostOuterTypeRef.getName(); + if (name != null && packageStr != null && mostOuterTypeName != null && name.trim().length() > 0 + && mostOuterTypeName.trim().length() > 0) { + String pathStr = packageStr.replaceAll("\\.", "/") + "/" + mostOuterTypeName; + String typeStr = packageStr + "." + name.replace(".", "$"); + return pathStr + "|" + typeStr; + } + return null; + } + + private TypeReference getMostOuterTypeRef(TypeReference typeRef) { + int maxDecraringDepth = typeRef.getFullName().split("(\\.|\\$)").length; + for (int i = 0; i < maxDecraringDepth; i++) { + TypeReference declaringTypeRef = typeRef.getDeclaringType(); + if (declaringTypeRef == null) { + break; + } else { + typeRef = declaringTypeRef; + } + } + if (typeRef.getName().contains("$")) { + return getMostOuterTypeRefBySlowLookuping(typeRef); + } + return typeRef; + } + + private TypeReference getMostOuterTypeRefBySlowLookuping(TypeReference typeRef) { + String name = typeRef.getName(); + if (name == null) + return typeRef; + String packageName = typeRef.getPackageName(); + if (packageName == null) + return typeRef; + String[] nameParts = name.split("\\$"); + String newName = ""; + String sep = ""; + for (int i = 0; i < nameParts.length - 1; i++) { + newName = newName + sep + nameParts[i]; + sep = "$"; + String newInternalName = packageName.replaceAll("\\.", "/") + "/" + newName; + TypeReference newTypeRef = metadataSystem.lookupType(newInternalName); + if (newTypeRef != null) { + TypeDefinition newTypeDef = newTypeRef.resolve(); + if (newTypeDef != null) { + return newTypeRef; + } + } + } + return typeRef; + } + + @Override + public String getTextContent() { + return textContent; + } + + @Override + public void processLinks() { + } + + @Override + public Map getDefinitionToSelectionMap() { + return definitionToSelectionMap; + } + + @Override + public Map> getReferenceToSelectionsMap() { + return referenceToSelectionsMap; + } + + @Override + public boolean isLinkNavigable(String uniqueStr) { + if (isSelectionMapsPopulated && definitionToSelectionMap.containsKey(uniqueStr)) + return true; + if (uniqueStr == null) + return false; + String[] linkParts = uniqueStr.split("\\|"); + if (linkParts.length < 3) + return false; + String typeStr = linkParts[2]; + if (typeStr.trim().length() <= 0) + return false; + TypeReference typeRef = metadataSystem.lookupType(typeStr.replaceAll("\\.", "/")); + if (typeRef == null) + return false; + TypeDefinition typeDef = typeRef.resolve(); + if (typeDef == null) + return false; + if (typeDef.isSynthetic()) + return false; + + if (isSelectionMapsPopulated) { + // current type's navigable definitions checked already, now it's erroneous + if (currentTypeQualifiedName == null || currentTypeQualifiedName.trim().length() <= 0) + return false; + if (typeStr.equals(currentTypeQualifiedName) || typeStr.startsWith(currentTypeQualifiedName + ".") + || typeStr.startsWith(currentTypeQualifiedName + "$")) + return false; + } + + // check linked field/method exists + if (uniqueStr.startsWith("method")) { + if (findMethodInType(typeDef, uniqueStr) == null) { + return false; + } + } else if (uniqueStr.startsWith("field")) { + if (findFieldInType(typeDef, uniqueStr) == null) { + return false; + } + } + return true; + } + + private MethodDefinition findMethodInType(TypeDefinition typeDef, String uniqueStr) { + String[] linkParts = uniqueStr.split("\\|"); + if (linkParts.length != 5) + return null; + String methodName = linkParts[3]; + String methodErasedSignature = linkParts[4]; + if (methodName.trim().length() <= 0 || methodErasedSignature.trim().length() <= 0) + return null; + List declaredMethods = typeDef.getDeclaredMethods(); + if (declaredMethods == null) + return null; + boolean isFound = false; + for (MethodDefinition declaredMethod : declaredMethods) { + isFound = (declaredMethod != null && methodName.equals(declaredMethod.getName())); + isFound = (isFound && methodErasedSignature.equals(declaredMethod.getErasedSignature())); + if (isFound) { + if (declaredMethod.isSynthetic() && !settings.getShowSyntheticMembers()) { + return null; + } else { + return declaredMethod; + } + } + } + return null; + } + + private FieldDefinition findFieldInType(TypeDefinition typeDef, String uniqueStr) { + String[] linkParts = uniqueStr.split("\\|"); + if (linkParts.length != 4) + return null; + String fieldName = linkParts[3]; + if (fieldName.trim().length() <= 0) + return null; + List declaredFields = typeDef.getDeclaredFields(); + if (declaredFields == null) + return null; + boolean isFound = false; + for (FieldDefinition declaredField : declaredFields) { + isFound = (declaredField != null && fieldName.equals(declaredField.getName())); + if (isFound) { + if (declaredField.isSynthetic()) { + return null; + } else { + return declaredField; + } + } + } + return null; + } + + @Override + public String getLinkDescription(String uniqueStr) { + String readableLink = null; + try { + if (uniqueStr == null) + return null; + String[] linkParts = uniqueStr.split("\\|"); + if (linkParts.length < 3) + return null; + String typeStr = linkParts[2]; + TypeReference typeRef = metadataSystem.lookupType(typeStr.replaceAll("\\.", "/")); + if (typeRef == null) + return null; + TypeDefinition typeDef = typeRef.resolve(); + if (typeDef == null) + return null; + + String declaredSuffix = ""; + String mostOuterTypeStr = linkParts[1].replaceAll("/", "."); + boolean isOwnFile = mostOuterTypeStr.equals(currentTypeQualifiedName); + if (!isOwnFile) { + declaredSuffix = " - Declared: " + mostOuterTypeStr; + } + + if (uniqueStr.startsWith("type")) { + String desc = typeDef.getBriefDescription(); + if (desc != null && desc.trim().length() > 0) { + readableLink = desc; + } + } else if (uniqueStr.startsWith("method")) { + MethodDefinition methodDef = findMethodInType(typeDef, uniqueStr); + if (methodDef == null) + return null; + String desc = methodDef.getBriefDescription(); + if (desc != null && desc.trim().length() > 0) { + + if (desc.contains("void ")) { + String constructorName = typeDef.getName(); + TypeReference declaringTypeRef = typeRef.getDeclaringType(); + if (declaringTypeRef != null) { + TypeDefinition declaringTypeDef = declaringTypeRef.resolve(); + if (declaringTypeDef != null) { + String declaringTypeName = declaringTypeDef.getName(); + if (declaringTypeName != null) { + constructorName = StringUtilities.removeLeft(constructorName, declaringTypeName); + constructorName = constructorName.replaceAll("^(\\.|\\$)", ""); + } + } + } + desc = desc.replace("void ", constructorName); + readableLink = "Constructor: " + erasePackageInfoFromDesc(desc) + declaredSuffix; + } else { + readableLink = erasePackageInfoFromDesc(desc) + declaredSuffix; + } + } + } else if (uniqueStr.startsWith("field")) { + FieldDefinition fieldDef = findFieldInType(typeDef, uniqueStr); + if (fieldDef == null) + return null; + String desc = fieldDef.getBriefDescription(); + if (desc != null && desc.trim().length() > 0) { + readableLink = erasePackageInfoFromDesc(desc) + declaredSuffix; + } + + } + if (readableLink != null) { + readableLink = readableLink.replace("$", "."); + } + } catch (Exception e) { + readableLink = null; + Luyten.showExceptionDialog("Exception!", e); + } + return readableLink; + } + + private String erasePackageInfoFromDesc(String desc) { + String limiters = "\\(\\)\\<\\>\\[\\]\\?\\s,"; + desc = desc.replaceAll("(?<=[^" + limiters + "]*)([^" + limiters + "]*)\\.", ""); + return desc; + } + + public void setDecompilerReferences(MetadataSystem metadataSystem, DecompilerSettings settings, + DecompilationOptions decompilationOptions) { + this.metadataSystem = metadataSystem; + this.settings = settings; + this.decompilationOptions = decompilationOptions; + } + + public void setType(TypeDefinition type) { + this.type = type; + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DirPreferences.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DirPreferences.java new file mode 100644 index 0000000..ea5df80 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DirPreferences.java @@ -0,0 +1,62 @@ +package us.deathmarine.luyten; + +import javax.swing.*; +import java.io.File; + +class DirPreferences { + private LuytenPreferences luytenPrefs; + + public DirPreferences(LuytenPreferences luytenPrefs) { + this.luytenPrefs = luytenPrefs; + } + + void retrieveOpenDialogDir(JFileChooser fc) { + try { + String currentDirStr = luytenPrefs.getFileOpenCurrentDirectory(); + if (currentDirStr != null && currentDirStr.trim().length() > 0) { + File currentDir = new File(currentDirStr); + if (currentDir.exists() && currentDir.isDirectory()) { + fc.setCurrentDirectory(currentDir); + } + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + void saveOpenDialogDir(JFileChooser fc) { + try { + File currentDir = fc.getCurrentDirectory(); + if (currentDir != null && currentDir.exists() && currentDir.isDirectory()) { + luytenPrefs.setFileOpenCurrentDirectory(currentDir.getAbsolutePath()); + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + void retrieveSaveDialogDir(JFileChooser fc) { + try { + String currentDirStr = luytenPrefs.getFileSaveCurrentDirectory(); + if (currentDirStr != null && currentDirStr.trim().length() > 0) { + File currentDir = new File(currentDirStr); + if (currentDir.exists() && currentDir.isDirectory()) { + fc.setCurrentDirectory(currentDir); + } + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + void saveSaveDialogDir(JFileChooser fc) { + try { + File currentDir = fc.getCurrentDirectory(); + if (currentDir != null && currentDir.exists() && currentDir.isDirectory()) { + luytenPrefs.setFileSaveCurrentDirectory(currentDir.getAbsolutePath()); + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } +} \ No newline at end of file diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DropListener.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DropListener.java new file mode 100644 index 0000000..ff32a01 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/DropListener.java @@ -0,0 +1,108 @@ +package us.deathmarine.luyten; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.io.BufferedReader; +import java.io.File; +import java.io.Reader; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +/** + * Drag-Drop (only MainWindow should be called from here) + */ +public class DropListener implements DropTargetListener { + private MainWindow mainWindow; + + public DropListener(MainWindow mainWindow) { + this.mainWindow = mainWindow; + } + + @SuppressWarnings("unchecked") + @Override + public void drop(DropTargetDropEvent event) { + event.acceptDrop(DnDConstants.ACTION_COPY); + Transferable transferable = event.getTransferable(); + if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { + DataFlavor[] flavors = transferable.getTransferDataFlavors(); + for (DataFlavor flavor : flavors) { + try { + if (flavor.isFlavorJavaFileListType()) { + List files = (List) transferable.getTransferData(flavor); + if (files.size() > 1) { + event.rejectDrop(); + return; + } + if (files.size() == 1) { + mainWindow.onFileDropped(files.get(0)); + } + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + event.dropComplete(true); + } else { + DataFlavor[] flavors = transferable.getTransferDataFlavors(); + boolean handled = false; + for (int zz = 0; zz < flavors.length; zz++) { + if (flavors[zz].isRepresentationClassReader()) { + try { + Reader reader = flavors[zz].getReaderForText(transferable); + BufferedReader br = new BufferedReader(reader); + List list = new ArrayList(); + String line = null; + while ((line = br.readLine()) != null) { + try { + if (new String("" + (char) 0).equals(line)) + continue; + File file = new File(new URI(line)); + list.add(file); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + if (list.size() > 1) { + event.rejectDrop(); + return; + } + if (list.size() == 1) { + mainWindow.onFileDropped(list.get(0)); + } + event.getDropTargetContext().dropComplete(true); + handled = true; + } catch (Exception e) { + e.printStackTrace(); + } + break; + } + } + if (!handled) { + event.rejectDrop(); + } + } + + } + + @Override + public void dragEnter(DropTargetDragEvent arg0) { + } + + @Override + public void dragExit(DropTargetEvent arg0) { + } + + @Override + public void dragOver(DropTargetDragEvent arg0) { + } + + @Override + public void dropActionChanged(DropTargetDragEvent arg0) { + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileDialog.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileDialog.java new file mode 100644 index 0000000..b573ac8 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileDialog.java @@ -0,0 +1,135 @@ +package us.deathmarine.luyten; + +import java.awt.Component; +import java.io.File; +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileFilter; + +/** + * FileChoosers for Open and Save + */ +public class FileDialog { + private final DirPreferences dirPreferences; + private ConfigSaver configSaver; + private Component parent; + private JFileChooser fcOpen; + private JFileChooser fcSave; + private JFileChooser fcSaveAll; + + public FileDialog(Component parent) { + this.parent = parent; + configSaver = ConfigSaver.getLoadedInstance(); + LuytenPreferences luytenPrefs = configSaver.getLuytenPreferences(); + dirPreferences = new DirPreferences(luytenPrefs); + + new Thread() { + public void run() { + try { + initOpenDialog(); + Thread.sleep(500); + initSaveAllDialog(); + Thread.sleep(500); + initSaveDialog(); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + }; + }.start(); + } + + public File doOpenDialog() { + File selectedFile = null; + initOpenDialog(); + + dirPreferences.retrieveOpenDialogDir(fcOpen); + int returnVal = fcOpen.showOpenDialog(parent); + dirPreferences.saveOpenDialogDir(fcOpen); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + selectedFile = fcOpen.getSelectedFile(); + } + return selectedFile; + } + + public File doSaveDialog(String recommendedFileName) { + File selectedFile = null; + initSaveDialog(); + + dirPreferences.retrieveSaveDialogDir(fcSave); + fcSave.setSelectedFile(new File(recommendedFileName)); + int returnVal = fcSave.showSaveDialog(parent); + dirPreferences.saveSaveDialogDir(fcSave); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + selectedFile = fcSave.getSelectedFile(); + } + return selectedFile; + } + + public File doSaveAllDialog(String recommendedFileName) { + File selectedFile = null; + initSaveAllDialog(); + + dirPreferences.retrieveSaveDialogDir(fcSaveAll); + fcSaveAll.setSelectedFile(new File(recommendedFileName)); + int returnVal = fcSaveAll.showSaveDialog(parent); + dirPreferences.saveSaveDialogDir(fcSaveAll); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + selectedFile = fcSaveAll.getSelectedFile(); + } + return selectedFile; + } + + public synchronized void initOpenDialog() { + if (fcOpen == null) { + fcOpen = createFileChooser("*.jar", "*.zip", "*.class"); + dirPreferences.retrieveOpenDialogDir(fcOpen); + } + } + + public synchronized void initSaveDialog() { + if (fcSave == null) { + fcSave = createFileChooser("*.txt", "*.java"); + dirPreferences.retrieveSaveDialogDir(fcSave); + } + } + + public synchronized void initSaveAllDialog() { + if (fcSaveAll == null) { + fcSaveAll = createFileChooser("*.jar", "*.zip"); + dirPreferences.retrieveSaveDialogDir(fcSaveAll); + } + } + + private JFileChooser createFileChooser(String... fileFilters) { + JFileChooser fc = new JFileChooser(); + for (String fileFilter : fileFilters) { + fc.addChoosableFileFilter(new FileChooserFileFilter(fileFilter)); + } + fc.setFileSelectionMode(JFileChooser.FILES_ONLY); + fc.setMultiSelectionEnabled(false); + return fc; + } + + public class FileChooserFileFilter extends FileFilter { + String objType; + + public FileChooserFileFilter(String string) { + objType = string; + } + + @Override + public boolean accept(File f) { + if (f.isDirectory()) + return true; + return f.getName().toLowerCase().endsWith(objType.substring(1)); + } + + @Override + public String getDescription() { + return objType; + } + } + +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileEntryNotFoundException.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileEntryNotFoundException.java new file mode 100644 index 0000000..b625b58 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileEntryNotFoundException.java @@ -0,0 +1,6 @@ +package us.deathmarine.luyten; + +public class FileEntryNotFoundException extends Exception { + private static final long serialVersionUID = -1019729947179642460L; + +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileIsBinaryException.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileIsBinaryException.java new file mode 100644 index 0000000..19b6c4e --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileIsBinaryException.java @@ -0,0 +1,6 @@ +package us.deathmarine.luyten; + +public class FileIsBinaryException extends Exception { + private static final long serialVersionUID = -1497200371383232314L; + +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileSaver.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileSaver.java new file mode 100644 index 0000000..e6ee49b --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FileSaver.java @@ -0,0 +1,334 @@ +package us.deathmarine.luyten; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.BufferedOutputStream; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.zip.ZipException; +import java.util.zip.ZipOutputStream; + +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JProgressBar; +import javax.swing.SwingUtilities; + +import com.strobel.assembler.metadata.ITypeLoader; +import com.strobel.assembler.metadata.JarTypeLoader; +import com.strobel.assembler.metadata.MetadataSystem; +import com.strobel.assembler.metadata.TypeDefinition; +import com.strobel.assembler.metadata.TypeReference; +import com.strobel.core.StringUtilities; +import com.strobel.decompiler.DecompilationOptions; +import com.strobel.decompiler.DecompilerSettings; +import com.strobel.decompiler.PlainTextOutput; +import com.strobel.decompiler.languages.java.JavaFormattingOptions; + +/** + * Performs Save and Save All + */ +public class FileSaver { + + private JProgressBar bar; + private JLabel label; + private boolean cancel; + private boolean extracting; + + public FileSaver(JProgressBar bar, JLabel label) { + this.bar = bar; + this.label = label; + final JPopupMenu menu = new JPopupMenu("Cancel"); + final JMenuItem item = new JMenuItem("Cancel"); + item.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + setCancel(true); + } + }); + menu.add(item); + this.label.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent ev) { + if (SwingUtilities.isRightMouseButton(ev) && isExtracting()) + menu.show(ev.getComponent(), ev.getX(), ev.getY()); + } + }); + } + + public void saveText(final String text, final File file) { + new Thread(new Runnable() { + @Override + public void run() { + DecompilerSettings settings = cloneSettings(); + boolean isUnicodeEnabled = settings.isUnicodeOutputEnabled(); + long time = System.currentTimeMillis(); + try (FileOutputStream fos = new FileOutputStream(file); + OutputStreamWriter writer = isUnicodeEnabled ? new OutputStreamWriter(fos, "UTF-8") + : new OutputStreamWriter(fos); + BufferedWriter bw = new BufferedWriter(writer);) { + label.setText("Extracting: " + file.getName()); + bar.setVisible(true); + bw.write(text); + bw.flush(); + label.setText("Completed: " + getTime(time)); + } catch (Exception e1) { + label.setText("Cannot save file: " + file.getName()); + Luyten.showExceptionDialog("Unable to save file!\n", e1); + } finally { + setExtracting(false); + bar.setVisible(false); + } + } + }).start(); + } + + public void saveAllDecompiled(final File inFile, final File outFile) { + new Thread(new Runnable() { + @Override + public void run() { + long time = System.currentTimeMillis(); + try { + bar.setVisible(true); + setExtracting(true); + label.setText("Extracting: " + outFile.getName()); + System.out.println("[SaveAll]: " + inFile.getName() + " -> " + outFile.getName()); + String inFileName = inFile.getName().toLowerCase(); + + if (inFileName.endsWith(".jar") || inFileName.endsWith(".zip")) { + doSaveJarDecompiled(inFile, outFile); + } else if (inFileName.endsWith(".class")) { + doSaveClassDecompiled(inFile, outFile); + } else { + doSaveUnknownFile(inFile, outFile); + } + if (cancel) { + label.setText("Cancelled"); + outFile.delete(); + setCancel(false); + } else { + label.setText("Completed: " + getTime(time)); + } + } catch (Exception e1) { + label.setText("Cannot save file: " + outFile.getName()); + Luyten.showExceptionDialog("Unable to save file!\n", e1); + } finally { + setExtracting(false); + bar.setVisible(false); + } + } + }).start(); + } + + private void doSaveJarDecompiled(File inFile, File outFile) throws Exception { + try (JarFile jfile = new JarFile(inFile); + FileOutputStream dest = new FileOutputStream(outFile); + BufferedOutputStream buffDest = new BufferedOutputStream(dest); + ZipOutputStream out = new ZipOutputStream(buffDest);) { + bar.setMinimum(0); + bar.setMaximum(jfile.size()); + byte data[] = new byte[1024]; + DecompilerSettings settings = cloneSettings(); + LuytenTypeLoader typeLoader = new LuytenTypeLoader(); + MetadataSystem metadataSystem = new MetadataSystem(typeLoader); + ITypeLoader jarLoader = new JarTypeLoader(jfile); + typeLoader.getTypeLoaders().add(jarLoader); + + DecompilationOptions decompilationOptions = new DecompilationOptions(); + decompilationOptions.setSettings(settings); + decompilationOptions.setFullDecompilation(true); + + List mass = null; + JarEntryFilter jarEntryFilter = new JarEntryFilter(jfile); + LuytenPreferences luytenPrefs = ConfigSaver.getLoadedInstance().getLuytenPreferences(); + if (luytenPrefs.isFilterOutInnerClassEntries()) { + mass = jarEntryFilter.getEntriesWithoutInnerClasses(); + } else { + mass = jarEntryFilter.getAllEntriesFromJar(); + } + + Enumeration ent = jfile.entries(); + Set history = new HashSet(); + int tick = 0; + while (ent.hasMoreElements() && !cancel) { + bar.setValue(++tick); + JarEntry entry = ent.nextElement(); + if (!mass.contains(entry.getName())) + continue; + label.setText("Extracting: " + entry.getName()); + bar.setVisible(true); + if (entry.getName().endsWith(".class")) { + JarEntry etn = new JarEntry(entry.getName().replace(".class", ".java")); + label.setText("Extracting: " + etn.getName()); + System.out.println("[SaveAll]: " + etn.getName() + " -> " + outFile.getName()); + + if (history.add(etn.getName())) { + out.putNextEntry(etn); + try { + boolean isUnicodeEnabled = decompilationOptions.getSettings().isUnicodeOutputEnabled(); + String internalName = StringUtilities.removeRight(entry.getName(), ".class"); + TypeReference type = metadataSystem.lookupType(internalName); + TypeDefinition resolvedType = null; + if ((type == null) || ((resolvedType = type.resolve()) == null)) { + throw new Exception("Unable to resolve type."); + } + Writer writer = isUnicodeEnabled ? new OutputStreamWriter(out, "UTF-8") + : new OutputStreamWriter(out); + PlainTextOutput plainTextOutput = new PlainTextOutput(writer); + plainTextOutput.setUnicodeOutputEnabled(isUnicodeEnabled); + settings.getLanguage().decompileType(resolvedType, plainTextOutput, decompilationOptions); + writer.flush(); + } catch (Exception e) { + label.setText("Cannot decompile file: " + entry.getName()); + Luyten.showExceptionDialog("Unable to Decompile file!\nSkipping file...", e); + } finally { + out.closeEntry(); + } + } + } else { + try { + JarEntry etn = new JarEntry(entry.getName()); + if (entry.getName().endsWith(".java")) + etn = new JarEntry(entry.getName().replace(".java", ".src.java")); + if (history.add(etn.getName())) { + out.putNextEntry(etn); + try { + InputStream in = jfile.getInputStream(etn); + if (in != null) { + try { + int count; + while ((count = in.read(data, 0, 1024)) != -1) { + out.write(data, 0, count); + } + } finally { + in.close(); + } + } + } finally { + out.closeEntry(); + } + } + } catch (ZipException ze) { + if (!ze.getMessage().contains("duplicate")) { + throw ze; + } + } + } + } + } + } + + private void doSaveClassDecompiled(File inFile, File outFile) throws Exception { + DecompilerSettings settings = cloneSettings(); + LuytenTypeLoader typeLoader = new LuytenTypeLoader(); + MetadataSystem metadataSystem = new MetadataSystem(typeLoader); + TypeReference type = metadataSystem.lookupType(inFile.getCanonicalPath()); + + DecompilationOptions decompilationOptions = new DecompilationOptions(); + decompilationOptions.setSettings(settings); + decompilationOptions.setFullDecompilation(true); + + boolean isUnicodeEnabled = decompilationOptions.getSettings().isUnicodeOutputEnabled(); + TypeDefinition resolvedType = null; + if (type == null || ((resolvedType = type.resolve()) == null)) { + throw new Exception("Unable to resolve type."); + } + StringWriter stringwriter = new StringWriter(); + PlainTextOutput plainTextOutput = new PlainTextOutput(stringwriter); + plainTextOutput.setUnicodeOutputEnabled(isUnicodeEnabled); + settings.getLanguage().decompileType(resolvedType, plainTextOutput, decompilationOptions); + String decompiledSource = stringwriter.toString(); + + System.out.println("[SaveAll]: " + inFile.getName() + " -> " + outFile.getName()); + try (FileOutputStream fos = new FileOutputStream(outFile); + OutputStreamWriter writer = isUnicodeEnabled ? new OutputStreamWriter(fos, "UTF-8") + : new OutputStreamWriter(fos); + BufferedWriter bw = new BufferedWriter(writer);) { + bw.write(decompiledSource); + bw.flush(); + } + } + + private void doSaveUnknownFile(File inFile, File outFile) throws Exception { + try (FileInputStream in = new FileInputStream(inFile); FileOutputStream out = new FileOutputStream(outFile);) { + System.out.println("[SaveAll]: " + inFile.getName() + " -> " + outFile.getName()); + + byte data[] = new byte[1024]; + int count; + while ((count = in.read(data, 0, 1024)) != -1) { + out.write(data, 0, count); + } + } + } + + private DecompilerSettings cloneSettings() { + DecompilerSettings settings = ConfigSaver.getLoadedInstance().getDecompilerSettings(); + DecompilerSettings newSettings = new DecompilerSettings(); + if (newSettings.getJavaFormattingOptions() == null) { + newSettings.setJavaFormattingOptions(JavaFormattingOptions.createDefault()); + } + // synchronized: against main menu changes + synchronized (settings) { + newSettings.setExcludeNestedTypes(settings.getExcludeNestedTypes()); + newSettings.setFlattenSwitchBlocks(settings.getFlattenSwitchBlocks()); + newSettings.setForceExplicitImports(settings.getForceExplicitImports()); + newSettings.setForceExplicitTypeArguments(settings.getForceExplicitTypeArguments()); + newSettings.setOutputFileHeaderText(settings.getOutputFileHeaderText()); + newSettings.setLanguage(settings.getLanguage()); + newSettings.setShowSyntheticMembers(settings.getShowSyntheticMembers()); + newSettings.setAlwaysGenerateExceptionVariableForCatchBlocks( + settings.getAlwaysGenerateExceptionVariableForCatchBlocks()); + newSettings.setOutputDirectory(settings.getOutputDirectory()); + newSettings.setRetainRedundantCasts(settings.getRetainRedundantCasts()); + newSettings.setIncludeErrorDiagnostics(settings.getIncludeErrorDiagnostics()); + newSettings.setIncludeLineNumbersInBytecode(settings.getIncludeLineNumbersInBytecode()); + newSettings.setRetainPointlessSwitches(settings.getRetainPointlessSwitches()); + newSettings.setUnicodeOutputEnabled(settings.isUnicodeOutputEnabled()); + newSettings.setMergeVariables(settings.getMergeVariables()); + newSettings.setShowDebugLineNumbers(settings.getShowDebugLineNumbers()); + } + return newSettings; + } + + public boolean isCancel() { + return cancel; + } + + public void setCancel(boolean cancel) { + this.cancel = cancel; + } + + public boolean isExtracting() { + return extracting; + } + + public void setExtracting(boolean extracting) { + this.extracting = extracting; + } + + public static String getTime(long time) { + long lap = System.currentTimeMillis() - time; + lap = lap / 1000; + StringBuilder sb = new StringBuilder(); + long hour = ((lap / 60) / 60); + long min = ((lap - (hour * 60 * 60)) / 60); + long sec = ((lap - (hour * 60 * 60) - (min * 60))); + if (hour > 0) + sb.append("Hour:").append(hour).append(" "); + sb.append("Min(s): ").append(min).append(" Sec: ").append(sec); + return sb.toString(); + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FindAllBox.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FindAllBox.java new file mode 100644 index 0000000..92bb1e3 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FindAllBox.java @@ -0,0 +1,369 @@ +package us.deathmarine.luyten; + +import com.strobel.assembler.metadata.TypeDefinition; +import com.strobel.assembler.metadata.TypeReference; +import com.strobel.core.StringUtilities; +import com.strobel.decompiler.DecompilationOptions; +import com.strobel.decompiler.DecompilerSettings; +import com.strobel.decompiler.PlainTextOutput; + +import us.deathmarine.luyten.ConfigSaver; +import us.deathmarine.luyten.MainWindow; +import us.deathmarine.luyten.Model; + +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.StringWriter; +import java.util.Collections; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.regex.Pattern; + +import javax.swing.*; +import javax.swing.GroupLayout.Alignment; + +/** + * + * this is the Find All Dialog + *

+ * Change with 1.1 + * Adjust the find all box width + *

+ * + * @author clevertension + * @version 1.1 + */ +public class FindAllBox extends JDialog { + private static final long serialVersionUID = -4125409760166690462L; + private static final int MIN_WIDTH = 640; + private boolean searching; + + private JButton findButton; + private JTextField textField; + private JCheckBox mcase; + private JCheckBox regex; + private JCheckBox wholew; + private JCheckBox classname; + private JList list; + private JProgressBar progressBar; + boolean locked; + + private JLabel statusLabel = new JLabel(""); + + private DefaultListModel classesList = new DefaultListModel(); + + private Thread tmp_thread; + + public FindAllBox(final MainWindow mainWindow) { + this.setDefaultCloseOperation(HIDE_ON_CLOSE); + this.setHideOnEscapeButton(); + + progressBar = new JProgressBar(0, 100); + + JLabel label = new JLabel("Find What:"); + textField = new JTextField(); + findButton = new JButton("Find"); + findButton.addActionListener(new FindButton()); + + mcase = new JCheckBox("Match Case"); + regex = new JCheckBox("Regex"); + wholew = new JCheckBox("Whole Words"); + classname = new JCheckBox("Classnames"); + + this.getRootPane().setDefaultButton(findButton); + + list = new JList(classesList); + list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); + list.setLayoutOrientation(JList.VERTICAL_WRAP); + list.setVisibleRowCount(-1); + list.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent evt) { + @SuppressWarnings("unchecked") + JList list = (JList) evt.getSource(); + if (evt.getClickCount() == 2) { + int index = list.locationToIndex(evt.getPoint()); + String entryName = (String) list.getModel().getElementAt(index); + String[] array = entryName.split("/"); + if (entryName.toLowerCase().endsWith(".class")) { + String internalName = StringUtilities.removeRight(entryName, ".class"); + TypeReference type = Model.metadataSystem.lookupType(internalName); + try { + mainWindow.getModel().extractClassToTextPane(type, array[array.length - 1], entryName, + null); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + + } else { + try { + JarFile jfile = new JarFile(MainWindow.model.getOpenedFile()); + mainWindow.getModel().extractSimpleFileEntryToTextPane( + jfile.getInputStream(jfile.getEntry(entryName)), array[array.length - 1], + entryName); + jfile.close(); + } catch (IOException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + } + }); + list.setLayoutOrientation(JList.VERTICAL); + JScrollPane listScroller = new JScrollPane(list, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, + JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + int width = (int) (screenSize.width * 0.35); + if (width < MIN_WIDTH) { + width = MIN_WIDTH; + } + final Dimension center = new Dimension(width, 500); + final int x = (int) (center.width * 0.2); + final int y = (int) (center.height * 0.2); + this.setBounds(x, y, center.width, center.height); + this.setResizable(false); + + GroupLayout layout = new GroupLayout(getRootPane()); + getRootPane().setLayout(layout); + layout.setAutoCreateGaps(true); + layout.setAutoCreateContainerGaps(true); + + layout.setHorizontalGroup( + layout.createSequentialGroup().addComponent(label) + .addGroup( + layout.createParallelGroup(Alignment.LEADING).addComponent(statusLabel) + .addComponent(textField) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(Alignment.LEADING) + .addComponent(mcase)) + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(wholew)) + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(regex)) + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(classname))) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(listScroller) + .addComponent(progressBar)))) + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(findButton)) + + ); + + layout.linkSize(SwingConstants.HORIZONTAL, findButton); + layout.setVerticalGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(label).addComponent(textField) + .addComponent(findButton)) + .addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(mcase).addComponent(wholew) + .addComponent(regex).addComponent(classname)) + .addGroup(layout.createParallelGroup(Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(listScroller)))) + .addGroup(layout.createParallelGroup(Alignment.LEADING)).addComponent(statusLabel) + .addComponent(progressBar)); + this.adjustWindowPositionBySavedState(); + this.setSaveWindowPositionOnClosing(); + + this.setName("Find All"); + this.setTitle("Find All"); + } + + private class FindButton extends AbstractAction { + private static final long serialVersionUID = 75954129199541874L; + + @Override + public void actionPerformed(ActionEvent event) { + tmp_thread = new Thread() { + public void run() { + if (findButton.getText().equals("Stop")) { + if (tmp_thread != null) + tmp_thread.interrupt(); + setStatus("Stopped."); + findButton.setText("Find"); + locked = false; + } else { + findButton.setText("Stop"); + classesList.clear(); + ConfigSaver configSaver = ConfigSaver.getLoadedInstance(); + DecompilerSettings settings = configSaver.getDecompilerSettings(); + File inFile = MainWindow.model.getOpenedFile(); + boolean filter = ConfigSaver.getLoadedInstance().getLuytenPreferences() + .isFilterOutInnerClassEntries(); + try { + JarFile jfile = new JarFile(inFile); + Enumeration entLength = jfile.entries(); + initProgressBar(Collections.list(entLength).size()); + Enumeration ent = jfile.entries(); + while (ent.hasMoreElements() && findButton.getText().equals("Stop")) { + JarEntry entry = ent.nextElement(); + String name = entry.getName(); + setStatus(name); + if (filter && name.contains("$")) + continue; + if(locked || classname.isSelected()){ + locked = true; + if(search(entry.getName())) + addClassName(entry.getName()); + }else{ + if (entry.getName().endsWith(".class")) { + synchronized (settings) { + String internalName = StringUtilities.removeRight(entry.getName(), ".class"); + TypeReference type = Model.metadataSystem.lookupType(internalName); + TypeDefinition resolvedType = null; + if (type == null || ((resolvedType = type.resolve()) == null)) { + throw new Exception("Unable to resolve type."); + } + StringWriter stringwriter = new StringWriter(); + DecompilationOptions decompilationOptions; + decompilationOptions = new DecompilationOptions(); + decompilationOptions.setSettings(settings); + decompilationOptions.setFullDecompilation(true); + PlainTextOutput plainTextOutput = new PlainTextOutput(stringwriter); + plainTextOutput.setUnicodeOutputEnabled( + decompilationOptions.getSettings().isUnicodeOutputEnabled()); + settings.getLanguage().decompileType(resolvedType, plainTextOutput, + decompilationOptions); + if (search(stringwriter.toString())) + addClassName(entry.getName()); + } + } else { + + StringBuilder sb = new StringBuilder(); + long nonprintableCharactersCount = 0; + try (InputStreamReader inputStreamReader = new InputStreamReader( + jfile.getInputStream(entry)); + BufferedReader reader = new BufferedReader(inputStreamReader);) { + String line; + while ((line = reader.readLine()) != null) { + sb.append(line).append("\n"); + + for (byte nextByte : line.getBytes()) { + if (nextByte <= 0) { + nonprintableCharactersCount++; + } + } + + } + } + if (nonprintableCharactersCount < 5 && search(sb.toString())) + addClassName(entry.getName()); + } + } + } + setSearching(false); + if (findButton.getText().equals("Stop")) { + setStatus("Done."); + findButton.setText("Find"); + locked = false; + } + jfile.close(); + locked = false; + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + + } + } + }; + tmp_thread.start(); + + } + + } + + private boolean search(String bulk) { + String a = textField.getText(); + String b = bulk; + if (regex.isSelected()) + return Pattern.matches(a, b); + if (wholew.isSelected()) + a = " " + a + " "; + if (!mcase.isSelected()) { + a = a.toLowerCase(); + b = b.toLowerCase(); + } + if (b.contains(a)) + return true; + return false; + } + + private void setHideOnEscapeButton() { + Action escapeAction = new AbstractAction() { + private static final long serialVersionUID = 6846566740472934801L; + + @Override + public void actionPerformed(ActionEvent e) { + FindAllBox.this.setVisible(false); + } + }; + + KeyStroke escapeKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false); + this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escapeKeyStroke, "ESCAPE"); + this.getRootPane().getActionMap().put("ESCAPE", escapeAction); + } + + private void adjustWindowPositionBySavedState() { + WindowPosition windowPosition = ConfigSaver.getLoadedInstance().getFindWindowPosition(); + + if (windowPosition.isSavedWindowPositionValid()) { + this.setLocation(windowPosition.getWindowX(), windowPosition.getWindowY()); + } + } + + private void setSaveWindowPositionOnClosing() { + this.addWindowListener(new WindowAdapter() { + @Override + public void windowDeactivated(WindowEvent e) { + WindowPosition windowPosition = ConfigSaver.getLoadedInstance().getFindWindowPosition(); + windowPosition.readPositionFromDialog(FindAllBox.this); + } + }); + } + + public void showFindBox() { + this.setVisible(true); + this.textField.requestFocus(); + } + + public void hideFindBox() { + this.setVisible(false); + } + + public void setStatus(String text) { + if (text.length() > 25) { + this.statusLabel.setText("Searching in file: ..." + text.substring(text.length() - 25)); + } else { + this.statusLabel.setText("Searching in file: " + text); + } + + progressBar.setValue(progressBar.getValue() + 1); + } + + public void addClassName(String className) { + this.classesList.addElement(className); + } + + public void initProgressBar(Integer length) { + progressBar.setMaximum(length); + progressBar.setValue(0); + progressBar.setStringPainted(true); + } + + public boolean isSearching() { + return searching; + } + + public void setSearching(boolean searching) { + this.searching = searching; + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FindBox.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FindBox.java new file mode 100644 index 0000000..d43dc8f --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/FindBox.java @@ -0,0 +1,232 @@ +package us.deathmarine.luyten; + +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.GroupLayout; +import javax.swing.GroupLayout.Alignment; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import javax.swing.SwingConstants; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rtextarea.SearchContext; +import org.fife.ui.rtextarea.SearchEngine; + +public class FindBox extends JDialog { + private static final long serialVersionUID = -4125409760166690462L; + + JCheckBox mcase; + JCheckBox regex; + JCheckBox wholew; + JCheckBox reverse; + JCheckBox wrap; + private JButton findButton; + JTextField textField; + private MainWindow mainWindow; + + public void showFindBox() { + this.setVisible(true); + this.textField.requestFocus(); + this.textField.selectAll(); + } + + public void hideFindBox() { + this.setVisible(false); + } + + public FindBox(final MainWindow mainWindow) { + this.mainWindow = mainWindow; + this.setDefaultCloseOperation(HIDE_ON_CLOSE); + this.setHideOnEscapeButton(); + + JLabel label = new JLabel("Find What:"); + textField = new JTextField(); + + RSyntaxTextArea pane = mainWindow.getModel().getCurrentTextArea(); + if (pane != null) { + textField.setText(pane.getSelectedText()); + } + mcase = new JCheckBox("Match Case"); + regex = new JCheckBox("Regex"); + wholew = new JCheckBox("Whole Words"); + reverse = new JCheckBox("Search Backwards"); + wrap = new JCheckBox("Wrap"); + + findButton = new JButton("Find"); + findButton.addActionListener(new FindButton()); + this.getRootPane().setDefaultButton(findButton); + + KeyStroke funcF3 = KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0, false); + this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(funcF3, "FindNext"); + this.getRootPane().getActionMap().put("FindNext", new FindExploreAction(true)); + + KeyStroke sfuncF3 = KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_DOWN_MASK, false); + this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sfuncF3, "FindPrevious"); + this.getRootPane().getActionMap().put("FindPrevious", new FindExploreAction(false)); + + mcase.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + regex.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + wholew.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + reverse.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + wrap.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + final Dimension center = new Dimension((int) (screenSize.width * 0.35), + Math.min((int) (screenSize.height * 0.20), 200)); + final int x = (int) (center.width * 0.2); + final int y = (int) (center.height * 0.2); + this.setBounds(x, y, center.width, center.height); + this.setResizable(false); + + GroupLayout layout = new GroupLayout(getRootPane()); + getRootPane().setLayout(layout); + layout.setAutoCreateGaps(true); + layout.setAutoCreateContainerGaps(true); + + layout.setHorizontalGroup(layout.createSequentialGroup().addComponent(label) + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(textField) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(mcase) + .addComponent(wholew).addComponent(wrap)) + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(regex) + .addComponent(reverse)))) + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(findButton))); + + layout.linkSize(SwingConstants.HORIZONTAL, findButton); + layout.setVerticalGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(label).addComponent(textField) + .addComponent(findButton)) + .addGroup(layout.createParallelGroup(Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(mcase) + .addComponent(regex)) + .addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(wholew) + .addComponent(reverse)) + .addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(wrap))))); + + this.adjustWindowPositionBySavedState(); + this.setSaveWindowPositionOnClosing(); + + this.setName("Find"); + this.setTitle("Find"); + this.setVisible(true); + } + + private class FindButton extends AbstractAction { + private static final long serialVersionUID = 75954129199541874L; + + @Override + public void actionPerformed(ActionEvent event) { + if (textField.getText().length() == 0) + return; + + RSyntaxTextArea pane = mainWindow.getModel().getCurrentTextArea(); + if (pane == null) + return; + + SearchContext context = new SearchContext(); + context.setSearchFor(textField.getText()); + context.setMatchCase(mcase.isSelected()); + context.setRegularExpression(regex.isSelected()); + context.setSearchForward(!reverse.isSelected()); + context.setWholeWord(wholew.isSelected()); + + if (!SearchEngine.find(pane, context).wasFound()) { + if (wrap.isSelected()) { + pane.setSelectionStart(0); + pane.setSelectionEnd(0); + } else { + mainWindow.getLabel().setText("Search Complete"); + } + } + } + + } + + private void setHideOnEscapeButton() { + Action escapeAction = new AbstractAction() { + private static final long serialVersionUID = 5572504000935312338L; + + @Override + public void actionPerformed(ActionEvent e) { + FindBox.this.setVisible(false); + } + }; + + KeyStroke escapeKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false); + this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escapeKeyStroke, "ESCAPE"); + this.getRootPane().getActionMap().put("ESCAPE", escapeAction); + } + + private void adjustWindowPositionBySavedState() { + WindowPosition windowPosition = ConfigSaver.getLoadedInstance().getFindWindowPosition(); + + if (windowPosition.isSavedWindowPositionValid()) { + this.setLocation(windowPosition.getWindowX(), windowPosition.getWindowY()); + } + } + + private void setSaveWindowPositionOnClosing() { + this.addWindowListener(new WindowAdapter() { + @Override + public void windowDeactivated(WindowEvent e) { + WindowPosition windowPosition = ConfigSaver.getLoadedInstance().getFindWindowPosition(); + windowPosition.readPositionFromDialog(FindBox.this); + } + }); + } + + public void fireExploreAction(boolean direction) { + new FindExploreAction(direction).actionPerformed(null); + } + + class FindExploreAction extends AbstractAction { + /** + * + */ + private static final long serialVersionUID = -4391670062679240573L; + boolean direction; + + public FindExploreAction(boolean forward) { + direction = forward; + } + + @Override + public void actionPerformed(ActionEvent e) { + if (textField.getText().length() == 0) + return; + RSyntaxTextArea pane = mainWindow.getModel().getCurrentTextArea(); + if (pane == null) + return; + SearchContext context = new SearchContext(); + context.setSearchFor(textField.getText()); + context.setMatchCase(mcase.isSelected()); + context.setRegularExpression(regex.isSelected()); + context.setSearchForward(direction); + context.setWholeWord(wholew.isSelected()); + + if (!SearchEngine.find(pane, context).wasFound()) { + if (wrap.isSelected()) { + pane.setSelectionStart(0); + pane.setSelectionEnd(0); + } else { + mainWindow.getLabel().setText("Search Complete"); + } + } + + } + + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/JFontChooser.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/JFontChooser.java new file mode 100644 index 0000000..5d5fa3e --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/JFontChooser.java @@ -0,0 +1,772 @@ +package us.deathmarine.luyten; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GraphicsEnvironment; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ActionMap; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.DefaultListCellRenderer; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; +import javax.swing.border.Border; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.JTextComponent; +import javax.swing.text.Position; + +/** + * The JFontChooser class is a swing component for font selection. + * This class has JFileChooser like APIs. The following code pops + * up a font chooser dialog. + * + **/ +public class JFontChooser extends JComponent { + /** + * + */ + private static final long serialVersionUID = 8856126034081661L; + // class variables + /** + * Return value from showDialog(). + * + * @see #showDialog + **/ + public static final int OK_OPTION = 0; + /** + * Return value from showDialog(). + * + * @see #showDialog + **/ + public static final int CANCEL_OPTION = 1; + /** + * Return value from showDialog(). + * + * @see #showDialog + **/ + public static final int ERROR_OPTION = -1; + private static final Font DEFAULT_SELECTED_FONT = new Font("Serif", Font.PLAIN, 12); + private static final Font DEFAULT_FONT = new Font("Dialog", Font.PLAIN, 10); + private static final int[] FONT_STYLE_CODES = { Font.PLAIN, Font.BOLD, Font.ITALIC, Font.BOLD | Font.ITALIC }; + private static final String[] DEFAULT_FONT_SIZE_STRINGS = { "8", "9", "10", "11", "12", "14", "16", "18", "20", + "22", "24", "26", "28", "36", "48", "72", }; + + // instance variables + protected int dialogResultValue = ERROR_OPTION; + + protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer(); + + private String[] fontStyleNames; + private String[] fontFamilyNames; + private String[] fontSizeStrings; + private JTextField fontFamilyTextField; + private JTextField fontStyleTextField; + private JTextField fontSizeTextField; + private JList fontNameList; + private JList fontStyleList; + private JList fontSizeList; + private JPanel fontNamePanel; + private JPanel fontStylePanel; + private JPanel fontSizePanel; + private JPanel samplePanel; + private JTextField sampleText; + + /** + * Constructs a JFontChooser object. + **/ + public JFontChooser() { + this(DEFAULT_FONT_SIZE_STRINGS); + } + + /** + * Constructs a JFontChooser object using the given font size + * array. + * + * @param fontSizeStrings + * the array of font size string. + **/ + public JFontChooser(String[] fontSizeStrings) { + if (fontSizeStrings == null) { + fontSizeStrings = DEFAULT_FONT_SIZE_STRINGS; + } + this.fontSizeStrings = fontSizeStrings; + + JPanel selectPanel = new JPanel(); + selectPanel.setLayout(new BoxLayout(selectPanel, BoxLayout.X_AXIS)); + selectPanel.add(getFontFamilyPanel()); + selectPanel.add(getFontStylePanel()); + selectPanel.add(getFontSizePanel()); + + JPanel contentsPanel = new JPanel(); + contentsPanel.setLayout(new GridLayout(2, 1)); + contentsPanel.add(selectPanel, BorderLayout.NORTH); + contentsPanel.add(getSamplePanel(), BorderLayout.CENTER); + + this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); + this.add(contentsPanel); + this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + this.setSelectedFont(DEFAULT_SELECTED_FONT); + } + + public JTextField getFontFamilyTextField() { + if (fontFamilyTextField == null) { + fontFamilyTextField = new JTextField(); + fontFamilyTextField.addFocusListener(new TextFieldFocusHandlerForTextSelection(fontFamilyTextField)); + fontFamilyTextField.addKeyListener(new TextFieldKeyHandlerForListSelectionUpDown(getFontFamilyList())); + fontFamilyTextField.getDocument() + .addDocumentListener(new ListSearchTextFieldDocumentHandler(getFontFamilyList())); + fontFamilyTextField.setFont(DEFAULT_FONT); + + } + return fontFamilyTextField; + } + + public JTextField getFontStyleTextField() { + if (fontStyleTextField == null) { + fontStyleTextField = new JTextField(); + fontStyleTextField.addFocusListener(new TextFieldFocusHandlerForTextSelection(fontStyleTextField)); + fontStyleTextField.addKeyListener(new TextFieldKeyHandlerForListSelectionUpDown(getFontStyleList())); + fontStyleTextField.getDocument() + .addDocumentListener(new ListSearchTextFieldDocumentHandler(getFontStyleList())); + fontStyleTextField.setFont(DEFAULT_FONT); + + } + return fontStyleTextField; + } + + public JTextField getFontSizeTextField() { + if (fontSizeTextField == null) { + fontSizeTextField = new JTextField(); + fontSizeTextField.addFocusListener(new TextFieldFocusHandlerForTextSelection(fontSizeTextField)); + fontSizeTextField.addKeyListener(new TextFieldKeyHandlerForListSelectionUpDown(getFontSizeList())); + fontSizeTextField.getDocument() + .addDocumentListener(new ListSearchTextFieldDocumentHandler(getFontSizeList())); + fontSizeTextField.setFont(DEFAULT_FONT); + } + return fontSizeTextField; + } + + public JList getFontFamilyList() { + if (fontNameList == null) { + fontNameList = new JList(getFontFamilies()); + fontNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + fontNameList.addListSelectionListener(new ListSelectionHandler(getFontFamilyTextField())); + fontNameList.setSelectedIndex(0); + + // Draw Fonts + fontNameList.setCellRenderer(new DefaultListCellRenderer() { + /** + * + */ + private static final long serialVersionUID = -6753380853569310954L; + + public Component getListCellRendererComponent(JList list, Object value, int index, + boolean isSelected, boolean cellHasFocus) { + + JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, + isSelected, cellHasFocus); + + if (value instanceof String) { + renderer.setText((String) value); + renderer.setFont(new Font((String) value, DEFAULT_FONT.getStyle(), DEFAULT_FONT.getSize() + 2)); + } else { + renderer.setText(""); + } + return renderer; + } + }); + fontNameList.setFocusable(false); + } + return fontNameList; + } + + public JList getFontStyleList() { + if (fontStyleList == null) { + fontStyleList = new JList(getFontStyleNames()); + fontStyleList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + fontStyleList.addListSelectionListener(new ListSelectionHandler(getFontStyleTextField())); + fontStyleList.setSelectedIndex(0); + fontStyleList.setFocusable(false); + fontStyleList.setCellRenderer(new DefaultListCellRenderer() { + /** + * + */ + private static final long serialVersionUID = -3904668242514776943L; + + public Component getListCellRendererComponent(JList list, Object value, int index, + boolean isSelected, boolean cellHasFocus) { + + JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, + isSelected, cellHasFocus); + + if (value instanceof String) { + renderer.setText((String) value); + renderer.setFont( + new Font(DEFAULT_FONT.getName(), FONT_STYLE_CODES[index], DEFAULT_FONT.getSize() + 2)); + } else { + renderer.setText(""); + } + return renderer; + } + }); + } + return fontStyleList; + } + + public JList getFontSizeList() { + if (fontSizeList == null) { + fontSizeList = new JList(this.fontSizeStrings); + fontSizeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + fontSizeList.addListSelectionListener(new ListSelectionHandler(getFontSizeTextField())); + fontSizeList.setSelectedIndex(0); + fontSizeList.setFont(DEFAULT_FONT); + fontSizeList.setFocusable(false); + } + return fontSizeList; + } + + /** + * Get the family name of the selected font. + * + * @return the font family of the selected font. + * + * @see #setSelectedFontFamily + **/ + public String getSelectedFontFamily() { + String fontName = (String) getFontFamilyList().getSelectedValue(); + return fontName; + } + + /** + * Get the style of the selected font. + * + * @return the style of the selected font. Font.PLAIN, + * Font.BOLD, Font.ITALIC, + * Font.BOLD|Font.ITALIC + * + * @see java.awt.Font#PLAIN + * @see java.awt.Font#BOLD + * @see java.awt.Font#ITALIC + * @see #setSelectedFontStyle + **/ + public int getSelectedFontStyle() { + int index = getFontStyleList().getSelectedIndex(); + return FONT_STYLE_CODES[index]; + } + + /** + * Get the size of the selected font. + * + * @return the size of the selected font + * + * @see #setSelectedFontSize + **/ + public int getSelectedFontSize() { + int fontSize = 1; + String fontSizeString = getFontSizeTextField().getText(); + while (true) { + try { + fontSize = Integer.parseInt(fontSizeString); + break; + } catch (NumberFormatException e) { + fontSizeString = (String) getFontSizeList().getSelectedValue(); + getFontSizeTextField().setText(fontSizeString); + } + } + + return fontSize; + } + + /** + * Get the selected font. + * + * @return the selected font + * + * @see #setSelectedFont + * @see java.awt.Font + **/ + public Font getSelectedFont() { + Font font = new Font(getSelectedFontFamily(), getSelectedFontStyle(), getSelectedFontSize()); + return font; + } + + /** + * Set the family name of the selected font. + * + * @param name + * the family name of the selected font. + * + * @see getSelectedFontFamily + **/ + public void setSelectedFontFamily(String name) { + String[] names = getFontFamilies(); + for (int i = 0; i < names.length; i++) { + if (names[i].toLowerCase().equals(name.toLowerCase())) { + getFontFamilyList().setSelectedIndex(i); + break; + } + } + updateSampleFont(); + } + + /** + * Set the style of the selected font. + * + * @param style + * the size of the selected font. Font.PLAIN, + * Font.BOLD, Font.ITALIC, or + * Font.BOLD|Font.ITALIC. + * + * @see java.awt.Font#PLAIN + * @see java.awt.Font#BOLD + * @see java.awt.Font#ITALIC + * @see #getSelectedFontStyle + **/ + public void setSelectedFontStyle(int style) { + for (int i = 0; i < FONT_STYLE_CODES.length; i++) { + if (FONT_STYLE_CODES[i] == style) { + getFontStyleList().setSelectedIndex(i); + break; + } + } + updateSampleFont(); + } + + /** + * Set the size of the selected font. + * + * @param size + * the size of the selected font + * + * @see #getSelectedFontSize + **/ + public void setSelectedFontSize(int size) { + String sizeString = String.valueOf(size); + for (int i = 0; i < this.fontSizeStrings.length; i++) { + if (this.fontSizeStrings[i].equals(sizeString)) { + getFontSizeList().setSelectedIndex(i); + break; + } + } + getFontSizeTextField().setText(sizeString); + updateSampleFont(); + } + + /** + * Set the selected font. + * + * @param font + * the selected font + * + * @see #getSelectedFont + * @see java.awt.Font + **/ + public void setSelectedFont(Font font) { + setSelectedFontFamily(font.getFamily()); + setSelectedFontStyle(font.getStyle()); + setSelectedFontSize(font.getSize()); + } + + public String getVersionString() { + return ("Version"); + } + + /** + * Show font selection dialog. + * + * @param parent + * Dialog's Parent component. + * @return OK_OPTION, CANCEL_OPTION or ERROR_OPTION + * + * @see #OK_OPTION + * @see #CANCEL_OPTION + * @see #ERROR_OPTION + **/ + public int showDialog(Component parent) { + dialogResultValue = ERROR_OPTION; + JDialog dialog = createDialog(parent); + dialog.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + dialogResultValue = CANCEL_OPTION; + } + }); + + dialog.setVisible(true); + dialog.dispose(); + dialog = null; + + return dialogResultValue; + } + + protected class ListSelectionHandler implements ListSelectionListener { + private JTextComponent textComponent; + + ListSelectionHandler(JTextComponent textComponent) { + this.textComponent = textComponent; + } + + public void valueChanged(ListSelectionEvent e) { + if (e.getValueIsAdjusting() == false) { + JList list = (JList) e.getSource(); + String selectedValue = (String) list.getSelectedValue(); + + String oldValue = textComponent.getText(); + textComponent.setText(selectedValue); + if (!oldValue.equalsIgnoreCase(selectedValue)) { + textComponent.selectAll(); + textComponent.requestFocus(); + } + + updateSampleFont(); + } + } + } + + protected class TextFieldFocusHandlerForTextSelection extends FocusAdapter { + private JTextComponent textComponent; + + public TextFieldFocusHandlerForTextSelection(JTextComponent textComponent) { + this.textComponent = textComponent; + } + + public void focusGained(FocusEvent e) { + textComponent.selectAll(); + } + + public void focusLost(FocusEvent e) { + textComponent.select(0, 0); + updateSampleFont(); + } + } + + protected class TextFieldKeyHandlerForListSelectionUpDown extends KeyAdapter { + private JList targetList; + + public TextFieldKeyHandlerForListSelectionUpDown(JList list) { + this.targetList = list; + } + + public void keyPressed(KeyEvent e) { + int i = targetList.getSelectedIndex(); + switch (e.getKeyCode()) { + case KeyEvent.VK_UP: + i = targetList.getSelectedIndex() - 1; + if (i < 0) { + i = 0; + } + targetList.setSelectedIndex(i); + break; + case KeyEvent.VK_DOWN: + int listSize = targetList.getModel().getSize(); + i = targetList.getSelectedIndex() + 1; + if (i >= listSize) { + i = listSize - 1; + } + targetList.setSelectedIndex(i); + break; + default: + break; + } + } + } + + protected class ListSearchTextFieldDocumentHandler implements DocumentListener { + JList targetList; + + public ListSearchTextFieldDocumentHandler(JList targetList) { + this.targetList = targetList; + } + + public void insertUpdate(DocumentEvent e) { + update(e); + } + + public void removeUpdate(DocumentEvent e) { + update(e); + } + + public void changedUpdate(DocumentEvent e) { + update(e); + } + + private void update(DocumentEvent event) { + String newValue = ""; + try { + Document doc = event.getDocument(); + newValue = doc.getText(0, doc.getLength()); + } catch (BadLocationException e) { + Luyten.showExceptionDialog("Exception!", e); + } + + if (newValue.length() > 0) { + int index = targetList.getNextMatch(newValue, 0, Position.Bias.Forward); + if (index < 0) { + index = 0; + } + targetList.ensureIndexIsVisible(index); + + String matchedName = targetList.getModel().getElementAt(index).toString(); + if (newValue.equalsIgnoreCase(matchedName)) { + if (index != targetList.getSelectedIndex()) { + SwingUtilities.invokeLater(new ListSelector(index)); + } + } + } + } + + public class ListSelector implements Runnable { + private int index; + + public ListSelector(int index) { + this.index = index; + } + + public void run() { + targetList.setSelectedIndex(this.index); + } + } + } + + protected class DialogOKAction extends AbstractAction { + /** + * + */ + private static final long serialVersionUID = 1618273732543947323L; + protected static final String ACTION_NAME = "OK"; + private JDialog dialog; + + protected DialogOKAction(JDialog dialog) { + this.dialog = dialog; + putValue(Action.DEFAULT, ACTION_NAME); + putValue(Action.ACTION_COMMAND_KEY, ACTION_NAME); + putValue(Action.NAME, (ACTION_NAME)); + } + + public void actionPerformed(ActionEvent e) { + dialogResultValue = OK_OPTION; + dialog.setVisible(false); + } + } + + protected class DialogCancelAction extends AbstractAction { + /** + * + */ + private static final long serialVersionUID = -4941763616565382601L; + protected static final String ACTION_NAME = "Cancel"; + private JDialog dialog; + + protected DialogCancelAction(JDialog dialog) { + this.dialog = dialog; + putValue(Action.DEFAULT, ACTION_NAME); + putValue(Action.ACTION_COMMAND_KEY, ACTION_NAME); + putValue(Action.NAME, (ACTION_NAME)); + } + + public void actionPerformed(ActionEvent e) { + dialogResultValue = CANCEL_OPTION; + dialog.setVisible(false); + } + } + + protected JDialog createDialog(Component parent) { + Frame frame = parent instanceof Frame ? (Frame) parent + : (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parent); + JDialog dialog = new JDialog(frame, ("Select Font"), true); + + Action okAction = new DialogOKAction(dialog); + Action cancelAction = new DialogCancelAction(dialog); + + JButton okButton = new JButton(okAction); + okButton.setFont(DEFAULT_FONT); + JButton cancelButton = new JButton(cancelAction); + cancelButton.setFont(DEFAULT_FONT); + + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setLayout(new GridLayout(2, 1)); + buttonsPanel.add(okButton); + buttonsPanel.add(cancelButton); + buttonsPanel.setBorder(BorderFactory.createEmptyBorder(25, 0, 10, 10)); + + ActionMap actionMap = buttonsPanel.getActionMap(); + actionMap.put(cancelAction.getValue(Action.DEFAULT), cancelAction); + actionMap.put(okAction.getValue(Action.DEFAULT), okAction); + InputMap inputMap = buttonsPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); + inputMap.put(KeyStroke.getKeyStroke("ESCAPE"), cancelAction.getValue(Action.DEFAULT)); + inputMap.put(KeyStroke.getKeyStroke("ENTER"), okAction.getValue(Action.DEFAULT)); + + JPanel dialogEastPanel = new JPanel(); + dialogEastPanel.setLayout(new BorderLayout()); + dialogEastPanel.add(buttonsPanel, BorderLayout.NORTH); + + dialog.getContentPane().add(this, BorderLayout.CENTER); + dialog.getContentPane().add(dialogEastPanel, BorderLayout.EAST); + dialog.pack(); + dialog.setLocationRelativeTo(frame); + return dialog; + } + + protected void updateSampleFont() { + Font font = getSelectedFont(); + getSampleTextField().setFont(font); + } + + protected JPanel getFontFamilyPanel() { + if (fontNamePanel == null) { + fontNamePanel = new JPanel(); + fontNamePanel.setLayout(new BorderLayout()); + fontNamePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + fontNamePanel.setPreferredSize(new Dimension(180, 130)); + + JScrollPane scrollPane = new JScrollPane(getFontFamilyList()); + scrollPane.getVerticalScrollBar().setFocusable(false); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + + JPanel p = new JPanel(); + p.setLayout(new BorderLayout()); + p.add(getFontFamilyTextField(), BorderLayout.NORTH); + p.add(scrollPane, BorderLayout.CENTER); + + JLabel label = new JLabel(("Font Name")); + label.setHorizontalAlignment(JLabel.LEFT); + label.setHorizontalTextPosition(JLabel.LEFT); + label.setLabelFor(getFontFamilyTextField()); + label.setDisplayedMnemonic('F'); + + fontNamePanel.add(label, BorderLayout.NORTH); + fontNamePanel.add(p, BorderLayout.CENTER); + + } + return fontNamePanel; + } + + protected JPanel getFontStylePanel() { + if (fontStylePanel == null) { + fontStylePanel = new JPanel(); + fontStylePanel.setLayout(new BorderLayout()); + fontStylePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + fontStylePanel.setPreferredSize(new Dimension(140, 130)); + + JScrollPane scrollPane = new JScrollPane(getFontStyleList()); + scrollPane.getVerticalScrollBar().setFocusable(false); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + + JPanel p = new JPanel(); + p.setLayout(new BorderLayout()); + p.add(getFontStyleTextField(), BorderLayout.NORTH); + p.add(scrollPane, BorderLayout.CENTER); + + JLabel label = new JLabel(("Font Style")); + label.setHorizontalAlignment(JLabel.LEFT); + label.setHorizontalTextPosition(JLabel.LEFT); + label.setLabelFor(getFontStyleTextField()); + label.setDisplayedMnemonic('Y'); + + fontStylePanel.add(label, BorderLayout.NORTH); + fontStylePanel.add(p, BorderLayout.CENTER); + } + return fontStylePanel; + } + + protected JPanel getFontSizePanel() { + if (fontSizePanel == null) { + fontSizePanel = new JPanel(); + fontSizePanel.setLayout(new BorderLayout()); + fontSizePanel.setPreferredSize(new Dimension(70, 130)); + fontSizePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + JScrollPane scrollPane = new JScrollPane(getFontSizeList()); + scrollPane.getVerticalScrollBar().setFocusable(false); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + + JPanel p = new JPanel(); + p.setLayout(new BorderLayout()); + p.add(getFontSizeTextField(), BorderLayout.NORTH); + p.add(scrollPane, BorderLayout.CENTER); + + JLabel label = new JLabel(("Font Size")); + label.setHorizontalAlignment(JLabel.LEFT); + label.setHorizontalTextPosition(JLabel.LEFT); + label.setLabelFor(getFontSizeTextField()); + label.setDisplayedMnemonic('S'); + + fontSizePanel.add(label, BorderLayout.NORTH); + fontSizePanel.add(p, BorderLayout.CENTER); + } + return fontSizePanel; + } + + protected JPanel getSamplePanel() { + if (samplePanel == null) { + Border titledBorder = BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), ("Sample")); + Border empty = BorderFactory.createEmptyBorder(5, 10, 10, 10); + Border border = BorderFactory.createCompoundBorder(titledBorder, empty); + + samplePanel = new JPanel(); + samplePanel.setLayout(new BorderLayout()); + samplePanel.setBorder(border); + + samplePanel.add(getSampleTextField(), BorderLayout.CENTER); + } + return samplePanel; + } + + protected JTextField getSampleTextField() { + if (sampleText == null) { + Border lowered = BorderFactory.createLoweredBevelBorder(); + + sampleText = new JTextField(("AaBbYyZz")); + sampleText.setHorizontalAlignment(JTextField.CENTER); + sampleText.setBorder(lowered); + sampleText.setPreferredSize(new Dimension(300, 100)); + } + return sampleText; + } + + protected String[] getFontFamilies() { + if (fontFamilyNames == null) { + GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); + fontFamilyNames = env.getAvailableFontFamilyNames(); + } + return fontFamilyNames; + } + + protected String[] getFontStyleNames() { + if (fontStyleNames == null) { + int i = 0; + fontStyleNames = new String[4]; + fontStyleNames[i++] = ("Plain"); + fontStyleNames[i++] = ("Bold"); + fontStyleNames[i++] = ("Italic"); + fontStyleNames[i++] = ("BoldItalic"); + } + return fontStyleNames; + } +} \ No newline at end of file diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/JarEntryFilter.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/JarEntryFilter.java new file mode 100644 index 0000000..fc8a292 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/JarEntryFilter.java @@ -0,0 +1,82 @@ +package us.deathmarine.luyten; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +public class JarEntryFilter { + + private JarFile jfile; + + public JarEntryFilter() { + } + + public JarEntryFilter(JarFile jfile) { + this.jfile = jfile; + } + + public List getAllEntriesFromJar() { + List mass = new ArrayList<>(); + Enumeration entries = jfile.entries(); + while (entries.hasMoreElements()) { + JarEntry e = entries.nextElement(); + if (!e.isDirectory()) { + mass.add(e.getName()); + } + } + return mass; + } + + public List getEntriesWithoutInnerClasses() { + List mass = new ArrayList<>(); + Enumeration entries = jfile.entries(); + Set possibleInnerClasses = new HashSet(); + Set baseClasses = new HashSet(); + + while (entries.hasMoreElements()) { + JarEntry e = entries.nextElement(); + if (!e.isDirectory()) { + String entryName = e.getName(); + + if (entryName != null && entryName.trim().length() > 0) { + entryName = entryName.trim(); + + if (!entryName.endsWith(".class")) { + mass.add(entryName); + + // com/acme/Model$16.class + } else if (entryName.matches(".*[^(/|\\\\)]+\\$[^(/|\\\\)]+$")) { + possibleInnerClasses.add(entryName); + + } else { + baseClasses.add(entryName); + mass.add(entryName); + } + } + } + } + + // keep Badly$Named but not inner classes + for (String inner : possibleInnerClasses) { + + // com/acme/Connection$Conn$1.class -> com/acme/Connection + String innerWithoutTail = inner.replaceAll("\\$[^(/|\\\\)]+\\.class$", ""); + if (!baseClasses.contains(innerWithoutTail + ".class")) { + mass.add(inner); + } + } + return mass; + } + + public JarFile getJfile() { + return jfile; + } + + public void setJfile(JarFile jfile) { + this.jfile = jfile; + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Keymap.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Keymap.java new file mode 100644 index 0000000..c84f26b --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Keymap.java @@ -0,0 +1,14 @@ +package us.deathmarine.luyten; + +import java.awt.event.InputEvent; + +public final class Keymap { + /** + * Ctrl+click defaults to "context menu" in macOS, so META+click is used there. + * + * @return META_DOWN_MASK for macOS, CTRL_DOWN_MASK otherwise + */ + public static int ctrlDownModifier() { + return SystemInfo.IS_MAC ? InputEvent.META_DOWN_MASK : InputEvent.CTRL_DOWN_MASK; + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LinkProvider.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LinkProvider.java new file mode 100644 index 0000000..e6911e9 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LinkProvider.java @@ -0,0 +1,22 @@ +package us.deathmarine.luyten; + +import java.util.Map; +import java.util.Set; + +public interface LinkProvider { + + public void generateContent(); + + public String getTextContent(); + + public void processLinks(); + + public Map getDefinitionToSelectionMap(); + + public Map> getReferenceToSelectionsMap(); + + public boolean isLinkNavigable(String uniqueStr); + + public String getLinkDescription(String uniqueStr); + +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Luyten.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Luyten.java new file mode 100644 index 0000000..c12db57 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Luyten.java @@ -0,0 +1,224 @@ +package us.deathmarine.luyten; + +import java.awt.Cursor; +import java.awt.Desktop; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URI; +import java.util.concurrent.atomic.AtomicReference; +import java.util.List; +import java.util.ArrayList; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.BevelBorder; +import javax.swing.border.CompoundBorder; +import javax.swing.text.DefaultEditorKit; + +/** + * Starter, the main class + */ +public class Luyten { + + private static final AtomicReference mainWindowRef = new AtomicReference<>(); + private static final List pendingFiles = new ArrayList<>(); + + public static void main(String[] args) { + + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + e.printStackTrace(); + } + + // for TotalCommander External Viewer setting: + // javaw -jar "c:\Program Files\Luyten\luyten.jar" + // (TC will not complain about temporary file when opening .class from + // .zip or .jar) + final File fileFromCommandLine = getFileFromCommandLine(args); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { +// if (!mainWindowRef.compareAndSet(null, new MainWindow(fileFromCommandLine))) { + // Already set - so add the files to open +// openFileInInstance(fileFromCommandLine); +// } +// processPendingFiles(); +// mainWindowRef.get().setVisible(true); + new MainWindow(fileFromCommandLine).setVisible(true); + } + }); + } + + // Private function which processes all pending files - synchronized on the + // list of pending files + private static void processPendingFiles() { + final MainWindow mainWindow = mainWindowRef.get(); + if (mainWindow != null) { + synchronized (pendingFiles) { + for (File f : pendingFiles) { + mainWindow.getModel().loadFile(f); + } + pendingFiles.clear(); + } + } + } + + // Function which opens the given file in the instance, if it's running - + // and if not, it processes the files + public static void openFileInInstance(File fileToOpen) { + synchronized (pendingFiles) { + if (fileToOpen != null) { + pendingFiles.add(fileToOpen); + } + } + processPendingFiles(); + } + + // Function which exits the application if it's running + public static void quitInstance() { + final MainWindow mainWindow = mainWindowRef.get(); + if (mainWindow != null) { + mainWindow.onExitMenu(); + } + } + + public static File getFileFromCommandLine(String[] args) { + File fileFromCommandLine = null; + try { + if (args.length > 0) { + String realFileName = new File(args[0]).getCanonicalPath(); + fileFromCommandLine = new File(realFileName); + } + } catch (Exception e) { + e.printStackTrace(); + } + return fileFromCommandLine; + } + + public static String getVersion() { + String result = ""; + try { + String line; + BufferedReader br = new BufferedReader(new InputStreamReader( + ClassLoader.getSystemResourceAsStream("META-INF/maven/us.deathmarine/luyten/pom.properties"))); + while ((line = br.readLine()) != null) { + if (line.contains("version")) + result = line.split("=")[1]; + } + br.close(); + } catch (Exception e) { + return result; + } + return result; + + } + + /** + * Method allows for users to copy the stacktrace for reporting any issues. + * Add Cool Hyperlink Enhanced for mouse users. + * + * @param message + * @param e + */ + public static void showExceptionDialog(String message, Exception e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + String stacktrace = sw.toString(); + try { + sw.close(); + pw.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + System.out.println(stacktrace); + + JPanel pane = new JPanel(); + pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS)); + if (message.contains("\n")) { + for (String s : message.split("\n")) { + pane.add(new JLabel(s)); + } + } else { + pane.add(new JLabel(message)); + } + pane.add(new JLabel(" \n")); // Whitespace + final JTextArea exception = new JTextArea(25, 100); + exception.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 10)); + exception.setText(stacktrace); + exception.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + new JPopupMenu() { + { + JMenuItem menuitem = new JMenuItem("Select All"); + menuitem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + exception.requestFocus(); + exception.selectAll(); + } + }); + this.add(menuitem); + menuitem = new JMenuItem("Copy"); + menuitem.addActionListener(new DefaultEditorKit.CopyAction()); + this.add(menuitem); + } + + private static final long serialVersionUID = 562054483562666832L; + }.show(e.getComponent(), e.getX(), e.getY()); + } + } + }); + JScrollPane scroll = new JScrollPane(exception); + scroll.setBorder(new CompoundBorder(BorderFactory.createTitledBorder("Stacktrace"), + new BevelBorder(BevelBorder.LOWERED))); + pane.add(scroll); + final String issue = "https://github.com/deathmarine/Luyten/issues"; + final JLabel link = new JLabel("Submit to " + issue + ""); + link.setCursor(new Cursor(Cursor.HAND_CURSOR)); + link.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + try { + Desktop.getDesktop().browse(new URI(issue)); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + + @Override + public void mouseEntered(MouseEvent e) { + link.setText("Submit to " + issue + ""); + } + + @Override + public void mouseExited(MouseEvent e) { + link.setText("Submit to " + issue + ""); + } + }); + pane.add(link); + JOptionPane.showMessageDialog(null, pane, "Error!", JOptionPane.ERROR_MESSAGE); + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenOsx.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenOsx.java new file mode 100644 index 0000000..46670ae --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenOsx.java @@ -0,0 +1,30 @@ +package us.deathmarine.luyten; + +import java.io.File; +import com.apple.eawt.Application; +import com.apple.eawt.ApplicationAdapter; +import com.apple.eawt.ApplicationEvent; + +/** + * An OS X-specific initialization method for dragging/dropping + */ +public class LuytenOsx extends Luyten { + public static void main(String[] args) { + // Add an adapter as the handler to a new instance of the application + // class + @SuppressWarnings("deprecation") + Application app = new Application(); + app.addApplicationListener(new ApplicationAdapter() { + public void handleOpenFile(ApplicationEvent e) { + Luyten.openFileInInstance(new File(e.getFilename())); + } + + public void handleQuit(ApplicationEvent e) { + Luyten.quitInstance(); + } + }); + + // Call the superclass's main function + Luyten.main(args); + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenPreferences.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenPreferences.java new file mode 100644 index 0000000..341e440 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenPreferences.java @@ -0,0 +1,87 @@ +package us.deathmarine.luyten; + +/** + * Do not instantiate this class, get the instance from ConfigSaver. All + * not-static fields will be saved automatically named by the field's java + * variable name. (Watch for collisions with existing IDs defined in + * ConfigSaver.) Only String, boolean and int fields are supported. Write + * default values into the field declarations. + */ +public class LuytenPreferences { + public static final String THEME_XML_PATH = "/org/fife/ui/rsyntaxtextarea/themes/"; + public static final String DEFAULT_THEME_XML = "eclipse.xml"; + + private String themeXml = DEFAULT_THEME_XML; + private String fileOpenCurrentDirectory = ""; + private String fileSaveCurrentDirectory = ""; + private int font_size = 10; + + private boolean isPackageExplorerStyle = true; + private boolean isFilterOutInnerClassEntries = true; + private boolean isSingleClickOpenEnabled = true; + private boolean isExitByEscEnabled = false; + + public String getThemeXml() { + return themeXml; + } + + public void setThemeXml(String themeXml) { + this.themeXml = themeXml; + } + + public String getFileOpenCurrentDirectory() { + return fileOpenCurrentDirectory; + } + + public void setFileOpenCurrentDirectory(String fileOpenCurrentDirectory) { + this.fileOpenCurrentDirectory = fileOpenCurrentDirectory; + } + + public String getFileSaveCurrentDirectory() { + return fileSaveCurrentDirectory; + } + + public void setFileSaveCurrentDirectory(String fileSaveCurrentDirectory) { + this.fileSaveCurrentDirectory = fileSaveCurrentDirectory; + } + + public boolean isPackageExplorerStyle() { + return isPackageExplorerStyle; + } + + public void setPackageExplorerStyle(boolean isPackageExplorerStyle) { + this.isPackageExplorerStyle = isPackageExplorerStyle; + } + + public boolean isFilterOutInnerClassEntries() { + return isFilterOutInnerClassEntries; + } + + public void setFilterOutInnerClassEntries(boolean isFilterOutInnerClassEntries) { + this.isFilterOutInnerClassEntries = isFilterOutInnerClassEntries; + } + + public boolean isSingleClickOpenEnabled() { + return isSingleClickOpenEnabled; + } + + public void setSingleClickOpenEnabled(boolean isSingleClickOpenEnabled) { + this.isSingleClickOpenEnabled = isSingleClickOpenEnabled; + } + + public boolean isExitByEscEnabled() { + return isExitByEscEnabled; + } + + public void setExitByEscEnabled(boolean isExitByEscEnabled) { + this.isExitByEscEnabled = isExitByEscEnabled; + } + + public int getFont_size() { + return font_size; + } + + public void setFont_size(int font_size) { + this.font_size = font_size; + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenTypeLoader.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenTypeLoader.java new file mode 100644 index 0000000..1198ac0 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/LuytenTypeLoader.java @@ -0,0 +1,34 @@ +package us.deathmarine.luyten; + +import com.strobel.assembler.InputTypeLoader; +import com.strobel.assembler.metadata.Buffer; +import com.strobel.assembler.metadata.ITypeLoader; + +import java.util.ArrayList; +import java.util.List; + +public final class LuytenTypeLoader implements ITypeLoader { + private final List _typeLoaders; + + public LuytenTypeLoader() { + _typeLoaders = new ArrayList(); + _typeLoaders.add(new InputTypeLoader()); + } + + public final List getTypeLoaders() { + return _typeLoaders; + } + + @Override + public boolean tryLoadType(final String internalName, final Buffer buffer) { + for (final ITypeLoader typeLoader : _typeLoaders) { + if (typeLoader.tryLoadType(internalName, buffer)) { + return true; + } + + buffer.reset(); + } + + return false; + } +} \ No newline at end of file diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/MainMenuBar.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/MainMenuBar.java new file mode 100644 index 0000000..b9af8ba --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/MainMenuBar.java @@ -0,0 +1,677 @@ +package us.deathmarine.luyten; + +import java.awt.Cursor; +import java.awt.Desktop; +import java.awt.Font; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.File; +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.ListIterator; +import java.util.Map; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.ButtonModel; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JTabbedPane; +import javax.swing.KeyStroke; +import javax.swing.text.DefaultEditorKit; + +import com.strobel.Procyon; +import com.strobel.decompiler.DecompilerSettings; +import com.strobel.decompiler.languages.Language; +import com.strobel.decompiler.languages.Languages; + +/** + * Main menu (only MainWindow should be called from here) + */ +public class MainMenuBar extends JMenuBar { + private static final long serialVersionUID = -7949855817172562075L; + private final MainWindow mainWindow; + private final Map languageLookup = new HashMap(); + + private JMenu recentFiles; + private JMenuItem clearRecentFiles; + private JCheckBoxMenuItem flattenSwitchBlocks; + private JCheckBoxMenuItem forceExplicitImports; + private JCheckBoxMenuItem forceExplicitTypes; + private JCheckBoxMenuItem showSyntheticMembers; + private JCheckBoxMenuItem excludeNestedTypes; + private JCheckBoxMenuItem retainRedundantCasts; + private JCheckBoxMenuItem unicodeReplacement; + private JCheckBoxMenuItem debugLineNumbers; + private JCheckBoxMenuItem showDebugInfo; + private JCheckBoxMenuItem bytecodeLineNumbers; + private JRadioButtonMenuItem java; + private JRadioButtonMenuItem bytecode; + private JRadioButtonMenuItem bytecodeAST; + private ButtonGroup languagesGroup; + private ButtonGroup themesGroup; + private JCheckBoxMenuItem packageExplorerStyle; + private JCheckBoxMenuItem filterOutInnerClassEntries; + private JCheckBoxMenuItem singleClickOpenEnabled; + private JCheckBoxMenuItem exitByEscEnabled; + private DecompilerSettings settings; + private LuytenPreferences luytenPrefs; + + public MainMenuBar(MainWindow mainWnd) { + this.mainWindow = mainWnd; + final ConfigSaver configSaver = ConfigSaver.getLoadedInstance(); + settings = configSaver.getDecompilerSettings(); + luytenPrefs = configSaver.getLuytenPreferences(); + + final JMenu fileMenu = new JMenu("File"); + fileMenu.add(new JMenuItem("...")); + this.add(fileMenu); + final JMenu editMenu = new JMenu("Edit"); + editMenu.add(new JMenuItem("...")); + this.add(editMenu); + final JMenu themesMenu = new JMenu("Themes"); + themesMenu.add(new JMenuItem("...")); + this.add(themesMenu); + final JMenu operationMenu = new JMenu("Operation"); + operationMenu.add(new JMenuItem("...")); + this.add(operationMenu); + final JMenu settingsMenu = new JMenu("Settings"); + settingsMenu.add(new JMenuItem("...")); + this.add(settingsMenu); + final JMenu helpMenu = new JMenu("Help"); + helpMenu.add(new JMenuItem("...")); + this.add(helpMenu); + + // start quicker + new Thread() { + public void run() { + try { + // build menu later + buildFileMenu(fileMenu); + refreshMenuPopup(fileMenu); + + buildEditMenu(editMenu); + refreshMenuPopup(editMenu); + + buildThemesMenu(themesMenu); + refreshMenuPopup(themesMenu); + + buildOperationMenu(operationMenu); + refreshMenuPopup(operationMenu); + + buildSettingsMenu(settingsMenu, configSaver); + refreshMenuPopup(settingsMenu); + + buildHelpMenu(helpMenu); + refreshMenuPopup(helpMenu); + + updateRecentFiles(); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + // refresh currently opened menu + // (if user selected a menu before it was ready) + private void refreshMenuPopup(JMenu menu) { + try { + if (menu.isPopupMenuVisible()) { + menu.getPopupMenu().setVisible(false); + menu.getPopupMenu().setVisible(true); + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + }.start(); + } + + public void updateRecentFiles() { + if (RecentFiles.paths.isEmpty()) { + recentFiles.setEnabled(false); + clearRecentFiles.setEnabled(false); + return; + } else { + recentFiles.setEnabled(true); + clearRecentFiles.setEnabled(true); + } + + recentFiles.removeAll(); + ListIterator li = RecentFiles.paths.listIterator(RecentFiles.paths.size()); + boolean rfSaveNeeded = false; + + while (li.hasPrevious()) { + String path = li.previous(); + final File file = new File(path); + + if (!file.exists()) { + rfSaveNeeded = true; + continue; + } + + JMenuItem menuItem = new JMenuItem(path); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mainWindow.getModel().loadFile(file); + } + }); + recentFiles.add(menuItem); + } + + if (rfSaveNeeded) RecentFiles.save(); + } + + private void buildFileMenu(final JMenu fileMenu) { + fileMenu.removeAll(); + JMenuItem menuItem = new JMenuItem("Open File..."); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_O, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mainWindow.onOpenFileMenu(); + } + }); + fileMenu.add(menuItem); + fileMenu.addSeparator(); + + menuItem = new JMenuItem("Close File"); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JTabbedPane house = mainWindow.getModel().house; + + if (e.getModifiers() != 2 || house.getTabCount() == 0) + mainWindow.onCloseFileMenu(); + else { + mainWindow.getModel().closeOpenTab(house.getSelectedIndex()); + } + } + }); + fileMenu.add(menuItem); + fileMenu.addSeparator(); + + menuItem = new JMenuItem("Save As..."); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mainWindow.onSaveAsMenu(); + } + }); + fileMenu.add(menuItem); + + menuItem = new JMenuItem("Save All..."); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mainWindow.onSaveAllMenu(); + } + }); + fileMenu.add(menuItem); + fileMenu.addSeparator(); + + recentFiles = new JMenu("Recent Files"); + fileMenu.add(recentFiles); + + clearRecentFiles = new JMenuItem("Clear Recent Files"); + clearRecentFiles.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + RecentFiles.paths.clear(); + RecentFiles.save(); + updateRecentFiles(); + } + }); + fileMenu.add(clearRecentFiles); + + fileMenu.addSeparator(); + + // Only add the exit command for non-OS X. OS X handles its close + // automatically + if (!Boolean.getBoolean("apple.laf.useScreenMenuBar")) { + menuItem = new JMenuItem("Exit"); + menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, ActionEvent.ALT_MASK)); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mainWindow.onExitMenu(); + } + }); + fileMenu.add(menuItem); + } + } + + private void buildEditMenu(JMenu editMenu) { + editMenu.removeAll(); + JMenuItem menuItem = new JMenuItem("Cut"); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + menuItem.setEnabled(false); + editMenu.add(menuItem); + + menuItem = new JMenuItem("Copy"); + menuItem.addActionListener(new DefaultEditorKit.CopyAction()); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + editMenu.add(menuItem); + + menuItem = new JMenuItem("Paste"); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + menuItem.setEnabled(false); + editMenu.add(menuItem); + + editMenu.addSeparator(); + + menuItem = new JMenuItem("Select All"); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_A, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mainWindow.onSelectAllMenu(); + } + }); + editMenu.add(menuItem); + editMenu.addSeparator(); + + menuItem = new JMenuItem("Find..."); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mainWindow.onFindMenu(); + } + }); + editMenu.add(menuItem); + + menuItem = new JMenuItem("Find Next"); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0)); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(mainWindow.findBox != null) mainWindow.findBox.fireExploreAction(true); + } + }); + editMenu.add(menuItem); + + menuItem = new JMenuItem("Find Previous"); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_DOWN_MASK)); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(mainWindow.findBox != null) mainWindow.findBox.fireExploreAction(false); + } + }); + editMenu.add(menuItem); + + menuItem = new JMenuItem("Find All"); + menuItem.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mainWindow.onFindAllMenu(); + + } + }); + editMenu.add(menuItem); + } + + private void buildThemesMenu(JMenu themesMenu) { + themesMenu.removeAll(); + themesGroup = new ButtonGroup(); + JRadioButtonMenuItem a = new JRadioButtonMenuItem(new ThemeAction("Default", "default.xml")); + a.setSelected("default.xml".equals(luytenPrefs.getThemeXml())); + themesGroup.add(a); + themesMenu.add(a); + + a = new JRadioButtonMenuItem(new ThemeAction("Default-Alt", "default-alt.xml")); + a.setSelected("default-alt.xml".equals(luytenPrefs.getThemeXml())); + themesGroup.add(a); + themesMenu.add(a); + + a = new JRadioButtonMenuItem(new ThemeAction("Dark", "dark.xml")); + a.setSelected("dark.xml".equals(luytenPrefs.getThemeXml())); + themesGroup.add(a); + themesMenu.add(a); + + a = new JRadioButtonMenuItem(new ThemeAction("Eclipse", "eclipse.xml")); + a.setSelected("eclipse.xml".equals(luytenPrefs.getThemeXml())); + themesGroup.add(a); + themesMenu.add(a); + + a = new JRadioButtonMenuItem(new ThemeAction("Visual Studio", "vs.xml")); + a.setSelected("vs.xml".equals(luytenPrefs.getThemeXml())); + themesGroup.add(a); + themesMenu.add(a); + + a = new JRadioButtonMenuItem(new ThemeAction("IntelliJ", "idea.xml")); + a.setSelected("idea.xml".equals(luytenPrefs.getThemeXml())); + themesGroup.add(a); + themesMenu.add(a); + } + + private void buildOperationMenu(JMenu operationMenu) { + operationMenu.removeAll(); + packageExplorerStyle = new JCheckBoxMenuItem("Package Explorer Style"); + packageExplorerStyle.setSelected(luytenPrefs.isPackageExplorerStyle()); + packageExplorerStyle.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + luytenPrefs.setPackageExplorerStyle(packageExplorerStyle.isSelected()); + mainWindow.onTreeSettingsChanged(); + } + }); + operationMenu.add(packageExplorerStyle); + + filterOutInnerClassEntries = new JCheckBoxMenuItem("Filter Out Inner Class Entries"); + filterOutInnerClassEntries.setSelected(luytenPrefs.isFilterOutInnerClassEntries()); + filterOutInnerClassEntries.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + luytenPrefs.setFilterOutInnerClassEntries(filterOutInnerClassEntries.isSelected()); + mainWindow.onTreeSettingsChanged(); + } + }); + operationMenu.add(filterOutInnerClassEntries); + + singleClickOpenEnabled = new JCheckBoxMenuItem("Single Click Open"); + singleClickOpenEnabled.setSelected(luytenPrefs.isSingleClickOpenEnabled()); + singleClickOpenEnabled.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + luytenPrefs.setSingleClickOpenEnabled(singleClickOpenEnabled.isSelected()); + } + }); + operationMenu.add(singleClickOpenEnabled); + + exitByEscEnabled = new JCheckBoxMenuItem("Exit By Esc"); + exitByEscEnabled.setSelected(luytenPrefs.isExitByEscEnabled()); + exitByEscEnabled.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + luytenPrefs.setExitByEscEnabled(exitByEscEnabled.isSelected()); + } + }); + operationMenu.add(exitByEscEnabled); + } + + private void buildSettingsMenu(JMenu settingsMenu, ConfigSaver configSaver) { + settingsMenu.removeAll(); + ActionListener settingsChanged = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + new Thread() { + @Override + public void run() { + populateSettingsFromSettingsMenu(); + mainWindow.onSettingsChanged(); + } + }.start(); + } + }; + flattenSwitchBlocks = new JCheckBoxMenuItem("Flatten Switch Blocks"); + flattenSwitchBlocks.setSelected(settings.getFlattenSwitchBlocks()); + flattenSwitchBlocks.addActionListener(settingsChanged); + settingsMenu.add(flattenSwitchBlocks); + + forceExplicitImports = new JCheckBoxMenuItem("Force Explicit Imports"); + forceExplicitImports.setSelected(settings.getForceExplicitImports()); + forceExplicitImports.addActionListener(settingsChanged); + settingsMenu.add(forceExplicitImports); + + forceExplicitTypes = new JCheckBoxMenuItem("Force Explicit Types"); + forceExplicitTypes.setSelected(settings.getForceExplicitTypeArguments()); + forceExplicitTypes.addActionListener(settingsChanged); + settingsMenu.add(forceExplicitTypes); + + showSyntheticMembers = new JCheckBoxMenuItem("Show Synthetic Members"); + showSyntheticMembers.setSelected(settings.getShowSyntheticMembers()); + showSyntheticMembers.addActionListener(settingsChanged); + settingsMenu.add(showSyntheticMembers); + + excludeNestedTypes = new JCheckBoxMenuItem("Exclude Nested Types"); + excludeNestedTypes.setSelected(settings.getExcludeNestedTypes()); + excludeNestedTypes.addActionListener(settingsChanged); + settingsMenu.add(excludeNestedTypes); + + retainRedundantCasts = new JCheckBoxMenuItem("Retain Redundant Casts"); + retainRedundantCasts.setSelected(settings.getRetainRedundantCasts()); + retainRedundantCasts.addActionListener(settingsChanged); + settingsMenu.add(retainRedundantCasts); + + unicodeReplacement = new JCheckBoxMenuItem("Enable Unicode Replacement"); + unicodeReplacement.setSelected(settings.isUnicodeOutputEnabled()); + unicodeReplacement.addActionListener(settingsChanged); + settingsMenu.add(unicodeReplacement); + + debugLineNumbers = new JCheckBoxMenuItem("Show Debug Line Numbers"); + debugLineNumbers.setSelected(settings.getShowDebugLineNumbers()); + debugLineNumbers.addActionListener(settingsChanged); + settingsMenu.add(debugLineNumbers); + + JMenu debugSettingsMenu = new JMenu("Debug Settings"); + showDebugInfo = new JCheckBoxMenuItem("Include Error Diagnostics"); + showDebugInfo.setSelected(settings.getIncludeErrorDiagnostics()); + showDebugInfo.addActionListener(settingsChanged); + + debugSettingsMenu.add(showDebugInfo); + settingsMenu.add(debugSettingsMenu); + settingsMenu.addSeparator(); + + languageLookup.put(Languages.java().getName(), Languages.java()); + languageLookup.put(Languages.bytecode().getName(), Languages.bytecode()); + languageLookup.put(Languages.bytecodeAst().getName(), Languages.bytecodeAst()); + + languagesGroup = new ButtonGroup(); + java = new JRadioButtonMenuItem(Languages.java().getName()); + java.getModel().setActionCommand(Languages.java().getName()); + java.setSelected(Languages.java().getName().equals(settings.getLanguage().getName())); + languagesGroup.add(java); + settingsMenu.add(java); + bytecode = new JRadioButtonMenuItem(Languages.bytecode().getName()); + bytecode.getModel().setActionCommand(Languages.bytecode().getName()); + bytecode.setSelected(Languages.bytecode().getName().equals(settings.getLanguage().getName())); + languagesGroup.add(bytecode); + settingsMenu.add(bytecode); + bytecodeAST = new JRadioButtonMenuItem(Languages.bytecodeAst().getName()); + bytecodeAST.getModel().setActionCommand(Languages.bytecodeAst().getName()); + bytecodeAST.setSelected(Languages.bytecodeAst().getName().equals(settings.getLanguage().getName())); + languagesGroup.add(bytecodeAST); + settingsMenu.add(bytecodeAST); + + JMenu debugLanguagesMenu = new JMenu("Debug Languages"); + for (final Language language : Languages.debug()) { + final JRadioButtonMenuItem m = new JRadioButtonMenuItem(language.getName()); + m.getModel().setActionCommand(language.getName()); + m.setSelected(language.getName().equals(settings.getLanguage().getName())); + languagesGroup.add(m); + debugLanguagesMenu.add(m); + languageLookup.put(language.getName(), language); + } + for (AbstractButton button : Collections.list(languagesGroup.getElements())) { + button.addActionListener(settingsChanged); + } + settingsMenu.add(debugLanguagesMenu); + + bytecodeLineNumbers = new JCheckBoxMenuItem("Show Line Numbers In Bytecode"); + bytecodeLineNumbers.setSelected(settings.getIncludeLineNumbersInBytecode()); + bytecodeLineNumbers.addActionListener(settingsChanged); + settingsMenu.add(bytecodeLineNumbers); + } + + private void buildHelpMenu(JMenu helpMenu) { + helpMenu.removeAll(); + JMenuItem menuItem = new JMenuItem("Legal"); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mainWindow.onLegalMenu(); + } + }); + helpMenu.add(menuItem); + JMenu menuDebug = new JMenu("Debug"); + menuItem = new JMenuItem("List JVM Classes"); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mainWindow.onListLoadedClasses(); + } + }); + menuDebug.add(menuItem); + helpMenu.add(menuDebug); + menuItem = new JMenuItem("About"); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent event) { + JPanel pane = new JPanel(); + pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS)); + JLabel title = new JLabel("Luyten " + Luyten.getVersion()); + title.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 18)); + pane.add(title); + pane.add(new JLabel("by Deathmarine")); + String project = "https://github.com/deathmarine/Luyten/"; + JLabel link = new JLabel("" + project + ""); + link.setCursor(new Cursor(Cursor.HAND_CURSOR)); + link.addMouseListener(new LinkListener(project, link)); + pane.add(link); + pane.add(new JLabel("Contributions By:")); + pane.add(new JLabel("zerdei, toonetown, dstmath")); + pane.add(new JLabel("virustotalop, xtrafrancyz,")); + pane.add(new JLabel("mbax, quitten, mstrobel,")); + pane.add(new JLabel("FisheyLP, and Syquel")); + pane.add(new JLabel(" ")); + pane.add(new JLabel("Powered By:")); + String procyon = "https://bitbucket.org/mstrobel/procyon"; + link = new JLabel("" + procyon + ""); + link.setCursor(new Cursor(Cursor.HAND_CURSOR)); + link.addMouseListener(new LinkListener(procyon, link)); + pane.add(link); + pane.add(new JLabel("Version: " + Procyon.version())); + pane.add(new JLabel("(c) 2018 Mike Strobel")); + String rsyntax = "https://github.com/bobbylight/RSyntaxTextArea"; + link = new JLabel("" + rsyntax + ""); + link.setCursor(new Cursor(Cursor.HAND_CURSOR)); + link.addMouseListener(new LinkListener(rsyntax, link)); + pane.add(link); + pane.add(new JLabel("Version: 3.0.2")); + pane.add(new JLabel("(c) 2019 Robert Futrell")); + pane.add(new JLabel(" ")); + JOptionPane.showMessageDialog(null, pane); + } + }); + helpMenu.add(menuItem); + } + + private void populateSettingsFromSettingsMenu() { + // synchronized: do not disturb decompiler at work (synchronize every + // time before run decompiler) + synchronized (settings) { + settings.setFlattenSwitchBlocks(flattenSwitchBlocks.isSelected()); + settings.setForceExplicitImports(forceExplicitImports.isSelected()); + settings.setShowSyntheticMembers(showSyntheticMembers.isSelected()); + settings.setExcludeNestedTypes(excludeNestedTypes.isSelected()); + settings.setForceExplicitTypeArguments(forceExplicitTypes.isSelected()); + settings.setRetainRedundantCasts(retainRedundantCasts.isSelected()); + settings.setIncludeErrorDiagnostics(showDebugInfo.isSelected()); + settings.setUnicodeOutputEnabled(unicodeReplacement.isSelected()); + settings.setShowDebugLineNumbers(debugLineNumbers.isSelected()); + // + // Note: You shouldn't ever need to set this. It's only for + // languages that support catch + // blocks without an exception variable. Java doesn't allow this. I + // think Scala does. + // + // settings.setAlwaysGenerateExceptionVariableForCatchBlocks(true); + // + + final ButtonModel selectedLanguage = languagesGroup.getSelection(); + if (selectedLanguage != null) { + final Language language = languageLookup.get(selectedLanguage.getActionCommand()); + + if (language != null) + settings.setLanguage(language); + } + + if (java.isSelected()) { + settings.setLanguage(Languages.java()); + } else if (bytecode.isSelected()) { + settings.setLanguage(Languages.bytecode()); + } else if (bytecodeAST.isSelected()) { + settings.setLanguage(Languages.bytecodeAst()); + } + settings.setIncludeLineNumbersInBytecode(bytecodeLineNumbers.isSelected()); + } + } + + private class ThemeAction extends AbstractAction { + private static final long serialVersionUID = -6618680171943723199L; + private String xml; + + public ThemeAction(String name, String xml) { + putValue(NAME, name); + this.xml = xml; + } + + @Override + public void actionPerformed(ActionEvent e) { + luytenPrefs.setThemeXml(xml); + mainWindow.onThemesChanged(); + } + } + + private class LinkListener extends MouseAdapter { + String link; + JLabel label; + + public LinkListener(String link, JLabel label) { + this.link = link; + this.label = label; + } + + @Override + public void mouseClicked(MouseEvent e) { + try { + Desktop.getDesktop().browse(new URI(link)); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + + @Override + public void mouseEntered(MouseEvent e) { + label.setText("" + link + ""); + } + + @Override + public void mouseExited(MouseEvent e) { + label.setText("" + link + ""); + } + + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/MainWindow.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/MainWindow.java new file mode 100644 index 0000000..68d27dc --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/MainWindow.java @@ -0,0 +1,440 @@ +package us.deathmarine.luyten; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Toolkit; +import java.awt.dnd.DropTarget; +import java.awt.event.ActionEvent; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Iterator; +import java.util.Vector; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.JSplitPane; +import javax.swing.KeyStroke; +import javax.swing.border.BevelBorder; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; + +/** + * Dispatcher + */ +public class MainWindow extends JFrame { + private static final long serialVersionUID = 5265556630724988013L; + + private static final String TITLE = "Luyten"; + + public static Model model; + private JProgressBar bar; + private JLabel label; + FindBox findBox; + private FindAllBox findAllBox; + private ConfigSaver configSaver; + private WindowPosition windowPosition; + private LuytenPreferences luytenPrefs; + private FileDialog fileDialog; + private FileSaver fileSaver; + public MainMenuBar mainMenuBar; + + public MainWindow(File fileFromCommandLine) { + configSaver = ConfigSaver.getLoadedInstance(); + windowPosition = configSaver.getMainWindowPosition(); + luytenPrefs = configSaver.getLuytenPreferences(); + + mainMenuBar = new MainMenuBar(this); + this.setJMenuBar(mainMenuBar); + + this.adjustWindowPositionBySavedState(); + this.setHideFindBoxOnMainWindowFocus(); + this.setShowFindAllBoxOnMainWindowFocus(); + this.setQuitOnWindowClosing(); + this.setTitle(TITLE); + this.setIconImage(new ImageIcon( + Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/resources/Luyten.png"))).getImage()); + + JPanel panel1 = new JPanel(new FlowLayout(FlowLayout.LEFT)); + label = new JLabel(); + label.setHorizontalAlignment(JLabel.LEFT); + panel1.setBorder(new BevelBorder(BevelBorder.LOWERED)); + panel1.setPreferredSize(new Dimension(this.getWidth() / 2, 20)); + panel1.add(label); + + JPanel panel2 = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + bar = new JProgressBar(); + + bar.setStringPainted(true); + bar.setOpaque(false); + bar.setVisible(false); + panel2.setPreferredSize(new Dimension(this.getWidth() / 3, 20)); + panel2.add(bar); + + model = new Model(this); + this.getContentPane().add(model); + + JSplitPane spt = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panel1, panel2) { + private static final long serialVersionUID = 2189946972124687305L; + private final int location = 400; + + { + setDividerLocation(location); + } + + @Override + public int getDividerLocation() { + return location; + } + + @Override + public int getLastDividerLocation() { + return location; + } + }; + spt.setBorder(new BevelBorder(BevelBorder.LOWERED)); + spt.setPreferredSize(new Dimension(this.getWidth(), 24)); + this.add(spt, BorderLayout.SOUTH); + if (fileFromCommandLine != null) { + model.loadFile(fileFromCommandLine); + } + + try { + DropTarget dt = new DropTarget(); + dt.addDropTargetListener(new DropListener(this)); + this.setDropTarget(dt); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + + fileDialog = new FileDialog(this); + fileSaver = new FileSaver(bar, label); + + this.setExitOnEscWhenEnabled(model); + + if (fileFromCommandLine == null || fileFromCommandLine.getName().toLowerCase().endsWith(".jar") + || fileFromCommandLine.getName().toLowerCase().endsWith(".zip")) { + model.startWarmUpThread(); + } + + if(RecentFiles.load() > 0) mainMenuBar.updateRecentFiles(); + } + + public void onOpenFileMenu() { + File selectedFile = fileDialog.doOpenDialog(); + if (selectedFile != null) { + System.out.println("[Open]: Opening " + selectedFile.getAbsolutePath()); + + this.getModel().loadFile(selectedFile); + } + } + + public void onCloseFileMenu() { + this.getModel().closeFile(); + } + + public void onSaveAsMenu() { + RSyntaxTextArea pane = this.getModel().getCurrentTextArea(); + if (pane == null) + return; + String tabTitle = this.getModel().getCurrentTabTitle(); + if (tabTitle == null) + return; + + String recommendedFileName = tabTitle.replace(".class", ".java"); + File selectedFile = fileDialog.doSaveDialog(recommendedFileName); + if (selectedFile != null) { + fileSaver.saveText(pane.getText(), selectedFile); + } + } + + public void onSaveAllMenu() { + File openedFile = this.getModel().getOpenedFile(); + if (openedFile == null) + return; + + String fileName = openedFile.getName(); + if (fileName.endsWith(".class")) { + fileName = fileName.replace(".class", ".java"); + } else if (fileName.toLowerCase().endsWith(".jar")) { + fileName = "decompiled-" + fileName.replaceAll("\\.[jJ][aA][rR]", ".zip"); + } else { + fileName = "saved-" + fileName; + } + + File selectedFileToSave = fileDialog.doSaveAllDialog(fileName); + if (selectedFileToSave != null) { + fileSaver.saveAllDecompiled(openedFile, selectedFileToSave); + } + } + + public void onExitMenu() { + quit(); + } + + public void onSelectAllMenu() { + try { + RSyntaxTextArea pane = this.getModel().getCurrentTextArea(); + if (pane != null) { + pane.requestFocusInWindow(); + pane.setSelectionStart(0); + pane.setSelectionEnd(pane.getText().length()); + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + public void onFindMenu() { + try { + RSyntaxTextArea pane = this.getModel().getCurrentTextArea(); + if (pane != null) { + if (findBox == null) + findBox = new FindBox(this); + findBox.showFindBox(); + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + public void onFindAllMenu() { + try { + if (findAllBox == null) + findAllBox = new FindAllBox(this); + findAllBox.showFindBox(); + + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + public void onLegalMenu() { + new Thread() { + public void run() { + try { + bar.setVisible(true); + bar.setIndeterminate(true); + String legalStr = getLegalStr(); + MainWindow.this.getModel().showLegal(legalStr); + } finally { + bar.setIndeterminate(false); + bar.setVisible(false); + } + } + }.start(); + } + + public void onListLoadedClasses() { + try { + StringBuilder sb = new StringBuilder(); + ClassLoader myCL = Thread.currentThread().getContextClassLoader(); + bar.setVisible(true); + bar.setIndeterminate(true); + while (myCL != null) { + sb.append("ClassLoader: " + myCL + "\n"); + for (Iterator iter = list(myCL); iter.hasNext();) { + sb.append("\t" + iter.next() + "\n"); + } + myCL = myCL.getParent(); + } + MainWindow.this.getModel().show("Debug", sb.toString()); + } finally { + bar.setIndeterminate(false); + bar.setVisible(false); + } + } + + private static Iterator list(ClassLoader CL) { + Class CL_class = CL.getClass(); + while (CL_class != java.lang.ClassLoader.class) { + CL_class = CL_class.getSuperclass(); + } + java.lang.reflect.Field ClassLoader_classes_field; + try { + ClassLoader_classes_field = CL_class.getDeclaredField("classes"); + ClassLoader_classes_field.setAccessible(true); + Vector classes = (Vector) ClassLoader_classes_field.get(CL); + return classes.iterator(); + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { + Luyten.showExceptionDialog("Exception!", e); + } + return null; + } + + private String getLegalStr() { + StringBuilder sb = new StringBuilder(); + try { + BufferedReader reader = new BufferedReader( + new InputStreamReader(getClass().getResourceAsStream("/distfiles/Procyon.License.txt"))); + String line; + while ((line = reader.readLine()) != null) + sb.append(line).append("\n"); + sb.append("\n\n\n\n\n"); + reader = new BufferedReader( + new InputStreamReader(getClass().getResourceAsStream("/distfiles/RSyntaxTextArea.License.txt"))); + while ((line = reader.readLine()) != null) + sb.append(line).append("\n"); + } catch (IOException e) { + Luyten.showExceptionDialog("Exception!", e); + } + return sb.toString(); + } + + public void onThemesChanged() { + this.getModel().changeTheme(luytenPrefs.getThemeXml()); + luytenPrefs.setFont_size(this.getModel().getTheme().baseFont.getSize()); + } + + public void onSettingsChanged() { + this.getModel().updateOpenClasses(); + } + + public void onTreeSettingsChanged() { + this.getModel().updateTree(); + } + + public void onFileDropped(File file) { + if (file != null) { + this.getModel().loadFile(file); + } + } + + public void onFileLoadEnded(File file, boolean isSuccess) { + try { + if (file != null && isSuccess) { + this.setTitle(TITLE + " - " + file.getName()); + } else { + this.setTitle(TITLE); + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + public void onNavigationRequest(String uniqueStr) { + this.getModel().navigateTo(uniqueStr); + } + + private void adjustWindowPositionBySavedState() { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + if (!windowPosition.isSavedWindowPositionValid()) { + final Dimension center = new Dimension((int) (screenSize.width * 0.75), (int) (screenSize.height * 0.75)); + final int x = (int) (center.width * 0.2); + final int y = (int) (center.height * 0.2); + this.setBounds(x, y, center.width, center.height); + + } else if (windowPosition.isFullScreen()) { + int heightMinusTray = screenSize.height; + if (screenSize.height > 30) + heightMinusTray -= 30; + this.setBounds(0, 0, screenSize.width, heightMinusTray); + this.setExtendedState(JFrame.MAXIMIZED_BOTH); + + this.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + if (MainWindow.this.getExtendedState() != JFrame.MAXIMIZED_BOTH) { + windowPosition.setFullScreen(false); + if (windowPosition.isSavedWindowPositionValid()) { + MainWindow.this.setBounds(windowPosition.getWindowX(), windowPosition.getWindowY(), + windowPosition.getWindowWidth(), windowPosition.getWindowHeight()); + } + MainWindow.this.removeComponentListener(this); + } + } + }); + + } else { + this.setBounds(windowPosition.getWindowX(), windowPosition.getWindowY(), windowPosition.getWindowWidth(), + windowPosition.getWindowHeight()); + } + } + + private void setHideFindBoxOnMainWindowFocus() { + this.addWindowFocusListener(new WindowAdapter() { + @Override + public void windowGainedFocus(WindowEvent e) { + if (findBox != null && findBox.isVisible()) { + findBox.setVisible(false); + } + } + }); + } + + private void setShowFindAllBoxOnMainWindowFocus() { + this.addWindowFocusListener(new WindowAdapter() { + @Override + public void windowGainedFocus(WindowEvent e) { + if (findAllBox != null && findAllBox.isVisible()) { + findAllBox.setVisible(false); + } + } + }); + } + + private void setQuitOnWindowClosing() { + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + quit(); + } + }); + } + + private void quit() { + try { + windowPosition.readPositionFromWindow(this); + configSaver.saveConfig(); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } finally { + try { + this.dispose(); + } finally { + System.exit(0); + } + } + } + + private void setExitOnEscWhenEnabled(JComponent mainComponent) { + Action escapeAction = new AbstractAction() { + private static final long serialVersionUID = -3460391555954575248L; + + @Override + public void actionPerformed(ActionEvent e) { + if (luytenPrefs.isExitByEscEnabled()) { + quit(); + } + } + }; + KeyStroke escapeKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false); + mainComponent.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(escapeKeyStroke, "ESCAPE"); + mainComponent.getActionMap().put("ESCAPE", escapeAction); + } + + public Model getModel() { + return model; + } + + public JProgressBar getBar() { + return bar; + } + + public JLabel getLabel() { + return label; + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Model.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Model.java new file mode 100644 index 0000000..2d0b802 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Model.java @@ -0,0 +1,1057 @@ +package us.deathmarine.luyten; + +import java.awt.Component; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.JTree; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.TreeExpansionEvent; +import javax.swing.event.TreeExpansionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.Theme; +import org.fife.ui.rtextarea.RTextScrollPane; +import com.strobel.assembler.InputTypeLoader; +import com.strobel.assembler.metadata.ITypeLoader; +import com.strobel.assembler.metadata.JarTypeLoader; +import com.strobel.assembler.metadata.MetadataSystem; +import com.strobel.assembler.metadata.TypeDefinition; +import com.strobel.assembler.metadata.TypeReference; +import com.strobel.core.StringUtilities; +import com.strobel.core.VerifyArgument; +import com.strobel.decompiler.DecompilationOptions; +import com.strobel.decompiler.DecompilerSettings; +import com.strobel.decompiler.PlainTextOutput; + +/** + * Jar-level model + */ +public class Model extends JSplitPane { + private static final long serialVersionUID = 6896857630400910200L; + + private static final long MAX_JAR_FILE_SIZE_BYTES = 10_000_000_000L; + private static final long MAX_UNPACKED_FILE_SIZE_BYTES = 10_000_000L; + + private static LuytenTypeLoader typeLoader = new LuytenTypeLoader(); + public static MetadataSystem metadataSystem = new MetadataSystem(typeLoader); + + private JTree tree; + public JTabbedPane house; + private File file; + private DecompilerSettings settings; + private DecompilationOptions decompilationOptions; + private Theme theme; + private MainWindow mainWindow; + private JProgressBar bar; + private JLabel label; + private HashSet hmap = new HashSet(); + private Set treeExpansionState; + private boolean open = false; + private State state; + private ConfigSaver configSaver; + private LuytenPreferences luytenPrefs; + + public Model(MainWindow mainWindow) { + this.mainWindow = mainWindow; + this.bar = mainWindow.getBar(); + this.setLabel(mainWindow.getLabel()); + + configSaver = ConfigSaver.getLoadedInstance(); + settings = configSaver.getDecompilerSettings(); + luytenPrefs = configSaver.getLuytenPreferences(); + + try { + String themeXml = luytenPrefs.getThemeXml(); + setTheme(Theme.load(getClass().getResourceAsStream(LuytenPreferences.THEME_XML_PATH + themeXml))); + } catch (Exception e1) { + try { + Luyten.showExceptionDialog("Exception!", e1); + String themeXml = LuytenPreferences.DEFAULT_THEME_XML; + luytenPrefs.setThemeXml(themeXml); + setTheme(Theme.load(getClass().getResourceAsStream(LuytenPreferences.THEME_XML_PATH + themeXml))); + } catch (Exception e2) { + Luyten.showExceptionDialog("Exception!", e2); + } + } + + tree = new JTree(); + tree.setModel(new DefaultTreeModel(null)); + tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + tree.setCellRenderer(new CellRenderer()); + TreeListener tl = new TreeListener(); + tree.addMouseListener(tl); + tree.addTreeExpansionListener(new FurtherExpandingTreeExpansionListener()); + tree.addKeyListener(new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + openEntryByTreePath(tree.getSelectionPath()); + } + } + }); + + JPanel panel2 = new JPanel(); + panel2.setLayout(new BoxLayout(panel2, 1)); + panel2.setBorder(BorderFactory.createTitledBorder("Structure")); + panel2.add(new JScrollPane(tree)); + + house = new JTabbedPane(); + house.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); + house.addChangeListener(new TabChangeListener()); + house.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isMiddleMouseButton(e)) { + closeOpenTab(house.getSelectedIndex()); + } + } + }); + + KeyStroke sfuncF4 = KeyStroke.getKeyStroke(KeyEvent.VK_F4, Keymap.ctrlDownModifier(), false); + mainWindow.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sfuncF4, "CloseTab"); + + mainWindow.getRootPane().getActionMap().put("CloseTab", new AbstractAction() { + private static final long serialVersionUID = -885398399200419492L; + + @Override + public void actionPerformed(ActionEvent e) { + closeOpenTab(house.getSelectedIndex()); + } + + }); + + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, 1)); + panel.setBorder(BorderFactory.createTitledBorder("Code")); + panel.add(house); + this.setOrientation(JSplitPane.HORIZONTAL_SPLIT); + this.setDividerLocation(250 % mainWindow.getWidth()); + this.setLeftComponent(panel2); + this.setRightComponent(panel); + + decompilationOptions = new DecompilationOptions(); + decompilationOptions.setSettings(settings); + decompilationOptions.setFullDecompilation(true); + } + + public void showLegal(String legalStr) { + show("Legal", legalStr); + } + + public void show(String name, String contents) { + OpenFile open = new OpenFile(name, "*/" + name, getTheme(), mainWindow); + open.setContent(contents); + hmap.add(open); + addOrSwitchToTab(open); + } + + private void addOrSwitchToTab(final OpenFile open) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + try { + final String title = open.name; + RTextScrollPane rTextScrollPane = open.scrollPane; + int index = house.indexOfTab(title); + if (index > -1 && house.getTabComponentAt(index) != open.scrollPane) { + index = -1; + for (int i = 0; i < house.getTabCount(); i++) { + if (house.getComponentAt(i) == open.scrollPane) { + index = i; + break; + } + } + } + if (index < 0) { + house.addTab(title, rTextScrollPane); + index = house.indexOfComponent(rTextScrollPane); + house.setSelectedIndex(index); + Tab ct = new Tab(title); + ct.getButton().addMouseListener(new CloseTab(title)); + house.setTabComponentAt(index, ct); + } else { + house.setSelectedIndex(index); + } + open.onAddedToScreen(); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + }); + } + + public void closeOpenTab(int index) { + RTextScrollPane co = (RTextScrollPane) house.getComponentAt(index); + RSyntaxTextArea pane = (RSyntaxTextArea) co.getViewport().getView(); + OpenFile open = null; + for (OpenFile file : hmap) + if (pane.equals(file.textArea)) + open = file; + if (open != null && hmap.contains(open)) + hmap.remove(open); + house.remove(co); + if (open != null) + open.close(); + } + + private String getName(String path) { + if (path == null) + return ""; + int i = path.lastIndexOf("/"); + if (i == -1) + i = path.lastIndexOf("\\"); + if (i != -1) + return path.substring(i + 1); + return path; + } + + private class TreeListener extends MouseAdapter { + @Override + public void mousePressed(MouseEvent event) { + boolean isClickCountMatches = (event.getClickCount() == 1 && luytenPrefs.isSingleClickOpenEnabled()) + || (event.getClickCount() == 2 && !luytenPrefs.isSingleClickOpenEnabled()); + if (!isClickCountMatches) + return; + + if (!SwingUtilities.isLeftMouseButton(event)) + return; + + final TreePath trp = tree.getPathForLocation(event.getX(), event.getY()); + if (trp == null) + return; + + Object lastPathComponent = trp.getLastPathComponent(); + boolean isLeaf = (lastPathComponent instanceof TreeNode && ((TreeNode) lastPathComponent).isLeaf()); + if (!isLeaf) + return; + + new Thread() { + public void run() { + openEntryByTreePath(trp); + } + }.start(); + } + } + + private class FurtherExpandingTreeExpansionListener implements TreeExpansionListener { + @Override + public void treeExpanded(final TreeExpansionEvent event) { + final TreePath treePath = event.getPath(); + + final Object expandedTreePathObject = treePath.getLastPathComponent(); + if (!(expandedTreePathObject instanceof TreeNode)) { + return; + } + + final TreeNode expandedTreeNode = (TreeNode) expandedTreePathObject; + if (expandedTreeNode.getChildCount() == 1) { + final TreeNode descendantTreeNode = expandedTreeNode.getChildAt(0); + + if (descendantTreeNode.isLeaf()) { + return; + } + + final TreePath nextTreePath = treePath.pathByAddingChild(descendantTreeNode); + tree.expandPath(nextTreePath); + } + } + + @Override + public void treeCollapsed(final TreeExpansionEvent event) { + + } + } + + public void openEntryByTreePath(TreePath trp) { + String name = ""; + String path = ""; + try { + bar.setVisible(true); + if (trp.getPathCount() > 1) { + for (int i = 1; i < trp.getPathCount(); i++) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) trp.getPathComponent(i); + TreeNodeUserObject userObject = (TreeNodeUserObject) node.getUserObject(); + if (i == trp.getPathCount() - 1) { + name = userObject.getOriginalName(); + } else { + path = path + userObject.getOriginalName() + "/"; + } + } + path = path + name; + + if (file.getName().endsWith(".jar") || file.getName().endsWith(".zip")) { + if (state == null) { + JarFile jfile = new JarFile(file); + ITypeLoader jarLoader = new JarTypeLoader(jfile); + + typeLoader.getTypeLoaders().add(jarLoader); + state = new State(file.getCanonicalPath(), file, jfile, jarLoader); + } + + JarEntry entry = state.jarFile.getJarEntry(path); + if (entry == null) { + throw new FileEntryNotFoundException(); + } + if (entry.getSize() > MAX_UNPACKED_FILE_SIZE_BYTES) { + throw new TooLargeFileException(entry.getSize()); + } + String entryName = entry.getName(); + if (entryName.endsWith(".class")) { + getLabel().setText("Extracting: " + name); + String internalName = StringUtilities.removeRight(entryName, ".class"); + TypeReference type = metadataSystem.lookupType(internalName); + extractClassToTextPane(type, name, path, null); + } else { + getLabel().setText("Opening: " + name); + try (InputStream in = state.jarFile.getInputStream(entry);) { + extractSimpleFileEntryToTextPane(in, name, path); + } + } + } + } else { + name = file.getName(); + path = file.getPath().replaceAll("\\\\", "/"); + if (file.length() > MAX_UNPACKED_FILE_SIZE_BYTES) { + throw new TooLargeFileException(file.length()); + } + if (name.endsWith(".class")) { + getLabel().setText("Extracting: " + name); + TypeReference type = metadataSystem.lookupType(path); + extractClassToTextPane(type, name, path, null); + } else { + getLabel().setText("Opening: " + name); + try (InputStream in = new FileInputStream(file);) { + extractSimpleFileEntryToTextPane(in, name, path); + } + } + } + + getLabel().setText("Complete"); + } catch (FileEntryNotFoundException e) { + getLabel().setText("File not found: " + name); + } catch (FileIsBinaryException e) { + getLabel().setText("Binary resource: " + name); + } catch (TooLargeFileException e) { + getLabel().setText("File is too large: " + name + " - size: " + e.getReadableFileSize()); + } catch (Exception e) { + getLabel().setText("Cannot open: " + name); + Luyten.showExceptionDialog("Unable to open file!", e); + } finally { + bar.setVisible(false); + } + } + + void extractClassToTextPane(TypeReference type, String tabTitle, String path, String navigatonLink) + throws Exception { + if (tabTitle == null || tabTitle.trim().length() < 1 || path == null) { + throw new FileEntryNotFoundException(); + } + OpenFile sameTitledOpen = null; + for (OpenFile nextOpen : hmap) { + if (tabTitle.equals(nextOpen.name) && path.equals(nextOpen.path) && type.equals(nextOpen.getType())) { + sameTitledOpen = nextOpen; + break; + } + } + if (sameTitledOpen != null && sameTitledOpen.isContentValid()) { + sameTitledOpen.setInitialNavigationLink(navigatonLink); + addOrSwitchToTab(sameTitledOpen); + return; + } + + // resolve TypeDefinition + TypeDefinition resolvedType = null; + if (type == null || ((resolvedType = type.resolve()) == null)) { + throw new Exception("Unable to resolve type."); + } + + // open tab, store type information, start decompilation + if (sameTitledOpen != null) { + sameTitledOpen.path = path; + sameTitledOpen.invalidateContent(); + sameTitledOpen.setDecompilerReferences(metadataSystem, settings, decompilationOptions); + sameTitledOpen.setType(resolvedType); + sameTitledOpen.setInitialNavigationLink(navigatonLink); + sameTitledOpen.resetScrollPosition(); + sameTitledOpen.decompile(); + addOrSwitchToTab(sameTitledOpen); + } else { + OpenFile open = new OpenFile(tabTitle, path, getTheme(), mainWindow); + open.setDecompilerReferences(metadataSystem, settings, decompilationOptions); + open.setType(resolvedType); + open.setInitialNavigationLink(navigatonLink); + open.decompile(); + hmap.add(open); + addOrSwitchToTab(open); + } + } + + public void extractSimpleFileEntryToTextPane(InputStream inputStream, String tabTitle, String path) + throws Exception { + if (inputStream == null || tabTitle == null || tabTitle.trim().length() < 1 || path == null) { + throw new FileEntryNotFoundException(); + } + OpenFile sameTitledOpen = null; + for (OpenFile nextOpen : hmap) { + if (tabTitle.equals(nextOpen.name) && path.equals(nextOpen.path)) { + sameTitledOpen = nextOpen; + break; + } + } + if (sameTitledOpen != null) { + addOrSwitchToTab(sameTitledOpen); + return; + } + + // build tab content + StringBuilder sb = new StringBuilder(); + long nonprintableCharactersCount = 0; + try (InputStreamReader inputStreamReader = new InputStreamReader(inputStream); + BufferedReader reader = new BufferedReader(inputStreamReader);) { + String line; + while ((line = reader.readLine()) != null) { + sb.append(line).append("\n"); + + for (byte nextByte : line.getBytes()) { + if (nextByte <= 0) { + nonprintableCharactersCount++; + } + } + + } + } + + // guess binary or text + String extension = "." + tabTitle.replaceAll("^[^\\.]*$", "").replaceAll("[^\\.]*\\.", ""); + boolean isTextFile = (OpenFile.WELL_KNOWN_TEXT_FILE_EXTENSIONS.contains(extension) + || nonprintableCharactersCount < sb.length() / 5); + if (!isTextFile) { + throw new FileIsBinaryException(); + } + + // open tab + if (sameTitledOpen != null) { + sameTitledOpen.path = path; + sameTitledOpen.setDecompilerReferences(metadataSystem, settings, decompilationOptions); + sameTitledOpen.resetScrollPosition(); + sameTitledOpen.setContent(sb.toString()); + addOrSwitchToTab(sameTitledOpen); + } else { + OpenFile open = new OpenFile(tabTitle, path, getTheme(), mainWindow); + open.setDecompilerReferences(metadataSystem, settings, decompilationOptions); + open.setContent(sb.toString()); + hmap.add(open); + addOrSwitchToTab(open); + } + } + + private class TabChangeListener implements ChangeListener { + @Override + public void stateChanged(ChangeEvent e) { + int selectedIndex = house.getSelectedIndex(); + if (selectedIndex < 0) { + return; + } + for (OpenFile open : hmap) { + if (house.indexOfTab(open.name) == selectedIndex) { + + if (open.getType() != null && !open.isContentValid()) { + updateOpenClass(open); + break; + } + + } + } + } + } + + public void updateOpenClasses() { + // invalidate all open classes (update will hapen at tab change) + for (OpenFile open : hmap) { + if (open.getType() != null) { + open.invalidateContent(); + } + } + // update the current open tab - if it is a class + for (OpenFile open : hmap) { + if (open.getType() != null && isTabInForeground(open)) { + updateOpenClass(open); + break; + } + } + } + + private void updateOpenClass(final OpenFile open) { + if (open.getType() == null) { + return; + } + new Thread(new Runnable() { + @Override + public void run() { + try { + bar.setVisible(true); + getLabel().setText("Extracting: " + open.name); + open.invalidateContent(); + open.decompile(); + getLabel().setText("Complete"); + } catch (Exception e) { + getLabel().setText("Error, cannot update: " + open.name); + } finally { + bar.setVisible(false); + } + } + }).start(); + } + + private boolean isTabInForeground(OpenFile open) { + String title = open.name; + int selectedIndex = house.getSelectedIndex(); + return (selectedIndex >= 0 && selectedIndex == house.indexOfTab(title)); + } + + final class State implements AutoCloseable { + private final String key; + private final File file; + final JarFile jarFile; + final ITypeLoader typeLoader; + + private State(String key, File file, JarFile jarFile, ITypeLoader typeLoader) { + this.key = VerifyArgument.notNull(key, "key"); + this.file = VerifyArgument.notNull(file, "file"); + this.jarFile = jarFile; + this.typeLoader = typeLoader; + } + + @Override + public void close() { + if (typeLoader != null) { + Model.typeLoader.getTypeLoaders().remove(typeLoader); + } + Closer.tryClose(jarFile); + } + + public File getFile() { + return file; + } + + public String getKey() { + return key; + } + } + + private class Tab extends JPanel { + private static final long serialVersionUID = -514663009333644974L; + private JLabel closeButton = new JLabel(new ImageIcon( + Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/resources/icon_close.png")))); + private JLabel tabTitle = new JLabel(); + private String title = ""; + + public Tab(String t) { + super(new GridBagLayout()); + this.setOpaque(false); + + this.title = t; + this.tabTitle = new JLabel(title); + + this.createTab(); + } + + public JLabel getButton() { + return this.closeButton; + } + + public void createTab() { + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 1; + this.add(tabTitle, gbc); + gbc.gridx++; + gbc.insets = new Insets(0, 5, 0, 0); + gbc.anchor = GridBagConstraints.EAST; + this.add(closeButton, gbc); + } + } + + private class CloseTab extends MouseAdapter { + String title; + + public CloseTab(String title) { + this.title = title; + } + + @Override + public void mouseClicked(MouseEvent e) { + int index = house.indexOfTab(title); + closeOpenTab(index); + } + } + + public DefaultMutableTreeNode loadNodesByNames(DefaultMutableTreeNode node, List originalNames) { + List args = new ArrayList<>(); + for (String originalName : originalNames) { + args.add(new TreeNodeUserObject(originalName)); + } + return loadNodesByUserObj(node, args); + } + + public DefaultMutableTreeNode loadNodesByUserObj(DefaultMutableTreeNode node, List args) { + if (args.size() > 0) { + TreeNodeUserObject name = args.remove(0); + DefaultMutableTreeNode nod = getChild(node, name); + if (nod == null) + nod = new DefaultMutableTreeNode(name); + node.add(loadNodesByUserObj(nod, args)); + } + return node; + } + + @SuppressWarnings("unchecked") + public DefaultMutableTreeNode getChild(DefaultMutableTreeNode node, TreeNodeUserObject name) { + Enumeration entry = node.children(); + while (entry.hasMoreElements()) { + DefaultMutableTreeNode nods = entry.nextElement(); + if (((TreeNodeUserObject) nods.getUserObject()).getOriginalName().equals(name.getOriginalName())) { + return nods; + } + } + return null; + } + + public void loadFile(File file) { + if (open) + closeFile(); + this.file = file; + + RecentFiles.add(file.getAbsolutePath()); + mainWindow.mainMenuBar.updateRecentFiles(); + loadTree(); + } + + public void updateTree() { + TreeUtil treeUtil = new TreeUtil(tree); + treeExpansionState = treeUtil.getExpansionState(); + loadTree(); + } + + public void loadTree() { + new Thread(new Runnable() { + @Override + public void run() { + try { + if (file == null) { + return; + } + tree.setModel(new DefaultTreeModel(null)); + + if (file.length() > MAX_JAR_FILE_SIZE_BYTES) { + throw new TooLargeFileException(file.length()); + } + if (file.getName().endsWith(".zip") || file.getName().endsWith(".jar")) { + JarFile jfile; + jfile = new JarFile(file); + getLabel().setText("Loading: " + jfile.getName()); + bar.setVisible(true); + + JarEntryFilter jarEntryFilter = new JarEntryFilter(jfile); + List mass = null; + if (luytenPrefs.isFilterOutInnerClassEntries()) { + mass = jarEntryFilter.getEntriesWithoutInnerClasses(); + } else { + mass = jarEntryFilter.getAllEntriesFromJar(); + } + buildTreeFromMass(mass); + + if (state == null) { + ITypeLoader jarLoader = new JarTypeLoader(jfile); + typeLoader.getTypeLoaders().add(jarLoader); + state = new State(file.getCanonicalPath(), file, jfile, jarLoader); + } + open = true; + getLabel().setText("Complete"); + } else { + TreeNodeUserObject topNodeUserObject = new TreeNodeUserObject(getName(file.getName())); + final DefaultMutableTreeNode top = new DefaultMutableTreeNode(topNodeUserObject); + tree.setModel(new DefaultTreeModel(top)); + settings.setTypeLoader(new InputTypeLoader()); + open = true; + getLabel().setText("Complete"); + + // open it automatically + new Thread() { + public void run() { + TreePath trp = new TreePath(top.getPath()); + openEntryByTreePath(trp); + }; + }.start(); + } + + if (treeExpansionState != null) { + try { + TreeUtil treeUtil = new TreeUtil(tree); + treeUtil.restoreExpanstionState(treeExpansionState); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + } catch (TooLargeFileException e) { + getLabel().setText("File is too large: " + file.getName() + " - size: " + e.getReadableFileSize()); + closeFile(); + } catch (Exception e1) { + Luyten.showExceptionDialog("Cannot open " + file.getName() + "!", e1); + getLabel().setText("Cannot open: " + file.getName()); + closeFile(); + } finally { + mainWindow.onFileLoadEnded(file, open); + bar.setVisible(false); + } + } + + }).start(); + } + + private void buildTreeFromMass(List mass) { + if (luytenPrefs.isPackageExplorerStyle()) { + buildFlatTreeFromMass(mass); + } else { + buildDirectoryTreeFromMass(mass); + } + } + + private void buildDirectoryTreeFromMass(List mass) { + TreeNodeUserObject topNodeUserObject = new TreeNodeUserObject(getName(file.getName())); + DefaultMutableTreeNode top = new DefaultMutableTreeNode(topNodeUserObject); + List sort = new ArrayList(); + Collections.sort(mass, String.CASE_INSENSITIVE_ORDER); + for (String m : mass) + if (m.contains("META-INF") && !sort.contains(m)) + sort.add(m); + Set set = new HashSet(); + for (String m : mass) { + if (m.contains("/")) { + set.add(m.substring(0, m.lastIndexOf("/") + 1)); + } + } + List packs = Arrays.asList(set.toArray(new String[] {})); + Collections.sort(packs, String.CASE_INSENSITIVE_ORDER); + Collections.sort(packs, new Comparator() { + public int compare(String o1, String o2) { + return o2.split("/").length - o1.split("/").length; + } + }); + for (String pack : packs) + for (String m : mass) + if (!m.contains("META-INF") && m.contains(pack) && !m.replace(pack, "").contains("/")) + sort.add(m); + for (String m : mass) + if (!m.contains("META-INF") && !m.contains("/") && !sort.contains(m)) + sort.add(m); + for (String pack : sort) { + LinkedList list = new LinkedList(Arrays.asList(pack.split("/"))); + loadNodesByNames(top, list); + } + tree.setModel(new DefaultTreeModel(top)); + } + + private void buildFlatTreeFromMass(List mass) { + TreeNodeUserObject topNodeUserObject = new TreeNodeUserObject(getName(file.getName())); + DefaultMutableTreeNode top = new DefaultMutableTreeNode(topNodeUserObject); + + TreeMap> packages = new TreeMap<>(); + HashSet classContainingPackageRoots = new HashSet<>(); + + Comparator sortByFileExtensionsComparator = new Comparator() { + // (assertion: mass does not contain null elements) + @Override + public int compare(String o1, String o2) { + int comp = o1.replaceAll("[^\\.]*\\.", "").compareTo(o2.replaceAll("[^\\.]*\\.", "")); + if (comp != 0) + return comp; + return o1.compareTo(o2); + } + }; + + for (String entry : mass) { + String packagePath = ""; + String packageRoot = ""; + if (entry.contains("/")) { + packagePath = entry.replaceAll("/[^/]*$", ""); + packageRoot = entry.replaceAll("/.*$", ""); + } + String packageEntry = entry.replace(packagePath + "/", ""); + if (!packages.containsKey(packagePath)) { + packages.put(packagePath, new TreeSet(sortByFileExtensionsComparator)); + } + packages.get(packagePath).add(packageEntry); + if (!entry.startsWith("META-INF") && packageRoot.trim().length() > 0 + && entry.matches(".*\\.(class|java|prop|properties)$")) { + classContainingPackageRoots.add(packageRoot); + } + } + + // META-INF comes first -> not flat + for (String packagePath : packages.keySet()) { + if (packagePath.startsWith("META-INF")) { + List packagePathElements = Arrays.asList(packagePath.split("/")); + for (String entry : packages.get(packagePath)) { + ArrayList list = new ArrayList<>(packagePathElements); + list.add(entry); + loadNodesByNames(top, list); + } + } + } + + // real packages: path starts with a classContainingPackageRoot -> flat + for (String packagePath : packages.keySet()) { + String packageRoot = packagePath.replaceAll("/.*$", ""); + if (classContainingPackageRoots.contains(packageRoot)) { + for (String entry : packages.get(packagePath)) { + ArrayList list = new ArrayList<>(); + list.add(new TreeNodeUserObject(packagePath, packagePath.replaceAll("/", "."))); + list.add(new TreeNodeUserObject(entry)); + loadNodesByUserObj(top, list); + } + } + } + + // the rest, not real packages but directories -> not flat + for (String packagePath : packages.keySet()) { + String packageRoot = packagePath.replaceAll("/.*$", ""); + if (!classContainingPackageRoots.contains(packageRoot) && !packagePath.startsWith("META-INF") + && packagePath.length() > 0) { + List packagePathElements = Arrays.asList(packagePath.split("/")); + for (String entry : packages.get(packagePath)) { + ArrayList list = new ArrayList<>(packagePathElements); + list.add(entry); + loadNodesByNames(top, list); + } + } + } + + // the default package -> not flat + String packagePath = ""; + if (packages.containsKey(packagePath)) { + for (String entry : packages.get(packagePath)) { + ArrayList list = new ArrayList<>(); + list.add(entry); + loadNodesByNames(top, list); + } + } + tree.setModel(new DefaultTreeModel(top)); + } + + public void closeFile() { + for (OpenFile co : hmap) { + int pos = house.indexOfTab(co.name); + if (pos >= 0) + house.remove(pos); + co.close(); + } + + final State oldState = state; + Model.this.state = null; + if (oldState != null) { + Closer.tryClose(oldState); + } + + hmap.clear(); + tree.setModel(new DefaultTreeModel(null)); + metadataSystem = new MetadataSystem(typeLoader); + file = null; + treeExpansionState = null; + open = false; + mainWindow.onFileLoadEnded(file, open); + } + + public void changeTheme(String xml) { + InputStream in = getClass().getResourceAsStream(LuytenPreferences.THEME_XML_PATH + xml); + try { + if (in != null) { + setTheme(Theme.load(in)); + for (OpenFile f : hmap) { + getTheme().apply(f.textArea); + } + } + } catch (Exception e1) { + Luyten.showExceptionDialog("Exception!", e1); + } + } + + public File getOpenedFile() { + File openedFile = null; + if (file != null && open) { + openedFile = file; + } + if (openedFile == null) { + getLabel().setText("No open file"); + } + return openedFile; + } + + public String getCurrentTabTitle() { + String tabTitle = null; + try { + int pos = house.getSelectedIndex(); + if (pos >= 0) { + tabTitle = house.getTitleAt(pos); + } + } catch (Exception e1) { + Luyten.showExceptionDialog("Exception!", e1); + } + if (tabTitle == null) { + getLabel().setText("No open tab"); + } + return tabTitle; + } + + public RSyntaxTextArea getCurrentTextArea() { + RSyntaxTextArea currentTextArea = null; + try { + int pos = house.getSelectedIndex(); + System.out.println(pos); + if (pos >= 0) { + RTextScrollPane co = (RTextScrollPane) house.getComponentAt(pos); + currentTextArea = (RSyntaxTextArea) co.getViewport().getView(); + } + } catch (Exception e1) { + Luyten.showExceptionDialog("Exception!", e1); + } + if (currentTextArea == null) { + getLabel().setText("No open tab"); + } + return currentTextArea; + } + + public void startWarmUpThread() { + new Thread() { + public void run() { + try { + Thread.sleep(500); + String internalName = FindBox.class.getName(); + TypeReference type = metadataSystem.lookupType(internalName); + TypeDefinition resolvedType = null; + if ((type == null) || ((resolvedType = type.resolve()) == null)) { + return; + } + StringWriter stringwriter = new StringWriter(); + PlainTextOutput plainTextOutput = new PlainTextOutput(stringwriter); + plainTextOutput + .setUnicodeOutputEnabled(decompilationOptions.getSettings().isUnicodeOutputEnabled()); + settings.getLanguage().decompileType(resolvedType, plainTextOutput, decompilationOptions); + String decompiledSource = stringwriter.toString(); + OpenFile open = new OpenFile(internalName, "*/" + internalName, getTheme(), mainWindow); + open.setContent(decompiledSource); + JTabbedPane pane = new JTabbedPane(); + pane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); + pane.addTab("title", open.scrollPane); + pane.setSelectedIndex(pane.indexOfTab("title")); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + }.start(); + } + + public void navigateTo(final String uniqueStr) { + new Thread(new Runnable() { + @Override + public void run() { + if (uniqueStr == null) + return; + String[] linkParts = uniqueStr.split("\\|"); + if (linkParts.length <= 1) + return; + String destinationTypeStr = linkParts[1]; + try { + bar.setVisible(true); + getLabel().setText("Navigating: " + destinationTypeStr.replaceAll("/", ".")); + + TypeReference type = metadataSystem.lookupType(destinationTypeStr); + if (type == null) + throw new RuntimeException("Cannot lookup type: " + destinationTypeStr); + TypeDefinition typeDef = type.resolve(); + if (typeDef == null) + throw new RuntimeException("Cannot resolve type: " + destinationTypeStr); + + String tabTitle = typeDef.getName() + ".class"; + extractClassToTextPane(typeDef, tabTitle, destinationTypeStr, uniqueStr); + + getLabel().setText("Complete"); + } catch (Exception e) { + getLabel().setText("Cannot navigate: " + destinationTypeStr.replaceAll("/", ".")); + Luyten.showExceptionDialog("Cannot Navigate!", e); + } finally { + bar.setVisible(false); + } + } + }).start(); + } + + public JLabel getLabel() { + return label; + } + + public void setLabel(JLabel label) { + this.label = label; + } + + public State getState() { + return state; + } + + public Theme getTheme() { + return theme; + } + + public void setTheme(Theme theme) { + this.theme = theme; + } + +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/OpenFile.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/OpenFile.java new file mode 100644 index 0000000..497db07 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/OpenFile.java @@ -0,0 +1,844 @@ +package us.deathmarine.luyten; + +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Font; +import java.awt.Panel; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; + +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JScrollBar; +import javax.swing.JViewport; +import javax.swing.ScrollPaneConstants; +import javax.swing.Scrollable; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.event.HyperlinkEvent; +import org.fife.ui.rsyntaxtextarea.LinkGenerator; +import org.fife.ui.rsyntaxtextarea.LinkGeneratorResult; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rsyntaxtextarea.Theme; +import org.fife.ui.rtextarea.RTextScrollPane; + +import com.strobel.assembler.metadata.MetadataSystem; +import com.strobel.assembler.metadata.TypeDefinition; +import com.strobel.decompiler.DecompilationOptions; +import com.strobel.decompiler.DecompilerSettings; +import com.strobel.decompiler.PlainTextOutput; +import com.strobel.decompiler.languages.Languages; + +public class OpenFile implements SyntaxConstants { + + public static final HashSet WELL_KNOWN_TEXT_FILE_EXTENSIONS = new HashSet<>( + Arrays.asList(".java", ".xml", ".rss", ".project", ".classpath", ".h", ".c", ".cpp", ".yaml", ".yml", ".ini", ".sql", ".js", ".php", ".php5", + ".phtml", ".html", ".htm", ".xhtm", ".xhtml", ".lua", ".bat", ".pl", ".sh", ".css", ".json", ".txt", + ".rb", ".make", ".mak", ".py", ".properties", ".prop")); + + // navigation links + private TreeMap selectionToUniqueStrTreeMap = new TreeMap<>(); + private Map isNavigableCache = new ConcurrentHashMap<>(); + private Map readableLinksCache = new ConcurrentHashMap<>(); + + private volatile boolean isContentValid = false; + private volatile boolean isNavigationLinksValid = false; + private volatile boolean isWaitForLinksCursor = false; + private volatile Double lastScrollPercent = null; + + private LinkProvider linkProvider; + private String initialNavigationLink; + private boolean isFirstTimeRun = true; + + MainWindow mainWindow; + RTextScrollPane scrollPane; + Panel image_pane; + RSyntaxTextArea textArea; + String name; + String path; + + private ConfigSaver configSaver; + private LuytenPreferences luytenPrefs; + + // decompiler and type references (not needed for text files) + private MetadataSystem metadataSystem; + private DecompilerSettings settings; + private DecompilationOptions decompilationOptions; + private TypeDefinition type; + + public OpenFile(String name, String path, Theme theme, final MainWindow mainWindow) { + this.name = name; + this.path = path; + this.mainWindow = mainWindow; + + configSaver = ConfigSaver.getLoadedInstance(); + luytenPrefs = configSaver.getLuytenPreferences(); + + textArea = new RSyntaxTextArea(25, 70); + textArea.setCaretPosition(0); + textArea.requestFocusInWindow(); + textArea.setMarkOccurrences(true); + textArea.setClearWhitespaceLinesEnabled(false); + textArea.setEditable(false); + textArea.setAntiAliasingEnabled(true); + textArea.setCodeFoldingEnabled(true); + + if (name.toLowerCase().endsWith(".class") || name.toLowerCase().endsWith(".java")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_JAVA); + else if (name.toLowerCase().endsWith(".xml") || name.toLowerCase().endsWith(".rss") + || name.toLowerCase().endsWith(".project") || name.toLowerCase().endsWith(".classpath")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_XML); + else if (name.toLowerCase().endsWith(".h") || name.toLowerCase().endsWith(".c")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_C); + else if (name.toLowerCase().endsWith(".cpp")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_CPLUSPLUS); + else if (name.toLowerCase().endsWith(".sql")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_SQL); + else if (name.toLowerCase().endsWith(".js")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_JAVASCRIPT); + else if (name.toLowerCase().endsWith(".php") || name.toLowerCase().endsWith(".php5") + || name.toLowerCase().endsWith(".phtml")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_PHP); + else if (name.toLowerCase().endsWith(".html") || name.toLowerCase().endsWith(".htm") + || name.toLowerCase().endsWith(".xhtm") || name.toLowerCase().endsWith(".xhtml")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_HTML); + else if (name.toLowerCase().endsWith(".js")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_JAVASCRIPT); + else if (name.toLowerCase().endsWith(".lua")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_LUA); + else if (name.toLowerCase().endsWith(".bat")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_WINDOWS_BATCH); + else if (name.toLowerCase().endsWith(".pl")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_PERL); + else if (name.toLowerCase().endsWith(".sh")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_UNIX_SHELL); + else if (name.toLowerCase().endsWith(".css")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_CSS); + else if (name.toLowerCase().endsWith(".json")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_JSON); + else if (name.toLowerCase().endsWith(".ini")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_INI); + else if (name.toLowerCase().endsWith(".yaml") || name.toLowerCase().endsWith(".yml")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_YAML); + else if (name.toLowerCase().endsWith(".rb")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_RUBY); + else if (name.toLowerCase().endsWith(".make") || name.toLowerCase().endsWith(".mak")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_MAKEFILE); + else if (name.toLowerCase().endsWith(".py")) + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_PYTHON); + else + textArea.setSyntaxEditingStyle(SYNTAX_STYLE_NONE); + scrollPane = new RTextScrollPane(textArea, true); + + scrollPane.setIconRowHeaderEnabled(true); + textArea.setText(""); + + // Edit RTextArea's PopupMenu + JPopupMenu pop = textArea.getPopupMenu(); + pop.addSeparator(); + JMenuItem item = new JMenuItem("Font"); + item.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFontChooser fontChooser = new JFontChooser(); + fontChooser.setSelectedFont(textArea.getFont()); + fontChooser.setSelectedFontSize(textArea.getFont().getSize()); + int result = fontChooser.showDialog(mainWindow); + if (result == JFontChooser.OK_OPTION) { + textArea.setFont(fontChooser.getSelectedFont()); + luytenPrefs.setFont_size(fontChooser.getSelectedFontSize()); + } + } + }); + pop.add(item); + textArea.setPopupMenu(pop); + + theme.apply(textArea); + + textArea.setFont(new Font(textArea.getFont().getName(), textArea.getFont().getStyle(), luytenPrefs.getFont_size())); + + scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + final JScrollBar verticalScrollbar = scrollPane.getVerticalScrollBar(); + if (verticalScrollbar != null) { + verticalScrollbar.addAdjustmentListener(new AdjustmentListener() { + @Override + public void adjustmentValueChanged(AdjustmentEvent e) { + String content = textArea.getText(); + if (content == null || content.length() == 0) + return; + int scrollValue = verticalScrollbar.getValue() - verticalScrollbar.getMinimum(); + int scrollMax = verticalScrollbar.getMaximum() - verticalScrollbar.getMinimum(); + if (scrollMax < 1 || scrollValue < 0 || scrollValue > scrollMax) + return; + lastScrollPercent = (((double) scrollValue) / ((double) scrollMax)); + } + }); + } + + textArea.setHyperlinksEnabled(true); + textArea.setLinkScanningMask(Keymap.ctrlDownModifier()); + + textArea.setLinkGenerator(new LinkGenerator() { + @Override + public LinkGeneratorResult isLinkAtOffset(RSyntaxTextArea textArea, final int offs) { + final String uniqueStr = getUniqueStrForOffset(offs); + final Integer selectionFrom = getSelectionFromForOffset(offs); + if (uniqueStr != null && selectionFrom != null) { + return new LinkGeneratorResult() { + @Override + public HyperlinkEvent execute() { + if (isNavigationLinksValid) + onNavigationClicked(uniqueStr); + return null; + } + + @Override + public int getSourceOffset() { + if (isNavigationLinksValid) + return selectionFrom; + return offs; + } + }; + } + return null; + } + }); + + /* + * Add Ctrl+Wheel Zoom for Text Size Removes all standard listeners and + * writes new listeners for wheelscroll movement. + */ + for (MouseWheelListener listeners : scrollPane.getMouseWheelListeners()) { + scrollPane.removeMouseWheelListener(listeners); + } + ; + scrollPane.addMouseWheelListener(new MouseWheelListener() { + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (e.getWheelRotation() == 0) { + // Nothing to do here. This happens when scroll event is delivered from a touchbar + // or MagicMouse. There's getPreciseWheelRotation, however it looks like there's no + // trivial and consistent way to use that + // See https://github.com/JetBrains/intellij-community/blob/21c99af7c78fc82aefc4d05646389f4991b08b38/bin/idea.properties#L133-L156 + return; + } + + if ((e.getModifiersEx() & Keymap.ctrlDownModifier()) != 0) { + Font font = textArea.getFont(); + int size = font.getSize(); + if (e.getWheelRotation() > 0) { + textArea.setFont(new Font(font.getName(), font.getStyle(), --size >= 8 ? --size : 8)); + } else { + textArea.setFont(new Font(font.getName(), font.getStyle(), ++size)); + } + luytenPrefs.setFont_size(size); + } else { + if (scrollPane.isWheelScrollingEnabled() && e.getWheelRotation() != 0) { + JScrollBar toScroll = scrollPane.getVerticalScrollBar(); + int direction = e.getWheelRotation() < 0 ? -1 : 1; + int orientation = SwingConstants.VERTICAL; + if (toScroll == null || !toScroll.isVisible()) { + toScroll = scrollPane.getHorizontalScrollBar(); + if (toScroll == null || !toScroll.isVisible()) { + return; + } + orientation = SwingConstants.HORIZONTAL; + } + e.consume(); + + if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { + JViewport vp = scrollPane.getViewport(); + if (vp == null) { + return; + } + Component comp = vp.getView(); + int units = Math.abs(e.getUnitsToScroll()); + boolean limitScroll = Math.abs(e.getWheelRotation()) == 1; + Object fastWheelScroll = toScroll.getClientProperty("JScrollBar.fastWheelScrolling"); + if (Boolean.TRUE == fastWheelScroll && comp instanceof Scrollable) { + Scrollable scrollComp = (Scrollable) comp; + Rectangle viewRect = vp.getViewRect(); + int startingX = viewRect.x; + boolean leftToRight = comp.getComponentOrientation().isLeftToRight(); + int scrollMin = toScroll.getMinimum(); + int scrollMax = toScroll.getMaximum() - toScroll.getModel().getExtent(); + + if (limitScroll) { + int blockIncr = scrollComp.getScrollableBlockIncrement(viewRect, orientation, + direction); + if (direction < 0) { + scrollMin = Math.max(scrollMin, toScroll.getValue() - blockIncr); + } else { + scrollMax = Math.min(scrollMax, toScroll.getValue() + blockIncr); + } + } + + for (int i = 0; i < units; i++) { + int unitIncr = scrollComp.getScrollableUnitIncrement(viewRect, orientation, + direction); + if (orientation == SwingConstants.VERTICAL) { + if (direction < 0) { + viewRect.y -= unitIncr; + if (viewRect.y <= scrollMin) { + viewRect.y = scrollMin; + break; + } + } else { // (direction > 0 + viewRect.y += unitIncr; + if (viewRect.y >= scrollMax) { + viewRect.y = scrollMax; + break; + } + } + } else { + if ((leftToRight && direction < 0) || (!leftToRight && direction > 0)) { + viewRect.x -= unitIncr; + if (leftToRight) { + if (viewRect.x < scrollMin) { + viewRect.x = scrollMin; + break; + } + } + } else if ((leftToRight && direction > 0) || (!leftToRight && direction < 0)) { + viewRect.x += unitIncr; + if (leftToRight) { + if (viewRect.x > scrollMax) { + viewRect.x = scrollMax; + break; + } + } + } else { + assert false : "Non-sensical ComponentOrientation / scroll direction"; + } + } + } + if (orientation == SwingConstants.VERTICAL) { + toScroll.setValue(viewRect.y); + } else { + if (leftToRight) { + toScroll.setValue(viewRect.x); + } else { + int newPos = toScroll.getValue() - (viewRect.x - startingX); + if (newPos < scrollMin) { + newPos = scrollMin; + } else if (newPos > scrollMax) { + newPos = scrollMax; + } + toScroll.setValue(newPos); + } + } + } else { + int delta; + int limit = -1; + + if (limitScroll) { + if (direction < 0) { + limit = toScroll.getValue() - toScroll.getBlockIncrement(direction); + } else { + limit = toScroll.getValue() + toScroll.getBlockIncrement(direction); + } + } + + for (int i = 0; i < units; i++) { + if (direction > 0) { + delta = toScroll.getUnitIncrement(direction); + } else { + delta = -toScroll.getUnitIncrement(direction); + } + int oldValue = toScroll.getValue(); + int newValue = oldValue + delta; + if (delta > 0 && newValue < oldValue) { + newValue = toScroll.getMaximum(); + } else if (delta < 0 && newValue > oldValue) { + newValue = toScroll.getMinimum(); + } + if (oldValue == newValue) { + break; + } + if (limitScroll && i > 0) { + assert limit != -1; + if ((direction < 0 && newValue < limit) + || (direction > 0 && newValue > limit)) { + break; + } + } + toScroll.setValue(newValue); + } + + } + } else if (e.getScrollType() == MouseWheelEvent.WHEEL_BLOCK_SCROLL) { + int oldValue = toScroll.getValue(); + int blockIncrement = toScroll.getBlockIncrement(direction); + int delta = blockIncrement * ((direction > 0) ? +1 : -1); + int newValue = oldValue + delta; + if (delta > 0 && newValue < oldValue) { + newValue = toScroll.getMaximum(); + } else if (delta < 0 && newValue > oldValue) { + newValue = toScroll.getMinimum(); + } + toScroll.setValue(newValue); + } + } + } + + e.consume(); + } + }); + + textArea.addMouseMotionListener(new MouseMotionAdapter() { + private boolean isLinkLabelPrev = false; + private String prevLinkText = null; + + @Override + public synchronized void mouseMoved(MouseEvent e) { + String linkText = null; + boolean isLinkLabel = false; + boolean isCtrlDown = (e.getModifiersEx() & Keymap.ctrlDownModifier()) != 0; + if (isCtrlDown) { + linkText = createLinkLabel(e); + isLinkLabel = linkText != null; + } + if (isCtrlDown && isWaitForLinksCursor) { + textArea.setCursor(new Cursor(Cursor.WAIT_CURSOR)); + } else if (textArea.getCursor().getType() == Cursor.WAIT_CURSOR) { + textArea.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + } + + JLabel label = OpenFile.this.mainWindow.getLabel(); + + if (isLinkLabel && isLinkLabelPrev) { + if (!linkText.equals(prevLinkText)) { + setLinkLabel(label, linkText); + } + } else if (isLinkLabel && !isLinkLabelPrev) { + setLinkLabel(label, linkText); + + } else if (!isLinkLabel && isLinkLabelPrev) { + setLinkLabel(label, null); + } + isLinkLabelPrev = isLinkLabel; + prevLinkText = linkText; + } + + private void setLinkLabel(JLabel label, String text) { + String current = label.getText(); + if (text == null && current != null) + if (current.startsWith("Navigating:") || current.startsWith("Cannot navigate:")) + return; + label.setText(text != null ? text : "Complete"); + } + + private String createLinkLabel(MouseEvent e) { + int offs = textArea.viewToModel(e.getPoint()); + if (isNavigationLinksValid) { + return getLinkDescriptionForOffset(offs); + } + return null; + } + }); + } + + public void setContent(String content) { + textArea.setText(content); + } + + public void decompile() { + this.invalidateContent(); + // synchronized: do not accept changes from menu while running + synchronized (settings) { + if (Languages.java().getName().equals(settings.getLanguage().getName())) { + decompileWithNavigationLinks(); + } else { + decompileWithoutLinks(); + } + } + } + + private void decompileWithoutLinks() { + this.invalidateContent(); + isNavigationLinksValid = false; + textArea.setHyperlinksEnabled(false); + + StringWriter stringwriter = new StringWriter(); + PlainTextOutput plainTextOutput = new PlainTextOutput(stringwriter); + plainTextOutput.setUnicodeOutputEnabled(decompilationOptions.getSettings().isUnicodeOutputEnabled()); + settings.getLanguage().decompileType(type, plainTextOutput, decompilationOptions); + setContentPreserveLastScrollPosition(stringwriter.toString()); + this.isContentValid = true; + } + + private void decompileWithNavigationLinks() { + this.invalidateContent(); + DecompilerLinkProvider newLinkProvider = new DecompilerLinkProvider(); + newLinkProvider.setDecompilerReferences(metadataSystem, settings, decompilationOptions); + newLinkProvider.setType(type); + linkProvider = newLinkProvider; + + linkProvider.generateContent(); + setContentPreserveLastScrollPosition(linkProvider.getTextContent()); + this.isContentValid = true; + enableLinks(); + } + + private void setContentPreserveLastScrollPosition(final String content) { + final Double scrollPercent = lastScrollPercent; + if (scrollPercent != null && initialNavigationLink == null) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + textArea.setText(content); + restoreScrollPosition(scrollPercent); + } + }); + } else { + textArea.setText(content); + } + } + + private void restoreScrollPosition(final double position) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JScrollBar verticalScrollbar = scrollPane.getVerticalScrollBar(); + if (verticalScrollbar == null) + return; + int scrollMax = verticalScrollbar.getMaximum() - verticalScrollbar.getMinimum(); + long newScrollValue = Math.round(position * scrollMax) + verticalScrollbar.getMinimum(); + if (newScrollValue < verticalScrollbar.getMinimum()) + newScrollValue = verticalScrollbar.getMinimum(); + if (newScrollValue > verticalScrollbar.getMaximum()) + newScrollValue = verticalScrollbar.getMaximum(); + verticalScrollbar.setValue((int) newScrollValue); + } + }); + } + + private void enableLinks() { + if (initialNavigationLink != null) { + doEnableLinks(); + } else { + new Thread(new Runnable() { + @Override + public void run() { + try { + isWaitForLinksCursor = true; + doEnableLinks(); + } finally { + isWaitForLinksCursor = false; + resetCursor(); + } + } + }).start(); + } + } + + private void resetCursor() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + textArea.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + } + }); + } + + private void doEnableLinks() { + isNavigationLinksValid = false; + linkProvider.processLinks(); + buildSelectionToUniqueStrTreeMap(); + clearLinksCache(); + isNavigationLinksValid = true; + textArea.setHyperlinksEnabled(true); + warmUpWithFirstLink(); + } + + private void warmUpWithFirstLink() { + if (selectionToUniqueStrTreeMap.keySet().size() > 0) { + Selection selection = selectionToUniqueStrTreeMap.keySet().iterator().next(); + getLinkDescriptionForOffset(selection.from); + } + } + + public void clearLinksCache() { + try { + isNavigableCache.clear(); + readableLinksCache.clear(); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + private void buildSelectionToUniqueStrTreeMap() { + TreeMap treeMap = new TreeMap<>(); + Map definitionToSelectionMap = linkProvider.getDefinitionToSelectionMap(); + Map> referenceToSelectionsMap = linkProvider.getReferenceToSelectionsMap(); + + for (String key : definitionToSelectionMap.keySet()) { + Selection selection = definitionToSelectionMap.get(key); + treeMap.put(selection, key); + } + for (String key : referenceToSelectionsMap.keySet()) { + for (Selection selection : referenceToSelectionsMap.get(key)) { + treeMap.put(selection, key); + } + } + selectionToUniqueStrTreeMap = treeMap; + } + + private Selection getSelectionForOffset(int offset) { + if (isNavigationLinksValid) { + Selection offsetSelection = new Selection(offset, offset); + Selection floorSelection = selectionToUniqueStrTreeMap.floorKey(offsetSelection); + if (floorSelection != null && floorSelection.from <= offset && floorSelection.to > offset) { + return floorSelection; + } + } + return null; + } + + private String getUniqueStrForOffset(int offset) { + Selection selection = getSelectionForOffset(offset); + if (selection != null) { + String uniqueStr = selectionToUniqueStrTreeMap.get(selection); + if (this.isLinkNavigable(uniqueStr) && this.getLinkDescription(uniqueStr) != null) { + return uniqueStr; + } + } + return null; + } + + private Integer getSelectionFromForOffset(int offset) { + Selection selection = getSelectionForOffset(offset); + if (selection != null) { + return selection.from; + } + return null; + } + + private String getLinkDescriptionForOffset(int offset) { + String uniqueStr = getUniqueStrForOffset(offset); + if (uniqueStr != null) { + String description = this.getLinkDescription(uniqueStr); + if (description != null) { + return description; + } + } + return null; + } + + private boolean isLinkNavigable(String uniqueStr) { + try { + Boolean isNavigableCached = isNavigableCache.get(uniqueStr); + if (isNavigableCached != null) + return isNavigableCached; + + boolean isNavigable = linkProvider.isLinkNavigable(uniqueStr); + isNavigableCache.put(uniqueStr, isNavigable); + return isNavigable; + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + return false; + } + + private String getLinkDescription(String uniqueStr) { + try { + String descriptionCached = readableLinksCache.get(uniqueStr); + if (descriptionCached != null) + return descriptionCached; + + String description = linkProvider.getLinkDescription(uniqueStr); + if (description != null && description.trim().length() > 0) { + readableLinksCache.put(uniqueStr, description); + return description; + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + return null; + } + + private void onNavigationClicked(String clickedReferenceUniqueStr) { + if (isLocallyNavigable(clickedReferenceUniqueStr)) { + onLocalNavigationRequest(clickedReferenceUniqueStr); + } else if (linkProvider.isLinkNavigable(clickedReferenceUniqueStr)) { + onOutboundNavigationRequest(clickedReferenceUniqueStr); + } else { + JLabel label = this.mainWindow.getLabel(); + if (label == null) + return; + String[] linkParts = clickedReferenceUniqueStr.split("\\|"); + if (linkParts.length <= 1) { + label.setText("Cannot navigate: " + clickedReferenceUniqueStr); + return; + } + String destinationTypeStr = linkParts[1]; + label.setText("Cannot navigate: " + destinationTypeStr.replaceAll("/", ".")); + } + } + + private boolean isLocallyNavigable(String uniqueStr) { + return linkProvider.getDefinitionToSelectionMap().keySet().contains(uniqueStr); + } + + private void onLocalNavigationRequest(String uniqueStr) { + try { + Selection selection = linkProvider.getDefinitionToSelectionMap().get(uniqueStr); + doLocalNavigation(selection); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + private void doLocalNavigation(Selection selection) { + try { + textArea.requestFocusInWindow(); + if (selection != null) { + textArea.setSelectionStart(selection.from); + textArea.setSelectionEnd(selection.to); + scrollToSelection(selection.from); + } else { + textArea.setSelectionStart(0); + textArea.setSelectionEnd(0); + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + + private void scrollToSelection(final int selectionBeginningOffset) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + try { + int fullHeight = textArea.getBounds().height; + int viewportHeight = textArea.getVisibleRect().height; + int viewportLineCount = viewportHeight / textArea.getLineHeight(); + int selectionLineNum = textArea.getLineOfOffset(selectionBeginningOffset); + int upperMarginToScroll = Math.round(viewportLineCount * 0.29f); + int upperLineToSet = selectionLineNum - upperMarginToScroll; + int currentUpperLine = textArea.getVisibleRect().y / textArea.getLineHeight(); + + if (selectionLineNum <= currentUpperLine + 2 + || selectionLineNum >= currentUpperLine + viewportLineCount - 4) { + Rectangle rectToScroll = new Rectangle(); + rectToScroll.x = 0; + rectToScroll.width = 1; + rectToScroll.y = Math.max(upperLineToSet * textArea.getLineHeight(), 0); + rectToScroll.height = Math.min(viewportHeight, fullHeight - rectToScroll.y); + textArea.scrollRectToVisible(rectToScroll); + } + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + } + }); + } + + private void onOutboundNavigationRequest(String uniqueStr) { + mainWindow.onNavigationRequest(uniqueStr); + } + + public void setDecompilerReferences(MetadataSystem metadataSystem, DecompilerSettings settings, + DecompilationOptions decompilationOptions) { + this.metadataSystem = metadataSystem; + this.settings = settings; + this.decompilationOptions = decompilationOptions; + } + + public TypeDefinition getType() { + return type; + } + + public void setType(TypeDefinition type) { + this.type = type; + } + + public boolean isContentValid() { + return isContentValid; + } + + public void invalidateContent() { + try { + this.setContent(""); + } finally { + this.isContentValid = false; + this.isNavigationLinksValid = false; + } + } + + public void resetScrollPosition() { + lastScrollPercent = null; + } + + public void setInitialNavigationLink(String initialNavigationLink) { + this.initialNavigationLink = initialNavigationLink; + } + + public void onAddedToScreen() { + try { + if (initialNavigationLink != null) { + onLocalNavigationRequest(initialNavigationLink); + } else if (isFirstTimeRun) { + // warm up scrolling + isFirstTimeRun = false; + doLocalNavigation(new Selection(0, 0)); + } + } finally { + initialNavigationLink = null; + } + } + + /** + * sun.swing.CachedPainter holds on OpenFile for a while even after + * JTabbedPane.remove(component) + */ + public void close() { + linkProvider = null; + type = null; + invalidateContent(); + clearLinksCache(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((path == null) ? 0 : path.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + OpenFile other = (OpenFile) obj; + if (path == null) { + if (other.path != null) + return false; + } else if (!path.equals(other.path)) + return false; + return true; + } + +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/RecentFiles.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/RecentFiles.java new file mode 100644 index 0000000..7799d36 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/RecentFiles.java @@ -0,0 +1,66 @@ +package us.deathmarine.luyten; + +import java.io.File; +import java.util.ArrayList; +import java.util.prefs.Preferences; + +public class RecentFiles { + + public static ArrayList paths = new ArrayList<>(); + private static Preferences prefs = Preferences.userNodeForPackage(RecentFiles.class); + + public static int load() { + boolean saveNeeded = false; + + String serializedPaths = prefs.get("recentFiles", null); + + if (serializedPaths == null) return 0; + + // "test","asdf.txt","text2" + for (String path : serializedPaths.split("\",\"")) { + + path = path.replace("\"", ""); + + if (!path.trim().isEmpty() && !new File(path).exists()) saveNeeded = true; + else paths.add(path); + } + + if (saveNeeded) save(); + + return paths.size(); + } + + public static void add(String path) { + if (paths.contains(path)) { + paths.remove(path); + paths.add(path); + return; + } + + if (paths.size() >= 10) paths.remove(0); + paths.add(path); + + save(); + } + + public static void save() { + if (paths.size() == 0) { + prefs.put("recentFiles", ""); + return; + } + + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < paths.size(); i++) { + if (i != 0) sb.append(','); + + /*if (!new File(paths.get(i)).exists()) { + paths.remove(i); + continue; + }*/ + sb.append("\"").append(paths.get(i)).append("\""); + } + + prefs.put("recentFiles", sb.toString()); + } +} \ No newline at end of file diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Selection.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Selection.java new file mode 100644 index 0000000..fdf507a --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/Selection.java @@ -0,0 +1,41 @@ +package us.deathmarine.luyten; + +public class Selection implements Comparable { + public final Integer from; + public final Integer to; + + public Selection(Integer from, Integer to) { + this.from = from; + this.to = to; + } + + @Override + public int compareTo(Selection o) { + return from.compareTo(o.from); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((from == null) ? 0 : from.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Selection other = (Selection) obj; + if (from == null) { + if (other.from != null) + return false; + } else if (!from.equals(other.from)) + return false; + return true; + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/SystemInfo.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/SystemInfo.java new file mode 100644 index 0000000..77722ef --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/SystemInfo.java @@ -0,0 +1,10 @@ +package us.deathmarine.luyten; + +import java.util.Locale; + +public class SystemInfo { + private static final String OS_NAME = System.getProperty("os.name"); + private static final String OS_NAME_LOWER = OS_NAME.toLowerCase(Locale.US); + + public static boolean IS_MAC = OS_NAME_LOWER.startsWith("mac"); +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TooLargeFileException.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TooLargeFileException.java new file mode 100644 index 0000000..3dc5abb --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TooLargeFileException.java @@ -0,0 +1,20 @@ +package us.deathmarine.luyten; + +import java.text.DecimalFormat; + +public class TooLargeFileException extends Exception { + private static final long serialVersionUID = 6091096838075139962L; + private long size; + + public TooLargeFileException(long size) { + this.size = size; + } + + public String getReadableFileSize() { + if (size <= 0) + return "0"; + final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" }; + int digitGroups = (int) (Math.log10(size) / Math.log10(1024)); + return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups]; + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TreeNodeUserObject.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TreeNodeUserObject.java new file mode 100644 index 0000000..7bed250 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TreeNodeUserObject.java @@ -0,0 +1,37 @@ +package us.deathmarine.luyten; + +public class TreeNodeUserObject { + + private String originalName; + private String displayName; + + public TreeNodeUserObject(String name) { + this(name, name); + } + + public TreeNodeUserObject(String originalName, String displayName) { + this.originalName = originalName; + this.displayName = displayName; + } + + public String getOriginalName() { + return originalName; + } + + public void setOriginalName(String originalName) { + this.originalName = originalName; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + @Override + public String toString() { + return displayName; + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TreeUtil.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TreeUtil.java new file mode 100644 index 0000000..4fdb95a --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/TreeUtil.java @@ -0,0 +1,81 @@ +package us.deathmarine.luyten; + +import java.util.HashSet; +import java.util.Set; +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; + +public class TreeUtil { + + private JTree tree; + + public TreeUtil() { + } + + public TreeUtil(JTree tree) { + this.tree = tree; + } + + public Set getExpansionState() { + Set openedSet = new HashSet<>(); + if (tree != null) { + int rowCount = tree.getRowCount(); + for (int i = 0; i < rowCount; i++) { + TreePath path = tree.getPathForRow(i); + if (tree.isExpanded(path)) { + String rowPathStr = getRowPathStr(path); + // for switching Package Explorer on/off + openedSet.addAll(getAllParentPathsStr(rowPathStr)); + } + } + } + return openedSet; + } + + private Set getAllParentPathsStr(String rowPathStr) { + Set parents = new HashSet<>(); + parents.add(rowPathStr); + if (rowPathStr.contains("/")) { + String[] pathElements = rowPathStr.split("/"); + String path = ""; + for (String pathElement : pathElements) { + path = path + pathElement + "/"; + parents.add(path); + } + } + return parents; + } + + public void restoreExpanstionState(Set expansionState) { + if (tree != null && expansionState != null) { + // tree.getRowCount() changes at tree.expandRow() + for (int i = 0; i < tree.getRowCount(); i++) { + TreePath path = tree.getPathForRow(i); + if (expansionState.contains(getRowPathStr(path))) { + tree.expandRow(i); + } + } + } + } + + private String getRowPathStr(TreePath trp) { + String pathStr = ""; + if (trp.getPathCount() > 1) { + for (int i = 1; i < trp.getPathCount(); i++) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) trp.getPathComponent(i); + TreeNodeUserObject userObject = (TreeNodeUserObject) node.getUserObject(); + pathStr = pathStr + userObject.getOriginalName() + "/"; + } + } + return pathStr; + } + + public JTree getTree() { + return tree; + } + + public void setTree(JTree tree) { + this.tree = tree; + } +} diff --git a/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/WindowPosition.java b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/WindowPosition.java new file mode 100644 index 0000000..8c70640 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/java/us/deathmarine/luyten/WindowPosition.java @@ -0,0 +1,93 @@ +package us.deathmarine.luyten; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Toolkit; +import javax.swing.JDialog; +import javax.swing.JFrame; + +public class WindowPosition { + + private boolean isFullScreen; + private int windowWidth; + private int windowHeight; + private int windowX; + private int windowY; + + public void readPositionFromWindow(JFrame window) { + isFullScreen = (window.getExtendedState() == JFrame.MAXIMIZED_BOTH); + if (!isFullScreen) { + this.readPositionFromComponent(window); + } + } + + public void readPositionFromDialog(JDialog dialog) { + this.readPositionFromComponent(dialog); + } + + private void readPositionFromComponent(Component component) { + isFullScreen = false; + windowWidth = component.getWidth(); + windowHeight = component.getHeight(); + windowX = component.getX(); + windowY = component.getY(); + } + + public boolean isSavedWindowPositionValid() { + if (isFullScreen) { + return true; + } + if (windowWidth < 100 || windowHeight < 100) { + return false; + } + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + if (windowWidth > screenSize.width + 50 || windowHeight > screenSize.height + 50) { + return false; + } + if (windowY < -20 || windowY > screenSize.height - 50 || windowX < 50 - windowWidth + || windowX > screenSize.width - 50) { + return false; + } + return true; + } + + public boolean isFullScreen() { + return isFullScreen; + } + + public void setFullScreen(boolean isFullScreen) { + this.isFullScreen = isFullScreen; + } + + public int getWindowWidth() { + return windowWidth; + } + + public void setWindowWidth(int windowWidth) { + this.windowWidth = windowWidth; + } + + public int getWindowHeight() { + return windowHeight; + } + + public void setWindowHeight(int windowHeight) { + this.windowHeight = windowHeight; + } + + public int getWindowX() { + return windowX; + } + + public void setWindowX(int windowX) { + this.windowX = windowX; + } + + public int getWindowY() { + return windowY; + } + + public void setWindowY(int windowY) { + this.windowY = windowY; + } +} diff --git a/developTools/x-LuytenTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/developTools/LuytenTool.fxml b/developTools/x-LuytenTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/developTools/LuytenTool.fxml new file mode 100644 index 0000000..c8150bc --- /dev/null +++ b/developTools/x-LuytenTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/developTools/LuytenTool.fxml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/developTools/x-LuytenTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml b/developTools/x-LuytenTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml new file mode 100644 index 0000000..77254c3 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml @@ -0,0 +1,14 @@ + + + + + /com/xwintop/xJavaFxTool/fxmlView/developTools/LuytenTool.fxml + locale.LuytenTool + + Title + + + p-javaFxTools + Node + + \ No newline at end of file diff --git a/developTools/x-LuytenTool/src/main/resources/locale/LuytenTool.properties b/developTools/x-LuytenTool/src/main/resources/locale/LuytenTool.properties new file mode 100644 index 0000000..9338ef9 --- /dev/null +++ b/developTools/x-LuytenTool/src/main/resources/locale/LuytenTool.properties @@ -0,0 +1,3 @@ +# Dorian.properties是默认的"Dorian"资源束文件。 +# 作为中国人,我用自己的地区作为默认 +Title=LuytenTool \ No newline at end of file diff --git a/developTools/x-LuytenTool/src/main/resources/locale/LuytenTool_en_US.properties b/developTools/x-LuytenTool/src/main/resources/locale/LuytenTool_en_US.properties new file mode 100644 index 0000000..1b5abac --- /dev/null +++ b/developTools/x-LuytenTool/src/main/resources/locale/LuytenTool_en_US.properties @@ -0,0 +1,3 @@ +# 文件Dorian_en_US.properties,是美国地区的资源束 +# 它覆盖了默认资源束 +Title=LuytenTool \ No newline at end of file diff --git a/developTools/x-LuytenTool/src/main/resources/resources/Luyten.icns b/developTools/x-LuytenTool/src/main/resources/resources/Luyten.icns new file mode 100644 index 0000000000000000000000000000000000000000..310ceeda1554f3213026ceb0786257b250d7ef44 GIT binary patch literal 283742 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%0DYh!jw94Kxx;9lJP-rCGsegZAt56p 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 z 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%0AqcVFP+xqxQ+ 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

;3=n@@Vp3FA)8|IGX&zxIRGg5tGCK&*i#E>Dsvb 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

B4Wm`uOzc;*yD+vDEj~a;pqdhvl_zWF^Y@ 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 V2u&X#R6xL^rlftp>>f1e{{yA9l%fCt literal 0 HcmV?d00001 diff --git a/developTools/x-LuytenTool/src/main/resources/resources/file.png b/developTools/x-LuytenTool/src/main/resources/resources/file.png new file mode 100644 index 0000000000000000000000000000000000000000..e02bc01b38ae705273f622e328cfa1af095cef29 GIT binary patch literal 414 zcmeAS@N?(olHy`uVBq!ia0vp^d_XL~!3HGNrubO_DYhhUcNd2LAh=-f^2tCE&H|6f zVxY=7KzxL;^jk|KP>{XE)7O>#E{iCioZcs^-D*G~$r9Iy66gHf+|;}h2Ir#G#FEq$ zh4Rdj3Wq zDd)nAUuTF^CHA<@QrgwHQuWxQrzTvk{olCNT8u7rs2Zvs-kZU~>%%f*`}~6;i<_SZ zsh)lrCee`2?(e!%@A1=zt9-W~+*Ye<)0|L`d!^Ld2V2^F?hQAxvX3?PDa8l`kXya8ayC4ARer4fNE#Xiv=WOQ=}Q{vd}8QyTI5|j-%&2>MG5a`HRfwk=zC)1 zL=of_ss}um{Zd2)jY2#f!<5e-~cU|W_1?NKzC9n9OF0v<4`8!M;PT+FY~#o z<5xH5PaU!+1m|Z*<6b}Ne`e~0YTh>rAE&00DGTPE!Ct z=GbNc0004EOGiWihy@);00009a7bBm000XU000XU0RWnu7ytkO2XskIMF-sk6%8X8 zRW8_A0002GNkle zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00C`DL_t(I%cYaON*z%Yg}*)i zG*ey$3#$Y~2>1gQ5wuE?DvyxDPQlhH)++h}B6fB*f_VV(1rj0_DN>~gq*1}fnX~t@ zm^XI-Cf=zM=c z_5QlDTF7NDetkUe@pg8(<@8A)$q3P?Z-4HXUq52&@RISo$5`Iu&Fp(lcb3#*klctE zh})1M4>7s0i2(wBTrIaDmVE~UIL}x)1b{&q))sKDsy=PjWa1K%A*N4g>PTXt40kXf zGq}F`&EMM_KFrOq{dt9=RJAB0bvbZ1BA^H{o#%X6TO|bVrY0!7YQdr!I&UEbL?7Zq zY0OOa0KoG6dLO`#V1Zy+PhIC^2iq00000NkvXX Hu0mjfahB3e literal 0 HcmV?d00001 diff --git a/developTools/x-LuytenTool/src/main/resources/resources/package_obj.png b/developTools/x-LuytenTool/src/main/resources/resources/package_obj.png new file mode 100644 index 0000000000000000000000000000000000000000..0afea5b86397301830f4ae696415e68e01d1dd42 GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}LV!<*>(7t7-(Fny^yI?*O@>FC zjc)Iscd$zL`py~qOSKM`YhT|neS5CP?n13|tGibwC{GTRUze=9G)8Gbq~fATrQ-{l z3T?#a6+~3}JN*CuA7~^d;J!5P7En~OB*-rqs0J%wU^L;{4phXLN2bZe?^J zG%heMF*7s+TY3Nh0n|xEK~y+TrI1Za8&MR7{R#e*TE8l${VP&ec2z~uMN)#F)k0mg zP&a}u6jTz#tcpp*Z>iRHk|?Kz_AUKFev42@T@0~}GDR9h>G|7UQp=RgGKWhZ*CqW|Mo_Ei}^lJ>W z)GG<5{mss@)V#QIHB=#T9KgA*LNhp~{VlR!>O(6EB@6jm8$T{1l3<&r>xPAt!SK!3 zDhs}NUs2dXu4o~VRk8M`dJ8c Date: Fri, 21 Aug 2020 18:49:26 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9host=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/xwintop/xJavaFxTool/SwitchHostsToolMain.java | 8 ++++++++ .../xJavaFxTool/fxmlView/debugTools/SwitchHostsTool.fxml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/debugTools/x-SwitchHostsTool/src/main/java/com/xwintop/xJavaFxTool/SwitchHostsToolMain.java b/debugTools/x-SwitchHostsTool/src/main/java/com/xwintop/xJavaFxTool/SwitchHostsToolMain.java index 1269709..f6de1d2 100644 --- a/debugTools/x-SwitchHostsTool/src/main/java/com/xwintop/xJavaFxTool/SwitchHostsToolMain.java +++ b/debugTools/x-SwitchHostsTool/src/main/java/com/xwintop/xJavaFxTool/SwitchHostsToolMain.java @@ -5,10 +5,12 @@ import java.util.ResourceBundle; import com.xwintop.xcore.util.javafx.JavaFxSystemUtil; import javafx.application.Application; +import javafx.event.EventHandler; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; +import javafx.stage.WindowEvent; public class SwitchHostsToolMain extends Application { public static void main(String[] args) { @@ -25,6 +27,12 @@ public class SwitchHostsToolMain extends Application { double[] screenSize = JavaFxSystemUtil.getScreenSizeByScale(0.74D, 0.8D); primaryStage.setScene(new Scene(root, screenSize[0], screenSize[1])); primaryStage.show(); + primaryStage.setOnCloseRequest(new EventHandler() { + @Override + public void handle(WindowEvent event) { + System.exit(0); + } + }); } public static FXMLLoader getFXMLLoader() { diff --git a/debugTools/x-SwitchHostsTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/SwitchHostsTool.fxml b/debugTools/x-SwitchHostsTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/SwitchHostsTool.fxml index bfabb51..2cbf66c 100644 --- a/debugTools/x-SwitchHostsTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/SwitchHostsTool.fxml +++ b/debugTools/x-SwitchHostsTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/SwitchHostsTool.fxml @@ -20,7 +20,7 @@ + -- Gitee From 860b2ee60d3ff74b51a7537d49e896a9b36238b1 Mon Sep 17 00:00:00 2001 From: xufeng <1277032935@qq.com> Date: Sun, 23 Aug 2020 22:01:02 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9host=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E5=B7=A5=E5=85=B7pom=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debugTools/x-SwitchHostsTool/pom.xml | 30 ++++++++-------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/debugTools/x-SwitchHostsTool/pom.xml b/debugTools/x-SwitchHostsTool/pom.xml index cf9c167..6d2155f 100644 --- a/debugTools/x-SwitchHostsTool/pom.xml +++ b/debugTools/x-SwitchHostsTool/pom.xml @@ -45,34 +45,20 @@ test - - - org.projectlombok - lombok - 1.18.12 - provided - - com.xwintop xcore - 0.0.3-SNAPSHOT - - - ch.qos.logback - logback-classic - 1.2.3 - - - cn.hutool - hutool-all - 5.1.4 + 0.0.6 + + + - commons-io - commons-io - 2.6 + org.projectlombok + lombok + 1.18.12 + provided -- Gitee From d22a3ac1ce4ae6d0cd8586003bec4043100fcd66 Mon Sep 17 00:00:00 2001 From: "XUFENG-PC\\xufeng" <1277032935@qq.com> Date: Mon, 24 Aug 2020 16:38:49 +0800 Subject: [PATCH 6/9] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9Luyten=E5=B7=A5?= =?UTF-8?q?=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ .../developTools/LuytenToolController.java | 25 +++++++----------- .../developTools/LuytenToolService.java | 26 +++++++++++++++---- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 9d6223e..5d4d909 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ /configuration /javaFxConfigure /executor +keystore.jks +truststore.jks diff --git a/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/controller/developTools/LuytenToolController.java b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/controller/developTools/LuytenToolController.java index 5fe25e2..2d97ec2 100644 --- a/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/controller/developTools/LuytenToolController.java +++ b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/controller/developTools/LuytenToolController.java @@ -26,24 +26,17 @@ public class LuytenToolController extends LuytenToolView { } private void initView() { -// SwingUtilities.invokeLater(new Runnable() { -// @Override -// public void run() { -// try { -// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// MainWindow mainWindow = new MainWindow(null); -// mainWindow.setSize(800,800); -// mainWindow.setBounds(0,0,800,800); -//// mainWindow.setVisible(true); -// JRootPane jRootPane = mainWindow.getRootPane(); -// jRootPane.setSize(800,800); -// jRootPane.setBounds(0,0,800,800); -// luytenSwingNode.setContent(jRootPane); +// SwingUtilities.invokeLater(() -> { +// try { +// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); +// } catch (Exception e) { +// e.printStackTrace(); // } +// MainWindow mainWindow = new MainWindow(); +////// mainWindow.setVisible(true); +// luytenSwingNode.setContent(mainWindow.getRootPane()); // }); +// luytenToolService.openLuytenOnJavaFx(); } private void initEvent() { diff --git a/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/services/developTools/LuytenToolService.java b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/services/developTools/LuytenToolService.java index 9c8fc7a..4d6c5b5 100644 --- a/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/services/developTools/LuytenToolService.java +++ b/developTools/x-LuytenTool/src/main/java/com/xwintop/xJavaFxTool/services/developTools/LuytenToolService.java @@ -1,14 +1,30 @@ package com.xwintop.xJavaFxTool.services.developTools; + import com.xwintop.xJavaFxTool.controller.developTools.LuytenToolController; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; + @Getter @Setter @Slf4j -public class LuytenToolService{ -private LuytenToolController luytenToolController; -public LuytenToolService(LuytenToolController luytenToolController) { -this.luytenToolController = luytenToolController; -} +public class LuytenToolService { + private LuytenToolController luytenToolController; + + public LuytenToolService(LuytenToolController luytenToolController) { + this.luytenToolController = luytenToolController; + } + + public void openLuytenOnJavaFx() { +// SwingUtilities.invokeLater(() -> { +// try { +// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// MainWindow mainWindow = new MainWindow(); +// Model model = new Model(mainWindow); +// luytenToolController.getLuytenSwingNode().setContent(model); +// }); + } } \ No newline at end of file -- Gitee From 92b7a446516289d577037cb3933c18a5a5bcb49a Mon Sep 17 00:00:00 2001 From: "XUFENG-PC\\xufeng" <1277032935@qq.com> Date: Mon, 24 Aug 2020 18:26:49 +0800 Subject: [PATCH 7/9] =?UTF-8?q?1.=E7=A7=BB=E9=99=A4debugTools=E5=92=8Clitt?= =?UTF-8?q?leTools=E7=9B=B8=E5=85=B3=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debugTools/x-ActiveMqTool/.gitignore | 5 - debugTools/x-ActiveMqTool/README.md | 2 - debugTools/x-ActiveMqTool/README_EN.md | 1 - debugTools/x-ActiveMqTool/pom.xml | 96 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../debugTools/ActiveMqToolController.java | 301 --------- .../xJavaFxTool/job/ActiveMqToolJob.java | 22 - .../xJavaFxTool/manager/ScheduleManager.java | 87 --- .../model/ActiveMqToolReceiverTableBean.java | 93 --- .../model/ActiveMqToolTableBean.java | 117 ---- .../debugTools/ActiveMqToolService.java | 347 ---------- .../view/debugTools/ActiveMqToolView.java | 105 ---- .../fxmlView/debugTools/ActiveMqTool.fxml | 200 ------ .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/ActiveMqTool.properties | 3 - .../locale/ActiveMqTool_en_US.properties | 3 - debugTools/x-CmdTool/.gitignore | 5 - debugTools/x-CmdTool/README.md | 2 - debugTools/x-CmdTool/README_EN.md | 1 - debugTools/x-CmdTool/pom.xml | 90 --- .../java/com/xwintop/xJavaFxTool/Main.java | 50 -- .../debugTools/CmdToolController.java | 271 -------- .../xwintop/xJavaFxTool/job/CmdToolJob.java | 28 - .../xJavaFxTool/model/CmdToolTableBean.java | 124 ---- .../services/debugTools/CmdToolService.java | 203 ------ .../view/debugTools/CmdToolView.java | 68 -- .../fxmlView/debugTools/CmdTool.fxml | 105 ---- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../main/resources/locale/CmdTool.properties | 3 - .../resources/locale/CmdTool_en_US.properties | 3 - debugTools/x-FtpClientTool/.gitignore | 5 - debugTools/x-FtpClientTool/README.md | 7 - debugTools/x-FtpClientTool/README_EN.md | 1 - debugTools/x-FtpClientTool/pom.xml | 104 --- .../xJavaFxTool/FtpClientToolMain.java | 51 -- .../debugTools/FtpClientToolController.java | 241 ------- .../xJavaFxTool/job/FtpClientToolJob.java | 28 - .../model/FtpClientToolTableBean.java | 80 --- .../debugTools/FtpClientToolService.java | 292 --------- .../xwintop/xJavaFxTool/utils/FtpUtil.java | 296 --------- .../view/debugTools/FtpClientToolView.java | 68 -- .../fxmlView/debugTools/FtpClientTool.fxml | 128 ---- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/FtpClientTool.properties | 3 - .../locale/FtpClientTool_en_US.properties | 3 - debugTools/x-FtpServer/.gitignore | 5 - debugTools/x-FtpServer/README.md | 2 - debugTools/x-FtpServer/README_EN.md | 1 - debugTools/x-FtpServer/pom.xml | 98 --- .../xwintop/xJavaFxTool/FtpServerMain.java | 51 -- .../debugTools/FtpServerController.java | 204 ------ .../xJavaFxTool/model/FtpServerTableBean.java | 115 ---- .../services/debugTools/FtpServerService.java | 157 ----- .../view/debugTools/FtpServerView.java | 64 -- .../fxmlView/debugTools/FtpServer.fxml | 92 --- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/FtpServer.properties | 3 - .../locale/FtpServer_en_US.properties | 3 - debugTools/x-HttpTool/.gitignore | 5 - debugTools/x-HttpTool/README.md | 2 - debugTools/x-HttpTool/README_EN.md | 1 - debugTools/x-HttpTool/pom.xml | 82 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../debugTools/HttpToolController.java | 173 ----- .../services/debugTools/HttpToolService.java | 153 ----- .../view/debugTools/HttpToolView.java | 77 --- .../fxmlView/debugTools/HttpTool.fxml | 144 ----- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../main/resources/locale/HttpTool.properties | 3 - .../locale/HttpTool_en_US.properties | 3 - debugTools/x-KafkaTool/.gitignore | 5 - debugTools/x-KafkaTool/README.md | 2 - debugTools/x-KafkaTool/README_EN.md | 1 - debugTools/x-KafkaTool/pom.xml | 102 --- .../java/com/xwintop/xJavaFxTool/Main.java | 50 -- .../debugTools/KafkaToolController.java | 288 --------- .../xwintop/xJavaFxTool/job/KafkaToolJob.java | 21 - .../xJavaFxTool/manager/ScheduleManager.java | 87 --- .../model/KafkaToolReceiverTableBean.java | 93 --- .../xJavaFxTool/model/KafkaToolTableBean.java | 117 ---- .../services/debugTools/KafkaToolService.java | 251 -------- .../view/debugTools/KafkaToolView.java | 97 --- .../fxmlView/debugTools/KafkaTool.fxml | 197 ------ .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/KafkaTool.properties | 3 - .../locale/KafkaTool_en_US.properties | 3 - debugTools/x-RedisTool/.gitignore | 5 - debugTools/x-RedisTool/README.md | 1 - debugTools/x-RedisTool/README_EN.md | 1 - debugTools/x-RedisTool/pom.xml | 92 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../redisTool/RedisToolController.java | 136 ---- .../RedisToolDataTableController.java | 91 --- .../RedisToolDataViewController.java | 264 -------- .../redisTool/RedisToolDialogController.java | 164 ----- .../model/RedisToolDataTableBean.java | 60 -- .../redisTool/RedisToolDataTableService.java | 219 ------- .../redisTool/RedisToolDataViewService.java | 215 ------- .../redisTool/RedisToolService.java | 150 ----- .../xwintop/xJavaFxTool/utils/RedisUtil.java | 289 --------- .../redisTool/RedisToolDataTableView.java | 26 - .../redisTool/RedisToolDataViewView.java | 92 --- .../debugTools/redisTool/RedisToolView.java | 29 - .../debugTools/redisTool/RedisTool.fxml | 54 -- .../redisTool/RedisToolDataTable.fxml | 21 - .../redisTool/RedisToolDataView.fxml | 122 ---- .../debugTools/redisTool/RedisToolDialog.fxml | 65 -- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/RedisTool.properties | 3 - .../locale/RedisTool_en_US.properties | 3 - debugTools/x-ScriptEngineTool/.gitignore | 5 - debugTools/x-ScriptEngineTool/README.md | 2 - debugTools/x-ScriptEngineTool/README_EN.md | 1 - debugTools/x-ScriptEngineTool/pom.xml | 110 ---- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../ScriptEngineToolController.java | 264 -------- .../xJavaFxTool/job/ScriptEngineToolJob.java | 29 - .../xJavaFxTool/manager/ScheduleManager.java | 87 --- .../manager/script/ScriptEngine.java | 20 - .../manager/script/ScriptEngineManager.java | 102 --- .../manager/script/ScriptEngineType.java | 31 - .../script/groovy/GroovyScriptEngine.java | 59 -- .../script/javaScript/JavaScriptEngine.java | 58 -- .../manager/script/lua/LuaScriptEngine.java | 51 -- .../script/python/PythonScriptEngine.java | 65 -- .../model/ScriptEngineToolTableBean.java | 125 ---- .../debugTools/ScriptEngineToolService.java | 212 ------- .../view/debugTools/ScriptEngineToolView.java | 80 --- .../fxmlView/debugTools/ScriptEngineTool.fxml | 112 ---- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/ScriptEngineTool.properties | 3 - .../locale/ScriptEngineTool_en_US.properties | 3 - debugTools/x-SocketTool/.gitignore | 5 - debugTools/x-SocketTool/README.md | 8 - debugTools/x-SocketTool/README_EN.md | 1 - debugTools/x-SocketTool/pom.xml | 105 ---- .../xwintop/xJavaFxTool/ScoketToolMain.java | 51 -- .../debugTools/SocketToolController.java | 176 ------ .../socketTool/SocketClientHandler.java | 64 -- .../socketTool/SocketServerHandler.java | 81 --- .../socketTool/SocketToolService.java | 267 -------- .../view/debugTools/SocketToolView.java | 103 --- .../fxmlView/debugTools/SocketTool.fxml | 255 -------- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/SocketTool.properties | 3 - .../locale/SocketTool_en_US.properties | 3 - debugTools/x-SwitchHostsTool/.gitignore | 5 - debugTools/x-SwitchHostsTool/README.md | 2 - debugTools/x-SwitchHostsTool/README_EN.md | 1 - debugTools/x-SwitchHostsTool/pom.xml | 103 --- .../xJavaFxTool/SwitchHostsToolMain.java | 43 -- .../debugTools/SwitchHostsToolController.java | 160 ----- .../debugTools/SwitchHostsToolService.java | 129 ---- .../view/debugTools/SwitchHostsToolView.java | 40 -- .../fxmlView/debugTools/SwitchHostsTool.fxml | 43 -- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../css/debugTools/hosts-keywords.css | 12 - .../locale/SwitchHostsTool.properties | 3 - .../locale/SwitchHostsTool_en_US.properties | 3 - debugTools/x-ZookeeperTool/.gitignore | 5 - debugTools/x-ZookeeperTool/README.md | 1 - debugTools/x-ZookeeperTool/README_EN.md | 1 - debugTools/x-ZookeeperTool/pom.xml | 97 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../debugTools/ZookeeperToolController.java | 128 ---- .../debugTools/ZookeeperToolService.java | 294 --------- .../view/debugTools/ZookeeperToolView.java | 64 -- .../view/debugTools/package-info.java | 18 - .../fxmlView/debugTools/ZookeeperTool.fxml | 135 ---- .../config/toolFxmlLoaderConfiguration.xml | 15 - .../src/main/resources/images/plugInIcon.jpg | Bin 10231 -> 0 bytes .../resources/locale/ZookeeperTool.properties | 3 - .../locale/ZookeeperTool_en_US.properties | 3 - .../com/xwintop/xJavaFxPlugIn/AppTest.java | 38 -- developTools/x-LuytenTool/README.md | 5 +- littleTools/x-CharacterConverter/.gitignore | 5 - littleTools/x-CharacterConverter/README.md | 1 - littleTools/x-CharacterConverter/README_EN.md | 1 - littleTools/x-CharacterConverter/pom.xml | 91 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../CharacterConverterController.java | 216 ------- .../CharacterConverterService.java | 71 --- .../xwintop/xJavaFxTool/utils/GuiUtils.java | 257 -------- .../xwintop/xJavaFxTool/utils/RadixUtils.java | 96 --- .../littleTools/CharacterConverterView.java | 34 - .../littleTools/CharacterConverter.fxml | 41 -- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/CharacterConverter.properties | 3 - .../CharacterConverter_en_US.properties | 3 - littleTools/x-CronExpBuilder/.editorconfig | 9 - littleTools/x-CronExpBuilder/.gitignore | 5 - littleTools/x-CronExpBuilder/README.md | 1 - littleTools/x-CronExpBuilder/README_EN.md | 1 - littleTools/x-CronExpBuilder/pom.xml | 96 --- .../xwintop/xJavaFxTool/CronBuilderMain.java | 32 - .../littleTools/CronExpBuilderController.java | 205 ------ .../littleTools/FragmentController.java | 167 ----- .../view/littleTools/CronExpBuilderView.java | 114 ---- .../fxmlView/littleTools/CronExpBuilder.fxml | 131 ---- .../fxmlView/littleTools/Fragment.fxml | 46 -- ...\345\274\217\350\257\246\350\247\243.html" | 156 ----- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/CronExpBuilder.properties | 3 - .../locale/CronExpBuilder_en_US.properties | 3 - littleTools/x-EmailTool/.gitignore | 5 - littleTools/x-EmailTool/README.md | 1 - littleTools/x-EmailTool/README_EN.md | 1 - littleTools/x-EmailTool/pom.xml | 98 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../littleTools/EmailToolController.java | 256 -------- .../xwintop/xJavaFxTool/job/EmailToolJob.java | 29 - .../xJavaFxTool/model/EmailToolTableBean.java | 86 --- .../littleTools/EmailToolService.java | 230 ------- .../view/littleTools/EmailToolView.java | 111 ---- .../fxmlView/littleTools/EmailTool.fxml | 161 ----- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/EmailTool.properties | 3 - .../locale/EmailTool_en_US.properties | 3 - littleTools/x-EncryptAndDecrypt/.gitignore | 5 - littleTools/x-EncryptAndDecrypt/README.md | 1 - littleTools/x-EncryptAndDecrypt/README_EN.md | 1 - littleTools/x-EncryptAndDecrypt/pom.xml | 90 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../EncryptAndDecryptController.java | 199 ------ .../xwintop/xJavaFxTool/utils/GuiUtils.java | 257 -------- .../xJavaFxTool/utils/MorseConventer.java | 101 --- .../littleTools/EncryptAndDecryptView.java | 29 - .../littleTools/EncryptAndDecrypt.fxml | 69 -- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/EncryptAndDecrypt.properties | 3 - .../locale/EncryptAndDecrypt_en_US.properties | 3 - littleTools/x-ExcelSplitTool/.gitignore | 5 - littleTools/x-ExcelSplitTool/README.md | 1 - littleTools/x-ExcelSplitTool/README_EN.md | 1 - littleTools/x-ExcelSplitTool/pom.xml | 104 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../littleTools/ExcelSplitToolController.java | 85 --- .../littleTools/ExcelSplitToolService.java | 441 ------------- .../xJavaFxTool/utils/DirectoryTreeUtil.java | 200 ------ .../view/littleTools/ExcelSplitToolView.java | 55 -- .../fxmlView/littleTools/ExcelSplitTool.fxml | 56 -- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/ExcelSplitTool.properties | 3 - .../locale/ExcelSplitTool_en_US.properties | 3 - littleTools/x-FileBuildTool/.gitignore | 5 - littleTools/x-FileBuildTool/README.md | 9 - littleTools/x-FileBuildTool/README_EN.md | 1 - littleTools/x-FileBuildTool/pom.xml | 101 --- .../xJavaFxTool/FileBuildToolMain.java | 51 -- .../littleTools/FileBuildToolController.java | 204 ------ .../littleTools/FileBuildToolService.java | 133 ---- .../view/littleTools/FileBuildToolView.java | 39 -- .../fxmlView/littleTools/FileBuildTool.fxml | 56 -- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/FileBuildTool.properties | 3 - .../locale/FileBuildTool_en_US.properties | 3 - littleTools/x-FileCompressTool/.gitignore | 5 - littleTools/x-FileCompressTool/README.md | 1 - littleTools/x-FileCompressTool/README_EN.md | 1 - littleTools/x-FileCompressTool/pom.xml | 102 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../FileCompressToolController.java | 104 --- .../littleTools/FileCompressToolService.java | 200 ------ .../littleTools/FileCompressToolView.java | 39 -- .../littleTools/FileCompressTool.fxml | 59 -- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/FileCompressTool.properties | 3 - .../locale/FileCompressTool_en_US.properties | 3 - littleTools/x-FileCopy/.gitignore | 5 - littleTools/x-FileCopy/README.md | 1 - littleTools/x-FileCopy/README_EN.md | 1 - littleTools/x-FileCopy/pom.xml | 91 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../littleTools/FileCopyController.java | 225 ------- .../xwintop/xJavaFxTool/job/FileCopyJob.java | 21 - .../xJavaFxTool/manager/ScheduleManager.java | 87 --- .../xJavaFxTool/model/FileCopyTableBean.java | 123 ---- .../services/littleTools/FileCopyService.java | 164 ----- .../view/littleTools/FileCopyView.java | 83 --- .../fxmlView/littleTools/FileCopy.fxml | 110 ---- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../main/resources/locale/FileCopy.properties | 3 - .../locale/FileCopy_en_US.properties | 3 - littleTools/x-FileMergeTool/.gitignore | 5 - littleTools/x-FileMergeTool/README.md | 1 - littleTools/x-FileMergeTool/README_EN.md | 1 - littleTools/x-FileMergeTool/pom.xml | 105 ---- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../littleTools/FileMergeToolController.java | 107 ---- .../littleTools/FileMergeToolService.java | 255 -------- .../view/littleTools/FileMergeToolView.java | 40 -- .../fxmlView/littleTools/FileMergeTool.fxml | 31 - .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/FileMergeTool.properties | 3 - .../locale/FileMergeTool_en_US.properties | 3 - littleTools/x-FileRenameTool/.gitignore | 5 - littleTools/x-FileRenameTool/README.md | 1 - littleTools/x-FileRenameTool/README_EN.md | 1 - littleTools/x-FileRenameTool/pom.xml | 91 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../littleTools/FileRenameToolController.java | 166 ----- .../littleTools/FileRenameToolService.java | 24 - .../view/littleTools/FileRenameToolView.java | 66 -- .../fxmlView/littleTools/FileRenameTool.fxml | 112 ---- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/FileRenameTool.properties | 3 - .../locale/FileRenameTool_en_US.properties | 3 - littleTools/x-FileSearchTool/.gitignore | 5 - littleTools/x-FileSearchTool/README.md | 1 - littleTools/x-FileSearchTool/README_EN.md | 1 - littleTools/x-FileSearchTool/pom.xml | 103 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../littleTools/FileSearchToolController.java | 221 ------- .../littleTools/FileSearchToolService.java | 289 --------- .../xJavaFxTool/utils/ImgToolUtil.java | 550 ---------------- .../view/littleTools/FileSearchToolView.java | 62 -- .../fxmlView/littleTools/FileSearchTool.fxml | 114 ---- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/FileSearchTool.properties | 3 - .../locale/FileSearchTool_en_US.properties | 3 - littleTools/x-IconTool/.gitignore | 5 - littleTools/x-IconTool/README.md | 1 - littleTools/x-IconTool/README_EN.md | 1 - littleTools/x-IconTool/pom.xml | 95 --- .../com/xwintop/xJavaFxTool/IconToolMain.java | 32 - .../littleTools/IconToolController.java | 275 -------- .../services/littleTools/IconToolService.java | 341 ---------- .../xJavaFxTool/utils/ImgToolUtil.java | 550 ---------------- .../view/littleTools/IconToolView.java | 85 --- .../fxmlView/littleTools/IconTool.fxml | 127 ---- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/data/iosAppIcon/Contents.json | 152 ----- .../main/resources/locale/IconTool.properties | 3 - .../locale/IconTool_en_US.properties | 3 - littleTools/x-ImageAnalysisTool/.gitignore | 5 - littleTools/x-ImageAnalysisTool/README.md | 4 - littleTools/x-ImageAnalysisTool/README_EN.md | 1 - littleTools/x-ImageAnalysisTool/pom.xml | 91 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../ImageAnalysisToolController.java | 88 --- .../littleTools/ImageAnalysisToolService.java | 113 ---- .../xJavaFxTool/utils/ImgToolUtil.java | 550 ---------------- .../littleTools/ImageAnalysisToolView.java | 48 -- .../littleTools/ImageAnalysisTool.fxml | 66 -- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/ImageAnalysisTool.properties | 3 - .../locale/ImageAnalysisTool_en_US.properties | 3 - littleTools/x-ImageTool/.editorconfig | 9 - littleTools/x-ImageTool/.gitignore | 5 - littleTools/x-ImageTool/README.md | 4 - littleTools/x-ImageTool/README_EN.md | 1 - littleTools/x-ImageTool/pom.xml | 98 --- .../xwintop/xJavaFxTool/ImageToolMain.java | 41 -- .../littleTools/ImageToolController.java | 339 ---------- .../littleTools/AcceptableFormats.java | 37 -- .../services/littleTools/ImageInfo.java | 165 ----- .../services/littleTools/ImageParameters.java | 52 -- .../littleTools/ImageToolService.java | 166 ----- .../services/littleTools/OutputFormats.java | 27 - .../services/littleTools/ResizeMode.java | 19 - .../view/littleTools/ImageToolView.java | 70 --- .../fxmlView/littleTools/image-tool-main.fxml | 102 --- .../fxmlView/littleTools/image-tool.png | Bin 360 -> 0 bytes .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/ImageTool.properties | 3 - .../locale/ImageTool_en_US.properties | 3 - .../x-LinuxPathToWindowsPath/.gitignore | 5 - .../x-LinuxPathToWindowsPath/README.md | 1 - .../x-LinuxPathToWindowsPath/README_EN.md | 1 - littleTools/x-LinuxPathToWindowsPath/pom.xml | 91 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../LinuxPathToWindowsPathController.java | 90 --- .../littleTools/LinuxPathToWindowsPath.fxml | 33 - .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/LinuxPathToWindowsPath.properties | 3 - .../LinuxPathToWindowsPath_en_US.properties | 3 - littleTools/x-LiteappCode/.gitignore | 5 - littleTools/x-LiteappCode/README.md | 1 - littleTools/x-LiteappCode/README_EN.md | 1 - littleTools/x-LiteappCode/pom.xml | 91 --- .../java/com/xwintop/xJavaFxTool/Main.java | 50 -- .../liteappcode/LiteappCodeController.java | 261 -------- .../liteappcode/LiteappCodeService.java | 14 - .../view/liteappcode/LiteappCodeView.java | 35 -- .../fxmlView/littleTools/LiteappCode.fxml | 34 - .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/LiteappCode.properties | 3 - .../locale/LiteappCode_en_US.properties | 3 - littleTools/x-Mp3ConvertTool/.gitignore | 5 - littleTools/x-Mp3ConvertTool/README.md | 1 - littleTools/x-Mp3ConvertTool/README_EN.md | 1 - littleTools/x-Mp3ConvertTool/pom.xml | 97 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../littleTools/Mp3ConvertToolController.java | 112 ---- .../littleTools/Mp3ConvertToolService.java | 131 ---- .../xwintop/xJavaFxTool/utils/NcmDump.java | 317 ---------- .../view/littleTools/Mp3ConvertToolView.java | 47 -- .../fxmlView/littleTools/Mp3ConvertTool.fxml | 57 -- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/Mp3ConvertTool.properties | 3 - .../locale/Mp3ConvertTool_en_US.properties | 3 - littleTools/x-PdfConvertTool/.gitignore | 5 - littleTools/x-PdfConvertTool/README.md | 1 - littleTools/x-PdfConvertTool/README_EN.md | 1 - littleTools/x-PdfConvertTool/pom.xml | 97 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../littleTools/PdfConvertToolController.java | 94 --- .../littleTools/PdfConvertToolService.java | 154 ----- .../xJavaFxTool/utils/ImgToolUtil.java | 550 ---------------- .../view/littleTools/PdfConvertToolView.java | 53 -- .../fxmlView/littleTools/PdfConvertTool.fxml | 79 --- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/PdfConvertTool.properties | 3 - .../locale/PdfConvertTool_en_US.properties | 3 - littleTools/x-QRCodeBuilder/.gitignore | 5 - littleTools/x-QRCodeBuilder/README.md | 9 - littleTools/x-QRCodeBuilder/README_EN.md | 1 - littleTools/x-QRCodeBuilder/pom.xml | 103 --- .../xJavaFxTool/QrCodeBuilderMain.java | 48 -- .../littleTools/QRCodeBuilderController.java | 208 ------ .../xJavaFxTool/utils/CorrectionLevel.java | 37 -- .../xwintop/xJavaFxTool/utils/QRCodeUtil.java | 256 -------- .../xJavaFxTool/utils/ScreenShoter.java | 382 ----------- .../view/littleTools/QRCodeBuilderView.java | 63 -- .../fxmlView/littleTools/QRCodeBuilder.fxml | 109 ---- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/QRCodeBuilder.properties | 3 - .../locale/QRCodeBuilder_en_US.properties | 3 - littleTools/x-SealBuilderTool/.gitignore | 5 - littleTools/x-SealBuilderTool/README.md | 1 - littleTools/x-SealBuilderTool/README_EN.md | 1 - littleTools/x-SealBuilderTool/pom.xml | 91 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../SealBuilderToolController.java | 127 ---- .../littleTools/SealBuilderToolService.java | 98 --- .../xJavaFxTool/utils/ImgToolUtil.java | 550 ---------------- .../xwintop/xJavaFxTool/utils/SealUtil.java | 591 ------------------ .../view/littleTools/SealBuilderToolView.java | 114 ---- .../fxmlView/littleTools/SealBuilderTool.fxml | 193 ------ .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/SealBuilderTool.properties | 3 - .../locale/SealBuilderTool_en_US.properties | 3 - .../x-SedentaryReminderTool/.gitignore | 5 - littleTools/x-SedentaryReminderTool/README.md | 1 - .../x-SedentaryReminderTool/README_EN.md | 1 - littleTools/x-SedentaryReminderTool/pom.xml | 91 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../SedentaryReminderToolController.java | 55 -- .../SedentaryReminderToolService.java | 50 -- .../SedentaryReminderToolView.java | 27 - .../littleTools/SedentaryReminderTool.fxml | 41 -- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../locale/SedentaryReminderTool.properties | 3 - .../SedentaryReminderTool_en_US.properties | 3 - littleTools/x-SmsTool/.gitignore | 5 - littleTools/x-SmsTool/README.md | 2 - littleTools/x-SmsTool/README_EN.md | 1 - littleTools/x-SmsTool/pom.xml | 91 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../littleTools/SmsToolController.java | 164 ----- .../xJavaFxTool/model/SmsToolTableBean.java | 86 --- .../services/littleTools/SmsToolService.java | 355 ----------- .../view/littleTools/SmsToolView.java | 106 ---- .../fxmlView/littleTools/SmsTool.fxml | 320 ---------- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../main/resources/locale/SmsTool.properties | 3 - .../resources/locale/SmsTool_en_US.properties | 3 - littleTools/x-TimeTool/.gitignore | 5 - littleTools/x-TimeTool/README.md | 2 - littleTools/x-TimeTool/README_EN.md | 1 - littleTools/x-TimeTool/pom.xml | 91 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../littleTools/TimeToolController.java | 100 --- .../services/littleTools/TimeToolService.java | 151 ----- .../view/littleTools/TimeToolView.java | 48 -- .../fxmlView/littleTools/TimeTool.fxml | 73 --- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../main/resources/locale/TimeTool.properties | 3 - .../locale/TimeTool_en_US.properties | 3 - littleTools/x-ZHConverter/.gitignore | 5 - littleTools/x-ZHConverter/README.md | 2 - littleTools/x-ZHConverter/README_EN.md | 1 - littleTools/x-ZHConverter/pom.xml | 97 --- .../java/com/xwintop/xJavaFxTool/Main.java | 51 -- .../littleTools/ZHConverterController.java | 68 -- .../littleTools/ZHConverterService.java | 106 ---- .../view/littleTools/ZHConverterView.java | 26 - .../fxmlView/littleTools/ZHConverter.fxml | 46 -- .../config/toolFxmlLoaderConfiguration.xml | 14 - .../resources/locale/ZHConverter.properties | 3 - .../locale/ZHConverter_en_US.properties | 3 - 491 files changed, 4 insertions(+), 34507 deletions(-) delete mode 100644 debugTools/x-ActiveMqTool/.gitignore delete mode 100644 debugTools/x-ActiveMqTool/README.md delete mode 100644 debugTools/x-ActiveMqTool/README_EN.md delete mode 100644 debugTools/x-ActiveMqTool/pom.xml delete mode 100644 debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/ActiveMqToolController.java delete mode 100644 debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/job/ActiveMqToolJob.java delete mode 100644 debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/manager/ScheduleManager.java delete mode 100644 debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/model/ActiveMqToolReceiverTableBean.java delete mode 100644 debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/model/ActiveMqToolTableBean.java delete mode 100644 debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/ActiveMqToolService.java delete mode 100644 debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/ActiveMqToolView.java delete mode 100644 debugTools/x-ActiveMqTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/ActiveMqTool.fxml delete mode 100644 debugTools/x-ActiveMqTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 debugTools/x-ActiveMqTool/src/main/resources/locale/ActiveMqTool.properties delete mode 100644 debugTools/x-ActiveMqTool/src/main/resources/locale/ActiveMqTool_en_US.properties delete mode 100644 debugTools/x-CmdTool/.gitignore delete mode 100644 debugTools/x-CmdTool/README.md delete mode 100644 debugTools/x-CmdTool/README_EN.md delete mode 100644 debugTools/x-CmdTool/pom.xml delete mode 100644 debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/CmdToolController.java delete mode 100644 debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/job/CmdToolJob.java delete mode 100644 debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/model/CmdToolTableBean.java delete mode 100644 debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/CmdToolService.java delete mode 100644 debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/CmdToolView.java delete mode 100644 debugTools/x-CmdTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/CmdTool.fxml delete mode 100644 debugTools/x-CmdTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 debugTools/x-CmdTool/src/main/resources/locale/CmdTool.properties delete mode 100644 debugTools/x-CmdTool/src/main/resources/locale/CmdTool_en_US.properties delete mode 100644 debugTools/x-FtpClientTool/.gitignore delete mode 100644 debugTools/x-FtpClientTool/README.md delete mode 100644 debugTools/x-FtpClientTool/README_EN.md delete mode 100644 debugTools/x-FtpClientTool/pom.xml delete mode 100644 debugTools/x-FtpClientTool/src/main/java/com/xwintop/xJavaFxTool/FtpClientToolMain.java delete mode 100644 debugTools/x-FtpClientTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/FtpClientToolController.java delete mode 100644 debugTools/x-FtpClientTool/src/main/java/com/xwintop/xJavaFxTool/job/FtpClientToolJob.java delete mode 100644 debugTools/x-FtpClientTool/src/main/java/com/xwintop/xJavaFxTool/model/FtpClientToolTableBean.java delete mode 100644 debugTools/x-FtpClientTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/FtpClientToolService.java delete mode 100644 debugTools/x-FtpClientTool/src/main/java/com/xwintop/xJavaFxTool/utils/FtpUtil.java delete mode 100644 debugTools/x-FtpClientTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/FtpClientToolView.java delete mode 100644 debugTools/x-FtpClientTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/FtpClientTool.fxml delete mode 100644 debugTools/x-FtpClientTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 debugTools/x-FtpClientTool/src/main/resources/locale/FtpClientTool.properties delete mode 100644 debugTools/x-FtpClientTool/src/main/resources/locale/FtpClientTool_en_US.properties delete mode 100644 debugTools/x-FtpServer/.gitignore delete mode 100644 debugTools/x-FtpServer/README.md delete mode 100644 debugTools/x-FtpServer/README_EN.md delete mode 100644 debugTools/x-FtpServer/pom.xml delete mode 100644 debugTools/x-FtpServer/src/main/java/com/xwintop/xJavaFxTool/FtpServerMain.java delete mode 100644 debugTools/x-FtpServer/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/FtpServerController.java delete mode 100644 debugTools/x-FtpServer/src/main/java/com/xwintop/xJavaFxTool/model/FtpServerTableBean.java delete mode 100644 debugTools/x-FtpServer/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/FtpServerService.java delete mode 100644 debugTools/x-FtpServer/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/FtpServerView.java delete mode 100644 debugTools/x-FtpServer/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/FtpServer.fxml delete mode 100644 debugTools/x-FtpServer/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 debugTools/x-FtpServer/src/main/resources/locale/FtpServer.properties delete mode 100644 debugTools/x-FtpServer/src/main/resources/locale/FtpServer_en_US.properties delete mode 100644 debugTools/x-HttpTool/.gitignore delete mode 100644 debugTools/x-HttpTool/README.md delete mode 100644 debugTools/x-HttpTool/README_EN.md delete mode 100644 debugTools/x-HttpTool/pom.xml delete mode 100644 debugTools/x-HttpTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 debugTools/x-HttpTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/HttpToolController.java delete mode 100644 debugTools/x-HttpTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/HttpToolService.java delete mode 100644 debugTools/x-HttpTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/HttpToolView.java delete mode 100644 debugTools/x-HttpTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/HttpTool.fxml delete mode 100644 debugTools/x-HttpTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 debugTools/x-HttpTool/src/main/resources/locale/HttpTool.properties delete mode 100644 debugTools/x-HttpTool/src/main/resources/locale/HttpTool_en_US.properties delete mode 100644 debugTools/x-KafkaTool/.gitignore delete mode 100644 debugTools/x-KafkaTool/README.md delete mode 100644 debugTools/x-KafkaTool/README_EN.md delete mode 100644 debugTools/x-KafkaTool/pom.xml delete mode 100644 debugTools/x-KafkaTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 debugTools/x-KafkaTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/KafkaToolController.java delete mode 100644 debugTools/x-KafkaTool/src/main/java/com/xwintop/xJavaFxTool/job/KafkaToolJob.java delete mode 100644 debugTools/x-KafkaTool/src/main/java/com/xwintop/xJavaFxTool/manager/ScheduleManager.java delete mode 100644 debugTools/x-KafkaTool/src/main/java/com/xwintop/xJavaFxTool/model/KafkaToolReceiverTableBean.java delete mode 100644 debugTools/x-KafkaTool/src/main/java/com/xwintop/xJavaFxTool/model/KafkaToolTableBean.java delete mode 100644 debugTools/x-KafkaTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/KafkaToolService.java delete mode 100644 debugTools/x-KafkaTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/KafkaToolView.java delete mode 100644 debugTools/x-KafkaTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/KafkaTool.fxml delete mode 100644 debugTools/x-KafkaTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 debugTools/x-KafkaTool/src/main/resources/locale/KafkaTool.properties delete mode 100644 debugTools/x-KafkaTool/src/main/resources/locale/KafkaTool_en_US.properties delete mode 100644 debugTools/x-RedisTool/.gitignore delete mode 100644 debugTools/x-RedisTool/README.md delete mode 100644 debugTools/x-RedisTool/README_EN.md delete mode 100644 debugTools/x-RedisTool/pom.xml delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/redisTool/RedisToolController.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/redisTool/RedisToolDataTableController.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/redisTool/RedisToolDataViewController.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/redisTool/RedisToolDialogController.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/model/RedisToolDataTableBean.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/redisTool/RedisToolDataTableService.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/redisTool/RedisToolDataViewService.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/redisTool/RedisToolService.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/utils/RedisUtil.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/redisTool/RedisToolDataTableView.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/redisTool/RedisToolDataViewView.java delete mode 100644 debugTools/x-RedisTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/redisTool/RedisToolView.java delete mode 100644 debugTools/x-RedisTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/redisTool/RedisTool.fxml delete mode 100644 debugTools/x-RedisTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/redisTool/RedisToolDataTable.fxml delete mode 100644 debugTools/x-RedisTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/redisTool/RedisToolDataView.fxml delete mode 100644 debugTools/x-RedisTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/redisTool/RedisToolDialog.fxml delete mode 100644 debugTools/x-RedisTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 debugTools/x-RedisTool/src/main/resources/locale/RedisTool.properties delete mode 100644 debugTools/x-RedisTool/src/main/resources/locale/RedisTool_en_US.properties delete mode 100644 debugTools/x-ScriptEngineTool/.gitignore delete mode 100644 debugTools/x-ScriptEngineTool/README.md delete mode 100644 debugTools/x-ScriptEngineTool/README_EN.md delete mode 100644 debugTools/x-ScriptEngineTool/pom.xml delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/ScriptEngineToolController.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/job/ScriptEngineToolJob.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/manager/ScheduleManager.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/manager/script/ScriptEngine.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/manager/script/ScriptEngineManager.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/manager/script/ScriptEngineType.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/manager/script/groovy/GroovyScriptEngine.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/manager/script/javaScript/JavaScriptEngine.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/manager/script/lua/LuaScriptEngine.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/manager/script/python/PythonScriptEngine.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/model/ScriptEngineToolTableBean.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/ScriptEngineToolService.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/ScriptEngineToolView.java delete mode 100644 debugTools/x-ScriptEngineTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/ScriptEngineTool.fxml delete mode 100644 debugTools/x-ScriptEngineTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 debugTools/x-ScriptEngineTool/src/main/resources/locale/ScriptEngineTool.properties delete mode 100644 debugTools/x-ScriptEngineTool/src/main/resources/locale/ScriptEngineTool_en_US.properties delete mode 100644 debugTools/x-SocketTool/.gitignore delete mode 100644 debugTools/x-SocketTool/README.md delete mode 100644 debugTools/x-SocketTool/README_EN.md delete mode 100644 debugTools/x-SocketTool/pom.xml delete mode 100644 debugTools/x-SocketTool/src/main/java/com/xwintop/xJavaFxTool/ScoketToolMain.java delete mode 100644 debugTools/x-SocketTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/SocketToolController.java delete mode 100644 debugTools/x-SocketTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/socketTool/SocketClientHandler.java delete mode 100644 debugTools/x-SocketTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/socketTool/SocketServerHandler.java delete mode 100644 debugTools/x-SocketTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/socketTool/SocketToolService.java delete mode 100644 debugTools/x-SocketTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/SocketToolView.java delete mode 100644 debugTools/x-SocketTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/SocketTool.fxml delete mode 100644 debugTools/x-SocketTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 debugTools/x-SocketTool/src/main/resources/locale/SocketTool.properties delete mode 100644 debugTools/x-SocketTool/src/main/resources/locale/SocketTool_en_US.properties delete mode 100644 debugTools/x-SwitchHostsTool/.gitignore delete mode 100644 debugTools/x-SwitchHostsTool/README.md delete mode 100644 debugTools/x-SwitchHostsTool/README_EN.md delete mode 100644 debugTools/x-SwitchHostsTool/pom.xml delete mode 100644 debugTools/x-SwitchHostsTool/src/main/java/com/xwintop/xJavaFxTool/SwitchHostsToolMain.java delete mode 100644 debugTools/x-SwitchHostsTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/SwitchHostsToolController.java delete mode 100644 debugTools/x-SwitchHostsTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/SwitchHostsToolService.java delete mode 100644 debugTools/x-SwitchHostsTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/SwitchHostsToolView.java delete mode 100644 debugTools/x-SwitchHostsTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/SwitchHostsTool.fxml delete mode 100644 debugTools/x-SwitchHostsTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 debugTools/x-SwitchHostsTool/src/main/resources/css/debugTools/hosts-keywords.css delete mode 100644 debugTools/x-SwitchHostsTool/src/main/resources/locale/SwitchHostsTool.properties delete mode 100644 debugTools/x-SwitchHostsTool/src/main/resources/locale/SwitchHostsTool_en_US.properties delete mode 100644 debugTools/x-ZookeeperTool/.gitignore delete mode 100644 debugTools/x-ZookeeperTool/README.md delete mode 100644 debugTools/x-ZookeeperTool/README_EN.md delete mode 100644 debugTools/x-ZookeeperTool/pom.xml delete mode 100644 debugTools/x-ZookeeperTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 debugTools/x-ZookeeperTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/ZookeeperToolController.java delete mode 100644 debugTools/x-ZookeeperTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/ZookeeperToolService.java delete mode 100644 debugTools/x-ZookeeperTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/ZookeeperToolView.java delete mode 100644 debugTools/x-ZookeeperTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/package-info.java delete mode 100644 debugTools/x-ZookeeperTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/ZookeeperTool.fxml delete mode 100644 debugTools/x-ZookeeperTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 debugTools/x-ZookeeperTool/src/main/resources/images/plugInIcon.jpg delete mode 100644 debugTools/x-ZookeeperTool/src/main/resources/locale/ZookeeperTool.properties delete mode 100644 debugTools/x-ZookeeperTool/src/main/resources/locale/ZookeeperTool_en_US.properties delete mode 100644 debugTools/x-ZookeeperTool/src/test/java/com/xwintop/xJavaFxPlugIn/AppTest.java delete mode 100644 littleTools/x-CharacterConverter/.gitignore delete mode 100644 littleTools/x-CharacterConverter/README.md delete mode 100644 littleTools/x-CharacterConverter/README_EN.md delete mode 100644 littleTools/x-CharacterConverter/pom.xml delete mode 100644 littleTools/x-CharacterConverter/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-CharacterConverter/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/CharacterConverterController.java delete mode 100644 littleTools/x-CharacterConverter/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/CharacterConverterService.java delete mode 100644 littleTools/x-CharacterConverter/src/main/java/com/xwintop/xJavaFxTool/utils/GuiUtils.java delete mode 100644 littleTools/x-CharacterConverter/src/main/java/com/xwintop/xJavaFxTool/utils/RadixUtils.java delete mode 100644 littleTools/x-CharacterConverter/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/CharacterConverterView.java delete mode 100644 littleTools/x-CharacterConverter/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/CharacterConverter.fxml delete mode 100644 littleTools/x-CharacterConverter/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-CharacterConverter/src/main/resources/locale/CharacterConverter.properties delete mode 100644 littleTools/x-CharacterConverter/src/main/resources/locale/CharacterConverter_en_US.properties delete mode 100644 littleTools/x-CronExpBuilder/.editorconfig delete mode 100644 littleTools/x-CronExpBuilder/.gitignore delete mode 100644 littleTools/x-CronExpBuilder/README.md delete mode 100644 littleTools/x-CronExpBuilder/README_EN.md delete mode 100644 littleTools/x-CronExpBuilder/pom.xml delete mode 100644 littleTools/x-CronExpBuilder/src/main/java/com/xwintop/xJavaFxTool/CronBuilderMain.java delete mode 100644 littleTools/x-CronExpBuilder/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/CronExpBuilderController.java delete mode 100644 littleTools/x-CronExpBuilder/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/FragmentController.java delete mode 100644 littleTools/x-CronExpBuilder/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/CronExpBuilderView.java delete mode 100644 littleTools/x-CronExpBuilder/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/CronExpBuilder.fxml delete mode 100644 littleTools/x-CronExpBuilder/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/Fragment.fxml delete mode 100644 "littleTools/x-CronExpBuilder/src/main/resources/com/xwintop/xJavaFxTool/web/littleTools/cron\350\241\250\350\276\276\345\274\217\350\257\246\350\247\243.html" delete mode 100644 littleTools/x-CronExpBuilder/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-CronExpBuilder/src/main/resources/locale/CronExpBuilder.properties delete mode 100644 littleTools/x-CronExpBuilder/src/main/resources/locale/CronExpBuilder_en_US.properties delete mode 100644 littleTools/x-EmailTool/.gitignore delete mode 100644 littleTools/x-EmailTool/README.md delete mode 100644 littleTools/x-EmailTool/README_EN.md delete mode 100644 littleTools/x-EmailTool/pom.xml delete mode 100644 littleTools/x-EmailTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-EmailTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/EmailToolController.java delete mode 100644 littleTools/x-EmailTool/src/main/java/com/xwintop/xJavaFxTool/job/EmailToolJob.java delete mode 100644 littleTools/x-EmailTool/src/main/java/com/xwintop/xJavaFxTool/model/EmailToolTableBean.java delete mode 100644 littleTools/x-EmailTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/EmailToolService.java delete mode 100644 littleTools/x-EmailTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/EmailToolView.java delete mode 100644 littleTools/x-EmailTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/EmailTool.fxml delete mode 100644 littleTools/x-EmailTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-EmailTool/src/main/resources/locale/EmailTool.properties delete mode 100644 littleTools/x-EmailTool/src/main/resources/locale/EmailTool_en_US.properties delete mode 100644 littleTools/x-EncryptAndDecrypt/.gitignore delete mode 100644 littleTools/x-EncryptAndDecrypt/README.md delete mode 100644 littleTools/x-EncryptAndDecrypt/README_EN.md delete mode 100644 littleTools/x-EncryptAndDecrypt/pom.xml delete mode 100644 littleTools/x-EncryptAndDecrypt/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-EncryptAndDecrypt/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/EncryptAndDecryptController.java delete mode 100644 littleTools/x-EncryptAndDecrypt/src/main/java/com/xwintop/xJavaFxTool/utils/GuiUtils.java delete mode 100644 littleTools/x-EncryptAndDecrypt/src/main/java/com/xwintop/xJavaFxTool/utils/MorseConventer.java delete mode 100644 littleTools/x-EncryptAndDecrypt/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/EncryptAndDecryptView.java delete mode 100644 littleTools/x-EncryptAndDecrypt/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/EncryptAndDecrypt.fxml delete mode 100644 littleTools/x-EncryptAndDecrypt/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-EncryptAndDecrypt/src/main/resources/locale/EncryptAndDecrypt.properties delete mode 100644 littleTools/x-EncryptAndDecrypt/src/main/resources/locale/EncryptAndDecrypt_en_US.properties delete mode 100644 littleTools/x-ExcelSplitTool/.gitignore delete mode 100644 littleTools/x-ExcelSplitTool/README.md delete mode 100644 littleTools/x-ExcelSplitTool/README_EN.md delete mode 100644 littleTools/x-ExcelSplitTool/pom.xml delete mode 100644 littleTools/x-ExcelSplitTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-ExcelSplitTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/ExcelSplitToolController.java delete mode 100644 littleTools/x-ExcelSplitTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/ExcelSplitToolService.java delete mode 100644 littleTools/x-ExcelSplitTool/src/main/java/com/xwintop/xJavaFxTool/utils/DirectoryTreeUtil.java delete mode 100644 littleTools/x-ExcelSplitTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/ExcelSplitToolView.java delete mode 100644 littleTools/x-ExcelSplitTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/ExcelSplitTool.fxml delete mode 100644 littleTools/x-ExcelSplitTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-ExcelSplitTool/src/main/resources/locale/ExcelSplitTool.properties delete mode 100644 littleTools/x-ExcelSplitTool/src/main/resources/locale/ExcelSplitTool_en_US.properties delete mode 100644 littleTools/x-FileBuildTool/.gitignore delete mode 100644 littleTools/x-FileBuildTool/README.md delete mode 100644 littleTools/x-FileBuildTool/README_EN.md delete mode 100644 littleTools/x-FileBuildTool/pom.xml delete mode 100644 littleTools/x-FileBuildTool/src/main/java/com/xwintop/xJavaFxTool/FileBuildToolMain.java delete mode 100644 littleTools/x-FileBuildTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/FileBuildToolController.java delete mode 100644 littleTools/x-FileBuildTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/FileBuildToolService.java delete mode 100644 littleTools/x-FileBuildTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/FileBuildToolView.java delete mode 100644 littleTools/x-FileBuildTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/FileBuildTool.fxml delete mode 100644 littleTools/x-FileBuildTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-FileBuildTool/src/main/resources/locale/FileBuildTool.properties delete mode 100644 littleTools/x-FileBuildTool/src/main/resources/locale/FileBuildTool_en_US.properties delete mode 100644 littleTools/x-FileCompressTool/.gitignore delete mode 100644 littleTools/x-FileCompressTool/README.md delete mode 100644 littleTools/x-FileCompressTool/README_EN.md delete mode 100644 littleTools/x-FileCompressTool/pom.xml delete mode 100644 littleTools/x-FileCompressTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-FileCompressTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/FileCompressToolController.java delete mode 100644 littleTools/x-FileCompressTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/FileCompressToolService.java delete mode 100644 littleTools/x-FileCompressTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/FileCompressToolView.java delete mode 100644 littleTools/x-FileCompressTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/FileCompressTool.fxml delete mode 100644 littleTools/x-FileCompressTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-FileCompressTool/src/main/resources/locale/FileCompressTool.properties delete mode 100644 littleTools/x-FileCompressTool/src/main/resources/locale/FileCompressTool_en_US.properties delete mode 100644 littleTools/x-FileCopy/.gitignore delete mode 100644 littleTools/x-FileCopy/README.md delete mode 100644 littleTools/x-FileCopy/README_EN.md delete mode 100644 littleTools/x-FileCopy/pom.xml delete mode 100644 littleTools/x-FileCopy/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-FileCopy/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/FileCopyController.java delete mode 100644 littleTools/x-FileCopy/src/main/java/com/xwintop/xJavaFxTool/job/FileCopyJob.java delete mode 100644 littleTools/x-FileCopy/src/main/java/com/xwintop/xJavaFxTool/manager/ScheduleManager.java delete mode 100644 littleTools/x-FileCopy/src/main/java/com/xwintop/xJavaFxTool/model/FileCopyTableBean.java delete mode 100644 littleTools/x-FileCopy/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/FileCopyService.java delete mode 100644 littleTools/x-FileCopy/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/FileCopyView.java delete mode 100644 littleTools/x-FileCopy/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/FileCopy.fxml delete mode 100644 littleTools/x-FileCopy/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-FileCopy/src/main/resources/locale/FileCopy.properties delete mode 100644 littleTools/x-FileCopy/src/main/resources/locale/FileCopy_en_US.properties delete mode 100644 littleTools/x-FileMergeTool/.gitignore delete mode 100644 littleTools/x-FileMergeTool/README.md delete mode 100644 littleTools/x-FileMergeTool/README_EN.md delete mode 100644 littleTools/x-FileMergeTool/pom.xml delete mode 100644 littleTools/x-FileMergeTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-FileMergeTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/FileMergeToolController.java delete mode 100644 littleTools/x-FileMergeTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/FileMergeToolService.java delete mode 100644 littleTools/x-FileMergeTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/FileMergeToolView.java delete mode 100644 littleTools/x-FileMergeTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/FileMergeTool.fxml delete mode 100644 littleTools/x-FileMergeTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-FileMergeTool/src/main/resources/locale/FileMergeTool.properties delete mode 100644 littleTools/x-FileMergeTool/src/main/resources/locale/FileMergeTool_en_US.properties delete mode 100644 littleTools/x-FileRenameTool/.gitignore delete mode 100644 littleTools/x-FileRenameTool/README.md delete mode 100644 littleTools/x-FileRenameTool/README_EN.md delete mode 100644 littleTools/x-FileRenameTool/pom.xml delete mode 100644 littleTools/x-FileRenameTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-FileRenameTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/FileRenameToolController.java delete mode 100644 littleTools/x-FileRenameTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/FileRenameToolService.java delete mode 100644 littleTools/x-FileRenameTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/FileRenameToolView.java delete mode 100644 littleTools/x-FileRenameTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/FileRenameTool.fxml delete mode 100644 littleTools/x-FileRenameTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-FileRenameTool/src/main/resources/locale/FileRenameTool.properties delete mode 100644 littleTools/x-FileRenameTool/src/main/resources/locale/FileRenameTool_en_US.properties delete mode 100644 littleTools/x-FileSearchTool/.gitignore delete mode 100644 littleTools/x-FileSearchTool/README.md delete mode 100644 littleTools/x-FileSearchTool/README_EN.md delete mode 100644 littleTools/x-FileSearchTool/pom.xml delete mode 100644 littleTools/x-FileSearchTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-FileSearchTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/FileSearchToolController.java delete mode 100644 littleTools/x-FileSearchTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/FileSearchToolService.java delete mode 100644 littleTools/x-FileSearchTool/src/main/java/com/xwintop/xJavaFxTool/utils/ImgToolUtil.java delete mode 100644 littleTools/x-FileSearchTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/FileSearchToolView.java delete mode 100644 littleTools/x-FileSearchTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/FileSearchTool.fxml delete mode 100644 littleTools/x-FileSearchTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-FileSearchTool/src/main/resources/locale/FileSearchTool.properties delete mode 100644 littleTools/x-FileSearchTool/src/main/resources/locale/FileSearchTool_en_US.properties delete mode 100644 littleTools/x-IconTool/.gitignore delete mode 100644 littleTools/x-IconTool/README.md delete mode 100644 littleTools/x-IconTool/README_EN.md delete mode 100644 littleTools/x-IconTool/pom.xml delete mode 100644 littleTools/x-IconTool/src/main/java/com/xwintop/xJavaFxTool/IconToolMain.java delete mode 100644 littleTools/x-IconTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/IconToolController.java delete mode 100644 littleTools/x-IconTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/IconToolService.java delete mode 100644 littleTools/x-IconTool/src/main/java/com/xwintop/xJavaFxTool/utils/ImgToolUtil.java delete mode 100644 littleTools/x-IconTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/IconToolView.java delete mode 100644 littleTools/x-IconTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/IconTool.fxml delete mode 100644 littleTools/x-IconTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-IconTool/src/main/resources/data/iosAppIcon/Contents.json delete mode 100644 littleTools/x-IconTool/src/main/resources/locale/IconTool.properties delete mode 100644 littleTools/x-IconTool/src/main/resources/locale/IconTool_en_US.properties delete mode 100644 littleTools/x-ImageAnalysisTool/.gitignore delete mode 100644 littleTools/x-ImageAnalysisTool/README.md delete mode 100644 littleTools/x-ImageAnalysisTool/README_EN.md delete mode 100644 littleTools/x-ImageAnalysisTool/pom.xml delete mode 100644 littleTools/x-ImageAnalysisTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-ImageAnalysisTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/ImageAnalysisToolController.java delete mode 100644 littleTools/x-ImageAnalysisTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/ImageAnalysisToolService.java delete mode 100644 littleTools/x-ImageAnalysisTool/src/main/java/com/xwintop/xJavaFxTool/utils/ImgToolUtil.java delete mode 100644 littleTools/x-ImageAnalysisTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/ImageAnalysisToolView.java delete mode 100644 littleTools/x-ImageAnalysisTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/ImageAnalysisTool.fxml delete mode 100644 littleTools/x-ImageAnalysisTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-ImageAnalysisTool/src/main/resources/locale/ImageAnalysisTool.properties delete mode 100644 littleTools/x-ImageAnalysisTool/src/main/resources/locale/ImageAnalysisTool_en_US.properties delete mode 100644 littleTools/x-ImageTool/.editorconfig delete mode 100644 littleTools/x-ImageTool/.gitignore delete mode 100644 littleTools/x-ImageTool/README.md delete mode 100644 littleTools/x-ImageTool/README_EN.md delete mode 100644 littleTools/x-ImageTool/pom.xml delete mode 100644 littleTools/x-ImageTool/src/main/java/com/xwintop/xJavaFxTool/ImageToolMain.java delete mode 100644 littleTools/x-ImageTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/ImageToolController.java delete mode 100644 littleTools/x-ImageTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/AcceptableFormats.java delete mode 100644 littleTools/x-ImageTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/ImageInfo.java delete mode 100644 littleTools/x-ImageTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/ImageParameters.java delete mode 100644 littleTools/x-ImageTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/ImageToolService.java delete mode 100644 littleTools/x-ImageTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/OutputFormats.java delete mode 100644 littleTools/x-ImageTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/ResizeMode.java delete mode 100644 littleTools/x-ImageTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/ImageToolView.java delete mode 100644 littleTools/x-ImageTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/image-tool-main.fxml delete mode 100644 littleTools/x-ImageTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/image-tool.png delete mode 100644 littleTools/x-ImageTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-ImageTool/src/main/resources/locale/ImageTool.properties delete mode 100644 littleTools/x-ImageTool/src/main/resources/locale/ImageTool_en_US.properties delete mode 100644 littleTools/x-LinuxPathToWindowsPath/.gitignore delete mode 100644 littleTools/x-LinuxPathToWindowsPath/README.md delete mode 100644 littleTools/x-LinuxPathToWindowsPath/README_EN.md delete mode 100644 littleTools/x-LinuxPathToWindowsPath/pom.xml delete mode 100644 littleTools/x-LinuxPathToWindowsPath/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-LinuxPathToWindowsPath/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/LinuxPathToWindowsPathController.java delete mode 100644 littleTools/x-LinuxPathToWindowsPath/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/LinuxPathToWindowsPath.fxml delete mode 100644 littleTools/x-LinuxPathToWindowsPath/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-LinuxPathToWindowsPath/src/main/resources/locale/LinuxPathToWindowsPath.properties delete mode 100644 littleTools/x-LinuxPathToWindowsPath/src/main/resources/locale/LinuxPathToWindowsPath_en_US.properties delete mode 100644 littleTools/x-LiteappCode/.gitignore delete mode 100644 littleTools/x-LiteappCode/README.md delete mode 100644 littleTools/x-LiteappCode/README_EN.md delete mode 100644 littleTools/x-LiteappCode/pom.xml delete mode 100644 littleTools/x-LiteappCode/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-LiteappCode/src/main/java/com/xwintop/xJavaFxTool/controller/liteappcode/LiteappCodeController.java delete mode 100644 littleTools/x-LiteappCode/src/main/java/com/xwintop/xJavaFxTool/service/liteappcode/LiteappCodeService.java delete mode 100644 littleTools/x-LiteappCode/src/main/java/com/xwintop/xJavaFxTool/view/liteappcode/LiteappCodeView.java delete mode 100644 littleTools/x-LiteappCode/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/LiteappCode.fxml delete mode 100644 littleTools/x-LiteappCode/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-LiteappCode/src/main/resources/locale/LiteappCode.properties delete mode 100644 littleTools/x-LiteappCode/src/main/resources/locale/LiteappCode_en_US.properties delete mode 100644 littleTools/x-Mp3ConvertTool/.gitignore delete mode 100644 littleTools/x-Mp3ConvertTool/README.md delete mode 100644 littleTools/x-Mp3ConvertTool/README_EN.md delete mode 100644 littleTools/x-Mp3ConvertTool/pom.xml delete mode 100644 littleTools/x-Mp3ConvertTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-Mp3ConvertTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/Mp3ConvertToolController.java delete mode 100644 littleTools/x-Mp3ConvertTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/Mp3ConvertToolService.java delete mode 100644 littleTools/x-Mp3ConvertTool/src/main/java/com/xwintop/xJavaFxTool/utils/NcmDump.java delete mode 100644 littleTools/x-Mp3ConvertTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/Mp3ConvertToolView.java delete mode 100644 littleTools/x-Mp3ConvertTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/Mp3ConvertTool.fxml delete mode 100644 littleTools/x-Mp3ConvertTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-Mp3ConvertTool/src/main/resources/locale/Mp3ConvertTool.properties delete mode 100644 littleTools/x-Mp3ConvertTool/src/main/resources/locale/Mp3ConvertTool_en_US.properties delete mode 100644 littleTools/x-PdfConvertTool/.gitignore delete mode 100644 littleTools/x-PdfConvertTool/README.md delete mode 100644 littleTools/x-PdfConvertTool/README_EN.md delete mode 100644 littleTools/x-PdfConvertTool/pom.xml delete mode 100644 littleTools/x-PdfConvertTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-PdfConvertTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/PdfConvertToolController.java delete mode 100644 littleTools/x-PdfConvertTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/PdfConvertToolService.java delete mode 100644 littleTools/x-PdfConvertTool/src/main/java/com/xwintop/xJavaFxTool/utils/ImgToolUtil.java delete mode 100644 littleTools/x-PdfConvertTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/PdfConvertToolView.java delete mode 100644 littleTools/x-PdfConvertTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/PdfConvertTool.fxml delete mode 100644 littleTools/x-PdfConvertTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-PdfConvertTool/src/main/resources/locale/PdfConvertTool.properties delete mode 100644 littleTools/x-PdfConvertTool/src/main/resources/locale/PdfConvertTool_en_US.properties delete mode 100644 littleTools/x-QRCodeBuilder/.gitignore delete mode 100644 littleTools/x-QRCodeBuilder/README.md delete mode 100644 littleTools/x-QRCodeBuilder/README_EN.md delete mode 100644 littleTools/x-QRCodeBuilder/pom.xml delete mode 100644 littleTools/x-QRCodeBuilder/src/main/java/com/xwintop/xJavaFxTool/QrCodeBuilderMain.java delete mode 100644 littleTools/x-QRCodeBuilder/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/QRCodeBuilderController.java delete mode 100644 littleTools/x-QRCodeBuilder/src/main/java/com/xwintop/xJavaFxTool/utils/CorrectionLevel.java delete mode 100644 littleTools/x-QRCodeBuilder/src/main/java/com/xwintop/xJavaFxTool/utils/QRCodeUtil.java delete mode 100644 littleTools/x-QRCodeBuilder/src/main/java/com/xwintop/xJavaFxTool/utils/ScreenShoter.java delete mode 100644 littleTools/x-QRCodeBuilder/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/QRCodeBuilderView.java delete mode 100644 littleTools/x-QRCodeBuilder/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/QRCodeBuilder.fxml delete mode 100644 littleTools/x-QRCodeBuilder/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-QRCodeBuilder/src/main/resources/locale/QRCodeBuilder.properties delete mode 100644 littleTools/x-QRCodeBuilder/src/main/resources/locale/QRCodeBuilder_en_US.properties delete mode 100644 littleTools/x-SealBuilderTool/.gitignore delete mode 100644 littleTools/x-SealBuilderTool/README.md delete mode 100644 littleTools/x-SealBuilderTool/README_EN.md delete mode 100644 littleTools/x-SealBuilderTool/pom.xml delete mode 100644 littleTools/x-SealBuilderTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-SealBuilderTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/SealBuilderToolController.java delete mode 100644 littleTools/x-SealBuilderTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/SealBuilderToolService.java delete mode 100644 littleTools/x-SealBuilderTool/src/main/java/com/xwintop/xJavaFxTool/utils/ImgToolUtil.java delete mode 100644 littleTools/x-SealBuilderTool/src/main/java/com/xwintop/xJavaFxTool/utils/SealUtil.java delete mode 100644 littleTools/x-SealBuilderTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/SealBuilderToolView.java delete mode 100644 littleTools/x-SealBuilderTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/SealBuilderTool.fxml delete mode 100644 littleTools/x-SealBuilderTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-SealBuilderTool/src/main/resources/locale/SealBuilderTool.properties delete mode 100644 littleTools/x-SealBuilderTool/src/main/resources/locale/SealBuilderTool_en_US.properties delete mode 100644 littleTools/x-SedentaryReminderTool/.gitignore delete mode 100644 littleTools/x-SedentaryReminderTool/README.md delete mode 100644 littleTools/x-SedentaryReminderTool/README_EN.md delete mode 100644 littleTools/x-SedentaryReminderTool/pom.xml delete mode 100644 littleTools/x-SedentaryReminderTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-SedentaryReminderTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/SedentaryReminderToolController.java delete mode 100644 littleTools/x-SedentaryReminderTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/SedentaryReminderToolService.java delete mode 100644 littleTools/x-SedentaryReminderTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/SedentaryReminderToolView.java delete mode 100644 littleTools/x-SedentaryReminderTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/SedentaryReminderTool.fxml delete mode 100644 littleTools/x-SedentaryReminderTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-SedentaryReminderTool/src/main/resources/locale/SedentaryReminderTool.properties delete mode 100644 littleTools/x-SedentaryReminderTool/src/main/resources/locale/SedentaryReminderTool_en_US.properties delete mode 100644 littleTools/x-SmsTool/.gitignore delete mode 100644 littleTools/x-SmsTool/README.md delete mode 100644 littleTools/x-SmsTool/README_EN.md delete mode 100644 littleTools/x-SmsTool/pom.xml delete mode 100644 littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/SmsToolController.java delete mode 100644 littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/model/SmsToolTableBean.java delete mode 100644 littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/SmsToolService.java delete mode 100644 littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/SmsToolView.java delete mode 100644 littleTools/x-SmsTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/SmsTool.fxml delete mode 100644 littleTools/x-SmsTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-SmsTool/src/main/resources/locale/SmsTool.properties delete mode 100644 littleTools/x-SmsTool/src/main/resources/locale/SmsTool_en_US.properties delete mode 100644 littleTools/x-TimeTool/.gitignore delete mode 100644 littleTools/x-TimeTool/README.md delete mode 100644 littleTools/x-TimeTool/README_EN.md delete mode 100644 littleTools/x-TimeTool/pom.xml delete mode 100644 littleTools/x-TimeTool/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-TimeTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/TimeToolController.java delete mode 100644 littleTools/x-TimeTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/TimeToolService.java delete mode 100644 littleTools/x-TimeTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/TimeToolView.java delete mode 100644 littleTools/x-TimeTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/TimeTool.fxml delete mode 100644 littleTools/x-TimeTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-TimeTool/src/main/resources/locale/TimeTool.properties delete mode 100644 littleTools/x-TimeTool/src/main/resources/locale/TimeTool_en_US.properties delete mode 100644 littleTools/x-ZHConverter/.gitignore delete mode 100644 littleTools/x-ZHConverter/README.md delete mode 100644 littleTools/x-ZHConverter/README_EN.md delete mode 100644 littleTools/x-ZHConverter/pom.xml delete mode 100644 littleTools/x-ZHConverter/src/main/java/com/xwintop/xJavaFxTool/Main.java delete mode 100644 littleTools/x-ZHConverter/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/ZHConverterController.java delete mode 100644 littleTools/x-ZHConverter/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/ZHConverterService.java delete mode 100644 littleTools/x-ZHConverter/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/ZHConverterView.java delete mode 100644 littleTools/x-ZHConverter/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/ZHConverter.fxml delete mode 100644 littleTools/x-ZHConverter/src/main/resources/config/toolFxmlLoaderConfiguration.xml delete mode 100644 littleTools/x-ZHConverter/src/main/resources/locale/ZHConverter.properties delete mode 100644 littleTools/x-ZHConverter/src/main/resources/locale/ZHConverter_en_US.properties diff --git a/debugTools/x-ActiveMqTool/.gitignore b/debugTools/x-ActiveMqTool/.gitignore deleted file mode 100644 index 82b762a..0000000 --- a/debugTools/x-ActiveMqTool/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -#/.gitignore -/x-ActiveMqTool.iml -/log/ -/target/ \ No newline at end of file diff --git a/debugTools/x-ActiveMqTool/README.md b/debugTools/x-ActiveMqTool/README.md deleted file mode 100644 index 69a546b..0000000 --- a/debugTools/x-ActiveMqTool/README.md +++ /dev/null @@ -1,2 +0,0 @@ -ActiveMqTool -ActiveMq调试工具(目前仅支持ActiveMq) \ No newline at end of file diff --git a/debugTools/x-ActiveMqTool/README_EN.md b/debugTools/x-ActiveMqTool/README_EN.md deleted file mode 100644 index dd2460d..0000000 --- a/debugTools/x-ActiveMqTool/README_EN.md +++ /dev/null @@ -1 +0,0 @@ -ActiveMqTool \ No newline at end of file diff --git a/debugTools/x-ActiveMqTool/pom.xml b/debugTools/x-ActiveMqTool/pom.xml deleted file mode 100644 index 9e94cab..0000000 --- a/debugTools/x-ActiveMqTool/pom.xml +++ /dev/null @@ -1,96 +0,0 @@ - - 4.0.0 - - com.xwintop - x-ActiveMqTool - 0.0.1 - jar - x-ActiveMqTool - - - 1.8 - 1.8 - UTF-8 - - - - - aliyunmaven - http://maven.aliyun.com/nexus/content/groups/public/ - - - xwintop-maven - https://864381832.github.io/maven/repository - - - spring-snapshots - http://repo.spring.io/snapshot - - true - - - - spring-milestones - http://repo.spring.io/milestone - - - - - - junit - junit - 4.12 - test - - - com.xwintop - xcore - 0.0.6 - - - - org.projectlombok - lombok - 1.18.12 - provided - - - ch.qos.logback - logback-classic - 1.2.3 - - - org.springframework.boot - spring-boot-starter-activemq - 2.1.3.RELEASE - - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - 2.5.5 - - false - utf-8 - - jar-with-dependencies - - - - - make-assembly - package - - single - - - - - - - diff --git a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/Main.java b/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/Main.java deleted file mode 100644 index f58b1ea..0000000 --- a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/Main.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.xwintop.xJavaFxTool; - -import com.xwintop.xcore.util.javafx.JavaFxSystemUtil; -import javafx.application.Application; -import javafx.event.EventHandler; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.stage.Stage; -import javafx.stage.WindowEvent; -import lombok.extern.slf4j.Slf4j; - -import java.net.URL; -import java.util.ResourceBundle; - -@Slf4j -public class Main extends Application { - public static void main(String[] args) { - try { - launch(args); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public void start(Stage primaryStage) throws Exception { - FXMLLoader fXMLLoader = Main.getFXMLLoader(); - ResourceBundle resourceBundle = fXMLLoader.getResources(); - Parent root = fXMLLoader.load(); - primaryStage.setResizable(true); - primaryStage.setTitle(resourceBundle.getString("Title")); -// primaryStage.getIcons().add(new Image("/images/icon.jpg")); - double[] screenSize = JavaFxSystemUtil.getScreenSizeByScale(0.74D, 0.8D); - primaryStage.setScene(new Scene(root, screenSize[0], screenSize[1])); - primaryStage.show(); - primaryStage.setOnCloseRequest(new EventHandler() { - @Override - public void handle(WindowEvent event) { - System.exit(0); - } - }); - } - - public static FXMLLoader getFXMLLoader() { - ResourceBundle resourceBundle = ResourceBundle.getBundle("locale.ActiveMqTool"); - URL url = Object.class.getResource("/com/xwintop/xJavaFxTool/fxmlView/debugTools/ActiveMqTool.fxml"); - FXMLLoader fXMLLoader = new FXMLLoader(url, resourceBundle); - return fXMLLoader; - } -} \ No newline at end of file diff --git a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/ActiveMqToolController.java b/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/ActiveMqToolController.java deleted file mode 100644 index 2cf0eb3..0000000 --- a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/ActiveMqToolController.java +++ /dev/null @@ -1,301 +0,0 @@ -package com.xwintop.xJavaFxTool.controller.debugTools; - -import com.xwintop.xJavaFxTool.model.ActiveMqToolReceiverTableBean; -import com.xwintop.xJavaFxTool.model.ActiveMqToolTableBean; -import com.xwintop.xJavaFxTool.services.debugTools.ActiveMqToolService; -import com.xwintop.xJavaFxTool.view.debugTools.ActiveMqToolView; -import com.xwintop.xcore.base.XProperty; - -import com.xwintop.xcore.util.javafx.JavaFxViewUtil; -import org.apache.activemq.ActiveMQSession; - -import java.net.URL; -import java.util.ResourceBundle; - -import javax.jms.JMSException; -import javax.jms.Session; - -import javafx.application.Platform; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener.Change; -import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.event.Event; -import javafx.fxml.FXML; -import javafx.scene.control.ContextMenu; -import javafx.scene.control.MenuItem; -import javafx.scene.control.TableColumn.CellEditEvent; -import javafx.scene.control.cell.CheckBoxTableCell; -import javafx.scene.control.cell.ChoiceBoxTableCell; -import javafx.scene.control.cell.PropertyValueFactory; -import javafx.scene.control.cell.TextFieldTableCell; -import javafx.scene.input.MouseButton; -import lombok.Getter; - -/** - * @ClassName: ActiveMqToolController - * @Description: ActiveMq调试工具 - * @author: xufeng - * @date: 2019/4/25 0025 23:21 - */ - -@Getter -public class ActiveMqToolController extends ActiveMqToolView { - private ActiveMqToolService activeMqToolService = new ActiveMqToolService(this); - private ObservableList tableData = FXCollections.observableArrayList(); - private ObservableList receiverTableData = FXCollections.observableArrayList(); - private String[] messageTypeStrings = new String[] { "TextMessage", "ObjectMessage", "BytesMessage", "MapMessage", - "StreamMessage" }; - private String[] quartzChoiceBoxStrings = new String[] { "简单表达式", "Cron表达式" }; - @SuppressWarnings("unchecked") - private XProperty[] receiverAcknowledgeModeChoiceBoxValues = new XProperty[] { - new XProperty("SESSION_TRANSACTED", Session.SESSION_TRANSACTED), - new XProperty("AUTO_ACKNOWLEDGE", Session.AUTO_ACKNOWLEDGE), - new XProperty("CLIENT_ACKNOWLEDGE", Session.CLIENT_ACKNOWLEDGE), - new XProperty("DUPS_OK_ACKNOWLEDGE", Session.DUPS_OK_ACKNOWLEDGE), - new XProperty("INDIVIDUAL_ACKNOWLEDGE", ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE) }; - - @Override - public void initialize(URL location, ResourceBundle resources) { - initService(); - initView(); - initEvent(); - } - - private void initView() { - JavaFxViewUtil.setSpinnerValueFactory(sendNumberSpinner, 1, Integer.MAX_VALUE); - messageTypeChoiceBox.getItems().addAll(messageTypeStrings); - messageTypeChoiceBox.setValue(messageTypeStrings[0]); - queueTableColumn.setCellValueFactory(new PropertyValueFactory("queue")); - queueTableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - queueTableColumn.setOnEditCommit((CellEditEvent t) -> { - t.getRowValue().setQueue(t.getNewValue()); - }); - messageTableColumn.setCellValueFactory(new PropertyValueFactory("message")); - messageTableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - messageTableColumn.setOnEditCommit((CellEditEvent t) -> { - t.getRowValue().setMessage(t.getNewValue()); - }); - sendNumberTableColumn - .setCellValueFactory(new PropertyValueFactory("sendNumber")); - sendNumberTableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - sendNumberTableColumn.setOnEditCommit((CellEditEvent t) -> { - t.getRowValue().setSendNumber(t.getNewValue()); - }); - messageTypeTableColumn - .setCellValueFactory(new PropertyValueFactory("messageType")); - messageTypeTableColumn - .setCellFactory(ChoiceBoxTableCell.forTableColumn(messageTypeStrings)); - isSendTableColumn.setCellValueFactory(new PropertyValueFactory("isSend")); - isSendTableColumn.setCellFactory(CheckBoxTableCell.forTableColumn(isSendTableColumn)); - isCreateTableColumn.setCellValueFactory(new PropertyValueFactory("isCreate")); - isCreateTableColumn.setCellFactory(CheckBoxTableCell.forTableColumn(isCreateTableColumn)); - isRequiredReplyTableColumn - .setCellValueFactory(new PropertyValueFactory("isRequiredReply")); - isRequiredReplyTableColumn.setCellFactory(CheckBoxTableCell.forTableColumn(isRequiredReplyTableColumn)); - tableViewMain.setItems(tableData); - quartzChoiceBox.getItems().addAll(quartzChoiceBoxStrings); - quartzChoiceBox.setValue(quartzChoiceBoxStrings[0]); - JavaFxViewUtil.setSpinnerValueFactory(intervalSpinner, 1, Integer.MAX_VALUE); - JavaFxViewUtil.setSpinnerValueFactory(repeatCountSpinner, -1, Integer.MAX_VALUE); - - initReceiverView(); - } - - private void initReceiverView() { - receiverAcknowledgeModeChoiceBox.getItems().addAll(receiverAcknowledgeModeChoiceBoxValues); - receiverAcknowledgeModeChoiceBox.setValue(receiverAcknowledgeModeChoiceBoxValues[4]); - receiverMessageIDTableColumn - .setCellValueFactory(new PropertyValueFactory("messageID")); - receiverQueueTableColumn - .setCellValueFactory(new PropertyValueFactory("queue")); - receiverMessageTableColumn - .setCellValueFactory(new PropertyValueFactory("message")); - receiverMessageTypeTableColumn - .setCellValueFactory(new PropertyValueFactory("messageType")); - receiverTimestampTableColumn - .setCellValueFactory(new PropertyValueFactory("timestamp")); - receiverIsAcknowledgeTableColumn - .setCellValueFactory(new PropertyValueFactory("isAcknowledge")); - receiverIsAcknowledgeTableColumn - .setCellFactory(CheckBoxTableCell.forTableColumn(receiverIsAcknowledgeTableColumn)); - receiverTableView.setItems(receiverTableData); - } - - private void initEvent() { - tableData.addListener((Change tableBean) -> { - try { - saveConfigureAction(null); - } catch (Exception e) { - e.printStackTrace(); - } - }); - tableViewMain.setOnMouseClicked(event -> { - if (event.getButton() == MouseButton.SECONDARY) { - MenuItem menu_Copy = new MenuItem("复制选中行"); - menu_Copy.setOnAction(event1 -> { - ActiveMqToolTableBean tableBean = tableViewMain.getSelectionModel().getSelectedItem(); - ActiveMqToolTableBean tableBean2 = new ActiveMqToolTableBean(tableBean.getPropertys()); - tableData.add(tableViewMain.getSelectionModel().getSelectedIndex(), tableBean2); - }); - MenuItem menu_Remove = new MenuItem("删除选中行"); - menu_Remove.setOnAction(event1 -> { - deleteSelectRowAction(null); - }); - MenuItem menu_RemoveAll = new MenuItem("删除所有"); - menu_RemoveAll.setOnAction(event1 -> { - tableData.clear(); - }); - tableViewMain.setContextMenu(new ContextMenu(menu_Copy, menu_Remove, menu_RemoveAll)); - } - }); - quartzChoiceBox.valueProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, String oldValue, String newValue) { - if (quartzChoiceBoxStrings[0].equals(newValue)) { - cronTextField.setVisible(false); - simpleScheduleAnchorPane.setVisible(true); - } else if (quartzChoiceBoxStrings[1].equals(newValue)) { - cronTextField.setVisible(true); - simpleScheduleAnchorPane.setVisible(false); - } - } - }); - initReceiverEvent(); - } - - private void initReceiverEvent() { - receiverTableView.setOnMouseClicked(event -> { - if (event.getButton() == MouseButton.SECONDARY) { - MenuItem menu_acknowledge1 = new MenuItem("消费该消息"); - menu_acknowledge1.setOnAction(event1 -> { - ActiveMqToolReceiverTableBean tableBean = receiverTableView.getSelectionModel().getSelectedItem(); - tableBean.setIsAcknowledge(true); - try { - activeMqToolService.getReceiverMessageMap().get(tableBean.getMessageID()).acknowledge(); - activeMqToolService.getReceiverMessageMap().remove(tableBean.getMessageID()); - } catch (JMSException e) { - e.printStackTrace(); - } - }); - MenuItem menu_acknowledge = new MenuItem("消费全部消息"); - menu_acknowledge.setOnAction(event1 -> { - for (ActiveMqToolReceiverTableBean tableBean : receiverTableData) { - tableBean.setIsAcknowledge(true); - try { - activeMqToolService.getReceiverMessageMap().get(tableBean.getMessageID()).acknowledge(); - activeMqToolService.getReceiverMessageMap().remove(tableBean.getMessageID()); - } catch (JMSException e) { - e.printStackTrace(); - } - } - }); - MenuItem menu_Remove = new MenuItem("删除选中行"); - menu_Remove.setOnAction(event1 -> { - deleteSelectRowAction(null); - receiverTableData.remove(receiverTableView.getSelectionModel().getSelectedIndex()); - }); - MenuItem menu_RemoveAll = new MenuItem("删除所有"); - menu_RemoveAll.setOnAction(event1 -> { - receiverTableData.clear(); - }); - receiverTableView.setContextMenu( - new ContextMenu(menu_acknowledge1, menu_acknowledge, menu_Remove, menu_RemoveAll)); - } - }); - } - - private void initService() { - activeMqToolService.loadingConfigure(); - } - - @FXML - private void addItemAction(ActionEvent event) { - tableData.add(new ActiveMqToolTableBean(queueTextField.getText(), messageTextField.getText(), - sendNumberSpinner.getValue().toString(), messageTypeChoiceBox.getValue(), isSendCheckBox.isSelected(), - isCreateCheckBox.isSelected(), isRequiredReplyCheckBox.isSelected())); - } - - @FXML - private void saveConfigureAction(ActionEvent event) throws Exception { - activeMqToolService.saveConfigure(); - } - - @FXML - private void otherSaveConfigureAction(ActionEvent event) throws Exception { - activeMqToolService.otherSaveConfigureAction(); - } - - @FXML - private void loadingConfigureAction(ActionEvent event) { - activeMqToolService.loadingConfigureAction(); - } - - @FXML - private void deleteSelectRowAction(ActionEvent event) { - tableData.remove(tableViewMain.getSelectionModel().getSelectedItem()); - } - - @FXML - private void runQuartzAction(ActionEvent event) throws Exception { - if ("定时发送".equals(runQuartzButton.getText())) { - boolean isTrue = activeMqToolService.runQuartzAction(quartzChoiceBox.getValue(), cronTextField.getText(), - intervalSpinner.getValue(), repeatCountSpinner.getValue()); - if (isTrue) { - runQuartzButton.setText("停止发送"); - } - } else { - boolean isTrue = activeMqToolService.stopQuartzAction(); - if (isTrue) { - runQuartzButton.setText("定时发送"); - } - } - } - - /** - * @Title: sendAction - * @Description: 客户端发送消息 - */ - @FXML - private void sendAction(ActionEvent event) { - activeMqToolService.sendAction(); - } - - /** - * @Title: receiverMessageListenerAction - * @Description: receiver端监听消息 - */ - @FXML - private void receiverMessageListenerAction(ActionEvent event) { - // receiverTableData.add(new ActiveMqToolReceiverTableBean("1", "2", - // "1", "1", "2", true)); - if ("监听消息".equals(receiverMessageListenerButton.getText())) { - activeMqToolService.receiverMessageListenerAction(); - receiverMessageListenerButton.setText("停止监听"); - } else { - activeMqToolService.receiverMessageStopListenerAction(); - receiverMessageListenerButton.setText("监听消息"); - } - } - - /** - * @Title: receiverPullMessageAction - * @Description: receiver端拉取消息 - */ - @FXML - private void receiverPullMessageAction(ActionEvent event) { - Platform.runLater(() -> { - activeMqToolService.receiverPullMessageAction(); - }); - } - - /** - * 父控件被移除前调用 - */ - public void onCloseRequest(Event event) throws Exception { - activeMqToolService.stopQuartzAction(); - activeMqToolService.receiverMessageStopListenerAction(); - } -} \ No newline at end of file diff --git a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/job/ActiveMqToolJob.java b/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/job/ActiveMqToolJob.java deleted file mode 100644 index 9835eec..0000000 --- a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/job/ActiveMqToolJob.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.xwintop.xJavaFxTool.job; - -import com.xwintop.xJavaFxTool.services.debugTools.ActiveMqToolService; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -import org.quartz.JobKey; - -public class ActiveMqToolJob implements Job { - - @Override - public void execute(JobExecutionContext context) throws JobExecutionException { - ActiveMqToolService activeMqToolService = (ActiveMqToolService) context.getMergedJobDataMap().get("Service"); - try { - activeMqToolService.sendAction(); - } catch (Exception e) { - e.printStackTrace(); - } - JobKey jobKey = context.getJobDetail().getKey(); - System.out.println("执行了"+jobKey); - } -} \ No newline at end of file diff --git a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/manager/ScheduleManager.java b/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/manager/ScheduleManager.java deleted file mode 100644 index 0ef56a8..0000000 --- a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/manager/ScheduleManager.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.xwintop.xJavaFxTool.manager; - -import com.xwintop.xcore.util.javafx.TooltipUtil; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.quartz.*; -import org.quartz.impl.StdSchedulerFactory; - -/** - * @ClassName: ScheduleManager - * @Description: 自动任务管理类 - * @author: xufeng - * @date: 2018/1/25 16:35 - */ - -@Getter -@Setter -@Slf4j -public class ScheduleManager { - private SchedulerFactory sf = new StdSchedulerFactory(); - private String schedulerKeyGroup = "x"; - private String schedulerKeyName = "x" + System.currentTimeMillis(); - - public enum QuartzType { - SIMPLE //简单表达式 - , CRON //Cron表达式 - } - - public void runQuartzAction(Class jobClass, String quartzType, Object jobDataMap, String cronText, int interval, int repeatCount) throws Exception { - if ("简单表达式".equals(quartzType)) { - this.runQuartzAction(jobClass, jobDataMap, interval, repeatCount); - } else if ("Cron表达式".equals(quartzType)) { - if (StringUtils.isEmpty(cronText)) { - TooltipUtil.showToast("cron表达式不能为空。"); - throw new Exception("cron表达式不能为空。"); - } - this.runQuartzAction(jobClass, jobDataMap, cronText); - } - } - - public void runQuartzAction(Class jobClass, Object jobDataMap, int interval, int repeatCount) throws Exception { - runQuartzAction(jobClass, jobDataMap, QuartzType.SIMPLE, null, interval, repeatCount); - } - - public void runQuartzAction(Class jobClass, Object jobDataMap, String cronText) throws Exception { - runQuartzAction(jobClass, jobDataMap, QuartzType.CRON, cronText, 0, 0); - } - - public void runQuartzAction(Class jobClass, Object jobDataMap, QuartzType quartzType, String cronText, int interval, int repeatCount) throws Exception { - schedulerKeyGroup = jobClass.toString(); - schedulerKeyName = schedulerKeyGroup + System.currentTimeMillis(); - JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(schedulerKeyName, schedulerKeyGroup) - .build(); - jobDetail.getJobDataMap().put("Service", jobDataMap); - ScheduleBuilder scheduleBuilder = null; - if (QuartzType.SIMPLE.equals(quartzType)) { - scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(interval)// 时间间隔 - .withRepeatCount(repeatCount);// 重复次数(将执行6次) - } else if (QuartzType.CRON.equals(quartzType)) { - if (StringUtils.isEmpty(cronText)) { - throw new Exception("cron表达式不能为空。"); - } - scheduleBuilder = CronScheduleBuilder.cronSchedule(cronText); - } - // 描叙触发Job执行的时间触发规则,Trigger实例化一个触发器 - Trigger trigger = TriggerBuilder.newTrigger()// 创建一个新的TriggerBuilder来规范一个触发器 - .withIdentity(schedulerKeyName, schedulerKeyGroup)// 给触发器一个名字和组名 - .startNow()// 立即执行 - .withSchedule(scheduleBuilder).build();// 产生触发器 - - // 运行容器,使用SchedulerFactory创建Scheduler实例 - Scheduler scheduler = sf.getScheduler(); - // 向Scheduler添加一个job和trigger - scheduler.scheduleJob(jobDetail, trigger); - if (!scheduler.isStarted()) { - scheduler.start(); - } - } - - public void stopQuartzAction() throws Exception { - Scheduler sched = sf.getScheduler(); - sched.unscheduleJob(new TriggerKey(schedulerKeyName, schedulerKeyGroup)); - sched.deleteJob(new JobKey(schedulerKeyName, schedulerKeyGroup)); - } -} diff --git a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/model/ActiveMqToolReceiverTableBean.java b/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/model/ActiveMqToolReceiverTableBean.java deleted file mode 100644 index 4ed22e6..0000000 --- a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/model/ActiveMqToolReceiverTableBean.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.xwintop.xJavaFxTool.model; - -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.SimpleStringProperty; - -public class ActiveMqToolReceiverTableBean { - private SimpleStringProperty messageID; - private SimpleStringProperty queue; - private SimpleStringProperty message; - private SimpleStringProperty messageType; - private SimpleStringProperty timestamp; - private SimpleBooleanProperty isAcknowledge; - - public ActiveMqToolReceiverTableBean(String messageID, String queue, String message, String messageType, - String timestamp, Boolean isAcknowledge) { - super(); - this.messageID = new SimpleStringProperty(messageID); - this.queue = new SimpleStringProperty(queue); - this.message = new SimpleStringProperty(message); - this.messageType = new SimpleStringProperty(messageType); - this.timestamp = new SimpleStringProperty(timestamp); - this.isAcknowledge = new SimpleBooleanProperty(isAcknowledge); - } - - public ActiveMqToolReceiverTableBean(String propertys) { - String[] strings = propertys.split("__",6); - this.messageID = new SimpleStringProperty(strings[0]); - this.queue = new SimpleStringProperty(strings[1]); - this.message = new SimpleStringProperty(strings[2]); - this.messageType = new SimpleStringProperty(strings[3]); - this.timestamp = new SimpleStringProperty(strings[4]); - this.isAcknowledge = new SimpleBooleanProperty(Boolean.valueOf(strings[5])); - } - - public String getPropertys() { - return messageID.get() + "__" + queue.get() + "__" + message.get() + "__" + messageType.get() + "__" - + timestamp.get() + "__" + isAcknowledge.get(); - } - - public String getMessageID() { - return messageID.get(); - } - - public void setMessageID(String messageID) { - this.messageID.set(messageID); - } - - public String getQueue() { - return queue.get(); - } - - public void setQueue(String queue) { - this.queue.set(queue); - } - - public String getMessage() { - return message.get(); - } - - public void setMessage(String message) { - this.message.set(message); - } - - public String getMessageType() { - return messageType.get(); - } - - public void setMessageType(String messageType) { - this.messageType.set(messageType); - } - - public String getTimestamp() { - return timestamp.get(); - } - - public void setTimestamp(String timestamp) { - this.timestamp.set(timestamp); - } - - public Boolean getIsAcknowledge() { - return isAcknowledge.getValue(); - } - - public BooleanProperty isAcknowledgeProperty() { - return isAcknowledge; - } - - public void setIsAcknowledge(Boolean isAcknowledge) { - this.isAcknowledge.set(isAcknowledge); - } - -} diff --git a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/model/ActiveMqToolTableBean.java b/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/model/ActiveMqToolTableBean.java deleted file mode 100644 index 7260d75..0000000 --- a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/model/ActiveMqToolTableBean.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.xwintop.xJavaFxTool.model; - -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; - -public class ActiveMqToolTableBean { - private SimpleStringProperty queue; - private SimpleStringProperty message; - private SimpleStringProperty sendNumber; - private SimpleStringProperty messageType; - private SimpleBooleanProperty isSend; - private SimpleBooleanProperty isCreate; - private SimpleBooleanProperty isRequiredReply; - - public ActiveMqToolTableBean(String queue, String message, String sendNumber, String messageType, Boolean isSend, - Boolean isCreate, Boolean isRequiredReply) { - super(); - this.queue = new SimpleStringProperty(queue); - this.message = new SimpleStringProperty(message); - this.sendNumber = new SimpleStringProperty(sendNumber); - this.messageType = new SimpleStringProperty(messageType); - this.isSend = new SimpleBooleanProperty(isSend); - this.isCreate = new SimpleBooleanProperty(isCreate); - this.isRequiredReply = new SimpleBooleanProperty(isRequiredReply); - } - - public ActiveMqToolTableBean(String propertys) { - String[] strings = propertys.split("__",7); - this.queue = new SimpleStringProperty(strings[0]); - this.message = new SimpleStringProperty(strings[1]); - this.sendNumber = new SimpleStringProperty(strings[2]); - this.messageType = new SimpleStringProperty(strings[3]); - this.isSend = new SimpleBooleanProperty(Boolean.valueOf(strings[4])); - this.isCreate = new SimpleBooleanProperty(Boolean.valueOf(strings[5])); - this.isRequiredReply = new SimpleBooleanProperty(Boolean.valueOf(strings[6])); - } - - public String getPropertys() { - return queue.get() + "__" + message.get() + "__" + sendNumber.get() + "__" + messageType.get() + "__" - + isSend.get() + "__" + isCreate.get() + "__" + isRequiredReply.get(); - } - - public String getQueue() { - return queue.get(); - } - - public void setQueue(String queue) { - this.queue.set(queue); - } - - public String getMessage() { - return message.get(); - } - - public void setMessage(String message) { - this.message.set(message); - } - - public String getSendNumber() { - return sendNumber.get(); - } - - public void setSendNumber(String sendNumber) { - this.sendNumber.set(sendNumber); - } - - public String getMessageType() { - return messageType.get(); - } - - public StringProperty messageTypeProperty() { - return messageType; - } - - public void setMessageType(String messageType) { - this.messageType.set(messageType); - } - - public Boolean getIsSend() { - return isSend.getValue(); - } - - public BooleanProperty isSendProperty() { - return isSend; - } - - public void setIsSend(Boolean isSend) { - this.isSend.set(isSend); - } - - public Boolean getIsCreate() { - return isCreate.getValue(); - } - - public BooleanProperty isCreateProperty() { - return isCreate; - } - - public void setIsCreate(Boolean isCreate) { - this.isCreate.set(isCreate); - } - - public Boolean getIsRequiredReply() { - return isRequiredReply.getValue(); - } - - public BooleanProperty isRequiredReplyProperty() { - return isRequiredReply; - } - - public void setIsRequiredReply(Boolean isRequiredReply) { - this.isRequiredReply.set(isRequiredReply); - } - -} diff --git a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/ActiveMqToolService.java b/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/ActiveMqToolService.java deleted file mode 100644 index 8c23ffc..0000000 --- a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/ActiveMqToolService.java +++ /dev/null @@ -1,347 +0,0 @@ -package com.xwintop.xJavaFxTool.services.debugTools; - -import cn.hutool.json.JSONUtil; -import com.xwintop.xJavaFxTool.controller.debugTools.ActiveMqToolController; -import com.xwintop.xJavaFxTool.job.ActiveMqToolJob; -import com.xwintop.xJavaFxTool.manager.ScheduleManager; -import com.xwintop.xJavaFxTool.model.ActiveMqToolReceiverTableBean; -import com.xwintop.xJavaFxTool.model.ActiveMqToolTableBean; -import com.xwintop.xcore.util.ConfigureUtil; -import com.xwintop.xcore.util.javafx.FileChooserUtil; -import com.xwintop.xcore.util.javafx.TooltipUtil; -import javafx.application.Platform; -import javafx.fxml.FXML; -import javafx.stage.FileChooser; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.apache.activemq.ActiveMQConnectionFactory; -import org.apache.activemq.command.ActiveMQBytesMessage; -import org.apache.activemq.command.ActiveMQMapMessage; -import org.apache.commons.configuration.PropertiesConfiguration; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.StringUtils; - -import javax.jms.*; -import java.io.File; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; - -/** - * @ClassName: ActiveMqToolService - * @Description: ActiveMq调试工具 - * @author: xufeng - * @date: 2019/4/25 0025 23:28 - */ - -@Getter -@Setter -@Slf4j -public class ActiveMqToolService { - private ActiveMqToolController activeMqToolController; - private ScheduleManager scheduleManager = new ScheduleManager(); - private Map receiverMessageMap = new HashMap(); - // ConnectionFactory :连接工厂,JMS 用它创建连接 - private ConnectionFactory connectionFactory = null; - // Connection :JMS 客户端到JMS Provider 的连接 - private Connection connection = null; - - public void saveConfigure() throws Exception { - saveConfigure(ConfigureUtil.getConfigureFile("ActiveMqToolConfigure.properties")); - } - - public void saveConfigure(File file) throws Exception { - FileUtils.touch(file); - PropertiesConfiguration xmlConfigure = new PropertiesConfiguration(file); - xmlConfigure.clear(); - for (int i = 0; i < activeMqToolController.getTableData().size(); i++) { - xmlConfigure.setProperty("tableBean" + i, activeMqToolController.getTableData().get(i).getPropertys()); - } - xmlConfigure.save(); - Platform.runLater(() -> { - TooltipUtil.showToast("保存配置成功,保存在:" + file.getPath()); - }); - } - - public void otherSaveConfigureAction() throws Exception { - String fileName = "ActiveMqToolConfigure.properties"; - File file = FileChooserUtil.chooseSaveFile(fileName, new FileChooser.ExtensionFilter("All File", "*.*"), - new FileChooser.ExtensionFilter("Properties", "*.properties")); - if (file != null) { - saveConfigure(file); - TooltipUtil.showToast("保存配置成功,保存在:" + file.getPath()); - } - } - - public void loadingConfigure() { - loadingConfigure(ConfigureUtil.getConfigureFile("ActiveMqToolConfigure.properties")); - } - - public void loadingConfigure(File file) { - try { - activeMqToolController.getTableData().clear(); - PropertiesConfiguration xmlConfigure = new PropertiesConfiguration(file); - xmlConfigure.getKeys().forEachRemaining(new Consumer() { - @Override - public void accept(String t) { - activeMqToolController.getTableData().add(new ActiveMqToolTableBean(xmlConfigure.getString(t))); - } - }); - } catch (Exception e) { - try { - TooltipUtil.showToast("加载配置失败:" + e.getMessage()); - } catch (Exception e2) { - } - } - } - - public void loadingConfigureAction() { - File file = FileChooserUtil.chooseFile(new FileChooser.ExtensionFilter("All File", "*.*"), - new FileChooser.ExtensionFilter("Properties", "*.properties")); - if (file != null) { - loadingConfigure(file); - } - } - - public void sendAction() { - for (ActiveMqToolTableBean tableBean : activeMqToolController.getTableData()) { - if (tableBean.getIsSend()) { - int sendNumber = Integer.parseInt(tableBean.getSendNumber()); - // Connection :JMS 客户端到JMS Provider 的连接 - Connection connection = null; - // TextMessage message; - // ConnectionFactory :连接工厂,JMS 用它创建连接 - // 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar - ConnectionFactory connectionFactory = new ActiveMQConnectionFactory( - activeMqToolController.getUserNameTextField().getText(), - activeMqToolController.getPasswordTextField().getText(), - "tcp://" + activeMqToolController.getUrlTextField().getText().trim()); - try { - // 构造从工厂得到连接对象 - connection = connectionFactory.createConnection(); - // 启动 - connection.start(); - // 获取操作连接(一个发送或接收消息的线程) - Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); - // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置 - Destination destination = session.createQueue(tableBean.getQueue()); - // 得到消息生成者【发送者】 - MessageProducer producer = session.createProducer(destination); - // 设置不持久化,此处学习,实际根据项目决定 - producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); - // 构造消息,此处写死,项目就是参数,或者方法获取 - for (int i = 0; i < sendNumber; i++) { - sendMessage(session, producer, tableBean.getMessageType(), tableBean.getMessage()); - } - session.commit(); - } catch (Exception e) { - e.printStackTrace(); - TooltipUtil.showToast("发送失败:" + e.getMessage()); - } finally { - try { - if (null != connection) { - connection.close(); - } - } catch (Throwable ignore) { - } - } - } - } - } - - private void sendMessage(Session session, MessageProducer producer, String messageType, String messageText) - throws Exception { - Message message = null; - String[] messageTypeStrings = activeMqToolController.getMessageTypeStrings(); - if (messageTypeStrings[0].equals(messageType)) { - message = session.createTextMessage(messageText); - } else if (messageTypeStrings[1].equals(messageType)) { - message = session.createObjectMessage(messageText); - } else if (messageTypeStrings[2].equals(messageType)) { - message = session.createBytesMessage(); - ((BytesMessage) message).writeBytes(messageText.getBytes()); - } else if (messageTypeStrings[3].equals(messageType)) { - message = session.createMapMessage(); - Map map = JSONUtil.toBean(messageText, Map.class); - final MapMessage mapMessage = (MapMessage) message; - map.forEach((String key, Object value) -> { - try { - mapMessage.setObject(key, value); - } catch (JMSException e) { - e.printStackTrace(); - } - }); - } else if (messageTypeStrings[4].equals(messageType)) { - message = session.createStreamMessage(); - ((StreamMessage) message).writeString(messageText); - } - producer.send(message); - TooltipUtil.showToast("消息发送成功!!!"); - } - - public boolean runQuartzAction(String quartzType, String cronText, int interval, int repeatCount) throws Exception { - if ("简单表达式".equals(quartzType)) { - scheduleManager.runQuartzAction(ActiveMqToolJob.class, this, interval, repeatCount); - } else if ("Cron表达式".equals(quartzType)) { - if (StringUtils.isEmpty(cronText)) { - TooltipUtil.showToast("cron表达式不能为空。"); - return false; - } - scheduleManager.runQuartzAction(ActiveMqToolJob.class, this, cronText); - } - return true; - } - - public boolean stopQuartzAction() throws Exception { - scheduleManager.stopQuartzAction(); - return true; - } - - /** - * @Title: receiverMessageListenerAction - * @Description: receiver端监听消息 - */ - public void receiverMessageListenerAction() { - // Session: 一个发送或接收消息的线程 - Session session; - // Destination :消息的目的地;消息发送给谁. - Destination destination; - // 消费者,消息接收者 - MessageConsumer consumer; - connectionFactory = new ActiveMQConnectionFactory(activeMqToolController.getUserNameTextField().getText(), - activeMqToolController.getPasswordTextField().getText(), - "tcp://" + activeMqToolController.getUrlTextField().getText().trim()); - try { - if (connection != null) { - connection.close(); - } - // 构造从工厂得到连接对象 - connection = connectionFactory.createConnection(); - // 启动 - connection.start(); - // 获取操作连接 - session = connection.createSession(Boolean.FALSE, activeMqToolController - .getReceiverAcknowledgeModeChoiceBox().getValue().getBean()); - // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置 - String queue = activeMqToolController.getReceiverQueueTextField().getText(); - destination = session.createQueue(queue); - consumer = session.createConsumer(destination); - activeMqToolController.getReceiverTableData().clear(); - receiverMessageMap.clear(); - consumer.setMessageListener(new MessageListener() {// 有事务限制 - @Override - public void onMessage(Message message) { - addReceiverTableBean(message); - // try { - // session.commit(); - // } catch (JMSException e) { - // e.printStackTrace(); - // } - } - }); - } catch (Exception e) { - log.error("receiver端监听消息失败", e); - TooltipUtil.showToast(e.getMessage()); - } - } - - public void receiverMessageStopListenerAction() { - if (connection != null) { - try { - connection.close(); - } catch (JMSException e) { - log.error("关闭连接失败", e); - TooltipUtil.showToast(e.getMessage()); - } - } - } - - private void addReceiverTableBean(Message message) { - String queue = activeMqToolController.getReceiverQueueTextField().getText(); - String messageType = "TextMessage"; - String messageSring = null; - boolean isAcknowledge = false; - try { - if (message instanceof TextMessage) { - messageType = "TextMessage"; - messageSring = ((TextMessage) message).getText(); - } else if (message instanceof ObjectMessage) { - messageType = "ObjectMessage"; - messageSring = ((ObjectMessage) message).getObject().toString(); - } else if (message instanceof BytesMessage) { - messageType = "BytesMessage"; - messageSring = new String(((ActiveMQBytesMessage) message).getContent().getData()); - } else if (message instanceof MapMessage) { - messageType = "MapMessage"; - messageSring = ((ActiveMQMapMessage) message).getContentMap().toString(); - } else if (message instanceof StreamMessage) { - messageType = "StreamMessage"; - messageSring = ((StreamMessage) message).readString(); - } - String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(message.getJMSTimestamp())); - ActiveMqToolReceiverTableBean activeMqToolReceiverTableBean = new ActiveMqToolReceiverTableBean( - message.getJMSMessageID(), queue, messageSring, messageType, timestamp, isAcknowledge); - activeMqToolController.getReceiverTableData().add(activeMqToolReceiverTableBean); - receiverMessageMap.put(message.getJMSMessageID(), message); - } catch (Exception e) { - log.error("添加配置失败", e); - } - } - - /** - * @Title: receiverPullMessageAction - * @Description: receiver端拉取消息 - */ - @FXML - public void receiverPullMessageAction() { - // Session: 一个发送或接收消息的线程 - Session session; - // Destination :消息的目的地;消息发送给谁. - Destination destination; - // 消费者,消息接收者 - MessageConsumer consumer; - connectionFactory = new ActiveMQConnectionFactory(activeMqToolController.getUserNameTextField().getText(), - activeMqToolController.getPasswordTextField().getText(), - "tcp://" + activeMqToolController.getUrlTextField().getText().trim()); - try { - if (connection != null) { - connection.close(); - } - // 构造从工厂得到连接对象 - connection = connectionFactory.createConnection(); - // 启动 - connection.start(); - // 获取操作连接 - // session = connection.createSession(Boolean.FALSE, - // Session.AUTO_ACKNOWLEDGE); - session = connection.createSession(Boolean.FALSE, activeMqToolController - .getReceiverAcknowledgeModeChoiceBox().getValue().getBean()); - // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置 - String queue = activeMqToolController.getReceiverQueueTextField().getText(); - destination = session.createQueue(queue); - consumer = session.createConsumer(destination); - activeMqToolController.getReceiverTableData().clear(); - receiverMessageMap.clear(); - while (true) { - // 设置接收者接收消息的时间,为了便于测试,这里谁定为100s - Message message = consumer.receive(1000); - if (null == message) { - break; - } - addReceiverTableBean(message); - } - } catch (Exception e) { - log.error("receiver端拉取消息失败", e); - TooltipUtil.showToast(e.getMessage()); - } - } - - public ActiveMqToolService(ActiveMqToolController activeMqToolController) { - super(); - this.activeMqToolController = activeMqToolController; - } - -} diff --git a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/ActiveMqToolView.java b/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/ActiveMqToolView.java deleted file mode 100644 index 3320c50..0000000 --- a/debugTools/x-ActiveMqTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/ActiveMqToolView.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.xwintop.xJavaFxTool.view.debugTools; - -import com.xwintop.xJavaFxTool.model.ActiveMqToolReceiverTableBean; -import com.xwintop.xJavaFxTool.model.ActiveMqToolTableBean; -import com.xwintop.xcore.base.XProperty; - -import javafx.fxml.FXML; -import javafx.fxml.Initializable; -import javafx.scene.control.Button; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ChoiceBox; -import javafx.scene.control.Spinner; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.TextArea; -import javafx.scene.control.TextField; -import javafx.scene.layout.AnchorPane; -import lombok.Getter; - -@Getter -public abstract class ActiveMqToolView implements Initializable { - @FXML - protected TextField urlTextField; - @FXML - protected TextField userNameTextField; - @FXML - protected TextField passwordTextField; - @FXML - protected TextField queueTextField; - @FXML - protected TextArea messageTextField; - @FXML - protected Spinner sendNumberSpinner; - @FXML - protected ChoiceBox messageTypeChoiceBox; - @FXML - protected CheckBox isSendCheckBox; - @FXML - protected CheckBox isCreateCheckBox; - @FXML - protected CheckBox isRequiredReplyCheckBox; - @FXML - protected Button addItemButton; - @FXML - protected TableView tableViewMain; - @FXML - protected TableColumn queueTableColumn; - @FXML - protected TableColumn messageTableColumn; - @FXML - protected TableColumn sendNumberTableColumn; - @FXML - protected TableColumn messageTypeTableColumn; - @FXML - protected TableColumn isSendTableColumn; - @FXML - protected TableColumn isCreateTableColumn; - @FXML - protected TableColumn isRequiredReplyTableColumn; - @FXML - protected Button saveConfigureButton; - @FXML - protected Button otherSaveConfigureButton; - @FXML - protected Button loadingConfigureButton; - @FXML - protected Button deleteSelectRowButton; - @FXML - protected ChoiceBox quartzChoiceBox; - @FXML - protected AnchorPane simpleScheduleAnchorPane; - @FXML - protected TextField cronTextField; - @FXML - protected Spinner intervalSpinner; - @FXML - protected Spinner repeatCountSpinner; - @FXML - protected Button runQuartzButton; - @FXML - protected Button sendButton; - - @FXML - protected TextField receiverQueueTextField; - @FXML - protected Button receiverPullMessageButton; - @FXML - protected Button receiverMessageListenerButton; - @FXML - protected ChoiceBox> receiverAcknowledgeModeChoiceBox; - @FXML - protected TableView receiverTableView; - @FXML - protected TableColumn receiverMessageIDTableColumn; - @FXML - protected TableColumn receiverQueueTableColumn; - @FXML - protected TableColumn receiverMessageTableColumn; - @FXML - protected TableColumn receiverMessageTypeTableColumn; - @FXML - protected TableColumn receiverTimestampTableColumn; - @FXML - protected TableColumn receiverIsAcknowledgeTableColumn; -} \ No newline at end of file diff --git a/debugTools/x-ActiveMqTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/ActiveMqTool.fxml b/debugTools/x-ActiveMqTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/ActiveMqTool.fxml deleted file mode 100644 index 5f22d4f..0000000 --- a/debugTools/x-ActiveMqTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/ActiveMqTool.fxml +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - -
- - - diff --git a/debugTools/x-ActiveMqTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml b/debugTools/x-ActiveMqTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml deleted file mode 100644 index c95b739..0000000 --- a/debugTools/x-ActiveMqTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - /com/xwintop/xJavaFxTool/fxmlView/debugTools/ActiveMqTool.fxml - locale.ActiveMqTool - - Title - - - p-debugTools - Node - - \ No newline at end of file diff --git a/debugTools/x-ActiveMqTool/src/main/resources/locale/ActiveMqTool.properties b/debugTools/x-ActiveMqTool/src/main/resources/locale/ActiveMqTool.properties deleted file mode 100644 index e64ac4b..0000000 --- a/debugTools/x-ActiveMqTool/src/main/resources/locale/ActiveMqTool.properties +++ /dev/null @@ -1,3 +0,0 @@ -# Dorian.properties\u662F\u9ED8\u8BA4\u7684"Dorian"\u8D44\u6E90\u675F\u6587\u4EF6\u3002 -# \u4F5C\u4E3A\u4E2D\u56FD\u4EBA,\u6211\u7528\u81EA\u5DF1\u7684\u5730\u533A\u4F5C\u4E3A\u9ED8\u8BA4 -Title=ActiveMq\u8C03\u8BD5\u5DE5\u5177 \ No newline at end of file diff --git a/debugTools/x-ActiveMqTool/src/main/resources/locale/ActiveMqTool_en_US.properties b/debugTools/x-ActiveMqTool/src/main/resources/locale/ActiveMqTool_en_US.properties deleted file mode 100644 index 159b1b7..0000000 --- a/debugTools/x-ActiveMqTool/src/main/resources/locale/ActiveMqTool_en_US.properties +++ /dev/null @@ -1,3 +0,0 @@ -# 文件Dorian_en_US.properties,是美国地区的资源束 -# 它覆盖了默认资源束 -Title=ActiveMqTool \ No newline at end of file diff --git a/debugTools/x-CmdTool/.gitignore b/debugTools/x-CmdTool/.gitignore deleted file mode 100644 index 1903c98..0000000 --- a/debugTools/x-CmdTool/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -#/.gitignore -/x-CmdTool.iml -/log/ -/target/ \ No newline at end of file diff --git a/debugTools/x-CmdTool/README.md b/debugTools/x-CmdTool/README.md deleted file mode 100644 index c83b4d0..0000000 --- a/debugTools/x-CmdTool/README.md +++ /dev/null @@ -1,2 +0,0 @@ -CmdTool -Cmd调试工具 \ No newline at end of file diff --git a/debugTools/x-CmdTool/README_EN.md b/debugTools/x-CmdTool/README_EN.md deleted file mode 100644 index e9bb519..0000000 --- a/debugTools/x-CmdTool/README_EN.md +++ /dev/null @@ -1 +0,0 @@ -CmdTool \ No newline at end of file diff --git a/debugTools/x-CmdTool/pom.xml b/debugTools/x-CmdTool/pom.xml deleted file mode 100644 index da3f6f3..0000000 --- a/debugTools/x-CmdTool/pom.xml +++ /dev/null @@ -1,90 +0,0 @@ - - 4.0.0 - - com.xwintop - x-CmdTool - 0.0.1 - jar - x-CmdTool - - - 1.8 - 1.8 - UTF-8 - - - - - aliyunmaven - http://maven.aliyun.com/nexus/content/groups/public/ - - - xwintop-maven - https://864381832.github.io/maven/repository - - - spring-snapshots - http://repo.spring.io/snapshot - - true - - - - spring-milestones - http://repo.spring.io/milestone - - - - - - junit - junit - 4.12 - test - - - com.xwintop - xcore - 0.0.4-SNAPSHOT - - - ch.qos.logback - logback-classic - 1.2.3 - - - org.projectlombok - lombok - 1.18.12 - provided - - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - 2.5.5 - - false - utf-8 - - jar-with-dependencies - - - - - make-assembly - package - - single - - - - - - - diff --git a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/Main.java b/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/Main.java deleted file mode 100644 index 323ad40..0000000 --- a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/Main.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.xwintop.xJavaFxTool; - -import javafx.application.Application; -import javafx.event.EventHandler; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.stage.Stage; -import javafx.stage.WindowEvent; -import lombok.extern.slf4j.Slf4j; - -import java.net.URL; -import java.util.ResourceBundle; - -@Slf4j -public class Main extends Application { - public static void main(String[] args) { - try { - launch(args); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public void start(Stage primaryStage) throws Exception { - FXMLLoader fXMLLoader = Main.getFXMLLoader(); - ResourceBundle resourceBundle = fXMLLoader.getResources(); - Parent root = fXMLLoader.load(); - primaryStage.setResizable(true); - primaryStage.setTitle(resourceBundle.getString("Title")); -// primaryStage.getIcons().add(new Image("/images/icon.jpg")); - double[] screenSize = JavaFxSystemUtil.getScreenSizeByScale(0.74D, 0.8D); - primaryStage.setScene(new Scene(root, screenSize[0], screenSize[1])); - primaryStage.show(); - primaryStage.setOnCloseRequest(new EventHandler() { - @Override - public void handle(WindowEvent event) { - System.exit(0); - } - }); - } - - public static FXMLLoader getFXMLLoader() { - ResourceBundle resourceBundle = ResourceBundle.getBundle("locale.CmdTool"); - URL url = Object.class.getResource("/com/xwintop/xJavaFxTool/fxmlView/debugTools/CmdTool.fxml"); - FXMLLoader fXMLLoader = new FXMLLoader(url, resourceBundle); - return fXMLLoader; - } -} \ No newline at end of file diff --git a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/CmdToolController.java b/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/CmdToolController.java deleted file mode 100644 index 231c7c9..0000000 --- a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/controller/debugTools/CmdToolController.java +++ /dev/null @@ -1,271 +0,0 @@ -package com.xwintop.xJavaFxTool.controller.debugTools; - -import com.xwintop.xJavaFxTool.model.CmdToolTableBean; -import com.xwintop.xJavaFxTool.services.debugTools.CmdToolService; -import com.xwintop.xJavaFxTool.view.debugTools.CmdToolView; - -import java.net.URL; -import java.util.ResourceBundle; - -import com.xwintop.xcore.util.javafx.JavaFxViewUtil; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener.Change; -import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.event.Event; -import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.ChoiceBox; -import javafx.scene.control.ContentDisplay; -import javafx.scene.control.ContextMenu; -import javafx.scene.control.MenuItem; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableColumn.CellEditEvent; -import javafx.scene.control.cell.CheckBoxTableCell; -import javafx.scene.control.cell.PropertyValueFactory; -import javafx.scene.control.cell.TextFieldTableCell; -import javafx.scene.input.MouseButton; -import javafx.util.Callback; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - -/** - * @ClassName: CmdToolController - * @Description: Cmd调试工具 - * @author: xufeng - * @date: 2019/4/25 0025 23:22 - */ - -@Getter -@Setter -@Slf4j -public class CmdToolController extends CmdToolView { - private CmdToolService cmdToolService = new CmdToolService(this); - private ObservableList tableData = FXCollections.observableArrayList(); - private String[] quartzChoiceBoxStrings = new String[] { "简单表达式", "Cron表达式" }; - private String[] typeChoiceBoxStrings = new String[] { "命令行", "脚本文件" }; - - @Override - public void initialize(URL location, ResourceBundle resources) { - initView(); - initEvent(); - initService(); - } - - private void initView() { - cmdToolService.loadingConfigure(); - orderTableColumn.setCellValueFactory(new PropertyValueFactory("order")); - orderTableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - orderTableColumn.setOnEditCommit((CellEditEvent t) -> { - t.getRowValue().setOrder(t.getNewValue()); - }); - - isEnabledTableColumn.setCellValueFactory(new PropertyValueFactory("isEnabled")); - isEnabledTableColumn.setCellFactory(CheckBoxTableCell.forTableColumn(isEnabledTableColumn)); - - scriptTableColumn.setCellValueFactory(new PropertyValueFactory("script")); - scriptTableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - scriptTableColumn.setOnEditCommit((CellEditEvent t) -> { - t.getRowValue().setScript(t.getNewValue()); - }); - - viewScriptTableColumn.setCellFactory((col) -> { - TableCell cell = new TableCell() { - @Override - public void updateItem(Boolean item, boolean empty) { - super.updateItem(item, empty); - this.setText(null); - this.setGraphic(null); - if (!empty) { - Button delBtn = new Button("查看"); - this.setContentDisplay(ContentDisplay.CENTER); - this.setGraphic(delBtn); - delBtn.setOnMouseClicked((me) -> { - CmdToolTableBean cmdToolTableBean = tableData.get(this.getIndex()); - cmdToolService.showScriptAction(cmdToolTableBean); - }); - } - } - }; - return cell; - }); - - typeTableColumn.setCellValueFactory(new PropertyValueFactory("type")); - typeTableColumn.setCellFactory( - new Callback, TableCell>() { - @Override - public TableCell call(TableColumn param) { - TableCell cell = new TableCell() { - @Override - protected void updateItem(String item, boolean empty) { - super.updateItem(item, empty); - this.setText(null); - this.setGraphic(null); - if (!empty) { - ChoiceBox choiceBox = new ChoiceBox(); - choiceBox.getItems().addAll(new String[] { "命令行", "脚本文件" }); - choiceBox.setValue(tableData.get(this.getIndex()).getType()); - choiceBox.valueProperty().addListener((obVal, oldVal, newVal) -> { - tableData.get(this.getIndex()).setType(newVal); - }); - this.setGraphic(choiceBox); - } - } - }; - return cell; - } - }); - - parameterTableColumn.setCellValueFactory(new PropertyValueFactory("parameter")); - parameterTableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - parameterTableColumn.setOnEditCommit((CellEditEvent t) -> { - t.getRowValue().setParameter(t.getNewValue()); - }); - - manualTableColumn.setCellFactory((col) -> { - TableCell cell = new TableCell() { - @Override - public void updateItem(Boolean item, boolean empty) { - super.updateItem(item, empty); - this.setText(null); - this.setGraphic(null); - if (!empty) { - Button delBtn = new Button("执行"); - this.setContentDisplay(ContentDisplay.CENTER); - this.setGraphic(delBtn); - delBtn.setOnMouseClicked((me) -> { - CmdToolTableBean cmdToolTableBean = tableData.get(this.getIndex()); - cmdToolService.runAction(cmdToolTableBean); - }); - } - } - }; - return cell; - }); - - isRunAfterActivateTableColumn - .setCellValueFactory(new PropertyValueFactory("isRunAfterActivate")); - isRunAfterActivateTableColumn.setCellFactory(CheckBoxTableCell.forTableColumn(isRunAfterActivateTableColumn)); - - runAfterActivateTableColumn - .setCellValueFactory(new PropertyValueFactory("runAfterActivate")); - runAfterActivateTableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - runAfterActivateTableColumn.setOnEditCommit((CellEditEvent t) -> { - t.getRowValue().setRunAfterActivate(t.getNewValue()); - }); - - remarksTableColumn.setCellValueFactory(new PropertyValueFactory("remarks")); - remarksTableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - remarksTableColumn.setOnEditCommit((CellEditEvent t) -> { - t.getRowValue().setRemarks(t.getNewValue()); - }); - - tableViewMain.setItems(tableData); - - quartzChoiceBox.getItems().addAll(quartzChoiceBoxStrings); - quartzChoiceBox.setValue(quartzChoiceBoxStrings[0]); - - typeChoiceBox.getItems().addAll(typeChoiceBoxStrings); - typeChoiceBox.setValue(typeChoiceBoxStrings[0]); - JavaFxViewUtil.setSpinnerValueFactory(intervalSpinner, 60, Integer.MAX_VALUE); - JavaFxViewUtil.setSpinnerValueFactory(repeatCountSpinner, -1, Integer.MAX_VALUE); - } - - private void initEvent() { - tableData.addListener((Change tableBean) -> { - try { - saveConfigure(null); - } catch (Exception e) { - log.error("保存配置失败",e); - } - }); - tableViewMain.setOnMouseClicked(event -> { - if (event.getButton() == MouseButton.SECONDARY) { - MenuItem menu_Copy = new MenuItem("复制选中行"); - menu_Copy.setOnAction(event1 -> { - CmdToolTableBean tableBean = tableViewMain.getSelectionModel().getSelectedItem(); - CmdToolTableBean tableBean2 = new CmdToolTableBean(tableBean.getPropertys()); - tableData.add(tableViewMain.getSelectionModel().getSelectedIndex(), tableBean2); - }); - MenuItem menu_Remove = new MenuItem("删除选中行"); - menu_Remove.setOnAction(event1 -> { - tableData.remove(tableViewMain.getSelectionModel().getSelectedItem()); - }); - MenuItem menu_RemoveAll = new MenuItem("删除所有"); - menu_RemoveAll.setOnAction(event1 -> { - tableData.clear(); - }); - tableViewMain.setContextMenu(new ContextMenu(menu_Copy, menu_Remove, menu_RemoveAll)); - } - }); - quartzChoiceBox.valueProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, String oldValue, String newValue) { - if (quartzChoiceBoxStrings[0].equals(newValue)) { - cronTextField.setVisible(false); - simpleScheduleAnchorPane.setVisible(true); - } else if (quartzChoiceBoxStrings[1].equals(newValue)) { - cronTextField.setVisible(true); - simpleScheduleAnchorPane.setVisible(false); - } - } - }); - } - - private void initService() { - } - - @FXML - private void addItemAction(ActionEvent event) { - String id = "x"+String.valueOf(System.currentTimeMillis()).substring(7); - tableData.add(new CmdToolTableBean(id, isEnabledCheckBox.isSelected(), - scriptTextField.getText(), typeChoiceBox.getValue(), parameterTextField.getText(), false, " ", " ")); - } - - @FXML - private void saveConfigure(ActionEvent event) throws Exception { - cmdToolService.saveConfigure(); - } - - @FXML - private void otherSaveConfigureAction(ActionEvent event) throws Exception { - cmdToolService.otherSaveConfigureAction(); - } - - @FXML - private void loadingConfigureAction(ActionEvent event) { - cmdToolService.loadingConfigureAction(); - } - - @FXML - private void runQuartzAction(ActionEvent event) throws Exception { - if("定时运行".equals(runQuartzButton.getText())){ - boolean isTrue = cmdToolService.runQuartzAction(quartzChoiceBox.getValue(), cronTextField.getText(), intervalSpinner.getValue(), - repeatCountSpinner.getValue()); - if(isTrue){ - runQuartzButton.setText("停止运行"); - } - }else{ - boolean isTrue = cmdToolService.stopQuartzAction(); - if(isTrue){ - runQuartzButton.setText("定时运行"); - } - } - } - - @FXML - private void runAllAction(ActionEvent event) { - cmdToolService.runAllAction(); - } - - /** - * 父控件被移除前调用 - */ - public void onCloseRequest(Event event) throws Exception { - cmdToolService.stopQuartzAction(); - } -} \ No newline at end of file diff --git a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/job/CmdToolJob.java b/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/job/CmdToolJob.java deleted file mode 100644 index 194df0e..0000000 --- a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/job/CmdToolJob.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.xwintop.xJavaFxTool.job; - -import com.xwintop.xJavaFxTool.services.debugTools.CmdToolService; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -import org.quartz.JobKey; - -/** - * @ClassName: CmdToolJob - * @Description: Cmd工具类Job - * @author: xufeng - * @date: 2017年10月26日 下午1:53:46 - */ -public class CmdToolJob implements Job{ - - @Override - public void execute(JobExecutionContext context) throws JobExecutionException { - CmdToolService cmdToolService = (CmdToolService) context.getMergedJobDataMap().get("cmdToolService"); - try { - cmdToolService.runAllAction(); - } catch (Exception e) { - e.printStackTrace(); - } - JobKey jobKey = context.getJobDetail().getKey(); - System.out.println("执行了"+jobKey); - } -} diff --git a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/model/CmdToolTableBean.java b/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/model/CmdToolTableBean.java deleted file mode 100644 index 103ede2..0000000 --- a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/model/CmdToolTableBean.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.xwintop.xJavaFxTool.model; - -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.SimpleStringProperty; - -/** - * @ClassName: CmdToolTableBean - * @Description: Cmd调试工具表bean - * @author: xufeng - * @date: 2017年10月26日 上午9:22:44 - */ -public class CmdToolTableBean { - private SimpleStringProperty order;// 序列 - private SimpleBooleanProperty isEnabled;// 是否启用 - private SimpleStringProperty script;// 脚本 - private SimpleStringProperty type;// 执行类型 - private SimpleStringProperty parameter;// 参数 - private SimpleBooleanProperty isRunAfterActivate;// 是否执行触发事件 - private SimpleStringProperty runAfterActivate;// 执行后触发事件 - private SimpleStringProperty remarks;// 备注 - - public CmdToolTableBean(String order, Boolean isEnabled, String script, String type, String parameter, - Boolean isRunAfterActivate, String runAfterActivate, String remarks) { - this.order = new SimpleStringProperty(order); - this.isEnabled = new SimpleBooleanProperty(isEnabled); - this.script = new SimpleStringProperty(script); - this.type = new SimpleStringProperty(type); - this.parameter = new SimpleStringProperty(parameter); - this.isRunAfterActivate = new SimpleBooleanProperty(isRunAfterActivate); - this.runAfterActivate = new SimpleStringProperty(runAfterActivate); - this.remarks = new SimpleStringProperty(remarks); - } - - public CmdToolTableBean(String propertys) { - String[] strings = propertys.split("__", 8); - this.order = new SimpleStringProperty(strings[0]); - this.isEnabled = new SimpleBooleanProperty(Boolean.valueOf(strings[1])); - this.script = new SimpleStringProperty(strings[2]); - this.type = new SimpleStringProperty(strings[3]); - this.parameter = new SimpleStringProperty(strings[4]); - this.isRunAfterActivate = new SimpleBooleanProperty(Boolean.valueOf(strings[5])); - this.runAfterActivate = new SimpleStringProperty(strings[6]); - this.remarks = new SimpleStringProperty(strings[7]); - } - - public String getPropertys() { - return order.get() + "__" + isEnabled.get() + "__" + script.get() + "__" + type.get() + "__" + parameter.get() - + "__" + isRunAfterActivate.get() + "__" + runAfterActivate.get() + "__" + remarks.get(); - } - - public String getOrder() { - return order.get(); - } - - public void setOrder(String order) { - this.order.set(order); - } - - public BooleanProperty isEnabledProperty() { - return isEnabled; - } - - public Boolean getIsEnabled() { - return isEnabled.get(); - } - - public void setIsEnabled(Boolean isEnabled) { - this.isEnabled.set(isEnabled); - } - - public String getScript() { - return script.get(); - } - - public void setScript(String script) { - this.script.set(script); - } - - public String getType() { - return type.get(); - } - - public void setType(String type) { - this.type.set(type); - } - - public String getParameter() { - return parameter.get(); - } - - public void setParameter(String parameter) { - this.parameter.set(parameter); - } - - public BooleanProperty isRunAfterActivateProperty() { - return isRunAfterActivate; - } - - public Boolean getIsRunAfterActivate() { - return isRunAfterActivate.get(); - } - - public void setIsRunAfterActivate(Boolean isRunAfterActivate) { - this.isRunAfterActivate.set(isRunAfterActivate); - } - - public String getRunAfterActivate() { - return runAfterActivate.get(); - } - - public void setRunAfterActivate(String runAfterActivate) { - this.runAfterActivate.set(runAfterActivate); - } - - public String getRemarks() { - return remarks.get(); - } - - public void setRemarks(String remarks) { - this.remarks.set(remarks); - } - -} diff --git a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/CmdToolService.java b/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/CmdToolService.java deleted file mode 100644 index b1648c2..0000000 --- a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/services/debugTools/CmdToolService.java +++ /dev/null @@ -1,203 +0,0 @@ -package com.xwintop.xJavaFxTool.services.debugTools; - -import com.xwintop.xJavaFxTool.controller.debugTools.CmdToolController; -import com.xwintop.xJavaFxTool.job.CmdToolJob; -import com.xwintop.xJavaFxTool.model.CmdToolTableBean; -import com.xwintop.xcore.util.ConfigureUtil; -import com.xwintop.xcore.util.javafx.AlertUtil; -import com.xwintop.xcore.util.javafx.FileChooserUtil; -import com.xwintop.xcore.util.javafx.TooltipUtil; -import javafx.stage.FileChooser; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.configuration.PropertiesConfiguration; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.StringUtils; -import org.quartz.*; -import org.quartz.impl.StdSchedulerFactory; - -import java.io.File; -import java.util.function.Consumer; - -/** - * @ClassName: CmdToolService - * @Description: Cmd调试工具 - * @author: xufeng - * @date: 2019/4/25 0025 23:28 - */ - -@Getter -@Setter -@Slf4j -public class CmdToolService { - private CmdToolController cmdToolController; - - private String fileName = "cmdToolConfigure.properties"; - private SchedulerFactory sf = new StdSchedulerFactory(); - private String schedulerKeyGroup = "runCmdTool"; - private String schedulerKeyName = "runCmdTool" + System.currentTimeMillis(); - - public CmdToolService(CmdToolController cmdToolController) { - this.cmdToolController = cmdToolController; - } - - /** - * @Title: runAllAction - * @Description: 运行所有动作 - */ - public void runAllAction() { - for (CmdToolTableBean cmdToolTableBean : cmdToolController.getTableData()) { - if (cmdToolTableBean.getIsEnabled()) { - runAction(cmdToolTableBean); - } - } - } - - /** - * @Title: runAction - * @Description: 单独运行 - */ - public void runAction(CmdToolTableBean cmdToolTableBean) { - String type = cmdToolTableBean.getType(); - String script = cmdToolTableBean.getScript(); - System.out.println("运行:" + type + " : " + script); - try { - if (cmdToolController.getTypeChoiceBoxStrings()[0].equals(type)) {// 命令行 - String[] strings = script.split("&&&"); - if (strings.length > 1) { - Runtime.getRuntime().exec(strings[0], null, new File(strings[1])); - } else { - Runtime.getRuntime().exec(script); - } - } else if (cmdToolController.getTypeChoiceBoxStrings()[1].equals(type)) {// 脚本文件 - File file = new File(script); - Runtime.getRuntime().exec("cmd /k start " + file.getName(), null, file.getParentFile()); - } - //继续执行后触发任务 - if (cmdToolTableBean.getIsRunAfterActivate()) { - for (CmdToolTableBean tableBean : cmdToolController.getTableData()) { - if (tableBean.getOrder().equals(cmdToolTableBean.getRunAfterActivate())) { - runAction(tableBean); - break; - } - } - } - } catch (Exception e) { - log.error("运行cmd失败", e); - } - } - - /** - * @Title: showScriptAction - * @Description: 查看脚本文件 - */ - public void showScriptAction(CmdToolTableBean cmdToolTableBean) { - String type = cmdToolTableBean.getType(); - String script = cmdToolTableBean.getScript(); - log.info("查看:" + type + " : " + script); - try { - if (cmdToolController.getTypeChoiceBoxStrings()[0].equals(type)) {// 命令行 - AlertUtil.showInfoAlert("脚本命令", script); - } else if (cmdToolController.getTypeChoiceBoxStrings()[1].equals(type)) {// 脚本文件 - Runtime.getRuntime().exec("NotePad.exe " + script); - } - } catch (Exception e) { - log.error("查看脚本文件失败", e); - } - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - public boolean runQuartzAction(String quartzType, String cronText, int interval, int repeatCount) throws Exception { - JobDetail jobDetail = JobBuilder.newJob(CmdToolJob.class).withIdentity(schedulerKeyName, schedulerKeyGroup) - .build(); - jobDetail.getJobDataMap().put("cmdToolService", this); - ScheduleBuilder scheduleBuilder = null; - if ("简单表达式".equals(quartzType)) { - scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(interval)// 时间间隔 - .withRepeatCount(repeatCount);// 重复次数(将执行6次) - } else if ("Cron表达式".equals(quartzType)) { - if (StringUtils.isEmpty(cronText)) { - TooltipUtil.showToast("cron表达式不能为空。"); - return false; - } - scheduleBuilder = CronScheduleBuilder.cronSchedule(cronText); - } - // 描叙触发Job执行的时间触发规则,Trigger实例化一个触发器 - Trigger trigger = TriggerBuilder.newTrigger()// 创建一个新的TriggerBuilder来规范一个触发器 - .withIdentity(schedulerKeyName, schedulerKeyGroup)// 给触发器一个名字和组名 - .startNow()// 立即执行 - .withSchedule(scheduleBuilder).build();// 产生触发器 - - // 运行容器,使用SchedulerFactory创建Scheduler实例 - Scheduler scheduler = sf.getScheduler(); - // 向Scheduler添加一个job和trigger - scheduler.scheduleJob(jobDetail, trigger); - if (!scheduler.isStarted()) { - scheduler.start(); - } - return true; - } - - public boolean stopQuartzAction() throws Exception { - Scheduler sched = sf.getScheduler(); - sched.unscheduleJob(new TriggerKey(schedulerKeyName, schedulerKeyGroup)); - sched.deleteJob(new JobKey(schedulerKeyName, schedulerKeyGroup)); - return true; - } - - public void saveConfigure() throws Exception { - saveConfigure(ConfigureUtil.getConfigureFile(fileName)); - } - - public void saveConfigure(File file) throws Exception { - FileUtils.touch(file); - PropertiesConfiguration xmlConfigure = new PropertiesConfiguration(file); - xmlConfigure.clear(); - for (int i = 0; i < cmdToolController.getTableData().size(); i++) { - xmlConfigure.setProperty("tableBean" + i, cmdToolController.getTableData().get(i).getPropertys()); - } - xmlConfigure.save(); - TooltipUtil.showToast("保存配置成功,保存在:" + file.getPath()); - } - - public void otherSaveConfigureAction() throws Exception { - File file = FileChooserUtil.chooseSaveFile(fileName, new FileChooser.ExtensionFilter("All File", "*.*"), - new FileChooser.ExtensionFilter("Properties", "*.properties")); - if (file != null) { - saveConfigure(file); - TooltipUtil.showToast("保存配置成功,保存在:" + file.getPath()); - } - } - - public void loadingConfigure() { - loadingConfigure(ConfigureUtil.getConfigureFile(fileName)); - } - - public void loadingConfigure(File file) { - try { - cmdToolController.getTableData().clear(); - PropertiesConfiguration xmlConfigure = new PropertiesConfiguration(file); - xmlConfigure.getKeys().forEachRemaining(new Consumer() { - @Override - public void accept(String t) { - cmdToolController.getTableData().add(new CmdToolTableBean(xmlConfigure.getString(t))); - } - }); - } catch (Exception e) { - try { - log.error("加载配置失败:" + e.getMessage()); - TooltipUtil.showToast("加载配置失败:" + e.getMessage()); - } catch (Exception e2) { - } - } - } - - public void loadingConfigureAction() { - File file = FileChooserUtil.chooseFile(new FileChooser.ExtensionFilter("All File", "*.*"), - new FileChooser.ExtensionFilter("Properties", "*.properties")); - if (file != null) { - loadingConfigure(file); - } - } -} diff --git a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/CmdToolView.java b/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/CmdToolView.java deleted file mode 100644 index 78c8e5e..0000000 --- a/debugTools/x-CmdTool/src/main/java/com/xwintop/xJavaFxTool/view/debugTools/CmdToolView.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.xwintop.xJavaFxTool.view.debugTools; - -import com.xwintop.xJavaFxTool.model.CmdToolTableBean; - -import javafx.fxml.FXML; -import javafx.fxml.Initializable; -import javafx.scene.control.Button; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ChoiceBox; -import javafx.scene.control.Spinner; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.TextField; -import javafx.scene.layout.AnchorPane; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public abstract class CmdToolView implements Initializable { - @FXML - protected CheckBox isEnabledCheckBox; - @FXML - protected TextField scriptTextField; - @FXML - protected ChoiceBox typeChoiceBox; - @FXML - protected TextField parameterTextField; - @FXML - protected Button addItemButton; - @FXML - protected ChoiceBox quartzChoiceBox; - @FXML - protected TextField cronTextField; - @FXML - protected AnchorPane simpleScheduleAnchorPane; - @FXML - protected Spinner intervalSpinner; - @FXML - protected Spinner repeatCountSpinner; - @FXML - protected Button runQuartzButton; - @FXML - protected Button runAllButton; - @FXML - protected TableView tableViewMain; - @FXML - protected TableColumn orderTableColumn; - @FXML - protected TableColumn isEnabledTableColumn; - @FXML - protected TableColumn scriptTableColumn; - @FXML - protected TableColumn viewScriptTableColumn; - @FXML - protected TableColumn typeTableColumn; - @FXML - protected TableColumn parameterTableColumn; - @FXML - protected TableColumn manualTableColumn; - @FXML - protected TableColumn isRunAfterActivateTableColumn; - @FXML - protected TableColumn runAfterActivateTableColumn; - @FXML - protected TableColumn remarksTableColumn; - -} \ No newline at end of file diff --git a/debugTools/x-CmdTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/CmdTool.fxml b/debugTools/x-CmdTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/CmdTool.fxml deleted file mode 100644 index 1abaf29..0000000 --- a/debugTools/x-CmdTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/debugTools/CmdTool.fxml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/littleTools/x-SedentaryReminderTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml b/littleTools/x-SedentaryReminderTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml deleted file mode 100644 index fd1f780..0000000 --- a/littleTools/x-SedentaryReminderTool/src/main/resources/config/toolFxmlLoaderConfiguration.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - /com/xwintop/xJavaFxTool/fxmlView/littleTools/SedentaryReminderTool.fxml - locale.SedentaryReminderTool - - Title - - - p-littleTools - Node - - \ No newline at end of file diff --git a/littleTools/x-SedentaryReminderTool/src/main/resources/locale/SedentaryReminderTool.properties b/littleTools/x-SedentaryReminderTool/src/main/resources/locale/SedentaryReminderTool.properties deleted file mode 100644 index a82cc76..0000000 --- a/littleTools/x-SedentaryReminderTool/src/main/resources/locale/SedentaryReminderTool.properties +++ /dev/null @@ -1,3 +0,0 @@ -# Dorian.properties\u662F\u9ED8\u8BA4\u7684"Dorian"\u8D44\u6E90\u675F\u6587\u4EF6\u3002 -# \u4F5C\u4E3A\u4E2D\u56FD\u4EBA,\u6211\u7528\u81EA\u5DF1\u7684\u5730\u533A\u4F5C\u4E3A\u9ED8\u8BA4 -Title=\u4E45\u5750\u63D0\u9192\u5DE5\u5177 \ No newline at end of file diff --git a/littleTools/x-SedentaryReminderTool/src/main/resources/locale/SedentaryReminderTool_en_US.properties b/littleTools/x-SedentaryReminderTool/src/main/resources/locale/SedentaryReminderTool_en_US.properties deleted file mode 100644 index 27bd30c..0000000 --- a/littleTools/x-SedentaryReminderTool/src/main/resources/locale/SedentaryReminderTool_en_US.properties +++ /dev/null @@ -1,3 +0,0 @@ -# 文件Dorian_en_US.properties,是美国地区的资源束 -# 它覆盖了默认资源束 -Title=SedentaryReminderTool \ No newline at end of file diff --git a/littleTools/x-SmsTool/.gitignore b/littleTools/x-SmsTool/.gitignore deleted file mode 100644 index 132a9a3..0000000 --- a/littleTools/x-SmsTool/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -#/.gitignore -/x-SmsTool.iml -/log/ -/target/ \ No newline at end of file diff --git a/littleTools/x-SmsTool/README.md b/littleTools/x-SmsTool/README.md deleted file mode 100644 index dab8b97..0000000 --- a/littleTools/x-SmsTool/README.md +++ /dev/null @@ -1,2 +0,0 @@ -SmsTool -短信群发工具(目前支持中国移动、中国电信、腾讯云、阿里云、梦网云通讯等平台) \ No newline at end of file diff --git a/littleTools/x-SmsTool/README_EN.md b/littleTools/x-SmsTool/README_EN.md deleted file mode 100644 index a1fa799..0000000 --- a/littleTools/x-SmsTool/README_EN.md +++ /dev/null @@ -1 +0,0 @@ -SmsTool \ No newline at end of file diff --git a/littleTools/x-SmsTool/pom.xml b/littleTools/x-SmsTool/pom.xml deleted file mode 100644 index 51c1317..0000000 --- a/littleTools/x-SmsTool/pom.xml +++ /dev/null @@ -1,91 +0,0 @@ - - 4.0.0 - - com.xwintop - x-SmsTool - 0.0.1 - jar - x-SmsTool - - - 1.8 - 1.8 - UTF-8 - - - - - aliyunmaven - http://maven.aliyun.com/nexus/content/groups/public/ - - - xwintop-maven - https://864381832.github.io/maven/repository - - - spring-snapshots - http://repo.spring.io/snapshot - - true - - - - spring-milestones - http://repo.spring.io/milestone - - - - - - junit - junit - 4.12 - test - - - com.xwintop - xcore - 0.0.6 - - - - org.projectlombok - lombok - 1.18.12 - provided - - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - 2.5.5 - - false - utf-8 - - - - - - - jar-with-dependencies - - - - - make-assembly - package - - single - - - - - - - diff --git a/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/Main.java b/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/Main.java deleted file mode 100644 index dbf642f..0000000 --- a/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/Main.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.xwintop.xJavaFxTool; - -import com.xwintop.xcore.util.javafx.JavaFxSystemUtil; -import javafx.application.Application; -import javafx.event.EventHandler; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.stage.Stage; -import javafx.stage.WindowEvent; -import lombok.extern.slf4j.Slf4j; - -import java.net.URL; -import java.util.ResourceBundle; - -@Slf4j -public class Main extends Application { - public static void main(String[] args) { - try { - launch(args); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public void start(Stage primaryStage) throws Exception { - FXMLLoader fXMLLoader = Main.getFXMLLoader(); - ResourceBundle resourceBundle = fXMLLoader.getResources(); - Parent root = fXMLLoader.load(); - primaryStage.setResizable(true); - primaryStage.setTitle(resourceBundle.getString("Title")); -// primaryStage.getIcons().add(new Image("/images/icon.jpg")); - double[] screenSize = JavaFxSystemUtil.getScreenSizeByScale(0.74D, 0.8D); - primaryStage.setScene(new Scene(root, screenSize[0], screenSize[1])); - primaryStage.show(); - primaryStage.setOnCloseRequest(new EventHandler() { - @Override - public void handle(WindowEvent event) { - System.exit(0); - } - }); - } - - public static FXMLLoader getFXMLLoader() { - ResourceBundle resourceBundle = ResourceBundle.getBundle("locale.SmsTool"); - URL url = Object.class.getResource("/com/xwintop/xJavaFxTool/fxmlView/littleTools/SmsTool.fxml"); - FXMLLoader fXMLLoader = new FXMLLoader(url, resourceBundle); - return fXMLLoader; - } -} \ No newline at end of file diff --git a/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/SmsToolController.java b/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/SmsToolController.java deleted file mode 100644 index 0c72ef5..0000000 --- a/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/SmsToolController.java +++ /dev/null @@ -1,164 +0,0 @@ -package com.xwintop.xJavaFxTool.controller.littleTools; - -import com.xwintop.xJavaFxTool.model.SmsToolTableBean; -import com.xwintop.xJavaFxTool.services.littleTools.SmsToolService; -import com.xwintop.xJavaFxTool.view.littleTools.SmsToolView; -import com.xwintop.xcore.util.HttpClientUtil; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.TableColumn.CellEditEvent; -import javafx.scene.control.ContentDisplay; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.scene.control.cell.CheckBoxTableCell; -import javafx.scene.control.cell.PropertyValueFactory; -import javafx.scene.control.cell.TextFieldTableCell; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - -import java.net.URL; -import java.util.ResourceBundle; - -/** - * @ClassName: SmsToolController - * @Description: 短信群发工具 - * @author: xufeng - * @date: 2019/4/25 0025 23:26 - */ - -@Getter -@Setter -@Slf4j -public class SmsToolController extends SmsToolView { - private SmsToolService smsToolService = new SmsToolService(this); - private ObservableList tableData = FXCollections.observableArrayList(); - - @Override - public void initialize(URL location, ResourceBundle resources) { - initView(); - initEvent(); - initService(); - } - - private void initView() { - orderTableColumn.setCellValueFactory(new PropertyValueFactory("order")); - - isEnabledTableColumn - .setCellValueFactory(new PropertyValueFactory("isEnabled")); - isEnabledTableColumn.setCellFactory(CheckBoxTableCell.forTableColumn(isEnabledTableColumn)); - - toPhoneTableColumn.setCellValueFactory(new PropertyValueFactory("toPhone")); - toPhoneTableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - toPhoneTableColumn.setOnEditCommit((CellEditEvent t) -> { - t.getRowValue().setToPhone(t.getNewValue()); - }); - - toPhoneNameTableColumn - .setCellValueFactory(new PropertyValueFactory("toPhoneName")); - toPhoneNameTableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - toPhoneNameTableColumn.setOnEditCommit((CellEditEvent t) -> { - t.getRowValue().setToPhoneName(t.getNewValue()); - }); - - manualTableColumn.setCellFactory((col) -> { - TableCell cell = new TableCell() { - @Override - public void updateItem(Boolean item, boolean empty) { - super.updateItem(item, empty); - this.setText(null); - this.setGraphic(null); - if (!empty) { - Button delBtn = new Button("运行"); - this.setContentDisplay(ContentDisplay.CENTER); - this.setGraphic(delBtn); - delBtn.setOnMouseClicked((me) -> { - SmsToolTableBean smsToolTableBean = tableData.get(this.getIndex()); - smsToolService.runAction(smsToolTableBean); - }); - } - } - }; - return cell; - }); - - sendStatusTableColumn.setCellValueFactory(new PropertyValueFactory("sendStatus")); - sendStatusTableColumn.setCellFactory(TextFieldTableCell.forTableColumn()); - sendStatusTableColumn.setOnEditCommit((CellEditEvent t) -> { - t.getRowValue().setSendStatus(t.getNewValue()); - }); - - tableViewMain.setItems(tableData); - - mainTabPane.getSelectionModel().select(2); - } - - private void initEvent() { - } - - private void initService() { - } - - @FXML - private void addItemAction(ActionEvent event) { - tableData.add(new SmsToolTableBean(tableData.size() + 1, isEnabledCheckBox.isSelected(), toPhoneTextField.getText(), toPhoneNameTextField.getText(), "")); - } - - @FXML - private void importToPhoneAction(ActionEvent event) { - smsToolService.importToPhoneAction(); - } - - @FXML - private void cmccSendAction(ActionEvent event) { - smsToolService.runAllAction(); - } - - @FXML - private void open189SendAction(ActionEvent event) { - smsToolService.runAllAction(); - } - - @FXML - private void tencentSendAction(ActionEvent event) { - smsToolService.runAllAction(); - } - - @FXML - private void aliyunSendAction(ActionEvent event) { - smsToolService.runAllAction(); - } - - @FXML - private void monyunSendAction(ActionEvent event) { - smsToolService.runAllAction(); - } - - @FXML - private void registerAliyunAction(ActionEvent event) { - HttpClientUtil.openBrowseURL("https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=vt7aiwvr&utm_source=vt7aiwvr"); - } - - @FXML - private void registerCmccAction(ActionEvent event) { - HttpClientUtil.openBrowseURL("http://www.openservice.com.cn"); - } - - @FXML - private void registerOpen189Action(ActionEvent event) { - HttpClientUtil.openBrowseURL("http://open.189.cn"); - } - - @FXML - private void registerTencentAction(ActionEvent event) { - HttpClientUtil.openBrowseURL("https://cloud.tencent.com/redirect.php?redirect=1005&cps_key=f312970b0318dd604cd33405d2c6d697"); - } - - @FXML - private void registerMonyunAction(ActionEvent event) { - HttpClientUtil.openBrowseURL("http://www.monyun.cn/?rsdlx7ba"); - } -} \ No newline at end of file diff --git a/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/model/SmsToolTableBean.java b/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/model/SmsToolTableBean.java deleted file mode 100644 index abb34f0..0000000 --- a/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/model/SmsToolTableBean.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.xwintop.xJavaFxTool.model; - -import javafx.beans.property.*; - -/** - * @ClassName: PhoneToolTableBean - * @Description: 邮件发送工具 - * @author: xufeng - * @date: 2017/12/30 0030 21:14 - */ -public class SmsToolTableBean { - private SimpleIntegerProperty order;// 序号 - private SimpleBooleanProperty isEnabled; - private SimpleStringProperty toPhone; - private SimpleStringProperty toPhoneName; - private SimpleStringProperty sendStatus; - - public SmsToolTableBean(Integer order, Boolean isEnabled, String toPhone, String toPhoneName, String sendStatus){ - this.order = new SimpleIntegerProperty(order); - this.isEnabled = new SimpleBooleanProperty(isEnabled); - this.toPhone = new SimpleStringProperty(toPhone); - this.toPhoneName = new SimpleStringProperty(toPhoneName); - this.sendStatus = new SimpleStringProperty(sendStatus); - } - - public SmsToolTableBean(String propertys) { - String[] strings = propertys.split("__",5); - this.order = new SimpleIntegerProperty(Integer.valueOf(strings[0])); - this.isEnabled = new SimpleBooleanProperty(Boolean.valueOf(strings[1])); - this.toPhone = new SimpleStringProperty(strings[2]); - this.toPhoneName = new SimpleStringProperty(strings[3]); - this.sendStatus = new SimpleStringProperty(strings[4]); - } - - public String getPropertys() { - return order.get() + "__" + isEnabled.get() + "__" + toPhone.get() + "__" + toPhoneName.get() + "__" + sendStatus.get(); - } - - public IntegerProperty orderProperty(){ - return order; - } - - public Integer getOrder(){ - return order.get(); - } - - public void setOrder(Integer order){ - this.order.set(order); - } - - public BooleanProperty isEnabledProperty(){ - return isEnabled; - } - - public Boolean getIsEnabled(){ - return isEnabled.get(); - } - - public void setIsEnabled(Boolean isEnabled){ - this.isEnabled.set(isEnabled); - } - - public String getToPhone(){ - return toPhone.get(); - } - - public void setToPhone(String toPhone){ - this.toPhone.set(toPhone); - } - - public String getToPhoneName(){ - return toPhoneName.get(); - } - - public void setToPhoneName(String toPhoneName){ - this.toPhoneName.set(toPhoneName); - } - - public String getSendStatus(){ - return sendStatus.get(); - } - - public void setSendStatus(String sendStatus){ - this.sendStatus.set(sendStatus); - } -} diff --git a/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/SmsToolService.java b/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/SmsToolService.java deleted file mode 100644 index 120fad9..0000000 --- a/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/services/littleTools/SmsToolService.java +++ /dev/null @@ -1,355 +0,0 @@ -package com.xwintop.xJavaFxTool.services.littleTools; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.xwintop.xJavaFxTool.controller.littleTools.SmsToolController; -import com.xwintop.xJavaFxTool.model.SmsToolTableBean; -import com.xwintop.xcore.util.HttpClientUtil; -import com.xwintop.xcore.util.javafx.FileChooserUtil; -import com.xwintop.xcore.util.javafx.TooltipUtil; -import javafx.collections.ObservableList; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.codec.digest.HmacUtils; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.RandomUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.time.DateFormatUtils; - -import java.io.File; -import java.util.*; - -/** - * @ClassName: SmsToolService - * @Description: 短信群发工具 - * @author: xufeng - * @date: 2019/4/25 0025 23:35 - */ - -@Getter -@Setter -@Slf4j -public class SmsToolService { - private SmsToolController smsToolController; - - public void runAllAction() { - ArrayList smsToolTableBeanArrayList = new ArrayList(); - for (SmsToolTableBean smsToolTableBean : smsToolController.getTableData()) { - if (smsToolTableBean.getIsEnabled()) { - smsToolTableBeanArrayList.add(smsToolTableBean); - } - } - if (!smsToolTableBeanArrayList.isEmpty()) { - runAction(smsToolTableBeanArrayList.toArray(new SmsToolTableBean[0])); - } else { - TooltipUtil.showToast("未选择联系人!!!"); - } - } - - public void runAction(SmsToolTableBean... smsToolTableBeans) { - int selectedIndex = smsToolController.getMainTabPane().getSelectionModel().getSelectedIndex(); - switch (selectedIndex) { - case 0://中国移动 - cmccSendAction(smsToolTableBeans); - break; - case 1://中国电信 - open189SendAction(smsToolTableBeans); - break; - case 2://腾讯云 - tencentSendAction(smsToolTableBeans); - break; - case 3://阿里云 - aliyunSendAction(smsToolTableBeans); - break; - case 4://梦网云通讯 - monyunSendAction(smsToolTableBeans); - break; - default: - break; - } - } - - /** - * 中国移动短信发送 - */ - public void cmccSendAction(SmsToolTableBean... smsToolTableBeans) { - String url = smsToolController.getCmccUrlTextField().getText(); - String apiKey = smsToolController.getCmccApiKeyTextField().getText(); - String secretKey = smsToolController.getCmccSecretKeyTextField().getText(); - String needReceipt = smsToolController.getCmccNeedReceiptCheckBox().isSelected() ? "1" : "0";//是否回执 1:回执0:不回执 - String message = smsToolController.getCmccMessageTextArea().getText(); - String receiptNotificationURL = smsToolController.getCmccReceiptNotificationUrlTextField().getText();//回调地址 - for (SmsToolTableBean smsToolTableBean : smsToolTableBeans) { -// String destAddr = "18356971618";//目标地址 - String destAddr = smsToolTableBean.getToPhone();//目标地址 - Map map = new HashMap<>(); - map.put("destAddr", destAddr); - map.put("apiKey", apiKey); - map.put("secretKey", secretKey); - map.put("needReceipt", needReceipt); - map.put("message", message); - if ("1".equals(needReceipt)) { - map.put("receiptNotificationURL", receiptNotificationURL); - } - String resJson = HttpClientUtil.getHttpDataByPost(url, "http://www.openservice.com.cn", JSON.toJSONString(map)); - log.info("中国移动短信发送返回:" + resJson); - if ("200".equals(JSON.parseObject(resJson).getString("resultCode"))) { - TooltipUtil.showToast("中国移动发送短信成功!!!"); - } else { - TooltipUtil.showToast("中国移动发送短信失败:" + resJson); - } - } - } - - /** - * 中国电信短信发送 - */ - public void open189SendAction(SmsToolTableBean... smsToolTableBeans) { - String url = smsToolController.getOpen189UrlTextField().getText(); - String app_id = smsToolController.getOpen189AppIdTextField().getText(); - String app_secret = smsToolController.getOpen189AppSecretTextField().getText(); - String template_id = smsToolController.getOpen189TemplateIdTextField().getText();//短信模板ID - String template_param = smsToolController.getOpen189TemplateParamTextArea().getText();//模板匹配参数,参数格式为(json对象字符串): {参数名:参数值,参数名:参数值} - - for (SmsToolTableBean smsToolTableBean : smsToolTableBeans) { -// String acceptor_tel = "18356971618";//接收方号码 - String acceptor_tel = smsToolTableBean.getToPhone();//接收方号码 - String access_token = ""; - Map map = new HashMap<>(); - map.put("app_id", app_id); - map.put("app_secret", app_secret); - map.put("grant_type", "client_credentials"); - String resJson = HttpClientUtil.getHttpDataByPost("https://oauth.api.189.cn/emp/oauth2/v3/access_token", "https://oauth.api.189.cn", map); - log.info("中国电信短信获取Token返回:" + resJson); - access_token = JSON.parseObject(resJson).getString("access_token"); - - String timestamp = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");//时间戳 - TreeMap map2 = new TreeMap<>(); - map2.put("app_id", app_id); - map2.put("access_token", access_token); - map2.put("acceptor_tel", acceptor_tel); - map2.put("template_id", template_id); - map2.put("template_param", template_param); - map2.put("timestamp", timestamp); - try { - resJson = HttpClientUtil.getHttpDataByPost(url, "http://api.189.cn", map2); - log.info("中国电信短信发送返回:" + resJson); - String res_message = JSON.parseObject(resJson).getString("res_message"); - if ("Success".equals(res_message)) { - TooltipUtil.showToast("中国电信发送短信成功!!!"); - } else { - TooltipUtil.showToast("中国电信发送短信失败:" + resJson); - } - } catch (Exception e) { - TooltipUtil.showToast("中国电信发送短信失败:" + e.getMessage()); - log.info("电信短信发送失败:" + e.getMessage()); - } - } - } - - /** - * 腾讯云短信发送 - */ - public void tencentSendAction(SmsToolTableBean... smsToolTableBeans) { - String url = "https://yun.tim.qq.com/v5/tlssmssvr/sendmultisms2"; - int appid = Integer.parseInt(smsToolController.getTencentAppidTextField().getText()); - String appkey = smsToolController.getTencentAppkeyTextField().getText(); - boolean isParam = smsToolController.getTencentIsParamCheckBox().isSelected(); - String msg = smsToolController.getTencentMsgTextField().getText(); - String params = smsToolController.getTencentParamsTextArea().getText(); - ArrayList phoneNumbers = new ArrayList(); -// phoneNumbers.add("18356971618"); - for (SmsToolTableBean smsToolTableBean : smsToolTableBeans) { - phoneNumbers.add(smsToolTableBean.getToPhone()); - } - try { - long random = RandomUtils.nextInt(0, 999999) + 100000; - long curTime = System.currentTimeMillis() / 1000; - - Map data = new HashMap(); - ArrayList tel = new ArrayList(); - int i = 0; - do { - Map telElement = new HashMap(); - telElement.put("nationcode", "86"); - telElement.put("mobile", phoneNumbers.get(i)); - tel.add(telElement); - } while (++i < phoneNumbers.size()); - data.put("tel", tel); - data.put("sign", ""); - if (isParam) { - data.put("tpl_id", msg); - data.put("params", JSON.parse(params)); - } else { - data.put("msg", msg); - } - String sigStr = String.format( - "appkey=%s&random=%d&time=%d&mobile=%s", - appkey, random, curTime, StringUtils.join(phoneNumbers, ",")); - data.put("sig", DigestUtils.sha256Hex(sigStr)); - data.put("time", curTime); - data.put("extend", ""); - data.put("ext", ""); - - String wholeUrl = String.format("%s?sdkappid=%d&random=%d", url, appid, random); - String resultStr = HttpClientUtil.getHttpDataByPost(wholeUrl, url, JSON.toJSONString(data)); - log.info("腾讯云短信发送返回:" + resultStr); - JSONObject jsonObject = JSON.parseObject(resultStr); - if (jsonObject.getInteger("result") == 0) { - TooltipUtil.showToast("腾讯云发送短信成功!!!"); - } else { - TooltipUtil.showToast("腾讯云发送短信失败:" + resultStr); - } - } catch (Exception e) { - log.error("腾讯云发送短信失败:", e); - TooltipUtil.showToast("腾讯云发送短信失败:" + e.getMessage()); - } - } - - /** - * 阿里云短信发送 - */ - public void aliyunSendAction(SmsToolTableBean... smsToolTableBeans) { - try { - ArrayList phoneNumbers = new ArrayList(); - for (SmsToolTableBean smsToolTableBean : smsToolTableBeans) { - phoneNumbers.add(smsToolTableBean.getToPhone()); - } - String accessKeyId = smsToolController.getAliyunAccessKeyIdTextField().getText(); - String accessKeySecret = smsToolController.getAliyunAccessKeySecretTextField().getText(); - String signName = smsToolController.getAliyunSignNameTextField().getText(); - String templateCode = smsToolController.getAliyunTemplateCodeTextField().getText(); - String templateParam = smsToolController.getAliyunTemplateParamTextArea().getText(); - - java.util.Map paras = new java.util.HashMap(); - // 1. 系统参数 - paras.put("SignatureMethod", "HMAC-SHA1"); - paras.put("SignatureNonce", java.util.UUID.randomUUID().toString()); - paras.put("AccessKeyId", accessKeyId); - paras.put("SignatureVersion", "1.0"); - paras.put("Timestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd'T'HH:mm:ss'Z'", new SimpleTimeZone(0, "GMT"))); - paras.put("Format", "JSON"); - // 2. 业务API参数 - paras.put("Action", "SendSms"); - paras.put("Version", "2017-05-25"); - paras.put("RegionId", "cn-hangzhou"); - paras.put("PhoneNumbers", StringUtils.join(phoneNumbers, ",")); - //必填:短信签名-可在短信控制台中找到 - paras.put("SignName", signName); - //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时 - paras.put("TemplateParam", templateParam); - //必填:短信模板-可在短信控制台中找到 - paras.put("TemplateCode", templateCode); - //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者 -// paras.put("OutId", "123"); - // 4. 参数KEY排序 - java.util.TreeMap sortParas = new java.util.TreeMap(); - sortParas.putAll(paras); - // 5. 构造待签名的字符串 - java.util.Iterator it = sortParas.keySet().iterator(); - StringBuilder sortQueryStringTmp = new StringBuilder(); - while (it.hasNext()) { - String key = it.next(); - sortQueryStringTmp.append("&").append(specialUrlEncode(key)).append("=").append(specialUrlEncode(paras.get(key))); - } - String sortedQueryString = sortQueryStringTmp.substring(1);// 去除第一个多余的&符号 - StringBuilder stringToSign = new StringBuilder(); - stringToSign.append("GET").append("&"); - stringToSign.append(specialUrlEncode("/")).append("&"); - stringToSign.append(specialUrlEncode(sortedQueryString)); - String sign = org.apache.commons.codec.binary.Base64.encodeBase64String(HmacUtils.hmacSha1(accessKeySecret + "&", stringToSign.toString())); - String signature = specialUrlEncode(sign); - String url = "http://dysmsapi.aliyuncs.com/?Signature=" + signature + sortQueryStringTmp; - String resJson = HttpClientUtil.getHttpDataAsUTF_8(url, url); - log.info("阿里云短信发送返回:" + resJson); - if ("OK".equals(JSON.parseObject(resJson).getString("Code"))) { - TooltipUtil.showToast("阿里云发送短信成功!!!"); - } else { - TooltipUtil.showToast("阿里云发送短信失败:" + resJson); - } - } catch (Exception e) { - TooltipUtil.showToast("阿里云发送短信失败:" + e.getMessage()); - log.error("阿里云发送短信失败:" + e.getMessage()); - } - } - - /** - * 梦网云通讯短信发送 - */ - public void monyunSendAction(SmsToolTableBean... smsToolTableBeans) { - try { - String url = smsToolController.getMonyunUrlTextField().getText();//Url - String userid = smsToolController.getMonyunUseridTextField().getText();//发送账号 - String pwd = smsToolController.getMonyunPwdTextField().getText();//发送账号密码 - String apikey = smsToolController.getMonyunApikeyTextField().getText();//用户唯一标识 -// String mobile = "18356971618";//短信接收的手机号:多个手机号请用英文逗号分隔 - String content = smsToolController.getMonyunContentTextArea().getText(); - String timestamp = DateFormatUtils.format(new Date(), "MMddHHmmss"); - String svrtype = smsToolController.getMonyunSvrtypeTextField().getText();//业务类型 - String exno = smsToolController.getMonyunExnoTextField().getText();//扩展号 - ArrayList phoneNumbers = new ArrayList(); - for (SmsToolTableBean smsToolTableBean : smsToolTableBeans) { - phoneNumbers.add(smsToolTableBean.getToPhone()); - } - Map params = new HashMap<>(); - if (StringUtils.isBlank(apikey)) { - pwd = DigestUtils.md5Hex(userid.toUpperCase() + "00000000" + pwd + timestamp); - params.put("userid", userid.toUpperCase()); - params.put("pwd", pwd); - } else { - params.put("apikey", apikey); - } - params.put("timestamp", timestamp); - params.put("mobile", StringUtils.join(phoneNumbers, ",")); - params.put("content", java.net.URLEncoder.encode(content, "GBK")); - params.put("svrtype", svrtype); - params.put("exno", exno); - String resultStr = HttpClientUtil.getHttpDataByPost(url + "batch_send", url, JSON.toJSONString(params), "text/json; charset=utf-8"); - log.info("梦网云通讯短信发送返回:" + resultStr); - if (JSON.parseObject(resultStr).getInteger("result") == 0) { - TooltipUtil.showToast("梦网云通讯发送短信成功!!!"); - } else { - TooltipUtil.showToast("梦网云通讯发送短信失败:" + resultStr); - } - } catch (Exception e) { - log.error("梦网云通讯发送短信失败:", e); - TooltipUtil.showToast("梦网云通讯发送短信失败:" + e.getMessage()); - } - } - - /** - * 导入联系人号码 - */ - public void importToPhoneAction() { - try { - File file = FileChooserUtil.chooseFile(); - if (file != null) { - List smsList = FileUtils.readLines(file, "utf-8"); - ObservableList tableData = smsToolController.getTableData(); - for (String sms : smsList) { - SmsToolTableBean smsToolTableBean = null; - if (sms.contains(" ")) { - String[] smsStr = sms.split(" "); - smsToolTableBean = new SmsToolTableBean(tableData.size() + 1, true, smsStr[0], smsStr[1], ""); - } else { - smsToolTableBean = new SmsToolTableBean(tableData.size() + 1, true, sms, sms, ""); - } - tableData.add(smsToolTableBean); - } - } - } catch (Exception e) { - log.error("导入联系人号码失败:" + e.getMessage()); - TooltipUtil.showToast("导入联系人号码失败:" + e.getMessage()); - } - } - - public SmsToolService(SmsToolController smsToolController) { - this.smsToolController = smsToolController; - } - - public static String specialUrlEncode(String value) throws Exception { - return java.net.URLEncoder.encode(value, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~"); - } -} \ No newline at end of file diff --git a/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/SmsToolView.java b/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/SmsToolView.java deleted file mode 100644 index 708bb7a..0000000 --- a/littleTools/x-SmsTool/src/main/java/com/xwintop/xJavaFxTool/view/littleTools/SmsToolView.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.xwintop.xJavaFxTool.view.littleTools; - -import com.xwintop.xJavaFxTool.model.SmsToolTableBean; -import javafx.fxml.FXML; -import javafx.fxml.Initializable; -import javafx.scene.control.*; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public abstract class SmsToolView implements Initializable { - @FXML - protected CheckBox isEnabledCheckBox; - @FXML - protected TextField toPhoneTextField; - @FXML - protected TextField toPhoneNameTextField; - @FXML - protected Button addItemButton; - @FXML - protected Button importToPhoneButton; - @FXML - protected TableView tableViewMain; - @FXML - protected TableColumn orderTableColumn; - @FXML - protected TableColumn isEnabledTableColumn; - @FXML - protected TableColumn toPhoneTableColumn; - @FXML - protected TableColumn toPhoneNameTableColumn; - @FXML - protected TableColumn manualTableColumn; - @FXML - protected TableColumn sendStatusTableColumn; - @FXML - protected TabPane mainTabPane; - @FXML - protected TextField cmccUrlTextField; - @FXML - protected TextField cmccApiKeyTextField; - @FXML - protected TextField cmccSecretKeyTextField; - @FXML - protected CheckBox cmccNeedReceiptCheckBox; - @FXML - protected TextField cmccReceiptNotificationUrlTextField; - @FXML - protected TextArea cmccMessageTextArea; - @FXML - protected Button cmccSendButton; - @FXML - protected TextField open189UrlTextField; - @FXML - protected TextField open189AppIdTextField; - @FXML - protected TextField open189AppSecretTextField; - @FXML - protected TextField open189TemplateIdTextField; - @FXML - protected TextArea open189TemplateParamTextArea; - @FXML - protected Button open189SendButton; - @FXML - protected TextField tencentAppidTextField; - @FXML - protected TextField tencentAppkeyTextField; - @FXML - protected CheckBox tencentIsParamCheckBox; - @FXML - protected TextField tencentMsgTextField; - @FXML - protected TextArea tencentParamsTextArea; - @FXML - protected Button tencentSendButton; - @FXML - protected TextField aliyunAccessKeyIdTextField; - @FXML - protected TextField aliyunAccessKeySecretTextField; - @FXML - protected TextField aliyunSignNameTextField; - @FXML - protected TextField aliyunTemplateCodeTextField; - @FXML - protected TextArea aliyunTemplateParamTextArea; - @FXML - protected Button aliyunSendButton; - @FXML - protected TextField monyunUrlTextField; - @FXML - protected TextField monyunUseridTextField; - @FXML - protected TextField monyunPwdTextField; - @FXML - protected TextField monyunApikeyTextField; - @FXML - protected TextArea monyunContentTextArea; - @FXML - protected TextField monyunSvrtypeTextField; - @FXML - protected TextField monyunExnoTextField; - @FXML - protected Button monyunSendButton; - -} \ No newline at end of file diff --git a/littleTools/x-SmsTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/SmsTool.fxml b/littleTools/x-SmsTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/SmsTool.fxml deleted file mode 100644 index f4d4f81..0000000 --- a/littleTools/x-SmsTool/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/SmsTool.fxml +++ /dev/null @@ -1,320 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -