diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 31a4c50fb2fb21d81daa9176a6cdb79bd7f30066..228e22955e8889fe7edc2261d3fdee82ac2f4d74 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -16,7 +16,6 @@ module org.jcnc.jnotepad { requires org.kordamp.ikonli.javafx; requires org.kordamp.ikonli.antdesignicons; exports org.jcnc.jnotepad; - exports org.jcnc.jnotepad.ui.dialog.alert; exports org.jcnc.jnotepad.app.config; exports org.jcnc.jnotepad.app.i18n; exports org.jcnc.jnotepad.constants; @@ -29,5 +28,6 @@ module org.jcnc.jnotepad { exports org.jcnc.jnotepad.interfaces; opens org.jcnc.jnotepad.app.config; exports org.jcnc.jnotepad.root.center.main.bottom.status; + exports org.jcnc.jnotepad.ui.dialog; } \ No newline at end of file diff --git a/src/main/java/org/jcnc/jnotepad/controller/config/AppConfigController.java b/src/main/java/org/jcnc/jnotepad/controller/config/AppConfigController.java index eda737be9693fbd7d328c795781000b16e0b0602..a047692240c219334149f76061ecd3b286d3c6bd 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/config/AppConfigController.java +++ b/src/main/java/org/jcnc/jnotepad/controller/config/AppConfigController.java @@ -4,6 +4,7 @@ import org.jcnc.jnotepad.app.config.AppConfig; import org.jcnc.jnotepad.exception.AppException; import org.jcnc.jnotepad.tool.JsonUtil; import org.jcnc.jnotepad.tool.LogUtil; +import org.jcnc.jnotepad.tool.PopUpUtil; import org.slf4j.Logger; import java.io.BufferedWriter; @@ -85,7 +86,7 @@ public class AppConfigController { writer.write(JsonUtil.toJsonString(appConfig)); } catch (Exception e) { logger.error("", e); -// PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!"); + PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!", null, null); } } diff --git a/src/main/java/org/jcnc/jnotepad/root/left/sidebar/tools/ToolBar.java b/src/main/java/org/jcnc/jnotepad/root/left/sidebar/tools/SidebarToolBar.java similarity index 75% rename from src/main/java/org/jcnc/jnotepad/root/left/sidebar/tools/ToolBar.java rename to src/main/java/org/jcnc/jnotepad/root/left/sidebar/tools/SidebarToolBar.java index 8fe6e8df00d16eb86623e0cb6ade071b36f15e0f..7b06885b507e7a99109a8496bd1be62bd731d6bb 100644 --- a/src/main/java/org/jcnc/jnotepad/root/left/sidebar/tools/ToolBar.java +++ b/src/main/java/org/jcnc/jnotepad/root/left/sidebar/tools/SidebarToolBar.java @@ -5,26 +5,26 @@ import javafx.scene.image.Image; import javafx.scene.image.ImageView; /** - * JNotepadToolBar 是 JNotepad 应用程序的工具栏类。 + * SidebarToolBar 是 JNotepad 应用程序的工具栏类。 * - *

该类继承自 JavaFX 的 ToolBar 类,并提供了一个单例实例,用于管理工具栏上的按钮。

+ *

该类继承自 JavaFX 的 SidebarToolBar 类,并提供了一个单例实例,用于管理工具栏上的按钮。

* *

工具栏上的按钮用于执行不同的操作,比如设置操作。

* * @author luke */ -public class ToolBar extends javafx.scene.control.ToolBar { +public class SidebarToolBar extends javafx.scene.control.ToolBar { /** * 单例模式,保证只有一个 JNotepadToolBar实例 */ - private static final ToolBar INSTANCE = new ToolBar(); + private static final SidebarToolBar INSTANCE = new SidebarToolBar(); /** * 工具栏上的设置按钮 */ Button setButton = new Button(); - private ToolBar() { + private SidebarToolBar() { // 创建工具栏上的按钮 Image image = new Image("tools.png"); ImageView imageView = new ImageView(image); @@ -46,7 +46,7 @@ public class ToolBar extends javafx.scene.control.ToolBar { * * @return JNotepadToolBar 的单例实例 */ - public static ToolBar getInstance() { + public static SidebarToolBar getInstance() { return INSTANCE; } diff --git a/src/main/java/org/jcnc/jnotepad/root/left/sidebar/tools/ToolHorizontalBox.java b/src/main/java/org/jcnc/jnotepad/root/left/sidebar/tools/ToolHorizontalBox.java index 4e769a2520ab0e395b7a0d2f44b43ef233d188c4..291de9544b5142b66dd1843a466560c176eb6ff2 100644 --- a/src/main/java/org/jcnc/jnotepad/root/left/sidebar/tools/ToolHorizontalBox.java +++ b/src/main/java/org/jcnc/jnotepad/root/left/sidebar/tools/ToolHorizontalBox.java @@ -21,10 +21,10 @@ public class ToolHorizontalBox extends AbstractHorizontalBox { private ToolHorizontalBox() { // 设置子节点水平拉伸 - HBox.setHgrow(ToolBar.getInstance(), Priority.ALWAYS); + HBox.setHgrow(SidebarToolBar.getInstance(), Priority.ALWAYS); // 将 JNotepadToolBar 添加为子节点 - getChildren().add(ToolBar.getInstance()); + getChildren().add(SidebarToolBar.getInstance()); } /** 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 e29bdf20d4281b0cd89e8b3510a7fa379ccf5ce3..8e4a218cb3ad80e842a69ad05e594326a222d334 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 @@ -12,7 +12,7 @@ import org.jcnc.jnotepad.controller.event.handler.tool.SetBtn; import org.jcnc.jnotepad.controller.i18n.LocalizationController; 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.ToolBar; +import org.jcnc.jnotepad.root.left.sidebar.tools.SidebarToolBar; import org.jcnc.jnotepad.tool.LogUtil; import org.slf4j.Logger; @@ -41,11 +41,11 @@ public class TopMenuBar extends MenuBar { /** * 工具栏 */ - ToolBar toolBar = ToolBar.getInstance(); + SidebarToolBar sidebarToolBar = SidebarToolBar.getInstance(); /** * 获取工具栏中的setButton */ - Button setButton = toolBar.getSetButton(); + Button setButton = sidebarToolBar.getSetButton(); /** * 文件菜单 */ diff --git a/src/main/java/org/jcnc/jnotepad/tool/PopUpUtil.java b/src/main/java/org/jcnc/jnotepad/tool/PopUpUtil.java index 3ab9af0e5b67b14b14d28cf8576d2ee2fc92a488..10726305e85e3d90d94c25ff560b4cf11ce9e405 100644 --- a/src/main/java/org/jcnc/jnotepad/tool/PopUpUtil.java +++ b/src/main/java/org/jcnc/jnotepad/tool/PopUpUtil.java @@ -1,7 +1,6 @@ package org.jcnc.jnotepad.tool; -import org.jcnc.jnotepad.ui.dialog.alert.AlertDialog; -import org.jcnc.jnotepad.ui.dialog.alert.AlertDialogButtonAction; +import org.jcnc.jnotepad.ui.dialog.AppDialog; /** * 弹窗工具类 @@ -16,14 +15,23 @@ public class PopUpUtil { /** * 获取错误弹窗 * - * @param title 弹窗标题 - * @param headerText 头文本 - * @param message 消息文本 - * @param action 按钮的事件类 + * @param title 弹窗标题 + * @param headerText 头文本 + * @param message 消息文本 + * @param leftBtnAction 左侧按钮点击事件 + * @param rightBtnAction 右侧按钮点击事件 * @apiNote * @since 2023/9/3 11:54 */ - public static void errorAlert(String title, String headerText, String message, AlertDialogButtonAction action) { - new AlertDialog(title, headerText, message, AlertDialog.DialogType.ERROR, action).showAndWait(); + public static void errorAlert(String title, String headerText, String message, AppDialog.ButtonAction leftBtnAction, AppDialog.ButtonAction rightBtnAction) { + AppDialog.AppDialogBuilder builder = new AppDialog.AppDialogBuilder(); + builder + .setDialogType(AppDialog.DialogType.ERROR) + .setTitle(title) + .setHeaderText(headerText) + .setCustomText(message) + .setLeftBtnAction(leftBtnAction) + .setRightBtnAction(rightBtnAction) + .build().showAndWait(); } } diff --git a/src/main/java/org/jcnc/jnotepad/ui/dialog/AppDialog.java b/src/main/java/org/jcnc/jnotepad/ui/dialog/AppDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..90b8ae4180a117efdff837bd867aeeab050d4e95 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/ui/dialog/AppDialog.java @@ -0,0 +1,344 @@ +package org.jcnc.jnotepad.ui.dialog; + +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import javafx.stage.Modality; +import javafx.stage.Stage; +import org.jcnc.jnotepad.tool.UiUtil; +import org.kordamp.ikonli.javafx.FontIcon; + +/** + * 应用对话框 + * + *

该类用于创建自定义的提示框窗口,包括图标、消息文本和确认、取消按钮。

+ * + * @author luke gewuyou + */ +public class AppDialog extends Stage { + /** + * 构造一个自定义提示框 + * + * @param builder 提示框构建器 + */ + private AppDialog( + AppDialogBuilder builder) { + // 设置窗口图标 + this.getIcons().add(builder.appIcon); + setTitle(builder.title); + setResizable(builder.isResizable); + initModality(builder.modality); + + BorderPane borderPane = createLayout(builder); + Scene scene = new Scene(borderPane, builder.width, builder.height); + + setScene(scene); + } + + /** + * 创建提示框的布局。 + * + * @return BorderPane 布局容器 + */ + private BorderPane createLayout( + AppDialogBuilder builder) { + BorderPane borderPane = new BorderPane(); + HBox iconBox = new HBox(builder.icon); + iconBox.setPadding(builder.iconCoxPaddingInsets); + VBox vbox = new VBox(builder.hBoxSpacing); + vbox.setAlignment(builder.vboxPos); + + Label label = new Label(builder.headerText); + + // 自定义文本 + Label customTextLabel = new Label(builder.customText); + + Button confirmButton = createButton(builder.leftBtnText, builder.leftBtnAction::handleAction); + Button cancelButton = createButton(builder.rightBtnText, builder.rightBtnAction::handleAction); + + HBox hBox = new HBox(builder.hBoxSpacing, confirmButton, cancelButton); + hBox.setAlignment(builder.hboxPos); + hBox.setPadding(builder.hBoxPaddingInsets); + vbox.getChildren().addAll(label, customTextLabel, hBox); + + borderPane.setLeft(iconBox); + borderPane.setCenter(vbox); + borderPane.setBottom(hBox); + + return borderPane; + } + + /** + * 创建按钮。 + * + * @param text 按钮文本 + * @param action 按钮点击时的操作 + * @return Button 按钮控件 + */ + private Button createButton(String text, Runnable action) { + Button button = new Button(text); + button.setOnAction(e -> action.run()); + return button; + } + + public enum DialogType { + /** + * 信息 + */ + INFO, + /** + * 警告 + */ + WARNING, + /** + * 错误 + */ + ERROR, + /** + * 疑问 + */ + QUESTION + } + + + public interface ButtonAction { + /** + * 处理按钮的操作。子类必须实现此方法以定义按钮的行为 + * + * @apiNote + * @since 2023/9/3 22:53 + */ + + void handleAction(); + } + + public static class AppDialogBuilder { + private AppDialog appDialog; + private Image appIcon = UiUtil.getAppIcon(); + private String title; + private String headerText; + private String customText; + private double width = 350; + private double height = 150; + private FontIcon icon; + + private ButtonAction leftBtnAction = () -> appDialog.close(); + + private ButtonAction rightBtnAction = () -> appDialog.close(); + + private String leftBtnText = "确定"; + + private String rightBtnText = "取消"; + + private Insets iconCoxPaddingInsets = new Insets(10, 10, 10, 10); + private Insets hBoxPaddingInsets = new Insets(10, 10, 10, 10); + private boolean isResizable = false; + private double hBoxSpacing = 10; + private Pos vboxPos = Pos.CENTER; + private Pos hboxPos = Pos.CENTER_RIGHT; + private Modality modality = Modality.APPLICATION_MODAL; + + /** + * 设置默认的对话框构造 + * + * @param type 对话框类型 + * @return org.jcnc.jnotepad.ui.dialog.AppDialog.AppDialogBuilder + * @apiNote 该方法只会设置默认的对话框配置,标题、图标,头文本和自定义文本需要自行设置 + * @since 2023/9/3 22:24 + */ + public AppDialogBuilder setDialogType(DialogType type) { + switch (type) { + case INFO -> + // 设置默认的对话框配置 + { + return setTitle("信息"). + setIcon(UiUtil.getInfoIcon()); + } + case WARNING -> + // 设置默认的对话框配置 + { + return setTitle("警告"). + setIcon(UiUtil.getWarningIcon()); + } + case ERROR -> + // 设置默认的对话框配置 + { + return setTitle("错误"). + setIcon(UiUtil.getErrorIcon()); + } + case QUESTION -> + // 设置默认的对话框配置 + { + return setTitle("问题"). + setIcon(UiUtil.getQuestionIcon()); + } + default -> { + return this; + } + } + } + + /** + * 设置应用图标 + */ + public AppDialogBuilder setAppIcon(Image appIcon) { + this.appIcon = appIcon; + return this; + } + + + /** + * 设置对话框标题 + */ + public AppDialogBuilder setTitle(String title) { + this.title = title; + return this; + } + + + /** + * 设置对话框头部文本 + */ + public AppDialogBuilder setHeaderText(String headerText) { + this.headerText = headerText; + return this; + } + + /** + * 设置自定义文本 + */ + public AppDialogBuilder setCustomText(String customText) { + this.customText = customText; + return this; + } + + /** + * 设置对话框宽度 + */ + public AppDialogBuilder setWidth(double width) { + this.width = width; + return this; + } + + /** + * 设置对话框高度 + */ + public AppDialogBuilder setHeight(double height) { + this.height = height; + return this; + } + + /** + * 设置对话框左侧图标 + */ + public AppDialogBuilder setIcon(FontIcon icon) { + this.icon = icon; + return this; + } + + /** + * 设置左按钮操作 + */ + public AppDialogBuilder setLeftBtnAction(ButtonAction leftBtnAction) { + if (leftBtnAction != null) { + this.leftBtnAction = leftBtnAction; + } + return this; + } + + /** + * 设置右按钮操作 + */ + public AppDialogBuilder setRightBtnAction(ButtonAction rightBtnAction) { + if (rightBtnAction != null) { + this.rightBtnAction = rightBtnAction; + } + return this; + } + + /** + * 设置左按钮文本 + */ + public AppDialogBuilder setLeftBtnText(String leftBtnText) { + this.leftBtnText = leftBtnText; + return this; + } + + /** + * 设置右按钮文本 + */ + public AppDialogBuilder setRightBtnText(String rightBtnText) { + this.rightBtnText = rightBtnText; + return this; + } + + /** + * 设置图标边距 + */ + public AppDialogBuilder setIconCoxPaddingInsets(Insets iconCoxPaddingInsets) { + this.iconCoxPaddingInsets = iconCoxPaddingInsets; + return this; + } + + /** + * 设置水平盒子边距 + */ + public AppDialogBuilder setHorizontalBoxPaddingInsets(Insets hBoxPaddingInsets) { + this.hBoxPaddingInsets = hBoxPaddingInsets; + return this; + } + + /** + * 设置是否可调整大小 + */ + public AppDialogBuilder setResizable(boolean resizable) { + isResizable = resizable; + return this; + } + + /** + * 设置水平盒子间距 + */ + public AppDialogBuilder setHorizontalBoxSpacing(double hBoxSpacing) { + this.hBoxSpacing = hBoxSpacing; + return this; + } + + /** + * 设置垂直盒子位置 + */ + public AppDialogBuilder setVboxPos(Pos vboxPos) { + this.vboxPos = vboxPos; + return this; + } + + /** + * 设置水平盒子位置 + */ + public AppDialogBuilder setHorizontalBoxPos(Pos hboxPos) { + this.hboxPos = hboxPos; + return this; + } + + /** + * 设置模态性 + */ + public AppDialogBuilder setModality(Modality modality) { + this.modality = modality; + return this; + } + + + public AppDialog build() { + appDialog = new AppDialog(this); + return appDialog; + } + } + +} diff --git a/src/main/java/org/jcnc/jnotepad/ui/dialog/alert/AlertDialog.java b/src/main/java/org/jcnc/jnotepad/ui/dialog/alert/AlertDialog.java deleted file mode 100644 index 68a2af597c7fad2beaa119fc137ee60600934aab..0000000000000000000000000000000000000000 --- a/src/main/java/org/jcnc/jnotepad/ui/dialog/alert/AlertDialog.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.jcnc.jnotepad.ui.dialog.alert; - -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.layout.BorderPane; -import javafx.scene.layout.HBox; -import javafx.scene.layout.VBox; -import javafx.stage.Modality; -import javafx.stage.Stage; -import org.jcnc.jnotepad.tool.UiUtil; -import org.kordamp.ikonli.javafx.FontIcon; - -/** - * 自定义提示框的抽象基类 - * - *

该类用于创建自定义的提示框窗口,包括图标、消息文本和确认、取消按钮。

- * - * @author luke - */ -public class AlertDialog extends Stage { - - /** - * 构造一个自定义提示框。 - * - * @param title 提示框的标题 - * @param message 提示框中显示的消息文本 - * @param customText 自定义的文本 - * @param width 提示框的宽度 - * @param height 提示框的高度 - * @param type 提示框的类型 - * @param action 按钮的事件类 - */ - public AlertDialog(String title, String message, String customText, double width, double height, DialogType type, AlertDialogButtonAction action) { - // 设置窗口图标 - this.getIcons().add(UiUtil.getAppIcon()); - this.customText = customText; - setTitle(title); - setResizable(false); - initModality(Modality.APPLICATION_MODAL); - - FontIcon icon = switch (type) { - case INFO -> UiUtil.getInfoIcon(); - case WARNING -> UiUtil.getWarningIcon(); - case ERROR -> UiUtil.getErrorIcon(); - default -> UiUtil.getQuestionIcon(); - }; - BorderPane borderPane = createLayout(message, icon, action); - Scene scene = new Scene(borderPane, width, height); - - setScene(scene); - } - - private final String customText; - - /** - * 构造一个自定义提示框,使用默认大小。 - * - * @param title 提示框的标题 - * @param message 提示框中显示的消息文本 - * @param customText 自定义的文本 - * @param type 提示框的类型 - * @param action 按钮的事件类 - */ - public AlertDialog(String title, String message, String customText, DialogType type, AlertDialogButtonAction action) { - // 使用默认的宽度和高度 - this(title, message, customText, 350, 150, type, action); - } - - /** - * 创建提示框的布局。 - * - * @param message 提示框中显示的消息文本 - * @param icon 提示框中显示的图标 - * @return BorderPane 布局容器 - */ - private BorderPane createLayout(String message, FontIcon icon, AlertDialogButtonAction action) { - BorderPane borderPane = new BorderPane(); - HBox iconBox = new HBox(icon); - iconBox.setPadding(new Insets(10, 10, 10, 10)); - VBox vbox = new VBox(10); - vbox.setAlignment(Pos.CENTER); - - Label label = new Label(message); - - // 自定义文本 - Label customTextLabel = new Label(customText); - - Button confirmButton = createButton("确认", action::handleConfirmAction); - Button cancelButton = createButton("取消", action::handleCancelAction); - - HBox hBox = new HBox(10, confirmButton, cancelButton); - hBox.setAlignment(Pos.CENTER_RIGHT); - hBox.setPadding(new Insets(10, 10, 10, 10)); - vbox.getChildren().addAll(label, customTextLabel, hBox); - - borderPane.setLeft(iconBox); - borderPane.setCenter(vbox); - borderPane.setBottom(hBox); - - return borderPane; - } - - - /** - * 对话框枚举 - */ - public enum DialogType { - /** - * 信息 - */ - INFO, - /** - * 警告 - */ - WARNING, - /** - * 错误 - */ - ERROR, - /** - * 疑问 - */ - QUESTION - } - - - /** - * 创建按钮。 - * - * @param text 按钮文本 - * @param action 按钮点击时的操作 - * @return Button 按钮控件 - */ - private Button createButton(String text, Runnable action) { - Button button = new Button(text); - button.setOnAction(e -> action.run()); - return button; - } - - -} diff --git a/src/main/java/org/jcnc/jnotepad/ui/dialog/alert/AlertDialogButtonAction.java b/src/main/java/org/jcnc/jnotepad/ui/dialog/alert/AlertDialogButtonAction.java deleted file mode 100644 index 31dd8b5f67a862026d3532209a5aaa707391ffbb..0000000000000000000000000000000000000000 --- a/src/main/java/org/jcnc/jnotepad/ui/dialog/alert/AlertDialogButtonAction.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.jcnc.jnotepad.ui.dialog.alert; - -/** - * 对话框按钮事件类 - * - * @author gewuyou - */ -public abstract class AlertDialogButtonAction { - /** - * 处理确认按钮的操作。子类必须实现此方法以定义确认按钮的行为。 - */ - protected abstract void handleConfirmAction(); - - /** - * 处理取消按钮的操作。默认情况下,此方法为空,子类可以选择性地实现它。 - */ - protected abstract void handleCancelAction(); -}