From dd096bf448c4b2fdb9e968be7d37adf3f0421d26 Mon Sep 17 00:00:00 2001 From: gewuyou <1063891901@qq.com> Date: Thu, 7 Sep 2023 12:53:33 +0800 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20=E9=87=8D=E6=9E=84=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=AA=97=E5=8F=A3=EF=BC=8C=E4=BD=BF=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=AC=A6=E5=90=88=E9=A1=B9=E7=9B=AE=E9=A3=8E=E6=A0=BC?= =?UTF-8?q?=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/org/jcnc/jnotepad/LunchApp.java | 2 - .../event/handler/menubar/OpenFile.java | 4 +- .../event/handler/menubar/RenameFile.java | 4 +- .../event/handler/menubar/SaveFile.java | 4 +- .../jcnc/jnotepad/plugin/ButtonPlugin.java | 4 +- .../org/jcnc/jnotepad/plugin/PluginDemo.java | 20 +++-- .../jcnc/jnotepad/plugin/PluginManager.java | 36 +++++++-- .../ui/dialog/factory/FileChooserFactory.java | 4 +- .../factory/impl/BasicFileChooserFactory.java | 80 +++++++++++++++++++ .../factory/impl/TextFileChooserFactory.java | 63 --------------- .../jnotepad/ui/module/SettingsComponent.java | 2 +- .../ui/setstage/DeveloperDebugStage.java | 1 - 12 files changed, 134 insertions(+), 90 deletions(-) create mode 100644 src/main/java/org/jcnc/jnotepad/ui/dialog/factory/impl/BasicFileChooserFactory.java delete mode 100644 src/main/java/org/jcnc/jnotepad/ui/dialog/factory/impl/TextFileChooserFactory.java diff --git a/src/main/java/org/jcnc/jnotepad/LunchApp.java b/src/main/java/org/jcnc/jnotepad/LunchApp.java index 78cb750..aaba292 100644 --- a/src/main/java/org/jcnc/jnotepad/LunchApp.java +++ b/src/main/java/org/jcnc/jnotepad/LunchApp.java @@ -11,7 +11,6 @@ import org.jcnc.jnotepad.constants.AppConstants; import org.jcnc.jnotepad.constants.TextConstants; import org.jcnc.jnotepad.controller.i18n.LocalizationController; import org.jcnc.jnotepad.manager.ThreadPoolManager; -import org.jcnc.jnotepad.tool.PopUpUtil; import org.jcnc.jnotepad.tool.SingletonUtil; import org.jcnc.jnotepad.tool.UiUtil; import org.jcnc.jnotepad.view.manager.ViewManager; @@ -73,7 +72,6 @@ public class LunchApp extends Application { primaryStage.setWidth(SCENE.getWidth()); primaryStage.setHeight(SCENE.getHeight()); primaryStage.getIcons().add(UiUtil.getAppIcon()); - // PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!", null, null); primaryStage.show(); } diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/OpenFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/OpenFile.java index 4a60a91..cb6038f 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/OpenFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/OpenFile.java @@ -14,7 +14,7 @@ import org.jcnc.jnotepad.root.center.main.center.tab.CenterTabPane; import org.jcnc.jnotepad.tool.EncodingDetector; import org.jcnc.jnotepad.tool.LogUtil; import org.jcnc.jnotepad.tool.UiUtil; -import org.jcnc.jnotepad.ui.dialog.factory.impl.TextFileChooserFactory; +import org.jcnc.jnotepad.ui.dialog.factory.impl.BasicFileChooserFactory; import org.jcnc.jnotepad.ui.module.LineNumberTextArea; import java.io.BufferedReader; @@ -41,7 +41,7 @@ public class OpenFile implements EventHandler { @Override public void handle(ActionEvent event) { // 显示文件选择对话框,并获取选中的文件 - File file = TextFileChooserFactory.getInstance().createFileChooser( + File file = BasicFileChooserFactory.getInstance().createFileChooser( UiResourceBundle.getContent(TextConstants.OPEN), null, null, diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/RenameFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/RenameFile.java index d749f93..74dbd91 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/RenameFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/RenameFile.java @@ -11,7 +11,7 @@ import org.jcnc.jnotepad.root.center.main.center.tab.CenterTab; import org.jcnc.jnotepad.root.center.main.center.tab.CenterTabPane; import org.jcnc.jnotepad.tool.LogUtil; import org.jcnc.jnotepad.tool.UiUtil; -import org.jcnc.jnotepad.ui.dialog.factory.impl.TextFileChooserFactory; +import org.jcnc.jnotepad.ui.dialog.factory.impl.BasicFileChooserFactory; import org.slf4j.Logger; import java.io.File; @@ -92,7 +92,7 @@ public class RenameFile implements EventHandler { // 获取原始文件对象 File file = (File) centerTab.getUserData(); // 获取应用窗口并绑定 - File newFile = TextFileChooserFactory.getInstance() + File newFile = BasicFileChooserFactory.getInstance() .createFileChooser( UiResourceBundle.getContent(TextConstants.RENAME), centerTab.getText(), diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/SaveFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/SaveFile.java index 9220de5..1d45ca2 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/SaveFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/SaveFile.java @@ -12,7 +12,7 @@ import org.jcnc.jnotepad.root.top.menu.TopMenuBar; import org.jcnc.jnotepad.tool.LogUtil; import org.jcnc.jnotepad.tool.SingletonUtil; import org.jcnc.jnotepad.tool.UiUtil; -import org.jcnc.jnotepad.ui.dialog.factory.impl.TextFileChooserFactory; +import org.jcnc.jnotepad.ui.dialog.factory.impl.BasicFileChooserFactory; import org.slf4j.Logger; import java.io.File; @@ -76,7 +76,7 @@ public class SaveFile implements EventHandler { if (selectedTab == null) { return; } - File file = TextFileChooserFactory.getInstance().createFileChooser( + File file = BasicFileChooserFactory.getInstance().createFileChooser( UiResourceBundle.getContent(TextConstants.SAVE_AS), selectedTab.getText(), null, diff --git a/src/main/java/org/jcnc/jnotepad/plugin/ButtonPlugin.java b/src/main/java/org/jcnc/jnotepad/plugin/ButtonPlugin.java index be080c9..4a0da50 100644 --- a/src/main/java/org/jcnc/jnotepad/plugin/ButtonPlugin.java +++ b/src/main/java/org/jcnc/jnotepad/plugin/ButtonPlugin.java @@ -1,5 +1,7 @@ package org.jcnc.jnotepad.plugin; +import org.jcnc.jnotepad.tool.LogUtil; + /** * 新按钮插件 * @@ -20,6 +22,6 @@ public class ButtonPlugin implements Plugin { @Override public void execute() { // 在这里实现新按钮插件的逻辑 - System.out.println("新按钮插件执行了!"); + LogUtil.getLogger(this.getClass()).info("新按钮插件执行了!"); } } \ No newline at end of file diff --git a/src/main/java/org/jcnc/jnotepad/plugin/PluginDemo.java b/src/main/java/org/jcnc/jnotepad/plugin/PluginDemo.java index 865887c..4a364d9 100644 --- a/src/main/java/org/jcnc/jnotepad/plugin/PluginDemo.java +++ b/src/main/java/org/jcnc/jnotepad/plugin/PluginDemo.java @@ -6,6 +6,9 @@ import javafx.scene.control.Label; import javafx.scene.layout.VBox; import javafx.stage.FileChooser; import javafx.stage.Stage; +import org.jcnc.jnotepad.tool.LogUtil; +import org.jcnc.jnotepad.tool.UiUtil; +import org.jcnc.jnotepad.ui.dialog.factory.impl.BasicFileChooserFactory; import java.io.File; import java.util.List; @@ -28,11 +31,12 @@ public class PluginDemo { public void start(Stage primaryStage) { PluginManager pluginManager = new PluginManager(); - FileChooser fileChooser = new FileChooser(); - fileChooser.getExtensionFilters().addAll( + FileChooser fileChooser = BasicFileChooserFactory.getInstance().createFileChooser( + "选择插件", + null, + null, new FileChooser.ExtensionFilter("JAR Files", "*.jar") ); - Button loadButton = createLoadButton(primaryStage, fileChooser, pluginManager); Button executeButton = new Button("执行插件"); @@ -40,6 +44,7 @@ public class PluginDemo { VBox root = new VBox(10, loadButton, executeButton); Scene scene = new Scene(root, 300, 200); + primaryStage.getIcons().add(UiUtil.getAppIcon()); primaryStage.setScene(scene); primaryStage.setTitle("插件演示"); primaryStage.show(); @@ -66,6 +71,7 @@ public class PluginDemo { displayPluginInfo(primaryStage, pluginManager); } } catch (Exception ignored) { + LogUtil.getLogger(this.getClass()).info("未加载插件!"); } }); return loadButton; @@ -81,17 +87,15 @@ public class PluginDemo { Map> loadedPluginsByCategory = pluginManager.getLoadedPluginsByCategory(); VBox infoBox = new VBox(); - for (String category : loadedPluginsByCategory.keySet()) { - Label categoryLabel = new Label("类别: " + category); + loadedPluginsByCategory.forEach((key, pluginNames) -> { + Label categoryLabel = new Label("类别: " + key); 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); diff --git a/src/main/java/org/jcnc/jnotepad/plugin/PluginManager.java b/src/main/java/org/jcnc/jnotepad/plugin/PluginManager.java index 57aa64a..a1caa36 100644 --- a/src/main/java/org/jcnc/jnotepad/plugin/PluginManager.java +++ b/src/main/java/org/jcnc/jnotepad/plugin/PluginManager.java @@ -1,6 +1,11 @@ package org.jcnc.jnotepad.plugin; +import org.jcnc.jnotepad.tool.LogUtil; +import org.slf4j.Logger; + import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; @@ -17,6 +22,7 @@ import java.util.Map; * @author luke */ public class PluginManager { + Logger logger = LogUtil.getLogger(this.getClass()); private final List plugins; private final Map> categories; @@ -32,16 +38,34 @@ public class PluginManager { * 加载插件 * * @param pluginFilePath 插件文件的路径 - * @throws Exception 如果加载插件时发生异常 */ - public void loadPlugins(String pluginFilePath) throws Exception { + public void loadPlugins(String pluginFilePath) { 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(); + Class pluginClass = null; + try (URLClassLoader classLoader = new URLClassLoader(new URL[]{file.toURI().toURL()})) { + pluginClass = classLoader.loadClass("org.jcnc.jnotepad.plugin.ButtonPlugin"); + } catch (ClassNotFoundException e) { + logger.error("无法找到对应的插件类!", e); + } catch (MalformedURLException e) { + logger.error("无法创建URL格式错误!", e); + } catch (IOException e) { + logger.error("IO异常!", e); + } + if (pluginClass == null) { + return; + } + Plugin plugin = null; + try { + plugin = (Plugin) pluginClass.getDeclaredConstructor().newInstance(); + } catch (Exception e) { + logger.error("发生异常!", e); + } + if (plugin == null) { + return; + } plugins.add(plugin); // 添加插件到类别中 @@ -49,7 +73,7 @@ public class PluginManager { String displayName = plugin.getDisplayName(); categories.computeIfAbsent(categoryName, k -> new ArrayList<>()).add(displayName); } else { - System.err.println("Plugin file not found: " + pluginFilePath); + LogUtil.getLogger(this.getClass()).info("Plugin file not found: {}", pluginFilePath); } } diff --git a/src/main/java/org/jcnc/jnotepad/ui/dialog/factory/FileChooserFactory.java b/src/main/java/org/jcnc/jnotepad/ui/dialog/factory/FileChooserFactory.java index 5cb0f6d..46457a7 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/dialog/factory/FileChooserFactory.java +++ b/src/main/java/org/jcnc/jnotepad/ui/dialog/factory/FileChooserFactory.java @@ -25,9 +25,9 @@ public interface FileChooserFactory { * @param title 对话框标题 * @param filename 默认选中的文件名 * @param directory 初始目录 - * @param extensionFilter 文件类型过滤器 + * @param extensionFilters 文件类型过滤器 * @return javafx.stage.FileChooser 详细文件选择对话框对象 * @apiNote 该方法用于创建一个带有标题、默认文件名、初始目录和文件类型过滤器的详细文件选择对话框。 */ - FileChooser createFileChooser(String title, String filename, File directory, FileChooser.ExtensionFilter extensionFilter); + FileChooser createFileChooser(String title, String filename, File directory, FileChooser.ExtensionFilter... extensionFilters); } diff --git a/src/main/java/org/jcnc/jnotepad/ui/dialog/factory/impl/BasicFileChooserFactory.java b/src/main/java/org/jcnc/jnotepad/ui/dialog/factory/impl/BasicFileChooserFactory.java new file mode 100644 index 0000000..7ba296a --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/ui/dialog/factory/impl/BasicFileChooserFactory.java @@ -0,0 +1,80 @@ +package org.jcnc.jnotepad.ui.dialog.factory.impl; + +import javafx.stage.FileChooser; +import org.jcnc.jnotepad.ui.dialog.factory.FileChooserFactory; + +import java.io.File; +import java.util.List; + +/** + * 基本文件选择对话框 + * + * @author gewuyou + * @see FileChooserFactory + */ +public class BasicFileChooserFactory implements FileChooserFactory { + + private static final BasicFileChooserFactory INSTANCE = new BasicFileChooserFactory(); + + private BasicFileChooserFactory() { + + } + + public static BasicFileChooserFactory getInstance() { + return INSTANCE; + } + + /** + * 创建原始文件选择对话框 + * + * @return javafx.stage.FileChooser + */ + @Override + public FileChooser createFileChooser() { + return new FileChooser(); + } + + /** + * 创建详细的文件选择对话框 + * + * @param title 对话框名字 + * @param filename 选中的文件名 + * @param directory 初始目录 + * @param extensionFilters 文件类型过滤器 + * @return javafx.stage.FileChooser + * @apiNote + */ + @Override + public FileChooser createFileChooser(String title, String filename, File directory, FileChooser.ExtensionFilter... extensionFilters) { + FileChooser fileChooser = createFileChooser(); + // 设置窗口名称 + fileChooser.setTitle(title); + if (filename != null) { + // 设置原始文件名称 + fileChooser.setInitialFileName(filename); + } + if (directory != null) { + // 设置打开的目录 + fileChooser.setInitialDirectory(directory); + } + for (FileChooser.ExtensionFilter extensionFilter : extensionFilters) { + // 设置文件类型 + fileChooser.getExtensionFilters().add(extensionFilter); + } + return fileChooser; + } + + /** + * 创建详细的文件选择对话框 + * + * @param title 对话框名字 + * @param filename 选中的文件名 + * @param directory 初始目录 + * @param extensionFilters 文件类型过滤器集合 + * @return javafx.stage.FileChooser + * @apiNote + */ + public FileChooser createFileChooser(String title, String filename, File directory, List extensionFilters) { + return createFileChooser(title, filename, directory, extensionFilters.toArray(new FileChooser.ExtensionFilter[0])); + } +} diff --git a/src/main/java/org/jcnc/jnotepad/ui/dialog/factory/impl/TextFileChooserFactory.java b/src/main/java/org/jcnc/jnotepad/ui/dialog/factory/impl/TextFileChooserFactory.java deleted file mode 100644 index 82f16de..0000000 --- a/src/main/java/org/jcnc/jnotepad/ui/dialog/factory/impl/TextFileChooserFactory.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.jcnc.jnotepad.ui.dialog.factory.impl; - -import javafx.stage.FileChooser; -import org.jcnc.jnotepad.ui.dialog.factory.FileChooserFactory; - -import java.io.File; - -/** - * 文本文件选择对话框 - * - * @author gewuyou - * @see FileChooserFactory - */ -public class TextFileChooserFactory implements FileChooserFactory { - - private static final TextFileChooserFactory INSTANCE = new TextFileChooserFactory(); - - private TextFileChooserFactory() { - - } - - public static TextFileChooserFactory getInstance() { - return INSTANCE; - } - - /** - * 创建原始文件选择对话框 - * - * @return javafx.stage.FileChooser - */ - @Override - public FileChooser createFileChooser() { - return new FileChooser(); - } - - /** - * 创建详细的文件选择对话框 - * - * @param title 对话框名字 - * @param filename 选中的文件名 - * @param directory 初始目录 - * @param extensionFilter 文件类型数组 - * @return javafx.stage.FileChooser - * @apiNote - */ - @Override - public FileChooser createFileChooser(String title, String filename, File directory, FileChooser.ExtensionFilter extensionFilter) { - FileChooser fileChooser = createFileChooser(); - // 设置窗口名称 - fileChooser.setTitle(title); - if (filename != null) { - // 设置原始文件名称 - fileChooser.setInitialFileName(filename); - } - if (directory != null) { - // 设置打开的目录 - fileChooser.setInitialDirectory(directory); - } - // 设置文件类型 - fileChooser.getExtensionFilters().add(extensionFilter); - return fileChooser; - } -} diff --git a/src/main/java/org/jcnc/jnotepad/ui/module/SettingsComponent.java b/src/main/java/org/jcnc/jnotepad/ui/module/SettingsComponent.java index 6d82278..1edb1ba 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/module/SettingsComponent.java +++ b/src/main/java/org/jcnc/jnotepad/ui/module/SettingsComponent.java @@ -2,8 +2,8 @@ package org.jcnc.jnotepad.ui.module; import javafx.event.ActionEvent; import javafx.event.EventHandler; -import javafx.scene.control.Label; import javafx.scene.control.Button; +import javafx.scene.control.Label; import javafx.scene.layout.VBox; /** diff --git a/src/main/java/org/jcnc/jnotepad/ui/setstage/DeveloperDebugStage.java b/src/main/java/org/jcnc/jnotepad/ui/setstage/DeveloperDebugStage.java index 3280ca1..b119b29 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/setstage/DeveloperDebugStage.java +++ b/src/main/java/org/jcnc/jnotepad/ui/setstage/DeveloperDebugStage.java @@ -1,6 +1,5 @@ package org.jcnc.jnotepad.ui.setstage; -import javafx.application.Application; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button;