♻️ 重构代码 重构插件测试窗口,使代码符合项目风格规范

This commit is contained in:
gewuyou 2023-09-07 12:53:33 +08:00
parent a378f6d6f1
commit dd096bf448
12 changed files with 134 additions and 90 deletions

View File

@ -11,7 +11,6 @@ import org.jcnc.jnotepad.constants.AppConstants;
import org.jcnc.jnotepad.constants.TextConstants; import org.jcnc.jnotepad.constants.TextConstants;
import org.jcnc.jnotepad.controller.i18n.LocalizationController; import org.jcnc.jnotepad.controller.i18n.LocalizationController;
import org.jcnc.jnotepad.manager.ThreadPoolManager; import org.jcnc.jnotepad.manager.ThreadPoolManager;
import org.jcnc.jnotepad.tool.PopUpUtil;
import org.jcnc.jnotepad.tool.SingletonUtil; import org.jcnc.jnotepad.tool.SingletonUtil;
import org.jcnc.jnotepad.tool.UiUtil; import org.jcnc.jnotepad.tool.UiUtil;
import org.jcnc.jnotepad.view.manager.ViewManager; import org.jcnc.jnotepad.view.manager.ViewManager;
@ -73,7 +72,6 @@ public class LunchApp extends Application {
primaryStage.setWidth(SCENE.getWidth()); primaryStage.setWidth(SCENE.getWidth());
primaryStage.setHeight(SCENE.getHeight()); primaryStage.setHeight(SCENE.getHeight());
primaryStage.getIcons().add(UiUtil.getAppIcon()); primaryStage.getIcons().add(UiUtil.getAppIcon());
// PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!", null, null);
primaryStage.show(); primaryStage.show();
} }

View File

