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