diff --git a/src/main/java/org/jcnc/jnotepad/plgin/ButtonPlugin.java b/src/main/java/org/jcnc/jnotepad/plgin/ButtonPlugin.java new file mode 100644 index 0000000..143df5e --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/plgin/ButtonPlugin.java @@ -0,0 +1,22 @@ +package org.jcnc.jnotepad.plgin; + +/** + * @author luke + */ +public class ButtonPlugin implements Plugin { + @Override + public String getCategoryName() { + return "新按钮插件"; + } + + @Override + public String getDisplayName() { + return "新按钮"; + } + + @Override + public void execute() { + // 在这里实现新按钮插件的逻辑 + System.out.println("新按钮插件执行了!"); + } +} diff --git a/src/main/java/org/jcnc/jnotepad/plgin/Plugin.java b/src/main/java/org/jcnc/jnotepad/plgin/Plugin.java new file mode 100644 index 0000000..16be5f0 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/plgin/Plugin.java @@ -0,0 +1,9 @@ +package org.jcnc.jnotepad.plgin; + +/** + * @author luke + */ +public interface Plugin extends PluginCategory { + String getDisplayName(); + void execute(); +} diff --git a/src/main/java/org/jcnc/jnotepad/plgin/PluginCategory.java b/src/main/java/org/jcnc/jnotepad/plgin/PluginCategory.java new file mode 100644 index 0000000..8085df1 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/plgin/PluginCategory.java @@ -0,0 +1,8 @@ +package org.jcnc.jnotepad.plgin; + +/** + * @author luke + */ +public interface PluginCategory { + String getCategoryName(); +} diff --git a/src/main/java/org/jcnc/jnotepad/plgin/PluginDemo.java b/src/main/java/org/jcnc/jnotepad/plgin/PluginDemo.java new file mode 100644 index 0000000..9781aa1 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/plgin/PluginDemo.java @@ -0,0 +1,72 @@ +package org.jcnc.jnotepad.plgin; + +import javafx.application.Application; +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 { + + public void start(Stage primaryStage) { + PluginManager pluginManager = new PluginManager(); + + FileChooser fileChooser = new FileChooser(); + fileChooser.getExtensionFilters().addAll( + new FileChooser.ExtensionFilter("JAR Files", "*.jar") + ); + + Button loadButton = new Button("加载插件"); + loadButton.setOnAction(event -> { + File selectedFile = fileChooser.showOpenDialog(primaryStage); + if (selectedFile != null) { + String pluginFilePath = selectedFile.getAbsolutePath(); + pluginManager.loadPlugins(pluginFilePath); + + // 更新插件信息显示 + displayPluginInfo(primaryStage, 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(); + } + + 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/plgin/PluginManager.java b/src/main/java/org/jcnc/jnotepad/plgin/PluginManager.java new file mode 100644 index 0000000..8fe0fe1 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/plgin/PluginManager.java @@ -0,0 +1,55 @@ +package org.jcnc.jnotepad.plgin; + +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; + +/** + * @author luke + */ +public class PluginManager { + private final List plugins; + private final Map> categories; + + public PluginManager() { + plugins = new ArrayList<>(); + categories = new HashMap<>(); + } + + public void loadPlugins(String pluginFilePath) { + try { + 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.plgin.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); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void executePlugins() { + for (Plugin plugin : plugins) { + plugin.execute(); + } + } + + 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..8c76053 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.plgin.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"