@ -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.EncodingDetector;
import org.jcnc.jnotepad.tool.LogUtil; import org.jcnc.jnotepad.tool.LogUtil;
import org.jcnc.jnotepad.tool.UiUtil; 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 org.jcnc.jnotepad.ui.module.LineNumberTextArea;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -41,7 +41,7 @@ public class OpenFile implements EventHandler<ActionEvent> {
@Override @Override
public void handle(ActionEvent event) { public void handle(ActionEvent event) {
// 显示文件选择对话框并获取选中的文件 // 显示文件选择对话框并获取选中的文件
File file = TextFileChooserFactory.getInstance().createFileChooser( File file = BasicFileChooserFactory.getInstance().createFileChooser(
UiResourceBundle.getContent(TextConstants.OPEN), UiResourceBundle.getContent(TextConstants.OPEN),
null, null,
null, null,

View File

@ -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.root.center.main.center.tab.CenterTabPane;
import org.jcnc.jnotepad.tool.LogUtil; import org.jcnc.jnotepad.tool.LogUtil;
import org.jcnc.jnotepad.tool.UiUtil; 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 org.slf4j.Logger;
import java.io.File; import java.io.File;
@ -92,7 +92,7 @@ public class RenameFile implements EventHandler<ActionEvent> {
// 获取原始文件对象 // 获取原始文件对象
File file = (File) centerTab.getUserData(); File file = (File) centerTab.getUserData();
// 获取应用窗口并绑定 // 获取应用窗口并绑定
File newFile = TextFileChooserFactory.getInstance() File newFile = BasicFileChooserFactory.getInstance()
.createFileChooser( .createFileChooser(
UiResourceBundle.getContent(TextConstants.RENAME), UiResourceBundle.getContent(TextConstants.RENAME),
centerTab.getText(), centerTab.getText(),

View File

@ -12,7 +12,7 @@ import org.jcnc.jnotepad.root.top.menu.TopMenuBar;
import org.jcnc.jnotepad.tool.LogUtil; import org.jcnc.jnotepad.tool.LogUtil;
import org.jcnc.jnotepad.tool.SingletonUtil; import org.jcnc.jnotepad.tool.SingletonUtil;
import org.jcnc.jnotepad.tool.UiUtil; 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 org.slf4j.Logger;
import java.io.File; import java.io.File;
@ -76,7 +76,7 @@ public class SaveFile implements EventHandler<ActionEvent> {
if (selectedTab == null) { if (selectedTab == null) {
return; return;
} }
File file = TextFileChooserFactory.getInstance().createFileChooser( File file = BasicFileChooserFactory.getInstance().createFileChooser(
UiResourceBundle.getContent(TextConstants.SAVE_AS), UiResourceBundle.getContent(TextConstants.SAVE_AS),
selectedTab.getText(), selectedTab.getText(),
null, null,

View File

@ -1,5 +1,7 @@
package org.jcnc.jnotepad.plugin; package org.jcnc.jnotepad.plugin;
import org.jcnc.jnotepad.tool.LogUtil;
/** /**
* 新按钮插件 * 新按钮插件
* *
@ -20,6 +22,6 @@ public class ButtonPlugin implements Plugin {
@Override @Override
public void execute() { public void execute() {
// 在这里实现新按钮插件的逻辑 // 在这里实现新按钮插件的逻辑
System.out.println("新按钮插件执行了!"); LogUtil.getLogger(this.getClass()).info("新按钮插件执行了!");
} }
} }

View File

@ -6,6 +6,9 @@ import javafx.scene.control.Label;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import javafx.stage.Stage; 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.io.File;
import java.util.List; import java.util.List;
@ -28,11 +31,12 @@ public class PluginDemo {
public void start(Stage primaryStage) { public void start(Stage primaryStage) {
PluginManager pluginManager = new PluginManager(); PluginManager pluginManager = new PluginManager();
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = BasicFileChooserFactory.getInstance().createFileChooser(
fileChooser.getExtensionFilters().addAll( "选择插件",
null,
null,
new FileChooser.ExtensionFilter("JAR Files", "*.jar") new FileChooser.ExtensionFilter("JAR Files", "*.jar")
); );
Button loadButton = createLoadButton(primaryStage, fileChooser, pluginManager); Button loadButton = createLoadButton(primaryStage, fileChooser, pluginManager);
Button executeButton = new Button("执行插件"); Button executeButton = new Button("执行插件");
@ -40,6 +44,7 @@ public class PluginDemo {
VBox root = new VBox(10, loadButton, executeButton); VBox root = new VBox(10, loadButton, executeButton);
Scene scene = new Scene(root, 300, 200); Scene scene = new Scene(root, 300, 200);
primaryStage.getIcons().add(UiUtil.getAppIcon());
primaryStage.setScene(scene); primaryStage.setScene(scene);
primaryStage.setTitle("插件演示"); primaryStage.setTitle("插件演示");
primaryStage.show(); primaryStage.show();
@ -66,6 +71,7 @@ public class PluginDemo {
displayPluginInfo(primaryStage, pluginManager); displayPluginInfo(primaryStage, pluginManager);
} }
} catch (Exception ignored) { } catch (Exception ignored) {
LogUtil.getLogger(this.getClass()).info("未加载插件!");
} }
}); });
return loadButton; return loadButton;
@ -81,17 +87,15 @@ public class PluginDemo {
Map<String, List<String>> loadedPluginsByCategory = pluginManager.getLoadedPluginsByCategory(); Map<String, List<String>> loadedPluginsByCategory = pluginManager.getLoadedPluginsByCategory();
VBox infoBox = new VBox(); VBox infoBox = new VBox();
for (String category : loadedPluginsByCategory.keySet()) { loadedPluginsByCategory.forEach((key, pluginNames) -> {
Label categoryLabel = new Label("类别: " + category); Label categoryLabel = new Label("类别: " + key);
VBox categoryInfoBox = new VBox(); VBox categoryInfoBox = new VBox();
List<String> pluginNames = loadedPluginsByCategory.get(category);
for (String pluginName : pluginNames) { for (String pluginName : pluginNames) {
Label pluginLabel = new Label("插件名称: " + pluginName); Label pluginLabel = new Label("插件名称: " + pluginName);
categoryInfoBox.getChildren().add(pluginLabel); categoryInfoBox.getChildren().add(pluginLabel);
} }
infoBox.getChildren().addAll(categoryLabel, categoryInfoBox); infoBox.getChildren().addAll(categoryLabel, categoryInfoBox);
} });
Scene infoScene = new Scene(infoBox, 400, 300); Scene infoScene = new Scene(infoBox, 400, 300);
Stage infoStage = new Stage(); Stage infoStage = new Stage();
infoStage.setScene(infoScene); infoStage.setScene(infoScene);

View File

@ -1,6 +1,11 @@
package org.jcnc.jnotepad.plugin; package org.jcnc.jnotepad.plugin;
import org.jcnc.jnotepad.tool.LogUtil;
import org.slf4j.Logger;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.ArrayList; import java.util.ArrayList;
@ -17,6 +22,7 @@ import java.util.Map;
* @author luke * @author luke
*/ */
public class PluginManager { public class PluginManager {
Logger logger = LogUtil.getLogger(this.getClass());
private final List<Plugin> plugins; private final List<Plugin> plugins;
private final Map<String, List<String>> categories; private final Map<String, List<String>> categories;
@ -32,16 +38,34 @@ public class PluginManager {
* 加载插件 * 加载插件
* *
* @param pluginFilePath 插件文件的路径 * @param pluginFilePath 插件文件的路径
* @throws Exception 如果加载插件时发生异常
*/ */
public void loadPlugins(String pluginFilePath) throws Exception { public void loadPlugins(String pluginFilePath) {
File file = new File(pluginFilePath); File file = new File(pluginFilePath);
if (file.exists() && file.isFile()) { if (file.exists() && file.isFile()) {
// 创建URLClassLoader以加载Jar文件中的类 // 创建URLClassLoader以加载Jar文件中的类
URLClassLoader classLoader = new URLClassLoader(new URL[]{file.toURI().toURL()}); Class<?> pluginClass = null;
Class<?> pluginClass = classLoader.loadClass("org.jcnc.jnotepad.plugin.ButtonPlugin"); try (URLClassLoader classLoader = new URLClassLoader(new URL[]{file.toURI().toURL()})) {
Plugin plugin = (Plugin) pluginClass.getDeclaredConstructor().newInstance(); 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); plugins.add(plugin);
// 添加插件到类别中 // 添加插件到类别中
@ -49,7 +73,7 @@ public class PluginManager {
String displayName = plugin.getDisplayName(); String displayName = plugin.getDisplayName();
categories.computeIfAbsent(categoryName, k -> new ArrayList<>()).add(displayName); categories.computeIfAbsent(categoryName, k -> new ArrayList<>()).add(displayName);
} else { } else {
System.err.println("Plugin file not found: " + pluginFilePath); LogUtil.getLogger(this.getClass()).info("Plugin file not found: {}", pluginFilePath);
} }
} }

View File

@ -25,9 +25,9 @@ public interface FileChooserFactory {
* @param title 对话框标题 * @param title 对话框标题
* @param filename 默认选中的文件名 * @param filename 默认选中的文件名
* @param directory 初始目录 * @param directory 初始目录
* @param extensionFilter 文件类型过滤器 * @param extensionFilters 文件类型过滤器
* @return javafx.stage.FileChooser 详细文件选择对话框对象 * @return javafx.stage.FileChooser 详细文件选择对话框对象
* @apiNote 该方法用于创建一个带有标题默认文件名初始目录和文件类型过滤器的详细文件选择对话框 * @apiNote 该方法用于创建一个带有标题默认文件名初始目录和文件类型过滤器的详细文件选择对话框
*/ */
FileChooser createFileChooser(String title, String filename, File directory, FileChooser.ExtensionFilter extensionFilter); FileChooser createFileChooser(String title, String filename, File directory, FileChooser.ExtensionFilter... extensionFilters);
} }

View File

@ -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<FileChooser.ExtensionFilter> extensionFilters) {
return createFileChooser(title, filename, directory, extensionFilters.toArray(new FileChooser.ExtensionFilter[0]));
}
}

View File

@ -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;
}
}

View File

@ -2,8 +2,8 @@ package org.jcnc.jnotepad.ui.module;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import javafx.scene.control.Label;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
/** /**

View File

@ -1,6 +1,5 @@
package org.jcnc.jnotepad.ui.setstage; package org.jcnc.jnotepad.ui.setstage;
import javafx.application.Application;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.Button; import javafx.scene.control.Button;