♻️ 重构代码 重构对话框创建,将对话框创建使用建造者模式创建

This commit is contained in:
gewuyou 2023-09-03 23:13:31 +08:00
parent 8cbea747bf
commit eb6084ca26
9 changed files with 374 additions and 183 deletions

View File

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

View File

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

View File

@ -5,26 +5,26 @@ import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
/**
* JNotepadToolBar JNotepad 应用程序的工具栏类
* SidebarToolBar JNotepad 应用程序的工具栏类
*
* <p>该类继承自 JavaFX ToolBar 并提供了一个单例实例用于管理工具栏上的按钮</p>
* <p>该类继承自 JavaFX SidebarToolBar 并提供了一个单例实例用于管理工具栏上的按钮</p>
*
* <p>工具栏上的按钮用于执行不同的操作比如设置操作</p>
*
* @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;
}

View File

@ -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());
}
/**

View File

@ -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();
/**
* 文件菜单
*/

View File

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

View File

@ -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;
/**
* 应用对话框
*
* <p>该类用于创建自定义的提示框窗口包括图标消息文本和确认取消按钮</p>
*
* @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;
}
}
}

View File

@ -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;
/**
* 自定义提示框的抽象基类
*
* <p>该类用于创建自定义的提示框窗口包括图标消息文本和确认取消按钮</p>
*
* @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;
}
}

View File

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