From 0045143ca5d11eabcc2b7da0a0f796b7e4d2aaf7 Mon Sep 17 00:00:00 2001 From: xufeng <1277032935@qq.com> Date: Wed, 30 Mar 2022 10:38:42 +0800 Subject: [PATCH 01/14] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E4=B8=BA0.3.2=EF=BC=9B2.=E6=B7=BB=E5=8A=A0=E6=89=8B?= =?UTF-8?q?=E5=8A=A8=E6=A3=80=E6=9F=A5=E7=89=88=E6=9C=AC=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README_EN.md | 10 +- pom.xml | 2 +- .../controller/IndexController.java | 45 +++-- .../newui/NewLauncherController.java | 188 ------------------ .../com/xwintop/xJavaFxTool/utils/Config.java | 2 +- .../xJavaFxTool/utils/VersionChecker.java | 7 +- .../xwintop/xJavaFxTool/fxmlView/Index.fxml | 1 + .../xJavaFxTool/fxmlView/newui/main.fxml | 48 ----- src/main/resources/locale/Menu.properties | 1 + .../resources/locale/Menu_en_US.properties | 1 + 10 files changed, 42 insertions(+), 263 deletions(-) delete mode 100644 src/main/java/com/xwintop/xJavaFxTool/newui/NewLauncherController.java delete mode 100644 src/main/resources/com/xwintop/xJavaFxTool/fxmlView/newui/main.fxml diff --git a/README_EN.md b/README_EN.md index 09f81bcd..a186ede0 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.1.jar](https://github.com/864381832/xJavaFxTool/releases/download/0.3.1/xJavaFxTool-0.3.1.jar) +- Windows x64 installation package (compatible with xp, windows7, 8, 10, etc.)[xJavaFxTool-0.3.1-windows-x64.exe](https://github.com/864381832/xJavaFxTool/releases/download/0.3.1/xJavaFxTool-0.3.1-windows-x64.exe) +- Mac OS x64 [xJavaFxTool-0.3.1-macos.pkg](https://github.com/864381832/xJavaFxTool/releases/download/0.3.1/xJavaFxTool-0.3.1-macos.pkg) +- Linux x64 [xJavaFxTool-0.3.1-linux-x64.zip](https://github.com/864381832/xJavaFxTool/releases/download/0.3.1/xJavaFxTool-0.3.1-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..d430ee26 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.xwintop xJavaFxTool - 0.3.1 + 0.3.2 jar xJavaFxTool 基于JavaFx搭建的实用小工具集合 diff --git a/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java b/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java index 8fe8e0ac..8d7519c2 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.plugin.PluginParser; 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; @@ -164,24 +166,24 @@ public class IndexController extends IndexView { } 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 (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); } public void selectAction(String selectText) { @@ -239,6 +241,13 @@ public class IndexController extends IndexView { 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); 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/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/VersionChecker.java b/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java index 21c25606..b147e017 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java +++ b/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java @@ -16,9 +16,9 @@ import lombok.extern.slf4j.Slf4j; @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"); @@ -31,10 +31,13 @@ public class VersionChecker { 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/resources/com/xwintop/xJavaFxTool/fxmlView/Index.fxml b/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/Index.fxml index 48c7d76c..ed83982f 100644 --- a/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/Index.fxml +++ b/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/Index.fxml @@ -57,6 +57,7 @@ + diff --git a/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/newui/main.fxml b/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/newui/main.fxml deleted file mode 100644 index 810ce198..00000000 --- a/src/main/resources/com/xwintop/xJavaFxTool/fxmlView/newui/main.fxml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/locale/Menu.properties b/src/main/resources/locale/Menu.properties index 530c9865..e16e1bbf 100644 --- a/src/main/resources/locale/Menu.properties +++ b/src/main/resources/locale/Menu.properties @@ -21,6 +21,7 @@ openLogFolder = \u6253\u5F00\u65E5\u5FD7\u76EE\u5F55 openConfigFolder = \u6253\u5F00\u914D\u7F6E\u76EE\u5F55 openPluginFolder = \u6253\u5F00\u63D2\u4EF6\u76EE\u5F55 userSupport = \u7528\u6237\u8BBA\u575B +checkerVersion = \u68C0\u67E5\u7248\u672C aboutText = \u6B22\u8FCE\u4F7F\u7528JavaFx\u5DE5\u5177\u96C6\u5408\u3002\ngit\u5730\u5740\uFF1Ahttps://gitee.com/xwintop/xJavaFxTool\n\u4F5C\u8005\uFF1A\u8FFD\u98CE\n\u535A\u5BA2\uFF1Awww.xwintop.com\n\u6B22\u8FCE\u524D\u6765\u63D0\u51FA\u610F\u89C1\uFF0C\u4E00\u8D77\u5B8C\u5584\u8BE5\u5DE5\u5177\uFF0C\u8C22\u8C22\uFF01\uFF01\n\u5F53\u524D\u7248\u672C\uFF1A SetLanguageText = \u8BED\u8A00\u9009\u62E9\u8BBE\u7F6E\u6210\u529F\uFF0C\u91CD\u542F\u540E\u751F\u6548\u3002 diff --git a/src/main/resources/locale/Menu_en_US.properties b/src/main/resources/locale/Menu_en_US.properties index 241a2e8f..4f81b375 100644 --- a/src/main/resources/locale/Menu_en_US.properties +++ b/src/main/resources/locale/Menu_en_US.properties @@ -21,6 +21,7 @@ openLogFolder = open Log Folder openConfigFolder = open Config Folder openPluginFolder = open Plugin Folder userSupport = user Support +checkerVersion = CheckerVersion aboutText = Welcome to the JavaFx tool set.\ngitUrl:https://gitee.com/xwintop/xJavaFxTool\nAuthor:xwintop\nblog:www.xwintop.com\nWelcome to make comments and improve the tool together. Thank you!!\ncurrent version: SetLanguageText = The language selection settings have been successful and will take effect after reboot. -- Gitee From bf1e52f1ee0c5e0a7931ebfbf377a1950df3bc5c Mon Sep 17 00:00:00 2001 From: xufeng <1277032935@qq.com> Date: Wed, 30 Mar 2022 19:13:21 +0800 Subject: [PATCH 02/14] =?UTF-8?q?1.=E4=BC=98=E5=8C=96=E5=A4=9A=E5=B1=8F?= =?UTF-8?q?=E6=97=B6=E8=AE=B0=E5=BD=95=E7=AA=97=E5=8F=A3=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xwintop/xJavaFxTool/utils/StageUtils.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) 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 class StageUtils { 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) { -- Gitee From f2dbb37714cb9e3dc259d85d5a8acdd9ea66893f Mon Sep 17 00:00:00 2001 From: Yiding He Date: Thu, 31 Mar 2022 20:40:09 +0800 Subject: [PATCH 03/14] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E5=A4=B1=E8=B4=A5=E5=AF=BC=E8=87=B4=E7=A9=BA?= =?UTF-8?q?=E6=8C=87=E9=92=88=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/xwintop/xJavaFxTool/utils/VersionChecker.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java b/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java index 21c25606..fa60793a 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java +++ b/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java @@ -23,6 +23,12 @@ public class VersionChecker { JSONObject node = JSON.parseObject(json); final String latestVersion = node.getString("tag_name"); final String features = node.getString("body"); + + if (latestVersion == null) { + log.info("检查新版本失败"); + return; + } + if (isLargerThanCurrent(latestVersion)) { final String content = new StringBuilder() .append("版本名:").append(node.getString("name")).append("\r\n") -- Gitee From add8e98dc8c6ae6d5742b35822029cefce215954 Mon Sep 17 00:00:00 2001 From: xufeng <1277032935@qq.com> Date: Fri, 1 Apr 2022 12:32:11 +0800 Subject: [PATCH 04/14] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E5=9B=BE=E6=A0=87=E8=AF=BB=E5=8F=96=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/IndexController.java | 21 ++++++++++-------- .../xJavaFxTool/model/PluginJarInfo.java | 4 ++++ .../newui/PluginItemController.java | 17 +++++++++----- .../xJavaFxTool/plugin/PluginParser.java | 6 +++++ .../xJavaFxTool/services/IndexService.java | 22 +++++++++++++++---- 5 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java b/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java index 8d7519c2..238eede1 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java +++ b/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java @@ -76,16 +76,12 @@ public class IndexController extends IndexView { 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); @@ -173,8 +169,15 @@ public class IndexController extends IndexView { moreToolsMenu.getItems().add(menu); } MenuItem menuItem = new MenuItem(jarInfo.getTitle()); - if (StringUtils.isNotEmpty(jarInfo.getIconPath())) { - ImageView imageView = new ImageView(new Image(jarInfo.getIconPath())); + if (jarInfo.getIconImage() == null) { + if (StringUtils.isNotEmpty(jarInfo.getIconPath())) { + ImageView imageView = new ImageView(new Image(jarInfo.getIconPath())); + imageView.setFitHeight(18); + imageView.setFitWidth(18); + menuItem.setGraphic(imageView); + } + } else { + ImageView imageView = new ImageView(jarInfo.getIconImage()); imageView.setFitHeight(18); imageView.setFitWidth(18); menuItem.setGraphic(imageView); diff --git a/src/main/java/com/xwintop/xJavaFxTool/model/PluginJarInfo.java b/src/main/java/com/xwintop/xJavaFxTool/model/PluginJarInfo.java index d1500989..da7fab4f 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; @@ -83,4 +84,7 @@ public class PluginJarInfo { public String getDefaultIconPath() { return bundleName == null ? "" : (bundleName.replace("locale.", "/logo/") + ".png"); } + + @JSONField(serialize = false) + private Image iconImage; } diff --git a/src/main/java/com/xwintop/xJavaFxTool/newui/PluginItemController.java b/src/main/java/com/xwintop/xJavaFxTool/newui/PluginItemController.java index 55424360..09dea1ae 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/newui/PluginItemController.java +++ b/src/main/java/com/xwintop/xJavaFxTool/newui/PluginItemController.java @@ -23,6 +23,7 @@ import java.net.URL; @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 +74,17 @@ public class PluginItemController { } 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()); + if (this.pluginJarInfo.getIconImage() != null) { + imgLogo.setImage(this.pluginJarInfo.getIconImage()); + } else { + 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)); } - imgLogo.setImage(new Image(url)); } } diff --git a/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginParser.java b/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginParser.java index da61bbd4..0af7f806 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 @@ package com.xwintop.xJavaFxTool.plugin; 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 class PluginParser { 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); diff --git a/src/main/java/com/xwintop/xJavaFxTool/services/IndexService.java b/src/main/java/com/xwintop/xJavaFxTool/services/IndexService.java index 4f32e7a2..8a749909 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/services/IndexService.java +++ b/src/main/java/com/xwintop/xJavaFxTool/services/IndexService.java @@ -153,8 +153,15 @@ public class IndexService { } 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 +210,15 @@ public class IndexService { 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); -- Gitee From 4c88bb533f0cd3f791f9c295672e2b61e8b56b99 Mon Sep 17 00:00:00 2001 From: xufeng <1277032935@qq.com> Date: Fri, 1 Apr 2022 14:34:24 +0800 Subject: [PATCH 05/14] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xJavaFxTool/utils/VersionChecker.java | 2 +- src/main/resources/logo/ScanPortTool.png | Bin 2516 -> 0 bytes 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 src/main/resources/logo/ScanPortTool.png diff --git a/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java b/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java index dc73fa09..3c85d92f 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java +++ b/src/main/java/com/xwintop/xJavaFxTool/utils/VersionChecker.java @@ -26,7 +26,7 @@ public class VersionChecker { if (latestVersion == null) { log.info("检查新版本失败"); - return; + return false; } if (isLargerThanCurrent(latestVersion)) { diff --git a/src/main/resources/logo/ScanPortTool.png b/src/main/resources/logo/ScanPortTool.png deleted file mode 100644 index 141c3dbc93dcb2060b502033d678f80d40e79d86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2516 zcmV;_2`l!AP)44(+&h<<3xbv8ELve^KA-dZ+%uZiDeah5-*@3ny z`mc1^cu%M{^1E?4ehAh2(q-*$xpo_}R_cM(^Jh|7EA_aMLDOaJ?g(l&Rm! zz^)VqU^(xF#j`1hW@eRS@oWl~^Iljf3^XA{zfG5ocfXy8bXg0Fz}HGWkSGkoQf{IS zD3K4rrs;>hsu#Xrjl!Wd1ShuxoE%z1@cn8O_NrdkH2sjshw8sy%1uC`Feo8IzfG65 z@S_7KRO_z=EFSoB{!f@coq=d(7E;9ke7$@H$2T4uSXDW`@xa&1SCA?OAexzl`O_I# z&i^SR;tQc#|6_rl7PZcR$FdRleBpBi{q1U0DsE(azVJaT8>tf^S_7flbXURGB75Ve ztLM*PAscc8{^R;NY*)sB6ax^;MqK?rmW==@24Jh~gCEz=9f?@ThG6yl8An9AY`pIZ z_*B{WN7Q;WGYg~`u=(_n<$>+W7{qg7<-pfW;<+$vm3?qz@#G#_LqP6b!)6U- zUccZTWVN~T z3qj5r4y_?bhdJLq3jwf_d^`DkXA3p%Q1uUZtT z6hE?b>I6QPjlhQKhiGP&s}l&--nfD9!=}HG4FM?zxPYeuew|KAf$v|wgmpRz$wH8; z_2aoPBnv^tw4Kg zBY;hEWZHMSnP~Ris14kry-cvHY?yx03aF_45ynoUFbL7itg`m;!yQ?kjx<0I1ut5` zp*2*qq{1M!f)PYOqvT!6O>mLl$@j6FoZJp{)a>2B$FdRlel_Z-oLyv@q!@su+=RSD zX4BiXQV&Ekd=PQcD0Y*rvhPvBvzX(gpm;9KrQm307Q4YO6#Z+gtP}ZN{(&{z68Km)0(&lV z2keSY1Td>+nE-+yg!W3=a=URW zX^{2i&Aux(S8kmpPJ>R05UrZf-bNaH>_SMK?=d0800-Vp`_T*^D^#AfNg>3S!m6yc zS_+FNy=);uwlLx5`ywzWcg3afhUu4;!hAEN8d%zChQu>HnW$(!nrW{YO5{VbX2{+S zvq0$7WW;k}+uTj%!Q;6wY*)rOi(oqhs?#KKUg`8ZR!=!9SwbsNNpDY)rKOg0o%HE-;Tt++xvf~Qb!u}5^1 zXvSeEdhZ4%bAwjL;y88wynfN~$uI-o$^k77((G_VYW_|KBdr8E@tnTX2P0VXPH9i3 zeWimDLbX0Z^}A+PpmH=O=6bfx)h=*$!YtMZZr8-VFVX&8(*si3;V7QhsT_{(3WuY| zHy-#@YW;BZQ^|h9tg@GY%k%?lSfc$Vhohnu$d1QVgWNiuw4LRh+}0+(pGuSPQ8*q? zHm0+N!L0#>i>|3Ha!Pz&A)}OpOTbt-t;v_V?}N{8oT(ntoetz@q))*^~fY zPjv)*gM@}9)S9Noy1aO}d3@u6oyvH}*5!99<2K+2)^L5amMHM+@*UH>goF?HM#*C1 zg^6Z4|L64!*r|*wuffK$5l9sSwjBalZLp9Hae2NYKJQL~HjPsxvj+Ccj7sstW`Uxp z7De-?GZL-qcU^yF29eN@izOBt7!k}h_Ag&PxDwpId|5Yj1|0i3D{>y~r73}kH=;EV z+6yb^gAmV8)Xh4P55b1%hux~T=|TisnApAF2IW?1^AoUgJ}3izr(E84k%T@%jX9AB zM#k#-AMo#gURcVhzc{&+n}UD;^TO)+A2!ep;Ktl Date: Fri, 1 Apr 2022 21:11:52 +0800 Subject: [PATCH 06/14] =?UTF-8?q?1.=E6=B7=BB=E5=8A=A0license=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 8 ++++---- .../xwintop/xJavaFxTool/XJavaFxToolApplication.java | 12 +++++++++++- .../com/xwintop/xJavaFxTool/XJavaFxToolMain.java | 9 +++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) 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/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 class XJavaFxToolApplication extends Application { 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; -- Gitee From 1858d5f06da0c81107d4559060ebaa5b0b3061ee Mon Sep 17 00:00:00 2001 From: xufeng <1277032935@qq.com> Date: Sat, 2 Apr 2022 16:37:05 +0800 Subject: [PATCH 07/14] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9=E7=B1=BB=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E5=99=A8bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 10 +++--- .../xJavaFxTool/plugin/PluginClassLoader.java | 32 +++++++++---------- .../xJavaFxTool/services/IndexService.java | 3 +- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/pom.xml b/pom.xml index d430ee26..b8fdcf6a 100755 --- a/pom.xml +++ b/pom.xml @@ -54,11 +54,11 @@ - - io.github.classgraph - classgraph - 4.8.100 - + + + + + 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 class PluginClassLoader extends URLClassLoader { } 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/services/IndexService.java b/src/main/java/com/xwintop/xJavaFxTool/services/IndexService.java index 8a749909..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.XJavaFxToolApplication; 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 class IndexService { */ 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; -- Gitee From 09d488e17a5bba60762aa6c405ad6aca2bb9cdc8 Mon Sep 17 00:00:00 2001 From: xufeng <1277032935@qq.com> Date: Sat, 2 Apr 2022 23:14:35 +0800 Subject: [PATCH 08/14] =?UTF-8?q?1.=E7=A7=BB=E9=99=A4=E6=8F=92=E4=BB=B6log?= =?UTF-8?q?o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 -- src/main/resources/logo/RegexTester.png | Bin 1207 -> 0 bytes 2 files changed, 2 deletions(-) delete mode 100644 src/main/resources/logo/RegexTester.png diff --git a/pom.xml b/pom.xml index b8fdcf6a..15e48a9f 100755 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,6 @@ true 17 17 - 17.0.2 @@ -48,7 +47,6 @@ org.projectlombok lombok 1.18.22 - true provided diff --git a/src/main/resources/logo/RegexTester.png b/src/main/resources/logo/RegexTester.png deleted file mode 100644 index eb90d6e21acb4549f0b85cdc3796c4ee2be0ebd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1207 zcmV;o1W5adP)u z0<$X92nv@pWKGkpFZhbWuCY;Phko}pFGcVFCddiks?Kk zl(#%IO&?p`ppTa;Y0Iy#(-q5+7`+mSp=?=;-lu8$7^i^cNQ_#E#IW*o2~pDri0Uj@ zdAfwv)kVY~v>^VV1*@xzc)qrTk%!kY^6)yIuPqh7RMrw=ZJYv_4c5GV#MD~E)LN{0 z{fLHVfgk|{2}HxQ2rbUT5z@gC(jl}sU;IK@6CFz{U?md6`rt6u2Z!0uFCRPb^09;c z?0w>d_lZ*kWpWt-(aDSg${Icay0%VSCOgU=d+(iyBtQ}%2}q5W?AR^#$sGk+eftlB z1sF*yyksN(B>fYhLm)E7p8i@b=qp-%K{8dQZ5&`0WvUQP&Jvav7%$`MIGwgRly z+i17;<(+HhFT^k4qxYQ{y|qy=iXlM~kjoS(1SK&A$`MIGHUchu{u$o!IZ;jhc;vk6 z9YVADM%pru?rGT9bzJmx8{bR-@%`e4e0EByb7Pw%O2RpF~41l^2@q zlW4YlS?u!M61W63eKHQsKs2v3+NZ=&K2-vjfJ>bN(DX0oRludr0r3b35HCQfD@3~n z2$2w7YsV%vQZJHN}ZJ6(t3Xe;u^@EWOq_)cW=qm`2QOji%5S5s~H{%0o7du)yEk)1q^?q zE9e~LlF-v_%(&mHnKMbn`|T}B$M6rG!?s7xZj*631PPRs0JfY*j`nu$k>npb#|qe; zuFg$BF{VH!0eik$w%FfeinQwoBWh=&GIs$-O*R64`L-eLvFPz?cH6QP5E>=Y9*bQN zJ@VWH+|-)bzsm^arj~nX=Su(r%ESWbs^UFPzr7`~227pKO~B8M`m6=GG_8dd5G1fW zofz7Szt*H2Yj zAfV(HAoNbKm@sd0_=fHNLS52yVDZTL?*J2IejFBa`NIq2p05^rzFO@26~gv8EJ17n zJl{2EQzSRU{y5D0B$)5=Vh(~T$6H&TNs5F3@j{pw)ich0OQ}2)w#b13udm_!0x05y zOeT|oQZ|)zc_s*`dJh&5DnKTCEuoalb0r%AWf@TF3Q)ueemH&sk|ITl6e&_t@;`yA VLbG54ulN7}002ovPDHLkV1mwOJTCwM -- Gitee From 44fc4164a714a131efe5ea85a748533cae2549d1 Mon Sep 17 00:00:00 2001 From: xufeng <1277032935@qq.com> Date: Tue, 5 Apr 2022 13:44:58 +0800 Subject: [PATCH 09/14] =?UTF-8?q?1.=E6=B7=BB=E5=8A=A0=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E6=97=B6=E5=88=A0=E9=99=A4=E8=80=81=E7=89=88?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E5=8C=85=E6=96=B9=E6=B3=95;2.=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=8F=92=E4=BB=B6=E4=BF=A1=E6=81=AF=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/IndexController.java | 11 +- .../index/PluginManageController.java | 29 ++- .../xJavaFxTool/plugin/PluginManager.java | 212 +----------------- .../services/index/PluginManageService.java | 185 +++++++++++++-- .../fxmlView/index/PluginManage.fxml | 38 ++-- src/main/resources/logo/ImageTool.png | Bin 1467 -> 0 bytes src/main/resources/logo/ZookeeperTool.png | Bin 14808 -> 0 bytes 7 files changed, 208 insertions(+), 267 deletions(-) delete mode 100644 src/main/resources/logo/ImageTool.png delete mode 100644 src/main/resources/logo/ZookeeperTool.png diff --git a/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java b/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java index 238eede1..9432362c 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java +++ b/src/main/java/com/xwintop/xJavaFxTool/controller/IndexController.java @@ -169,15 +169,8 @@ public class IndexController extends IndexView { moreToolsMenu.getItems().add(menu); } MenuItem menuItem = new MenuItem(jarInfo.getTitle()); - if (jarInfo.getIconImage() == null) { - if (StringUtils.isNotEmpty(jarInfo.getIconPath())) { - ImageView imageView = new ImageView(new Image(jarInfo.getIconPath())); - imageView.setFitHeight(18); - imageView.setFitWidth(18); - menuItem.setGraphic(imageView); - } - } else { - ImageView imageView = new ImageView(jarInfo.getIconImage()); + 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); 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..b356e578 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/controller/index/PluginManageController.java +++ b/src/main/java/com/xwintop/xJavaFxTool/controller/index/PluginManageController.java @@ -21,11 +21,11 @@ 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; @@ -63,10 +63,6 @@ public class PluginManageController extends PluginManageView { initService(); } - public Window getWindow() { - return this.pluginDataTableView.getScene().getWindow(); - } - private void initView() { addLocalPluginButton.setVisible(Boolean.parseBoolean(System.getProperty("localPluginEnabled", "false"))); @@ -95,7 +91,7 @@ public class PluginManageController extends PluginManageView { downloadButton.setDisable(true); } this.setContentDisplay(ContentDisplay.CENTER); - downloadButton.setOnMouseClicked(event -> downloadPlugin(dataRow, downloadButton)); + downloadButton.setOnMouseClicked(event -> downloadPlugin(dataRow)); this.setGraphic(downloadButton); } } @@ -106,10 +102,10 @@ public class PluginManageController extends PluginManageView { 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 +113,26 @@ public class PluginManageController extends PluginManageView { } } - private void afterDownload(Map dataRow, Button downloadButton, PluginJarInfo pluginJarInfo) { + private void afterDownload(Map dataRow, PluginJarInfo pluginJarInfo) { // 没有下载成功不做处理 if (pluginJarInfo.getIsDownload() == null || !pluginJarInfo.getIsDownload()) { return; } - try { + PluginJarInfo pluginJarInfoOld = PluginManager.getInstance().getPlugin(pluginJarInfo.getJarName()); + if (pluginJarInfoOld != null) { + FileUtils.delete(pluginJarInfoOld.getFile()); + } + PluginManager.getInstance().getPluginList().remove(pluginJarInfoOld); + PluginManager.getInstance().getPluginList().add(pluginJarInfo); PluginManager.getInstance().saveToFile(); TooltipUtil.showToast("插件 " + dataRow.get("nameTableColumn") + " 下载完成"); - PluginClassLoader tempClassLoader = PluginClassLoader.create(pluginJarInfo.getFile()); PluginParser.parse(pluginJarInfo.getFile(), pluginJarInfo, tempClassLoader); 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 +144,7 @@ public class PluginManageController extends PluginManageView { private void initEvent() { // 右键菜单 ContextMenu contextMenu = new ContextMenu(); - JavaFxViewUtil.addMenuItem(contextMenu,"保存配置", actionEvent -> { + JavaFxViewUtil.addMenuItem(contextMenu, "保存配置", actionEvent -> { try { PluginManager.getInstance().saveToFile(); TooltipUtil.showToast("保存配置成功"); @@ -155,7 +152,7 @@ public class PluginManageController extends PluginManageView { log.error("保存插件配置失败", ex); } }); - JavaFxViewUtil.addMenuItem(contextMenu,"删除插件", actionEvent -> { + JavaFxViewUtil.addMenuItem(contextMenu, "删除插件", actionEvent -> { pluginManageService.deletePlugin(); }); pluginDataTableView.setContextMenu(contextMenu); diff --git a/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginManager.java b/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginManager.java index a63a3bd8..27dffe21 100644 --- a/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginManager.java +++ b/src/main/java/com/xwintop/xJavaFxTool/plugin/PluginManager.java @@ -1,52 +1,25 @@ 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.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 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,9 +29,6 @@ public class PluginManager { return instance; } - ////////////////////////////////////////////////////////////// - private final OkHttpClient pluginDownloader = new OkHttpClient.Builder().addInterceptor(new DownloadProgressInterceptor()).build(); - private final List pluginList = new ArrayList<>(); // 插件列表 public PluginManager() { @@ -68,11 +38,11 @@ public class PluginManager { ////////////////////////////////////////////////////////////// 查询插件 public List getPluginList() { - return Collections.unmodifiableList(this.pluginList); + return 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 +51,6 @@ public class PluginManager { .findFirst().orElse(null); } - public PluginJarInfo getPluginByFxmlPath(String fxmlPath) { - return this.pluginList.stream() - .filter(plugin -> Objects.equals(plugin.getFxmlPath(), fxmlPath)) - .findFirst().orElse(null); - } - ////////////////////////////////////////////////////////////// 插件列表 /** @@ -116,6 +80,7 @@ public class PluginManager { * 解析本地插件文件 */ public void loadLocalPlugins() { + List removeList = new ArrayList(); this.pluginList.forEach(plugin -> { File pluginFile = plugin.getFile(); if (pluginFile.exists()) { @@ -124,8 +89,11 @@ public class PluginManager { } catch (Exception e) { log.error("解析失败", e); } + } else { + removeList.add(plugin); } }); + this.pluginList.removeAll(removeList); } /** @@ -157,29 +125,6 @@ public class PluginManager { 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); - } - /** * 向插件列表添加插件信息或更改插件列表中已有的插件信息 * @@ -187,7 +132,7 @@ public class PluginManager { * @param ifExists 如果插件已存在,则不会将 pluginJarInfo 加入, * 而是提供已有的插件信息对象供调用者更新其属性 */ - private void addOrUpdatePlugin(PluginJarInfo pluginJarInfo, Consumer ifExists) { + public void addOrUpdatePlugin(PluginJarInfo pluginJarInfo, Consumer ifExists) { PluginJarInfo exists = getPlugin(pluginJarInfo.getJarName()); if (exists == null) { this.pluginList.add(pluginJarInfo); @@ -196,78 +141,6 @@ public class PluginManager { } } - ////////////////////////////////////////////////////////////// 下载插件 - - 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 void saveToFile() throws IOException { String json = JSON.toJSONString(this.pluginList, true); @@ -286,75 +159,4 @@ public class PluginManager { 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/services/index/PluginManageService.java b/src/main/java/com/xwintop/xJavaFxTool/services/index/PluginManageService.java index 11e6250e..757d8837 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,8 @@ package com.xwintop.xJavaFxTool.services.index; +import cn.hutool.http.HttpStatus; +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; @@ -13,13 +16,24 @@ import javafx.stage.Window; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import okhttp3.*; +import okio.*; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiConsumer; import java.util.function.Consumer; /** @@ -31,17 +45,30 @@ import java.util.function.Consumer; @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,48 +79,39 @@ public class PluginManageService { 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) { @@ -103,7 +121,6 @@ public class PluginManageService { FxAlerts.error(controllerWindow, "下载失败", event.getSource().getMessage()); } }); - dialog.show(); } @@ -145,6 +162,27 @@ public class PluginManageService { return isEnable != null && isEnable; } + 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); + } + } + //删除插件 public void deletePlugin() { Integer index = pluginManageController.getPluginDataTableView().getSelectionModel().getSelectedIndex(); @@ -154,8 +192,8 @@ public class PluginManageService { 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 (BooleanUtils.isNotTrue(pluginJarInfo.getIsDownload())) { + FxAlerts.info("提示", pluginJarInfo.getName() + " 该插件未下载"); return; } if (!FxAlerts.confirmYesNo("删除插件", String.format("确定要删除插件 %s 吗?", pluginJarInfo.getName()))) { @@ -176,4 +214,117 @@ public class PluginManageService { } } } + + 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(totalBytesRead, responseBody.contentLength()); + return bytesRead; + } + }; + } + } } 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..635dcdad 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,35 @@ - - + + -