diff --git a/pom.xml b/pom.xml index 21c5020..c67b8b0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,14 +6,14 @@ org.jcnc JNotepad - 1.0-SNAPSHOT + 1.11.2-SNAPSHOT JNotepad UTF-8 5.9.2 - 17.0.1 + 20.0.2 diff --git a/src/main/java/org/jcnc/jnotepad/plugin/ButtonPlugin.java b/src/main/java/org/jcnc/jnotepad/plugin/ButtonPlugin.java new file mode 100644 index 0000000..be080c9 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/plugin/ButtonPlugin.java @@ -0,0 +1,25 @@ +package org.jcnc.jnotepad.plugin; + +/** + * 新按钮插件 + * + * @author luke + */ +public class ButtonPlugin implements Plugin { + + @Override + public String getCategoryName() { + return "新按钮插件"; + } + + @Override + public String getDisplayName() { + return "新按钮"; + } + + @Override + public void execute() { + // 在这里实现新按钮插件的逻辑 + System.out.println("新按钮插件执行了!"); + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/jnotepad/plugin/Plugin.java b/src/main/java/org/jcnc/jnotepad/plugin/Plugin.java new file mode 100644 index 0000000..f3ac557 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/plugin/Plugin.java @@ -0,0 +1,23 @@ +package org.jcnc.jnotepad.plugin; + +/** + * 插件接口 + *

+ * 描述插件的基本功能。 + * + * @author luke + */ +public interface Plugin extends PluginCategory { + + /** + * 获取插件的显示名称 + * + * @return 插件的显示名称 + */ + String getDisplayName(); + + /** + * 执行插件的逻辑 + */ + void execute(); +} diff --git a/src/main/java/org/jcnc/jnotepad/plugin/PluginCategory.java b/src/main/java/org/jcnc/jnotepad/plugin/PluginCategory.java new file mode 100644 index 0000000..c5c40f7 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/plugin/PluginCategory.java @@ -0,0 +1,18 @@ +package org.jcnc.jnotepad.plugin; + +/** + * 插件类别接口 + *

+ * 描述插件的类别信息。 + * + * @author luke + */ +public interface PluginCategory { + + /** + * 获取插件类别的名称 + * + * @return 插件类别的名称 + */ + String getCategoryName(); +} diff --git a/src/main/java/org/jcnc/jnotepad/plugin/PluginDemo.java b/src/main/java/org/jcnc/jnotepad/plugin/PluginDemo.java new file mode 100644 index 0000000..865887c --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/plugin/PluginDemo.java @@ -0,0 +1,102 @@ +package org.jcnc.jnotepad.plugin; + +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.layout.VBox; +import javafx.stage.FileChooser; +import javafx.stage.Stage; + +import java.io.File; +import java.util.List; +import java.util.Map; + +/** + * 插件演示类 + *

+ * 用于演示插件加载和执行的界面。 + * + * @author luke + */ +public class PluginDemo { + + /** + * 启动插件演示界面 + * + * @param primaryStage JavaFX的主舞台 + */ + public void start(Stage primaryStage) { + PluginManager pluginManager = new PluginManager(); + + FileChooser fileChooser = new FileChooser(); + fileChooser.getExtensionFilters().addAll( + new FileChooser.ExtensionFilter("JAR Files", "*.jar") + ); + + Button loadButton = createLoadButton(primaryStage, fileChooser, pluginManager); + + Button executeButton = new Button("执行插件"); + executeButton.setOnAction(event -> pluginManager.executePlugins()); + + VBox root = new VBox(10, loadButton, executeButton); + Scene scene = new Scene(root, 300, 200); + primaryStage.setScene(scene); + primaryStage.setTitle("插件演示"); + primaryStage.show(); + } + + /** + * 创建加载插件的按钮 + * + * @param primaryStage JavaFX的主舞台 + * @param fileChooser 文件选择器 + * @param pluginManager 插件管理器 + * @return 加载插件的按钮 + */ + private Button createLoadButton(Stage primaryStage, FileChooser fileChooser, PluginManager pluginManager) { + Button loadButton = new Button("加载插件"); + loadButton.setOnAction(event -> { + try { + File selectedFile = fileChooser.showOpenDialog(primaryStage); + if (selectedFile != null) { + String pluginFilePath = selectedFile.getAbsolutePath(); + pluginManager.loadPlugins(pluginFilePath); + + // 更新插件信息显示 + displayPluginInfo(primaryStage, pluginManager); + } + } catch (Exception ignored) { + } + }); + return loadButton; + } + + /** + * 显示已加载插件的信息 + * + * @param primaryStage JavaFX的主舞台 + * @param pluginManager 插件管理器 + */ + private void displayPluginInfo(Stage primaryStage, PluginManager pluginManager) { + Map> loadedPluginsByCategory = pluginManager.getLoadedPluginsByCategory(); + VBox infoBox = new VBox(); + + for (String category : loadedPluginsByCategory.keySet()) { + Label categoryLabel = new Label("类别: " + category); + VBox categoryInfoBox = new VBox(); + List pluginNames = loadedPluginsByCategory.get(category); + for (String pluginName : pluginNames) { + Label pluginLabel = new Label("插件名称: " + pluginName); + categoryInfoBox.getChildren().add(pluginLabel); + } + infoBox.getChildren().addAll(categoryLabel, categoryInfoBox); + } + + Scene infoScene = new Scene(infoBox, 400, 300); + Stage infoStage = new Stage(); + infoStage.setScene(infoScene); + infoStage.setTitle("已加载的插件"); + infoStage.initOwner(primaryStage); + infoStage.show(); + } +} diff --git a/src/main/java/org/jcnc/jnotepad/plugin/PluginManager.java b/src/main/java/org/jcnc/jnotepad/plugin/PluginManager.java new file mode 100644 index 0000000..57aa64a --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/plugin/PluginManager.java @@ -0,0 +1,73 @@ +package org.jcnc.jnotepad.plugin; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 插件管理器 + *

+ * 该类用于管理插件的加载和执行。 + * 插件可以通过加载外部JAR文件中的类来扩展应用程序的功能。 + * + * @author luke + */ +public class PluginManager { + private final List plugins; + private final Map> categories; + + /** + * 构造方法,初始化插件列表和类别映射 + */ + public PluginManager() { + plugins = new ArrayList<>(); + categories = new HashMap<>(); + } + + /** + * 加载插件 + * + * @param pluginFilePath 插件文件的路径 + * @throws Exception 如果加载插件时发生异常 + */ + public void loadPlugins(String pluginFilePath) throws Exception { + File file = new File(pluginFilePath); + + if (file.exists() && file.isFile()) { + // 创建URLClassLoader以加载Jar文件中的类 + URLClassLoader classLoader = new URLClassLoader(new URL[]{file.toURI().toURL()}); + Class pluginClass = classLoader.loadClass("org.jcnc.jnotepad.plugin.ButtonPlugin"); + Plugin plugin = (Plugin) pluginClass.getDeclaredConstructor().newInstance(); + plugins.add(plugin); + + // 添加插件到类别中 + String categoryName = plugin.getCategoryName(); + String displayName = plugin.getDisplayName(); + categories.computeIfAbsent(categoryName, k -> new ArrayList<>()).add(displayName); + } else { + System.err.println("Plugin file not found: " + pluginFilePath); + } + } + + /** + * 执行加载的插件 + */ + public void executePlugins() { + for (Plugin plugin : plugins) { + plugin.execute(); + } + } + + /** + * 获取按类别分类的已加载插件 + * + * @return 插件类别映射 + */ + public Map> getLoadedPluginsByCategory() { + return categories; + } +} diff --git a/src/main/java/org/jcnc/jnotepad/root/top/menu/TopMenuBar.java b/src/main/java/org/jcnc/jnotepad/root/top/menu/TopMenuBar.java index 8e4a218..3edcafa 100644 --- a/src/main/java/org/jcnc/jnotepad/root/top/menu/TopMenuBar.java +++ b/src/main/java/org/jcnc/jnotepad/root/top/menu/TopMenuBar.java @@ -10,6 +10,7 @@ import org.jcnc.jnotepad.controller.config.AppConfigController; import org.jcnc.jnotepad.controller.event.handler.menubar.*; import org.jcnc.jnotepad.controller.event.handler.tool.SetBtn; import org.jcnc.jnotepad.controller.i18n.LocalizationController; +import org.jcnc.jnotepad.plugin.PluginDemo; import org.jcnc.jnotepad.root.center.main.center.tab.CenterTab; import org.jcnc.jnotepad.root.center.main.center.tab.CenterTabPane; import org.jcnc.jnotepad.root.left.sidebar.tools.SidebarToolBar; @@ -264,6 +265,10 @@ public class TopMenuBar extends MenuBar { UiResourceBundle.bindStringProperty(pluginMenu.textProperty(), PLUGIN); addItem = new MenuItem(); + addItem.setOnAction(event -> { + PluginDemo pluginDemo = new PluginDemo(); + pluginDemo.start(new Stage()); + }); UiResourceBundle.bindStringProperty(addItem.textProperty(), ADD_PLUGIN); itemMap.put("addItem", addItem); diff --git a/tool/jpackage.txt b/tool/jpackage.txt index 85f61fc..84aa54c 100644 --- a/tool/jpackage.txt +++ b/tool/jpackage.txt @@ -4,7 +4,7 @@ jpackage ` -m org.jcnc.jnotepad/org.jcnc.jnotepad.LunchApp ` --runtime-image .\target\JNotepad\ ` --icon src/main/resources/img/icon.ico ` - --app-version 1.1.11 ` + --app-version 1.1.12 ` --vendor "JCNC"