diff --git a/.gitignore b/.gitignore index 47fa028e..4fff518e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ logs/ target/ libs/ +devLibs system_plugin_list.json RUNNING_PID diff --git a/LICENSE b/LICENSE index 18f1ffd2..b14292bb 100644 --- a/LICENSE +++ b/LICENSE @@ -53,8 +53,8 @@ 3, 请将如下声明文本放入每个源文件的头部注释中。 - Copyright (c) [Year] [name of copyright holder] - [Software Name] is licensed under Mulan PSL v2. + Copyright (c) [2019] [xufeng] + [xJavaFxTool] is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2 @@ -118,8 +118,8 @@ iii Attach the statement to the appropriate annotated syntax at the beginning of each source file. - Copyright (c) [Year] [name of copyright holder] - [Software Name] is licensed under Mulan PSL v2. + Copyright (c) [2019] [xufeng] + [xJavaFxTool] is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2 diff --git a/README.md b/README.md index fcdda762..bd845670 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,10 @@ xJavaFxTool是使用javaFx开发的实用小工具集,利用业余时间把工 由于SpringBoot的火热,项目已经出SpringBoot-javafx版本,[xJavaFxTool-spring](https://gitee.com/xwintop/xJavaFxTool-spring) 欢迎参考,谢谢。 #### 下载地址: -- 可直接运行的jar包(本地需要有jdk17环境)[xJavaFxTool-0.3.1.jar](https://gitee.com/xwintop/xJavaFxTool/attach_files/1011054/download/xJavaFxTool-0.3.1.jar) -- Windows x64安装包(兼容windows7、8、10、11等系统)[xJavaFxTool-0.3.1-windows-x64.exe](https://gitee.com/xwintop/xJavaFxTool/attach_files/1011059/download/xJavaFxTool-0.3.1-windows-x64.exe) -- Linux x64 [xJavaFxTool-0.3.1-linux-x64.zip](https://gitee.com/xwintop/xJavaFxTool/attach_files/1011058/download/xJavaFxTool-0.3.1-linux-x64.zip) -- Mac OS x64 [xJavaFxTool-0.3.1-macos.dmg](https://gitee.com/xwintop/xJavaFxTool/attach_files/1011060/download/xJavaFxTool-0.3.1-macos.dmg) +- 可直接运行的jar包(本地需要有jdk17环境)[xJavaFxTool-0.3.2.jar](https://gitee.com/xwintop/xJavaFxTool/attach_files/1022632/download/xJavaFxTool-0.3.2.jar) +- Windows x64安装包(兼容windows7、8、10、11等系统)[xJavaFxTool-0.3.2-windows-x64.exe](https://gitee.com/xwintop/xJavaFxTool/attach_files/1022629/download/xJavaFxTool_0.3.2-windows-x64.exe) +- Linux x64 [xJavaFxTool-0.3.2-linux-x64.zip](https://gitee.com/xwintop/xJavaFxTool/attach_files/1022631/download/xJavaFxTool-0.3.2-linux-x64.zip) +- Mac OS x64 [xJavaFxTool-0.3.2-macos.dmg](https://gitee.com/xwintop/xJavaFxTool/attach_files/1022635/download/xJavaFxTool_0.3.2-macos.dmg) - 更多下载地址见[发布页面](https://gitee.com/xwintop/xJavaFxTool/releases) #### 若上面下链接失效可使用下面下载链接: - 百度云链接:[https://pan.baidu.com/s/193fhGnJL4dDWcqDnFJcHbA](https://pan.baidu.com/s/193fhGnJL4dDWcqDnFJcHbA) 提取码:mokl diff --git a/README_EN.md b/README_EN.md index 09f81bcd..e3f2c83b 100644 --- a/README_EN.md +++ b/README_EN.md @@ -21,9 +21,10 @@ xJavaFxTool is a practical gadget set developed by javaFx. It uses some time to Due to the hot SpringBoot, the project has been released SpringBoot-javafx version, [xJavaFxTool-spring](https://gitee.com/xwintop/xJavaFxTool-spring) welcome reference, thank you. #### Download trial address: -- Jar package that can be run directly (local need to have jdk1.8 environment)[xJavaFxTool-0.2.3.jar](https://xwintop.gitee.io/maven/package/xJavaFxTool/xJavaFxTool-0.2.3.jar) -- Windows x64 installation package (compatible with xp, windows7, 8, 10, etc.)[xJavaFxTool-0.2.3-windows-x64.exe](https://xwintop.gitee.io/maven/package/xJavaFxTool/xJavaFxTool-0.2.3-windows-x64.exe) -- Mac OS X x64 [xJavaFxTool-0.2.3-macosx-x64.pkg](https://xwintop.gitee.io/maven/package/xJavaFxTool/xJavaFxTool-0.2.3-macosx-x64.pkg) +- Jar package that can be run directly (local need to have jdk1.8 environment)[xJavaFxTool-0.3.2.jar](https://github.com/864381832/xJavaFxTool/releases/download/0.3.2/xJavaFxTool-0.3.2.jar) +- Windows x64 installation package (compatible with xp, windows7, 8, 10, etc.)[xJavaFxTool-0.3.2-windows-x64.exe](https://github.com/864381832/xJavaFxTool/releases/download/0.3.2/xJavaFxTool-0.3.2-windows-x64.exe) +- Mac OS x64 [xJavaFxTool-0.3.2-macos.pkg](https://github.com/864381832/xJavaFxTool/releases/download/0.3.2/xJavaFxTool-0.3.2-macos.pkg) +- Linux x64 [xJavaFxTool-0.3.2-linux-x64.zip](https://github.com/864381832/xJavaFxTool/releases/download/0.3.2/xJavaFxTool-0.3.2-linux-x64.zip) #### If the above link fails, use the download link below: - Baidu cloud link: [https://pan.baidu.com/s/193fhGnJL4dDWcqDnFJcHbA](https://pan.baidu.com/s/193fhGnJL4dDWcqDnFJcHbA) extraction code: mokl - Tencent micro cloud link: [https://share.weiyun.com/5T6FPLW](https://share.weiyun.com/5T6FPLW) extraction code: java @@ -36,8 +37,7 @@ the plug-in jar package can be automatically loaded under the root directory lib - Developed with eclipase or Intellij Idea (Recommended to use [Intellij Idea](https://www.jetbrains.com/idea/) ) - This project uses [lombok](https://projectlombok.org/) . If you have not downloaded the lombok plugin when viewing this project, please install it first, otherwise you can't find the get/set method. - The dependent [xcore](https://gitee.com/xwintop/xcore) package has been uploaded to the git-hosted maven platform. The git hosting maven can refer to the tutorial (if you can't download it, please pull the project to compile it yourself ). Tutorial address: Click to enter -- Package using the [javafx-maven-plugin](https://github.com/javafx-maven-plugin/javafx-maven-plugin) (can be packaged for windows, Linux, Mac installation packages) -- Use [exe4j](https://www.ej-technologies.com/download/exe4j/files) to convert the jar package into an exe executable file (for reference only, you can use other programs to package) +- Package using the [javapackager](https://github.com/fvarrui/JavaPackager) (can be packaged for windows, Linux, Mac installation packages) - Use [InnoSetup](http://www.jrsoftware.org/) to make windows installation packages #### The currently integrated gadgets are: diff --git a/pom.xml b/pom.xml index aa9a6fb5..15e48a9f 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.xwintop xJavaFxTool - 0.3.1 + 0.3.2 jar xJavaFxTool 基于JavaFx搭建的实用小工具集合 @@ -19,7 +19,6 @@ true 17 17 - 17.0.2 @@ -48,17 +47,16 @@ org.projectlombok lombok 1.18.22 - true provided - - io.github.classgraph - classgraph - 4.8.100 - + + + + + diff --git a/src/main/java/com/xwintop/xJavaFxTool/XJavaFxToolApplication.java b/src/main/java/com/xwintop/xJavaFxTool/XJavaFxToolApplication.java index 55381403..67b441a1 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/XJavaFxToolApplication.java +++ b/src/main/java/com/xwintop/xJavaFxTool/XJavaFxToolApplication.java @@ -1,3 +1,13 @@ +/** + * Copyright (c) [2019] [xufeng] + * [xJavaFxTool] is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + package com.xwintop.xJavaFxTool; import com.xwintop.xJavaFxTool.controller.IndexController; @@ -40,7 +50,7 @@ public void start(Stage primaryStage) throws Exception { FxApp.styleSheets.add(XJavaFxToolApplication.class.getResource("/css/jfoenix-main.css").toExternalForm()); // if (SystemUtil.getOsInfo().isMac()) { - //Mac下设置dock栏图标 + //Mac下设置dock栏图标 // Taskbar.getTaskbar().setIconImage(ImageIO.read(XJavaFxToolApplication.class.getResourceAsStream(LOGO_PATH))); // } diff --git a/src/main/java/com/xwintop/xJavaFxTool/XJavaFxToolMain.java b/src/main/java/com/xwintop/xJavaFxTool/XJavaFxToolMain.java index 7d25db2f..fbd0dba3 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/XJavaFxToolMain.java +++ b/src/main/java/com/xwintop/xJavaFxTool/XJavaFxToolMain.java @@ -1,3 +1,12 @@ +/** + * Copyright (c) [2019] [xufeng] + * [xJavaFxTool] is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ package com.xwintop.xJavaFxTool; import com.xwintop.xJavaFxTool.utils.XJavaFxSystemUtil; diff --git a/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java b/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java index 8fe8e0ac..7e228b33 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java +++ b/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java @@ -12,8 +12,10 @@ import com.xwintop.xJavaFxTool.services.IndexService; import com.xwintop.xJavaFxTool.services.index.SystemSettingService; import com.xwintop.xJavaFxTool.utils.Config; +import com.xwintop.xJavaFxTool.utils.VersionChecker; import com.xwintop.xJavaFxTool.view.IndexView; import com.xwintop.xcore.javafx.FxApp; +import com.xwintop.xcore.javafx.dialog.FxAlerts; import com.xwintop.xcore.javafx.dialog.FxDialog; import com.xwintop.xcore.util.ConfigureUtil; import com.xwintop.xcore.util.HttpClientUtil; @@ -74,16 +76,12 @@ public void initialize(URL location, ResourceBundle resources) { initView(); initEvent(); initService(); - initNotepad(); - } - - private void initNotepad() { -// if (Config.getBoolean(Config.Keys.NotepadEnabled, true)) { -// addNodepadAction(null); -// } } private void initView() { + if (Config.getBoolean(Config.Keys.NotepadEnabled, true)) { + addNodepadAction(null); + } this.indexService.addWebView(XJavaFxToolApplication.RESOURCE_BUNDLE.getString("feedback"), QQ_URL, null); this.tongjiWebView.getEngine().load(STATISTICS_URL); this.tabPaneMain.getSelectionModel().select(0); @@ -95,6 +93,8 @@ private void initEvent() { } private void initService() { + PluginManager pluginManager = PluginManager.getInstance(); + pluginManager.loadLocalDevPluginConfiguration(); loadPlugins(); // 加载插件列表到界面上 AppEvents.addEventHandler(PluginEvent.PLUGIN_DOWNLOADED, pluginEvent -> { loadPlugins(); @@ -114,6 +114,7 @@ public void loadPlugins() { PluginManager pluginManager = PluginManager.getInstance(); pluginManager.loadLocalPlugins(); pluginManager.getEnabledPluginList().forEach(this::loadPlugin); + pluginManager.getDevPluginList().forEach(this::loadPlugin); } /** @@ -164,24 +165,24 @@ private void addCategory(PluginCategoryController category) { } private void addMenu(PluginJarInfo jarInfo) { - MenuItem menu = moreToolsMenu.getItems().stream().filter(menuItem1 -> jarInfo.getMenuParentId().equals(menuItem1.getId())).findAny().orElse(null); - if (menu == null) { - menu = new Menu(XJavaFxToolApplication.RESOURCE_BUNDLE.getString(jarInfo.getMenuParentTitle())); - menu.setId(jarInfo.getMenuParentId()); - moreToolsMenu.getItems().add(menu); - } - MenuItem menuItem = new MenuItem(jarInfo.getTitle()); - if (StringUtils.isNotEmpty(jarInfo.getIconPath())) { - ImageView imageView = new ImageView(new Image(jarInfo.getIconPath())); - imageView.setFitHeight(18); - imageView.setFitWidth(18); - menuItem.setGraphic(imageView); - } - menuItem.setOnAction((ActionEvent event) -> { - indexService.loadPlugin(jarInfo); - }); - ((Menu)menu).getItems().add(menuItem); - menuItemMap.put(menuItem.getText(), menuItem); + MenuItem menu = moreToolsMenu.getItems().stream().filter(menuItem1 -> jarInfo.getMenuParentId().equals(menuItem1.getId())).findAny().orElse(null); + if (menu == null) { + menu = new Menu(XJavaFxToolApplication.RESOURCE_BUNDLE.getString(jarInfo.getMenuParentTitle())); + menu.setId(jarInfo.getMenuParentId()); + moreToolsMenu.getItems().add(menu); + } + MenuItem menuItem = new MenuItem(jarInfo.getTitle()); + if (jarInfo.getIconImage() != null || StringUtils.isNotEmpty(jarInfo.getIconPath())) { + ImageView imageView = new ImageView(jarInfo.getIconImage() == null ? new Image(jarInfo.getIconPath()) : jarInfo.getIconImage()); + imageView.setFitHeight(18); + imageView.setFitWidth(18); + menuItem.setGraphic(imageView); + } + menuItem.setOnAction((ActionEvent event) -> { + indexService.loadPlugin(jarInfo); + }); + ((Menu) menu).getItems().add(menuItem); + menuItemMap.put(menuItem.getText(), menuItem); } public void selectAction(String selectText) { @@ -239,6 +240,13 @@ private void SettingAction() { SystemSettingService.openSystemSettings(bundle.getString("Setting")); } + @FXML + private void checkerVersionAction() { + if (!VersionChecker.checkNewVersion()) { + FxAlerts.info("提示", "已经是新版本"); + } + } + @FXML private void aboutAction() { AlertUtil.showInfoAlert(bundle.getString("aboutText") + Config.xJavaFxToolVersions); @@ -270,6 +278,11 @@ private void openConfigFolderAction() { private void openPluginFolderAction() { JavaFxSystemUtil.openDirectory("libs/"); } + + @FXML + private void openDevPluginFolderAction() { + JavaFxSystemUtil.openDirectory("devLibs/"); + } @FXML private void xwintopLinkOnAction() throws Exception { diff --git a/src/main/java/com/xwintop/xJavaFxTool/controller/index/PluginManageController.java b/src/main/java/com/xwintop/xJavaFxTool/controller/index/PluginManageController.java index e8063f10..852f47b8 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/controller/index/PluginManageController.java +++ b/src/main/java/com/xwintop/xJavaFxTool/controller/index/PluginManageController.java @@ -4,14 +4,11 @@ import com.xwintop.xJavaFxTool.event.AppEvents; import com.xwintop.xJavaFxTool.event.PluginEvent; import com.xwintop.xJavaFxTool.model.PluginJarInfo; -import com.xwintop.xJavaFxTool.plugin.AddPluginResult; -import com.xwintop.xJavaFxTool.plugin.PluginClassLoader; import com.xwintop.xJavaFxTool.plugin.PluginManager; import com.xwintop.xJavaFxTool.plugin.PluginParser; import com.xwintop.xJavaFxTool.services.index.PluginManageService; import com.xwintop.xJavaFxTool.view.index.PluginManageView; import com.xwintop.xcore.javafx.dialog.FxAlerts; -import com.xwintop.xcore.util.javafx.FileChooserUtil; import com.xwintop.xcore.util.javafx.JavaFxViewUtil; import com.xwintop.xcore.util.javafx.TooltipUtil; import javafx.application.Platform; @@ -20,14 +17,12 @@ import javafx.collections.transformation.FilteredList; import javafx.fxml.FXMLLoader; import javafx.scene.control.*; -import javafx.stage.FileChooser.ExtensionFilter; -import javafx.stage.Window; import javafx.util.Callback; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; -import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Map; @@ -63,13 +58,7 @@ public void initialize(URL location, ResourceBundle resources) { initService(); } - public Window getWindow() { - return this.pluginDataTableView.getScene().getWindow(); - } - private void initView() { - addLocalPluginButton.setVisible(Boolean.parseBoolean(System.getProperty("localPluginEnabled", "false"))); - JavaFxViewUtil.setTableColumnMapValueFactory(nameTableColumn, "nameTableColumn"); JavaFxViewUtil.setTableColumnMapValueFactory(synopsisTableColumn, "synopsisTableColumn"); JavaFxViewUtil.setTableColumnMapValueFactory(versionTableColumn, "versionTableColumn"); @@ -95,7 +84,7 @@ protected void updateItem(String item, boolean empty) { downloadButton.setDisable(true); } this.setContentDisplay(ContentDisplay.CENTER); - downloadButton.setOnMouseClicked(event -> downloadPlugin(dataRow, downloadButton)); + downloadButton.setOnMouseClicked(event -> downloadPlugin(dataRow)); this.setGraphic(downloadButton); } } @@ -106,10 +95,10 @@ protected void updateItem(String item, boolean empty) { pluginDataTableView.setItems(pluginDataTableData); } - private void downloadPlugin(Map dataRow, Button downloadButton) { + private void downloadPlugin(Map dataRow) { try { pluginManageService.downloadPluginJar(dataRow, pluginJarInfo -> - Platform.runLater(() -> afterDownload(dataRow, downloadButton, pluginJarInfo)) + Platform.runLater(() -> afterDownload(dataRow, pluginJarInfo)) ); } catch (Exception e) { log.error("下载插件失败:", e); @@ -117,25 +106,23 @@ private void downloadPlugin(Map dataRow, Button downloadButton) } } - private void afterDownload(Map dataRow, Button downloadButton, PluginJarInfo pluginJarInfo) { + private void afterDownload(Map dataRow, PluginJarInfo pluginJarInfo) { // 没有下载成功不做处理 if (pluginJarInfo.getIsDownload() == null || !pluginJarInfo.getIsDownload()) { return; } - try { - PluginManager.getInstance().saveToFile(); + PluginJarInfo pluginJarInfoOld = PluginManager.getInstance().getPlugin(pluginJarInfo.getJarName()); + if (pluginJarInfoOld != null) { + FileUtils.delete(pluginJarInfoOld.getFile()); + PluginManager.getInstance().getPluginList().remove(pluginJarInfoOld); + } + PluginManager.getInstance().getPluginList().add(pluginJarInfo); TooltipUtil.showToast("插件 " + dataRow.get("nameTableColumn") + " 下载完成"); - - PluginClassLoader tempClassLoader = PluginClassLoader.create(pluginJarInfo.getFile()); - PluginParser.parse(pluginJarInfo.getFile(), pluginJarInfo, tempClassLoader); - + PluginParser.parse(pluginJarInfo.getFile(), pluginJarInfo); + PluginManager.getInstance().saveToFile(); dataRow.put("isEnableTableColumn", "true"); dataRow.put("isDownloadTableColumn", "已下载"); - - downloadButton.setText("已下载"); - downloadButton.setDisable(true); - pluginDataTableView.refresh(); AppEvents.fire(new PluginEvent(PluginEvent.PLUGIN_DOWNLOADED, pluginJarInfo)); } catch (IOException e) { @@ -147,7 +134,7 @@ private void afterDownload(Map dataRow, Button downloadButton, P private void initEvent() { // 右键菜单 ContextMenu contextMenu = new ContextMenu(); - JavaFxViewUtil.addMenuItem(contextMenu,"保存配置", actionEvent -> { + JavaFxViewUtil.addMenuItem(contextMenu, "保存配置", actionEvent -> { try { PluginManager.getInstance().saveToFile(); TooltipUtil.showToast("保存配置成功"); @@ -155,7 +142,7 @@ private void initEvent() { log.error("保存插件配置失败", ex); } }); - JavaFxViewUtil.addMenuItem(contextMenu,"删除插件", actionEvent -> { + JavaFxViewUtil.addMenuItem(contextMenu, "删除插件", actionEvent -> { pluginManageService.deletePlugin(); }); pluginDataTableView.setContextMenu(contextMenu); @@ -170,15 +157,4 @@ private void initService() { public void searchPlugin() { pluginManageService.searchPlugin(selectPluginTextField.getText()); } - - public void addLocalPlugin() { - File jarFile = FileChooserUtil.chooseFile(new ExtensionFilter("打包插件(*.jar)", "*.jar")); - if (jarFile != null) { - AddPluginResult result = PluginManager.getInstance().addPluginJar(jarFile); - if (result.isNewPlugin()) { - pluginManageService.addDataRow(result.getPluginJarInfo()); - } - AppEvents.fire(new PluginEvent(PluginEvent.PLUGIN_DOWNLOADED, result.getPluginJarInfo())); - } - } } \ No newline at end of file diff --git a/src/main/java/com/xwintop/xJavaFxTool/model/PluginJarInfo.java b/src/main/java/com/xwintop/xJavaFxTool/model/PluginJarInfo.java index d1500989..83b2923a 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/model/PluginJarInfo.java +++ b/src/main/java/com/xwintop/xJavaFxTool/model/PluginJarInfo.java @@ -1,6 +1,7 @@ package com.xwintop.xJavaFxTool.model; import com.alibaba.fastjson.annotation.JSONField; +import javafx.scene.image.Image; import lombok.Data; import lombok.NoArgsConstructor; @@ -80,7 +81,5 @@ public File getFile() { } @JSONField(serialize = false) - public String getDefaultIconPath() { - return bundleName == null ? "" : (bundleName.replace("locale.", "/logo/") + ".png"); - } + private Image iconImage; } diff --git a/src/main/java/com/xwintop/xJavaFxTool/newui/NewLauncherController.java b/src/main/java/com/xwintop/xJavaFxTool/newui/NewLauncherController.java deleted file mode 100644 index 64211858..00000000 --- a/src/main/java/com/xwintop/xJavaFxTool/newui/NewLauncherController.java +++ /dev/null @@ -1,188 +0,0 @@ -//package com.xwintop.xJavaFxTool.newui; -// -//import com.xwintop.xJavaFxTool.XJavaFxToolApplication; -//import com.xwintop.xJavaFxTool.controller.IndexController; -//import com.xwintop.xJavaFxTool.controller.index.PluginManageController; -//import com.xwintop.xJavaFxTool.event.AppEvents; -//import com.xwintop.xJavaFxTool.event.PluginEvent; -//import com.xwintop.xJavaFxTool.model.PluginJarInfo; -//import com.xwintop.xJavaFxTool.plugin.PluginManager; -//import com.xwintop.xJavaFxTool.plugin.PluginParser; -//import com.xwintop.xJavaFxTool.services.index.SystemSettingService; -//import com.xwintop.xcore.javafx.FxApp; -//import com.xwintop.xcore.javafx.dialog.FxDialog; -//import javafx.beans.Observable; -//import javafx.scene.control.CheckMenuItem; -//import javafx.scene.control.ContextMenu; -//import javafx.scene.control.TabPane; -//import javafx.scene.control.TextField; -//import javafx.scene.layout.VBox; -//import javafx.scene.web.WebView; -//import lombok.extern.slf4j.Slf4j; -//import org.apache.commons.lang3.BooleanUtils; -//import org.apache.commons.lang3.StringUtils; -// -//import java.awt.*; -//import java.io.File; -//import java.net.URI; -//import java.util.ArrayList; -//import java.util.HashMap; -//import java.util.List; -//import java.util.Map; -// -//@Slf4j -//public class NewLauncherController { -// -// public static final String FAVORITE_CATEGORY_NAME = "置顶"; -// -// public VBox pluginCategories; -// -// public WebView startWebView; -// -// public TabPane tabPane; -// -// public TextField txtSearch; -// -// private ContextMenu itemContextMenu; -// -// // 实现搜索用 -// private final List pluginItemControllers = new ArrayList<>(); -// -// private final Map categoryControllers = new HashMap<>(); -// -// public void initialize() { -// NewLauncherService.getInstance().setTabPane(tabPane); -// txtSearch.textProperty().addListener(this::onSearchKeywordChanged); -// -// initContextMenu(); -// loadPlugins(); // 加载插件列表到界面上 -// -// startWebView.getEngine().load(IndexController.QQ_URL); // 额外再打开一个反馈页面,可关闭 -// -// AppEvents.addEventHandler(PluginEvent.PLUGIN_DOWNLOADED, pluginEvent -> { -// loadPlugins(); -// }); -// } -// -// private void initContextMenu() { -// CheckMenuItem chkFavorite = new CheckMenuItem("置顶"); -// chkFavorite.setStyle("-fx-padding: 0 35 0 0"); -// -// this.itemContextMenu = new ContextMenu(chkFavorite); -// -// chkFavorite.setOnAction(event -> { -// CheckMenuItem _this = (CheckMenuItem) event.getSource(); -// PluginItemController pluginItemController = NewLauncherService.getInstance().getCurrentPluginItem(); -// setFavorite(pluginItemController, _this.isSelected()); -// }); -// } -// -// public void onSearchKeywordChanged(Observable ob, String _old, String keyword) { -// boolean notSearching = StringUtils.isBlank(keyword); -// pluginItemControllers.forEach(itemController -> { -// itemController.setVisible(notSearching || itemController.matchKeyword(keyword)); -// }); -// } -// -// private void setFavorite(PluginItemController itemController, boolean isFavorite) { -// if (itemController == null) { -// return; -// } -// -// itemController.getPluginJarInfo().setIsFavorite(isFavorite); -// PluginManager.getInstance().saveToFileQuietly(); -// loadPlugins(); -// } -// -// /** -// * 加载/刷新插件列表 -// */ -// private void loadPlugins() { -// -// this.pluginCategories.getChildren().clear(); -// this.pluginItemControllers.clear(); -// this.categoryControllers.clear(); -// -// PluginManager pluginManager = PluginManager.getInstance(); -// pluginManager.loadLocalPlugins(); -// pluginManager.getEnabledPluginList().forEach(this::loadPlugin); -// } -// -// /** -// * 加载单个插件到界面,要求插件已经经过 {@link PluginParser#parse(File, PluginJarInfo)} 解析 -// * -// * @param jarInfo 插件信息 -// */ -// private void loadPlugin(PluginJarInfo jarInfo) { -// -// if (!jarInfo.getFile().exists()) { -// log.info("跳过插件 {}: 文件不存在", jarInfo.getName()); -// return; -// } -// -// if (BooleanUtils.isFalse(jarInfo.getIsEnable())) { -// log.info("跳过插件 {}: 插件未启用", jarInfo.getName()); -// return; -// } -// -// String menuParentTitle = jarInfo.getMenuParentTitle(); -// if (menuParentTitle == null) { -// log.info("跳过插件 {}: menuParentTitle 为空", jarInfo.getName()); -// return; -// } -// -// String categoryName = jarInfo.getIsFavorite() ? FAVORITE_CATEGORY_NAME : XJavaFxToolApplication.RESOURCE_BUNDLE.getString(menuParentTitle); -// -// PluginCategoryController category = categoryControllers.computeIfAbsent( -// categoryName, __ -> { -// PluginCategoryController _category = -// PluginCategoryController.newInstance(categoryName); -// addCategory(_category); -// return _category; -// } -// ); -// -// PluginItemController item = PluginItemController.newInstance(jarInfo); -// item.setContextMenu(itemContextMenu); -// category.addItem(item); -// -// if (!pluginItemControllers.contains(item)) { -// pluginItemControllers.add(item); -// } -// } -// -// private void addCategory(PluginCategoryController category) { -// if (category.lblCategoryName.getText().equals(FAVORITE_CATEGORY_NAME)) { -// this.pluginCategories.getChildren().add(0, category.root); -// } else { -// this.pluginCategories.getChildren().add(category.root); -// } -// } -// -// public TabPane getTabPane() { -// return tabPane; -// } -// -// public void openConfigDialog() { -// SystemSettingService.openSystemSettings("设置"); -// } -// -// public void openPluginManager() { -// new FxDialog() -// .setBodyFxml(PluginManageController.FXML) -// .setOwner(FxApp.primaryStage) -// .setResizable(true) -// .setTitle(XJavaFxToolApplication.RESOURCE_BUNDLE.getString("plugin_manage")) -// .setPrefWidth(800) -// .withStage(stage -> stage.setOnCloseRequest(event -> loadPlugins())) -// .show(); -// } -// -// public void openProjectUrl() { -// try { -// Desktop.getDesktop().browse(new URI("https://gitee.com/xwintop/xJavaFxTool")); -// } catch (Exception e) { -// log.error("打开项目地址失败", e); -// } -// } -//} diff --git a/src/main/java/com/xwintop/xJavaFxTool/newui/PluginItemController.java b/src/main/java/com/xwintop/xJavaFxTool/newui/PluginItemController.java index 55424360..108948e5 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/newui/PluginItemController.java +++ b/src/main/java/com/xwintop/xJavaFxTool/newui/PluginItemController.java @@ -3,7 +3,6 @@ import com.xwintop.xJavaFxTool.controller.IndexController; import com.xwintop.xJavaFxTool.model.PluginJarInfo; import com.xwintop.xJavaFxTool.plugin.PluginManager; -import com.xwintop.xJavaFxTool.utils.ResourceUtils; import com.xwintop.xcore.javafx.helper.FxmlHelper; import javafx.fxml.FXMLLoader; import javafx.scene.control.CheckMenuItem; @@ -17,12 +16,11 @@ import lombok.Data; import lombok.extern.slf4j.Slf4j; -import java.net.URL; - @Data @Slf4j public class PluginItemController { public static final String FXML_PATH = "/com/xwintop/xJavaFxTool/fxmlView/newui/plugin-item.fxml"; + public static PluginItemController newInstance(PluginJarInfo pluginJarInfo) { FXMLLoader fxmlLoader = FxmlHelper.loadFromResource(FXML_PATH); PluginItemController controller = fxmlLoader.getController(); @@ -73,13 +71,10 @@ private void onMouseLeftClicked(MouseEvent event) { } private void updateIcon() { - URL iconUrl = ResourceUtils.getResource(this.pluginJarInfo.getIconPath(), this.pluginJarInfo.getDefaultIconPath(), "/logo/plugin.png"); - if (iconUrl != null) { - String url = iconUrl.toExternalForm(); - if (url.endsWith("plugin.png")) { - log.info("please add logo to " + this.pluginJarInfo.getDefaultIconPath()); - } - imgLogo.setImage(new Image(url)); + if (this.pluginJarInfo.getIconImage() != null) { + imgLogo.setImage(this.pluginJarInfo.getIconImage()); + } else { + imgLogo.setImage(new Image("/images/plugin.png")); } } diff --git a/src/main/java/com/xwintop/xJavaFxTool/plugin/AddPluginResult.java b/src/main/java/com/xwintop/xJavaFxTool/plugin/AddPluginResult.java deleted file mode 100644 index 045d7f73..00000000 --- a/src/main/java/com/xwintop/xJavaFxTool/plugin/AddPluginResult.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.xwintop.xJavaFxTool.plugin; - -import com.xwintop.xJavaFxTool.model.PluginJarInfo; -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class AddPluginResult { - - private PluginJarInfo pluginJarInfo; - - private boolean newPlugin; -} diff --git a/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginClassLoader.java b/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginClassLoader.java index 808e934a..07b4c047 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginClassLoader.java +++ b/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginClassLoader.java @@ -1,14 +1,9 @@ package com.xwintop.xJavaFxTool.plugin; -import io.github.classgraph.ClassGraph; - import java.io.File; import java.net.MalformedURLException; -import java.net.URI; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.List; /** * 用于加载插件的 ClassLoader @@ -20,17 +15,22 @@ public static PluginClassLoader create(File jarFile) { } public static PluginClassLoader create(ClassLoader parent, File jarFile) { - List uris = new ArrayList<>(new ClassGraph().getClasspathURIs()); - uris.add(jarFile.toURI()); - - URL[] urls = uris.stream().map(uri -> { - try { - return uri.toURL(); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - }).toArray(URL[]::new); - +// List uris = new ArrayList<>(new ClassGraph().getClasspathURIs()); +// uris.add(jarFile.toURI()); +// URL[] urls = uris.stream().map(uri -> { +// try { +// return uri.toURL(); +// } catch (MalformedURLException e) { +// throw new RuntimeException(e); +// } +// }).toArray(URL[]::new); + + URL[] urls = null; + try { + urls = new URL[]{jarFile.toURI().toURL()}; + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } return new PluginClassLoader(urls, parent); } diff --git a/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginManager.java b/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginManager.java index a63a3bd8..75030fc7 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginManager.java +++ b/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginManager.java @@ -1,52 +1,26 @@ package com.xwintop.xJavaFxTool.plugin; -import cn.hutool.http.HttpStatus; -import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.xwintop.xJavaFxTool.model.PluginJarInfo; -import com.xwintop.xJavaFxTool.utils.Config; -import com.xwintop.xJavaFxTool.utils.Config.Keys; -import com.xwintop.xJavaFxTool.utils.XJavaFxSystemUtil; +import lombok.Data; import lombok.extern.slf4j.Slf4j; -import okhttp3.*; -import okhttp3.Request.Builder; -import okio.*; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.function.BiConsumer; -import java.util.function.Consumer; import java.util.stream.Collectors; @Slf4j +@Data public class PluginManager { - - public static final String SERVER_PLUGINS_URL = "https://xwintop.gitee.io/maven/plugin-libs/plugin-list.json"; - public static final String LOCAL_PLUGINS_PATH = "./system_plugin_list.json"; - /** - * 当下载插件时,模拟数种 UA - */ - public static final String[] OPTIONAL_UA_LIST = { - "Mozilla/5.0 (Windows NT 6.1; rv:51.0) Gecko/20100101 Firefox/51.0", - "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.0 Safari/537.36", - "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko" - }; - private static PluginManager instance; public static PluginManager getInstance() { @@ -56,23 +30,16 @@ public static PluginManager getInstance() { return instance; } - ////////////////////////////////////////////////////////////// - private final OkHttpClient pluginDownloader = new OkHttpClient.Builder().addInterceptor(new DownloadProgressInterceptor()).build(); - private final List pluginList = new ArrayList<>(); // 插件列表 + private final List devPluginList = new ArrayList<>(); // dev插件列表 public PluginManager() { this.loadLocalPluginConfiguration(); } ////////////////////////////////////////////////////////////// 查询插件 - - public List getPluginList() { - return Collections.unmodifiableList(this.pluginList); - } - public List getEnabledPluginList() { - return getPluginList().stream().filter(PluginJarInfo::getIsEnable).collect(Collectors.toList()); + return this.pluginList.stream().filter(PluginJarInfo::getIsEnable).collect(Collectors.toList()); } public PluginJarInfo getPlugin(String jarName) { @@ -81,12 +48,6 @@ public PluginJarInfo getPlugin(String jarName) { .findFirst().orElse(null); } - public PluginJarInfo getPluginByFxmlPath(String fxmlPath) { - return this.pluginList.stream() - .filter(plugin -> Objects.equals(plugin.getFxmlPath(), fxmlPath)) - .findFirst().orElse(null); - } - ////////////////////////////////////////////////////////////// 插件列表 /** @@ -98,175 +59,84 @@ private void loadLocalPluginConfiguration() { if (!Files.exists(path)) { return; } - String json = Files.readString(path, StandardCharsets.UTF_8); - JSON.parseArray(json, PluginJarInfo.class).forEach(plugin -> { - this.addOrUpdatePlugin(plugin, exist -> { - exist.setLocalVersionNumber(plugin.getLocalVersionNumber()); - exist.setIsDownload(plugin.getIsDownload()); - exist.setIsEnable(plugin.getIsEnable()); - }); - }); + this.pluginList.addAll(JSON.parseArray(json, PluginJarInfo.class)); } catch (IOException e) { log.error("读取插件配置失败", e); } } + public void loadLocalDevPluginConfiguration() { + try { + // 系统类库路径 + File libPath = new File("devLibs/"); + // 获取所有的.jar文件 + File[] jarFiles = libPath.listFiles((dir, name) -> name.endsWith(".jar")); + if (jarFiles != null) { + for (File file : jarFiles) { + try { + PluginJarInfo plugin = new PluginJarInfo(); + plugin.setLocalPath(file.getAbsolutePath()); + plugin.setIsEnable(true); + plugin.setIsDownload(true); + PluginParser.parse(file, plugin); + devPluginList.add(plugin); + } catch (Exception e) { + log.error("解析失败", e); + } + } + } + } catch (Exception e) { + log.error("添加libs中jar包到系统中异常:", e); + } + } + /** * 解析本地插件文件 */ public void loadLocalPlugins() { + List removeList = new ArrayList(); this.pluginList.forEach(plugin -> { File pluginFile = plugin.getFile(); if (pluginFile.exists()) { try { - PluginParser.parse(pluginFile, plugin); + PluginParser.initParse(pluginFile, plugin); } catch (Exception e) { log.error("解析失败", e); } + } else { + removeList.add(plugin); } }); + this.pluginList.removeAll(removeList); } /** * 添加本地插件。如果与已有插件同名,则替换已有插件信息 - * - * @param jarFile 插件文件 - */ - public AddPluginResult addPluginJar(File jarFile) { - PluginClassLoader tmpClassLoader = PluginClassLoader.create(jarFile); - PluginJarInfo newJarInfo = new PluginJarInfo(); - newJarInfo.setLocalPath(jarFile.getAbsolutePath()); - newJarInfo.setIsEnable(true); - newJarInfo.setIsDownload(true); - PluginParser.parse(jarFile, newJarInfo, tmpClassLoader); - - for (int i = 0; i < pluginList.size(); i++) { - PluginJarInfo jarInfo = pluginList.get(i); - if (Objects.equals(jarInfo.getFxmlPath(), newJarInfo.getFxmlPath())) { - newJarInfo.setVersion(jarInfo.getVersion()); - newJarInfo.setSynopsis(jarInfo.getSynopsis()); - pluginList.set(i, newJarInfo); - saveToFileQuietly(); - return new AddPluginResult(newJarInfo, false); - } - } - - pluginList.add(newJarInfo); - saveToFileQuietly(); - return new AddPluginResult(newJarInfo, true); - } - - public void loadServerPlugins() { - try { - String json = HttpUtil.get(SERVER_PLUGINS_URL); - JSON.parseArray(json, PluginJarInfo.class).forEach(plugin -> { - this.addOrUpdatePlugin(plugin, exist -> { - exist.setName(plugin.getName()); - exist.setSynopsis(plugin.getSynopsis()); - exist.setVersion(plugin.getVersion()); - exist.setVersionNumber(plugin.getVersionNumber()); - exist.setDownloadUrl(plugin.getDownloadUrl()); - }); - }); - log.info("下载插件列表完成。"); - } catch (Exception e) { - log.error("下载插件列表失败", e); - } - } - - // 异步下载服务器插件列表,便于界面上展示 loading 动画 - public CompletableFuture loadServerPluginsAsync() { - return CompletableFuture.runAsync(this::loadServerPlugins); - } - - /** - * 向插件列表添加插件信息或更改插件列表中已有的插件信息 - * - * @param pluginJarInfo 需要添加的插件信息 - * @param ifExists 如果插件已存在,则不会将 pluginJarInfo 加入, - * 而是提供已有的插件信息对象供调用者更新其属性 - */ - private void addOrUpdatePlugin(PluginJarInfo pluginJarInfo, Consumer ifExists) { - PluginJarInfo exists = getPlugin(pluginJarInfo.getJarName()); - if (exists == null) { - this.pluginList.add(pluginJarInfo); - } else { - ifExists.accept(exists); - } - } - - ////////////////////////////////////////////////////////////// 下载插件 - - public File downloadPlugin(PluginJarInfo pluginJarInfo, BiConsumer onProgressUpdate) throws IOException { - - PluginJarInfo plugin = getPlugin(pluginJarInfo.getJarName()); - if (plugin == null) { - throw new IllegalStateException("没有找到插件 " + pluginJarInfo.getJarName()); - } - - File file = pluginJarInfo.getFile(); - FileUtils.forceMkdirParent(file); - - this.currentProgressListener = (bytesRead, contentLength, done) -> onProgressUpdate.accept(contentLength, bytesRead); - - // 使用多个 UA 尝试下载 - Throwable downloadFailure = null; - for (String ua : OPTIONAL_UA_LIST) { - try { - tryDownload(plugin.getName(), pluginJarInfo.getDownloadUrl(), ua, file); - downloadFailure = null; - break; - } catch (Exception e) { - downloadFailure = e; - } - } - - if (downloadFailure != null) { - if (downloadFailure instanceof IOException) { - throw (IOException) downloadFailure; - } else { - throw new IOException("插件 '" + plugin.getName() + "' 下载失败 " + pluginJarInfo.getJarName(), downloadFailure); - } - } - - // 下载完毕 - plugin.setIsDownload(true); - plugin.setIsEnable(true); - plugin.setLocalVersionNumber(plugin.getVersionNumber()); - - if (!Config.getBoolean(Keys.NewLauncher, false)) { - XJavaFxSystemUtil.addJarClass(pluginJarInfo.getFile()); - } - - return file; - } - - /** - * 尝试指定的 UA 进行下载,如果下载失败则抛出异常 - * - * @param pluginName 插件名称 - * @param url 下载地址 - * @param ua UA 字符串 - * @param file 下载到的目标文件 - * @throws IOException 如果下载失败 */ - private void tryDownload(String pluginName, String url, String ua, File file) throws IOException { - Request request = new Builder().header("User-Agent", ua).url(url).build(); - - try (Response response = pluginDownloader.newCall(request).execute()) { - if (response.code() != HttpStatus.HTTP_OK) { - throw new IOException("插件 '" + pluginName + "' 下载失败 : HTTP " + response.code()); - } - - InputStream inputStream = Objects.requireNonNull(response.body()).byteStream(); - try (FileOutputStream outputStream = new FileOutputStream(file)) { - IOUtils.copy(inputStream, outputStream); - } - } - } - - ////////////////////////////////////////////////////////////// 保存配置 +// public AddPluginResult addPluginJar(File jarFile) { +// PluginClassLoader tmpClassLoader = PluginClassLoader.create(jarFile); +// PluginJarInfo newJarInfo = new PluginJarInfo(); +// newJarInfo.setLocalPath(jarFile.getAbsolutePath()); +// newJarInfo.setIsEnable(true); +// newJarInfo.setIsDownload(true); +// PluginParser.parse(jarFile, newJarInfo, tmpClassLoader); +// +// for (int i = 0; i < pluginList.size(); i++) { +// PluginJarInfo jarInfo = pluginList.get(i); +// if (Objects.equals(jarInfo.getFxmlPath(), newJarInfo.getFxmlPath())) { +// newJarInfo.setVersion(jarInfo.getVersion()); +// newJarInfo.setSynopsis(jarInfo.getSynopsis()); +// pluginList.set(i, newJarInfo); +// saveToFileQuietly(); +// return new AddPluginResult(newJarInfo, false); +// } +// } +// +// pluginList.add(newJarInfo); +// saveToFileQuietly(); +// return new AddPluginResult(newJarInfo, true); +// } // 保存配置,如果失败则抛出异常 public void saveToFile() throws IOException { @@ -286,75 +156,4 @@ public void saveToFileQuietly() { log.error("", e); } } - - ////////////////////////////////////////////////////////////// 下载进度 - - private ProgressListener currentProgressListener; - - private class DownloadProgressInterceptor implements Interceptor { - - @Override - public Response intercept(Chain chain) throws IOException { - Response originalResponse = chain.proceed(chain.request()); - return originalResponse.newBuilder() - .body(new ProgressResponseBody(originalResponse.body(), - (bytesRead, contentLength, done) -> { - if (currentProgressListener != null) { - currentProgressListener.update(bytesRead, contentLength, done); - } - } - )) - .build(); - } - } - - private static class ProgressResponseBody extends ResponseBody { - - private final ResponseBody responseBody; - - private final ProgressListener progressListener; - - private BufferedSource bufferedSource; - - ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) { - this.responseBody = responseBody; - this.progressListener = progressListener; - } - - @Override - public MediaType contentType() { - return responseBody.contentType(); - } - - @Override - public long contentLength() { - return responseBody.contentLength(); - } - - @Override - public BufferedSource source() { - if (bufferedSource == null) { - bufferedSource = Okio.buffer(source(responseBody.source())); - } - return bufferedSource; - } - - private Source source(Source source) { - return new ForwardingSource(source) { - long totalBytesRead = 0L; - @Override - public long read(Buffer sink, long byteCount) throws IOException { - long bytesRead = super.read(sink, byteCount); - // read() returns the number of bytes read, or -1 if this source is exhausted. - totalBytesRead += bytesRead != -1 ? bytesRead : 0; - progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1); - return bytesRead; - } - }; - } - } - - interface ProgressListener { - void update(long bytesRead, long contentLength, boolean done); - } } diff --git a/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginParser.java b/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginParser.java index da61bbd4..fa1a2bdf 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginParser.java +++ b/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginParser.java @@ -3,6 +3,7 @@ import com.xwintop.xJavaFxTool.AppException; import com.xwintop.xJavaFxTool.model.PluginJarInfo; import com.xwintop.xJavaFxTool.utils.Config; +import javafx.scene.image.Image; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.dom4j.Document; @@ -71,6 +72,11 @@ public static void parse(File pluginFile, PluginJarInfo pluginJarInfo, ClassLoad pluginJarInfo.setBundleName(resourceBundleName); pluginJarInfo.setControllerType(controllerType); pluginJarInfo.setTitle(title); + pluginJarInfo.setIconPath(pluginElement.elementTextTrim("iconPath")); + if (StringUtils.isNotBlank(pluginJarInfo.getIconPath())) { + Image iconImage = new Image(jarFile.getInputStream(jarFile.getJarEntry(StringUtils.removeStart(pluginJarInfo.getIconPath(),"/")))); + pluginJarInfo.setIconImage(iconImage); + } if (controllerType.equals("Node")) { pluginJarInfo.setFxmlPath(url); @@ -84,6 +90,27 @@ public static void parse(File pluginFile, PluginJarInfo pluginJarInfo, ClassLoad } } + //简单解析插件信息 + public static void initParse(File pluginFile, PluginJarInfo pluginJarInfo) { + try (JarFile jarFile = new JarFile(pluginFile)) { + JarEntry entry = jarFile.getJarEntry(ENTRY_NAME); + if (entry == null) { + return; + } + Element root = createRootElement(jarFile, entry); + Element pluginElement = selectSingleElement(root, "/root/ToolFxmlLoaderConfiguration[not(@isMenu)]"); + String title = getTitleFromResourceBundle(pluginFile, null, pluginElement, pluginJarInfo.getBundleName()); + pluginJarInfo.setTitle(title); + if (StringUtils.isNotBlank(pluginJarInfo.getIconPath())) { + Image iconImage = new Image(jarFile.getInputStream(jarFile.getJarEntry(StringUtils.removeStart(pluginJarInfo.getIconPath(),"/")))); + pluginJarInfo.setIconImage(iconImage); + } + pluginJarInfo.setName(StringUtils.defaultString(pluginJarInfo.getName(), title)); + } catch (IOException | DocumentException e) { + throw new AppException(e); + } + } + private static String getTitleFromResourceBundle(File pluginFile, ClassLoader classLoader, Element pluginElement, String bundleName) { String titleResourceBundleKey = getChildNodeText(pluginElement, "title"); ClassLoader tmpClassLoader = classLoader == null ? PluginClassLoader.create(pluginFile) : classLoader; diff --git a/src/main/java/com/xwintop/xJavaFxTool/services/IndexService.java b/src/main/java/com/xwintop/xJavaFxTool/services/IndexService.java index 4f32e7a2..ac75cd7c 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/services/IndexService.java +++ b/src/main/java/com/xwintop/xJavaFxTool/services/IndexService.java @@ -5,7 +5,6 @@ import com.xwintop.xJavaFxTool.common.logback.ConsoleLogAppender; import com.xwintop.xJavaFxTool.controller.IndexController; import com.xwintop.xJavaFxTool.model.PluginJarInfo; -import com.xwintop.xJavaFxTool.plugin.PluginClassLoader; import com.xwintop.xJavaFxTool.plugin.PluginContainer; import com.xwintop.xJavaFxTool.utils.Config; import com.xwintop.xJavaFxTool.utils.XJavaFxSystemUtil; @@ -141,7 +140,7 @@ public void loadPlugin(PluginJarInfo pluginJarInfo) { */ public static Tab loadIsolatedPluginAsTab(PluginJarInfo plugin, TabPane tabPane, boolean singleWindowBoot) { try { - PluginContainer pluginContainer = new PluginContainer(PluginClassLoader.class.getClassLoader(), plugin); + PluginContainer pluginContainer = new PluginContainer(plugin); FXMLLoader generatingCodeFXMLLoader = pluginContainer.createFXMLLoader(); if (generatingCodeFXMLLoader == null) { return null; @@ -153,8 +152,15 @@ public static Tab loadIsolatedPluginAsTab(PluginJarInfo plugin, TabPane tabPane, } Tab tab = new Tab(plugin.getTitle()); - if (StringUtils.isNotEmpty(plugin.getIconPath())) { - ImageView imageView = new ImageView(new Image(plugin.getIconPath())); + if (plugin.getIconImage() == null) { + if (StringUtils.isNotEmpty(plugin.getIconPath())) { + ImageView imageView = new ImageView(new Image(plugin.getIconPath())); + imageView.setFitHeight(18); + imageView.setFitWidth(18); + tab.setGraphic(imageView); + } + } else { + ImageView imageView = new ImageView(plugin.getIconImage()); imageView.setFitHeight(18); imageView.setFitWidth(18); tab.setGraphic(imageView); @@ -203,8 +209,15 @@ public static Tab loadWebViewAsTab(PluginJarInfo plugin, TabPane tabPane, boolea return null; } Tab tab = new Tab(title); - if (StringUtils.isNotEmpty(plugin.getIconPath())) { - ImageView imageView = new ImageView(new Image(plugin.getIconPath())); + if (plugin.getIconImage() == null) { + if (StringUtils.isNotEmpty(plugin.getIconPath())) { + ImageView imageView = new ImageView(new Image(plugin.getIconPath())); + imageView.setFitHeight(18); + imageView.setFitWidth(18); + tab.setGraphic(imageView); + } + } else { + ImageView imageView = new ImageView(plugin.getIconImage()); imageView.setFitHeight(18); imageView.setFitWidth(18); tab.setGraphic(imageView); diff --git a/src/main/java/com/xwintop/xJavaFxTool/services/index/PluginManageService.java b/src/main/java/com/xwintop/xJavaFxTool/services/index/PluginManageService.java index 11e6250e..2f8b0448 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/services/index/PluginManageService.java +++ b/src/main/java/com/xwintop/xJavaFxTool/services/index/PluginManageService.java @@ -1,5 +1,9 @@ package com.xwintop.xJavaFxTool.services.index; +import cn.hutool.core.io.StreamProgress; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; import com.xwintop.xJavaFxTool.AppException; import com.xwintop.xJavaFxTool.controller.index.PluginManageController; import com.xwintop.xJavaFxTool.event.AppEvents; @@ -17,9 +21,14 @@ import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import java.io.File; import java.io.IOException; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiConsumer; import java.util.function.Consumer; /** @@ -31,17 +40,30 @@ @Setter @Slf4j public class PluginManageService { + public static final String SERVER_PLUGINS_URL = "https://xwintop.gitee.io/maven/plugin-libs/plugin-list.json"; + + /** + * 当下载插件时,模拟数种 UA + */ +// public static final String[] OPTIONAL_UA_LIST = { +// "Mozilla/5.0 (Windows NT 6.1; rv:51.0) Gecko/20100101 Firefox/51.0", +// "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.0 Safari/537.36", +// "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko" +// }; + private PluginManageController pluginManageController; private PluginManager pluginManager = PluginManager.getInstance(); + private Map pluginJarInfoMap = new ConcurrentHashMap<>(); + public PluginManageService(PluginManageController pluginManageController) { this.pluginManageController = pluginManageController; } public void getPluginList() { - pluginManager.loadServerPlugins(); pluginManager.getPluginList().forEach(this::addDataRow); + CompletableFuture.runAsync(this::loadServerPlugins); } public void addDataRow(PluginJarInfo plugin) { @@ -52,59 +74,49 @@ public void addDataRow(PluginJarInfo plugin) { dataRow.put("jarName", plugin.getJarName()); dataRow.put("downloadUrl", plugin.getDownloadUrl()); dataRow.put("versionNumber", String.valueOf(plugin.getVersionNumber())); - if (plugin.getIsDownload() == null || !plugin.getIsDownload()) { dataRow.put("isDownloadTableColumn", "下载"); dataRow.put("isEnableTableColumn", "false"); } else { - if (plugin.getLocalVersionNumber() != null && - plugin.getVersionNumber() > plugin.getLocalVersionNumber()) { + if (plugin.getLocalVersionNumber() != null && plugin.getVersionNumber() > plugin.getLocalVersionNumber()) { dataRow.put("isDownloadTableColumn", "更新"); } else { dataRow.put("isDownloadTableColumn", "已下载"); } dataRow.put("isEnableTableColumn", plugin.getIsEnable().toString()); } - pluginManageController.getOriginPluginData().add(dataRow); } public void downloadPluginJar(Map dataRow, Consumer afterDownload) { - String jarName = dataRow.get("jarName"); - PluginJarInfo pluginJarInfo = pluginManager.getPlugin(jarName); - + PluginJarInfo pluginJarInfo = pluginJarInfoMap.get(jarName); ProgressTask progressTask = new ProgressTask() { @Override protected void execute() throws Exception { - pluginManager.downloadPlugin( + PluginManageService.this.downloadPlugin( pluginJarInfo, (total, current) -> updateProgress(current, total) ); - if (afterDownload != null) { afterDownload.accept(pluginJarInfo); } } }; - - Window controllerWindow = pluginManageController.getWindow(); + Window controllerWindow = pluginManageController.getPluginDataTableView().getScene().getWindow(); FxProgressDialog dialog = FxProgressDialog.create(controllerWindow, progressTask, "正在下载插件 " + pluginJarInfo.getName() + "..."); - progressTask.setOnCancelled(event -> { throw new AppException("下载被取消。"); }); - progressTask.setOnFailed(event -> { Throwable e = event.getSource().getException(); if (e != null) { - log.error("", e); + log.error("下载插件失败", e); FxAlerts.error(controllerWindow, "下载插件失败", e); } else { FxAlerts.error(controllerWindow, "下载失败", event.getSource().getMessage()); } }); - - dialog.show(); + dialog.showAndWait(); } public void setIsEnableTableColumn(Integer index) { @@ -132,17 +144,25 @@ private boolean isPluginDataMatch(Map map, String keyword) { ); } - /** - * 判断插件是否启用 - */ - public static boolean isPluginEnabled(String fileName) { - String jarName = StringUtils.substringBeforeLast(fileName, "-"); - PluginJarInfo pluginJarInfo = PluginManager.getInstance().getPlugin(jarName); - if (pluginJarInfo == null) { - return false; + public void loadServerPlugins() { + try { + String json = HttpUtil.get(SERVER_PLUGINS_URL); + List pluginJarInfoList = JSON.parseArray(json, PluginJarInfo.class); + pluginManageController.getOriginPluginData().clear(); + pluginJarInfoList.forEach(plugin -> { + pluginJarInfoMap.put(plugin.getJarName(), plugin); + PluginJarInfo exists = pluginManager.getPlugin(plugin.getJarName()); + if (exists != null) { + plugin.setLocalVersionNumber(exists.getLocalVersionNumber()); + plugin.setIsEnable(exists.getIsEnable()); + plugin.setIsDownload(exists.getIsDownload()); + } + addDataRow(plugin); + }); + log.info("下载插件列表完成。"); + } catch (Exception e) { + log.error("下载插件列表失败", e); } - Boolean isEnable = pluginJarInfo.getIsEnable(); - return isEnable != null && isEnable; } //删除插件 @@ -154,8 +174,8 @@ public void deletePlugin() { Map dataRow = pluginManageController.getOriginPluginData().get(index); String jarName = dataRow.get("jarName"); PluginJarInfo pluginJarInfo = this.pluginManager.getPlugin(jarName); - if(BooleanUtils.isNotTrue(pluginJarInfo.getIsDownload())){ - FxAlerts.info("提示",pluginJarInfo.getName() + " 该插件未下载"); + if (pluginJarInfo == null || BooleanUtils.isNotTrue(pluginJarInfo.getIsDownload())) { + FxAlerts.info("提示", pluginJarInfo.getName() + " 该插件未下载"); return; } if (!FxAlerts.confirmYesNo("删除插件", String.format("确定要删除插件 %s 吗?", pluginJarInfo.getName()))) { @@ -166,8 +186,10 @@ public void deletePlugin() { FileUtils.delete(pluginJarInfo.getFile()); dataRow.put("isEnableTableColumn", "false"); dataRow.put("isDownloadTableColumn", "下载"); - pluginJarInfo.setIsEnable(false); - pluginJarInfo.setIsDownload(false); + PluginJarInfo pluginJarInfo1 = this.pluginJarInfoMap.get(jarName); + pluginJarInfo1.setIsEnable(false); + pluginJarInfo1.setIsDownload(false); + this.pluginManager.getPluginList().remove(pluginJarInfo); PluginManager.getInstance().saveToFile(); pluginManageController.getPluginDataTableView().refresh(); AppEvents.fire(new PluginEvent(PluginEvent.PLUGIN_DOWNLOADED, pluginJarInfo)); @@ -176,4 +198,142 @@ public void deletePlugin() { } } } + + public void downloadPlugin(PluginJarInfo pluginJarInfo, BiConsumer onProgressUpdate) throws IOException { + File file = pluginJarInfo.getFile(); + FileUtils.forceMkdirParent(file); + HttpResponse response = HttpUtil.createGet(pluginJarInfo.getDownloadUrl(), true).executeAsync(); + long contentLength = response.contentLength(); + response.writeBodyForFile(file, new StreamProgress() { + @Override + public void start() { + } + + @Override + public void progress(long progressSize) { + onProgressUpdate.accept(contentLength, progressSize); + } + + @Override + public void finish() { + } + }); + // 下载完毕 + pluginJarInfo.setIsDownload(true); + pluginJarInfo.setIsEnable(true); + pluginJarInfo.setLocalVersionNumber(pluginJarInfo.getVersionNumber()); + } + +// public File downloadPlugin(PluginJarInfo pluginJarInfo, BiConsumer onProgressUpdate) throws IOException { +// File file = pluginJarInfo.getFile(); +// FileUtils.forceMkdirParent(file); +// OkHttpClient pluginDownloader = new OkHttpClient.Builder().addInterceptor(new PluginManageService.DownloadProgressInterceptor(onProgressUpdate)).build(); +// // 使用多个 UA 尝试下载 +// Throwable downloadFailure = null; +// for (String ua : OPTIONAL_UA_LIST) { +// try { +// tryDownload(pluginJarInfo.getName(), pluginJarInfo.getDownloadUrl(), ua, file, pluginDownloader); +// downloadFailure = null; +// break; +// } catch (Exception e) { +// downloadFailure = e; +// } +// } +// if (downloadFailure != null) { +// if (downloadFailure instanceof IOException) { +// throw (IOException) downloadFailure; +// } else { +// throw new IOException("插件 '" + pluginJarInfo.getName() + "' 下载失败 " + pluginJarInfo.getJarName(), downloadFailure); +// } +// } +// // 下载完毕 +// pluginJarInfo.setIsDownload(true); +// pluginJarInfo.setIsEnable(true); +// pluginJarInfo.setLocalVersionNumber(pluginJarInfo.getVersionNumber()); +// return file; +// } +// +// /** +// * 尝试指定的 UA 进行下载,如果下载失败则抛出异常 +// * +// * @param pluginName 插件名称 +// * @param url 下载地址 +// * @param ua UA 字符串 +// * @param file 下载到的目标文件 +// * @throws IOException 如果下载失败 +// */ +// private void tryDownload(String pluginName, String url, String ua, File file, OkHttpClient pluginDownloader) throws IOException { +// Request request = new Request.Builder().header("User-Agent", ua).url(url).build(); +// try (Response response = pluginDownloader.newCall(request).execute()) { +// if (response.code() != HttpStatus.HTTP_OK) { +// throw new IOException("插件 '" + pluginName + "' 下载失败 : HTTP " + response.code()); +// } +// +// InputStream inputStream = Objects.requireNonNull(response.body()).byteStream(); +// try (FileOutputStream outputStream = new FileOutputStream(file)) { +// IOUtils.copy(inputStream, outputStream); +// } +// } +// } + +// private class DownloadProgressInterceptor implements Interceptor { +// private BiConsumer onProgressUpdate; +// +// DownloadProgressInterceptor(BiConsumer onProgressUpdate) { +// this.onProgressUpdate = onProgressUpdate; +// } +// +// @Override +// public Response intercept(Chain chain) throws IOException { +// Response originalResponse = chain.proceed(chain.request()); +// return originalResponse.newBuilder() +// .body(new PluginManageService.ProgressResponseBody(originalResponse.body(), onProgressUpdate)).build(); +// } +// } +// +// private static class ProgressResponseBody extends ResponseBody { +// private final ResponseBody responseBody; +// +// private BiConsumer onProgressUpdate; +// +// private BufferedSource bufferedSource; +// +// ProgressResponseBody(ResponseBody responseBody, BiConsumer onProgressUpdate) { +// this.responseBody = responseBody; +// this.onProgressUpdate = onProgressUpdate; +// } +// +// @Override +// public MediaType contentType() { +// return responseBody.contentType(); +// } +// +// @Override +// public long contentLength() { +// return responseBody.contentLength(); +// } +// +// @Override +// public BufferedSource source() { +// if (bufferedSource == null) { +// bufferedSource = Okio.buffer(source(responseBody.source())); +// } +// return bufferedSource; +// } +// +// private Source source(Source source) { +// return new ForwardingSource(source) { +// long totalBytesRead = 0L; +// +// @Override +// public long read(Buffer sink, long byteCount) throws IOException { +// long bytesRead = super.read(sink, byteCount); +// // read() returns the number of bytes read, or -1 if this source is exhausted. +// totalBytesRead += bytesRead != -1 ? bytesRead : 0; +// onProgressUpdate.accept(responseBody.contentLength(), totalBytesRead); +// return bytesRead; +// } +// }; +// } +// } } diff --git a/src/main/java/com/xwintop/xJavaFxTool/utils/Config.java b/src/main/java/com/xwintop/xJavaFxTool/utils/Config.java index f409e211..e015844b 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/utils/Config.java +++ b/src/main/java/com/xwintop/xJavaFxTool/utils/Config.java @@ -16,7 +16,7 @@ public class Config { public static Locale defaultLocale = Locale.getDefault();// 设置系统语言 - public static final String xJavaFxToolVersions = "V0.3.1";// xJavaFxTool版本信息 + public static final String xJavaFxToolVersions = "V0.3.2";// xJavaFxTool版本信息 /////////////////////////////////////////////////////////////// diff --git a/src/main/java/com/xwintop/xJavaFxTool/utils/ResourceUtils.java b/src/main/java/com/xwintop/xJavaFxTool/utils/ResourceUtils.java deleted file mode 100644 index 75dceb47..00000000 --- a/src/main/java/com/xwintop/xJavaFxTool/utils/ResourceUtils.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.xwintop.xJavaFxTool.utils; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import org.apache.commons.lang3.StringUtils; - -public class ResourceUtils { - - public static URL getResource(String... candidates) { - for (String candidate : candidates) { - if (StringUtils.isNotBlank(candidate)) { - URL url = ResourceUtils.class.getResource(candidate); - if (url != null) { - return url; - } - } - } - return null; - } - - public static String readResource(String resource, Charset charset) throws URISyntaxException, IOException { - Path path = Paths.get(ResourceUtils.class.getResource(resource).toURI()); - return new String(Files.readAllBytes(path), charset); - } -} diff --git a/src/main/java/com/xwintop/xJavaFxTool/utils/StageUtils.java b/src/main/java/com/xwintop/xJavaFxTool/utils/StageUtils.java index 3005d213..abf4c21c 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/utils/StageUtils.java +++ b/src/main/java/com/xwintop/xJavaFxTool/utils/StageUtils.java @@ -1,9 +1,13 @@ package com.xwintop.xJavaFxTool.utils; import com.xwintop.xJavaFxTool.utils.Config.Keys; +import javafx.geometry.Rectangle2D; +import javafx.stage.Screen; import javafx.stage.Stage; import lombok.extern.slf4j.Slf4j; +import java.util.List; + /** * @ClassName: StageUtils * @Description: 更新场景工具类(解决点击任务栏图标无法最小化问题) @@ -20,12 +24,21 @@ public static void loadPrimaryStageBound(Stage stage) { return; } - double left = Config.getDouble(Keys.MainWindowLeft, -1); + double left = Config.getDouble(Keys.MainWindowLeft, stage.getX()); double top = Config.getDouble(Keys.MainWindowTop, -1); double width = Config.getDouble(Keys.MainWindowWidth, -1); double height = Config.getDouble(Keys.MainWindowHeight, -1); - if (left > 0) { + List list = Screen.getScreens(); + double minX = 0; + for (Screen screen : list) { + Rectangle2D screenRectangle2 = screen.getBounds(); + if (screenRectangle2.getMinX() < minX) { + minX = screenRectangle2.getMinX(); + } + } + + if (left > minX) { stage.setX(left); } if (top > 0) { diff --git a/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java b/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java index 21c25606..3c85d92f 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java +++ b/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java @@ -16,13 +16,19 @@ @Slf4j public class VersionChecker { - public static void checkNewVersion() { + public static boolean checkNewVersion() { try { - String json = HttpUtil.get("https://gitee.com/api/v5/repos/xwintop/xJavaFxTool/releases/latest?access_token=d0486279db39a5996eca48c620abeee1"); + String json = HttpUtil.get("https://gitee.com/api/v5/repos/xwintop/xJavaFxTool/releases/latest"); log.info("检查新版本:" + json); JSONObject node = JSON.parseObject(json); final String latestVersion = node.getString("tag_name"); final String features = node.getString("body"); + + if (latestVersion == null) { + log.info("检查新版本失败"); + return false; + } + if (isLargerThanCurrent(latestVersion)) { final String content = new StringBuilder() .append("版本名:").append(node.getString("name")).append("\r\n") @@ -31,10 +37,13 @@ public static void checkNewVersion() { if (FxAlerts.confirmOkCancel("发现新版本 " + latestVersion, content)) { HttpClientUtil.openBrowseURLThrowsException("https://gitee.com/xwintop/xJavaFxTool/releases"); } + } else { + return false; } } catch (Exception e) { log.error("检查新版本失败!", e); } + return true; } private static Boolean isLargerThanCurrent(String remoteVersion) { diff --git a/src/main/java/com/xwintop/xJavaFxTool/utils/XJavaFxSystemUtil.java b/src/main/java/com/xwintop/xJavaFxTool/utils/XJavaFxSystemUtil.java index e3e83bd1..02f32af3 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/utils/XJavaFxSystemUtil.java +++ b/src/main/java/com/xwintop/xJavaFxTool/utils/XJavaFxSystemUtil.java @@ -1,16 +1,9 @@ package com.xwintop.xJavaFxTool.utils; import com.xwintop.xJavaFxTool.XJavaFxToolApplication; -import com.xwintop.xJavaFxTool.plugin.PluginManager; -import com.xwintop.xJavaFxTool.services.index.PluginManageService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import java.io.File; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; import java.util.Locale; import java.util.ResourceBundle; @@ -47,66 +40,66 @@ public static void initSystemLocal() { * @Title: addJarByLibs * @Description: 添加libs中jar包到系统中 */ - public static void addJarByLibs() { - try { - // 系统类库路径 - File libPath = new File("libs/"); - // 获取所有的.jar和.zip文件 - File[] jarFiles = libPath.listFiles( - (dir, name) -> name.endsWith(".jar") - ); - if (jarFiles != null) { - for (File file : jarFiles) { - if (!PluginManageService.isPluginEnabled(file.getName())) { - continue; - } - addJarClass(file); - } - } - PluginManager.getInstance().loadLocalPlugins(); - } catch (Exception e) { - log.error("添加libs中jar包到系统中异常:", e); - } - } +// public static void addJarByLibs() { +// try { +// // 系统类库路径 +// File libPath = new File("libs/"); +// // 获取所有的.jar和.zip文件 +// File[] jarFiles = libPath.listFiles( +// (dir, name) -> name.endsWith(".jar") +// ); +// if (jarFiles != null) { +// for (File file : jarFiles) { +// if (!PluginManageService.isPluginEnabled(file.getName())) { +// continue; +// } +// addJarClass(file); +// } +// } +// PluginManager.getInstance().loadLocalPlugins(); +// } catch (Exception e) { +// log.error("添加libs中jar包到系统中异常:", e); +// } +// } /** * @Title: addJarClass * @Description: 添加jar包到系统中 */ - public static void addJarClass(File jarFile) { - try { - ClassLoader classLoader = ClassLoader.getSystemClassLoader(); - URL url = jarFile.toURI().toURL(); - if (classLoader instanceof URLClassLoader) { - System.out.println("DEB: classLoader instanceof URLClassLoader"); - URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); - Class sysclass = URLClassLoader.class; - try { - Method method = sysclass.getDeclaredMethod("addURL", URL.class); - method.setAccessible(true); - method.invoke(sysloader, url); - } catch (Exception var5) { - var5.printStackTrace(); - throw new IllegalStateException(var5.getMessage(), var5); - } - } else { - try { - Field field = classLoader.getClass().getDeclaredField("ucp"); - field.setAccessible(true); - Object ucp = field.get(classLoader); - - System.out.println("DEB: invoke method!"); - Method method = ucp.getClass().getDeclaredMethod("addURL", URL.class); - method.setAccessible(true); - - method.invoke(ucp, url); - } catch (Exception exception) { - exception.printStackTrace(); - throw new IllegalStateException(exception.getMessage(), exception); - } - } - } catch (Exception e) { - log.error("添加libs中jar包到系统中异常:", e); - } - } +// public static void addJarClass(File jarFile) { +// try { +// ClassLoader classLoader = ClassLoader.getSystemClassLoader(); +// URL url = jarFile.toURI().toURL(); +// if (classLoader instanceof URLClassLoader) { +// System.out.println("DEB: classLoader instanceof URLClassLoader"); +// URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); +// Class sysclass = URLClassLoader.class; +// try { +// Method method = sysclass.getDeclaredMethod("addURL", URL.class); +// method.setAccessible(true); +// method.invoke(sysloader, url); +// } catch (Exception var5) { +// var5.printStackTrace(); +// throw new IllegalStateException(var5.getMessage(), var5); +// } +// } else { +// try { +// Field field = classLoader.getClass().getDeclaredField("ucp"); +// field.setAccessible(true); +// Object ucp = field.get(classLoader); +// +// System.out.println("DEB: invoke method!"); +// Method method = ucp.getClass().getDeclaredMethod("addURL", URL.class); +// method.setAccessible(true); +// +// method.invoke(ucp, url); +// } catch (Exception exception) { +// exception.printStackTrace(); +// throw new IllegalStateException(exception.getMessage(), exception); +// } +// } +// } catch (Exception e) { +// log.error("添加libs中jar包到系统中异常:", e); +// } +// } } diff --git a/src/main/java/com/xwintop/xJavaFxTool/view/index/PluginManageView.java b/src/main/java/com/xwintop/xJavaFxTool/view/index/PluginManageView.java index 0676fce2..e936eac7 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/view/index/PluginManageView.java +++ b/src/main/java/com/xwintop/xJavaFxTool/view/index/PluginManageView.java @@ -27,9 +27,6 @@ public abstract class PluginManageView implements Initializable { @FXML protected Button selectPluginButton; - @FXML - protected Button addLocalPluginButton; - @FXML protected TableView> pluginDataTableView; diff --git a/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/Index.fxml b/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/Index.fxml index 48c7d76c..cfad9491 100644 --- a/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/Index.fxml +++ b/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/Index.fxml @@ -46,6 +46,8 @@ text="%openConfigFolder"/> + + diff --git a/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/index/PluginManage.fxml b/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/index/PluginManage.fxml index cff46410..038d8960 100644 --- a/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/index/PluginManage.fxml +++ b/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/index/PluginManage.fxml @@ -1,6 +1,5 @@ - @@ -10,36 +9,34 @@ - - + + -