diff --git a/src/main/java/cn/octopusyan/alistgui/util/alert/AlertBuilder.java b/src/main/java/cn/octopusyan/alistgui/util/alert/AlertBuilder.java index 47d9ea3..f1aafd1 100644 --- a/src/main/java/cn/octopusyan/alistgui/util/alert/AlertBuilder.java +++ b/src/main/java/cn/octopusyan/alistgui/util/alert/AlertBuilder.java @@ -1,18 +1,80 @@ package cn.octopusyan.alistgui.util.alert; -import javafx.scene.control.Alert; -import javafx.scene.control.ButtonType; +import javafx.scene.control.*; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; import javafx.stage.Window; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; /** * @author octopus_yan */ public class AlertBuilder extends BaseBuilder { - public AlertBuilder(Alert alert, Window owner) { - super(alert, owner); + public AlertBuilder(Window owner, Alert.AlertType alertType) { + super(new Alert(alertType), owner); + } + + public AlertBuilder buttons(String... buttons) { + dialog.getButtonTypes().addAll(getButtonList(buttons)); + return this; + } + + public AlertBuilder exception(Exception ex) { + dialog.setTitle("Exception Dialog"); + dialog.setHeaderText(ex.getClass().getSimpleName()); + dialog.setContentText(ex.getMessage()); + + // 创建可扩展的异常。 + var sw = new StringWriter(); + var pw = new PrintWriter(sw); + ex.printStackTrace(pw); + var exceptionText = sw.toString(); + + var label = new Label("The exception stacktrace was :"); + + var textArea = new TextArea(exceptionText); + textArea.setEditable(false); + textArea.setWrapText(true); + + textArea.setMaxWidth(Double.MAX_VALUE); + textArea.setMaxHeight(Double.MAX_VALUE); + GridPane.setVgrow(textArea, Priority.ALWAYS); + GridPane.setHgrow(textArea, Priority.ALWAYS); + + var expContent = new GridPane(); + expContent.setMaxWidth(Double.MAX_VALUE); + expContent.add(label, 0, 0); + expContent.add(textArea, 0, 1); + + // 将可扩展异常设置到对话框窗格中。 + dialog.getDialogPane().setExpandableContent(expContent); + return this; + } + + /** + * 获取按钮列表 + * + * @param buttons "Cancel" / "取消" 为取消按钮 + */ + private List getButtonList(String[] buttons) { + if (ArrayUtils.isEmpty(buttons)) return Collections.emptyList(); + + return Arrays.stream(buttons).map((type) -> { + ButtonBar.ButtonData buttonData = ButtonBar.ButtonData.OTHER; + if ("cancel".equals(StringUtils.lowerCase(type)) || "取消".equals(type)) + buttonData = ButtonBar.ButtonData.CANCEL_CLOSE; + return new ButtonType(type, buttonData); + }).collect(Collectors.toList()); } /** diff --git a/src/main/java/cn/octopusyan/alistgui/util/alert/AlertUtil.java b/src/main/java/cn/octopusyan/alistgui/util/alert/AlertUtil.java index eaf8309..722a440 100644 --- a/src/main/java/cn/octopusyan/alistgui/util/alert/AlertUtil.java +++ b/src/main/java/cn/octopusyan/alistgui/util/alert/AlertUtil.java @@ -1,17 +1,9 @@ package cn.octopusyan.alistgui.util.alert; -import javafx.scene.control.*; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.Priority; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; import javafx.stage.Stage; import javafx.stage.Window; -import org.apache.commons.lang3.StringUtils; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; /** * 弹窗工具 @@ -26,109 +18,61 @@ public class AlertUtil { } public static AlertBuilder info(String content) { - AlertBuilder alertBuilder = new AlertBuilder(new Alert(Alert.AlertType.INFORMATION), mOwner); - alertBuilder.content(content).header(null); - return alertBuilder; + return info().content(content).header(null); } public static AlertBuilder info() { - return new AlertBuilder(new Alert(Alert.AlertType.INFORMATION), mOwner); + return alert(Alert.AlertType.INFORMATION); } public static AlertBuilder error(String message) { - AlertBuilder alertBuilder = new AlertBuilder(new Alert(Alert.AlertType.ERROR), mOwner); - alertBuilder.header(null).content(message); - return alertBuilder; + return alert(Alert.AlertType.ERROR).header(null).content(message); } public static AlertBuilder warning() { - return new AlertBuilder(new Alert(Alert.AlertType.WARNING), mOwner); + return alert(Alert.AlertType.WARNING); } public static AlertBuilder exception(Exception ex) { - return new AlertBuilder(exceptionAlert(ex), mOwner); - } - - private static Alert exceptionAlert(Exception ex) { - Alert alert = new Alert(Alert.AlertType.ERROR); - alert.setTitle("Exception Dialog"); - alert.setHeaderText(ex.getClass().getSimpleName()); - alert.setContentText(ex.getMessage()); - - // 创建可扩展的异常。 - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - ex.printStackTrace(pw); - String exceptionText = sw.toString(); - - Label label = new Label("The exception stacktrace was :"); - - TextArea textArea = new TextArea(exceptionText); - textArea.setEditable(false); - textArea.setWrapText(true); - - textArea.setMaxWidth(Double.MAX_VALUE); - textArea.setMaxHeight(Double.MAX_VALUE); - GridPane.setVgrow(textArea, Priority.ALWAYS); - GridPane.setHgrow(textArea, Priority.ALWAYS); - - GridPane expContent = new GridPane(); - expContent.setMaxWidth(Double.MAX_VALUE); - expContent.add(label, 0, 0); - expContent.add(textArea, 0, 1); - - // 将可扩展异常设置到对话框窗格中。 - alert.getDialogPane().setExpandableContent(expContent); - return alert; + return alert(Alert.AlertType.ERROR).exception(ex); } /** * 确认对话框 */ public static AlertBuilder confirm() { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - alert.setTitle("确认对话框"); - return new AlertBuilder(alert, mOwner); + return alert(Alert.AlertType.CONFIRMATION); } /** * 自定义确认对话框

- * "Cancel" OR "取消" 为取消按钮 + * + * @param buttons "Cancel" OR "取消" 为取消按钮 */ public static AlertBuilder confirm(String... buttons) { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + return confirm().buttons(buttons); + } - List buttonList = Arrays.stream(buttons).map((type) -> { - ButtonBar.ButtonData buttonData = ButtonBar.ButtonData.OTHER; - if ("cancel".equals(StringUtils.lowerCase(type)) || "取消".equals(type)) - buttonData = ButtonBar.ButtonData.CANCEL_CLOSE; - return new ButtonType(type, buttonData); - }).collect(Collectors.toList()); - - alert.getButtonTypes().setAll(buttonList); - - return new AlertBuilder(alert, mOwner); + public static AlertBuilder alert(Alert.AlertType type) { + return new AlertBuilder(mOwner, type); } public static TextInputBuilder input(String content) { - TextInputDialog dialog = new TextInputDialog(); - dialog.setContentText(content); - return new TextInputBuilder(dialog, mOwner); + return new TextInputBuilder(mOwner); } public static TextInputBuilder input(String content, String defaultResult) { - TextInputDialog dialog = new TextInputDialog(defaultResult); - dialog.setContentText(content); - return new TextInputBuilder(dialog, mOwner); + return new TextInputBuilder(mOwner, defaultResult).content(content); } @SafeVarargs public static ChoiceBuilder choices(String hintText, T... choices) { - ChoiceDialog dialog = new ChoiceDialog<>(choices[0], choices); - dialog.setContentText(hintText); - return new ChoiceBuilder<>(dialog, mOwner); + return new ChoiceBuilder<>(mOwner, choices).content(hintText); } + public static ProgressBuilder progress() { + return new ProgressBuilder(mOwner); + } public interface OnChoseListener { void confirm(); diff --git a/src/main/java/cn/octopusyan/alistgui/util/alert/BaseBuilder.java b/src/main/java/cn/octopusyan/alistgui/util/alert/BaseBuilder.java index ccb2cf4..e19dbae 100644 --- a/src/main/java/cn/octopusyan/alistgui/util/alert/BaseBuilder.java +++ b/src/main/java/cn/octopusyan/alistgui/util/alert/BaseBuilder.java @@ -13,7 +13,7 @@ import java.util.Objects; * @author octopus_yan */ public abstract class BaseBuilder, D extends Dialog> { - D dialog; + protected D dialog; public BaseBuilder(D dialog, Window mOwner) { this.dialog = dialog; @@ -49,14 +49,19 @@ public abstract class BaseBuilder, D extends Dialog< return (T) this; } + public D getDialog() { + return dialog; + } + public void show() { - if (dialog.isShowing()) { - if (!Objects.equals(dialog.getContentText(), dialog.getContentText())) - dialog.setOnHidden(_ -> show()); - } dialog.showAndWait(); } + public void close() { + if(dialog.isShowing()) + dialog.close(); + } + private Stage getStage() { return (Stage) dialog.getDialogPane().getScene().getWindow(); } diff --git a/src/main/java/cn/octopusyan/alistgui/util/alert/ChoiceBuilder.java b/src/main/java/cn/octopusyan/alistgui/util/alert/ChoiceBuilder.java index 7f79d82..7be7c17 100644 --- a/src/main/java/cn/octopusyan/alistgui/util/alert/ChoiceBuilder.java +++ b/src/main/java/cn/octopusyan/alistgui/util/alert/ChoiceBuilder.java @@ -10,6 +10,12 @@ import java.util.Optional; * @author octopus_yan */ public class ChoiceBuilder extends BaseBuilder, ChoiceDialog> { + + @SafeVarargs + public ChoiceBuilder(Window mOwner, R... choices) { + this(new ChoiceDialog<>(choices[0], choices), mOwner); + } + public ChoiceBuilder(ChoiceDialog dialog, Window mOwner) { super(dialog, mOwner); } @@ -17,7 +23,7 @@ public class ChoiceBuilder extends BaseBuilder, ChoiceDialog /** * AlertUtil.choices */ - public R getChoice(Collection choices) { + public R showAndGetChoice() { Optional result = dialog.showAndWait(); return result.orElse(null); } diff --git a/src/main/java/cn/octopusyan/alistgui/util/alert/ProgressBuilder.java b/src/main/java/cn/octopusyan/alistgui/util/alert/ProgressBuilder.java new file mode 100644 index 0000000..fd3eb5c --- /dev/null +++ b/src/main/java/cn/octopusyan/alistgui/util/alert/ProgressBuilder.java @@ -0,0 +1,70 @@ +package cn.octopusyan.alistgui.util.alert; + +import cn.octopusyan.alistgui.config.Context; +import javafx.beans.binding.Bindings; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.control.*; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.stage.Window; + +/** + * 加载弹窗 + * + * @author octopus_yan + */ +public class ProgressBuilder extends BaseBuilder> { + + public ProgressBuilder(Window mOwner) { + this(new Dialog<>(), mOwner); + } + + public ProgressBuilder(Dialog dialog, Window mOwner) { + super(dialog, mOwner); + + var content = getContent(); + + DialogPane pane = dialog.getDialogPane(); + pane.setContent(content); + pane.getButtonTypes().add(new ButtonType( + Context.getLanguageBinding("label.cancel").get(), + ButtonType.CANCEL.getButtonData() + )); + for (Node child : pane.getChildren()) { + if (child instanceof ButtonBar bar) { + pane.getChildren().remove(child); + break; + } + } + } + + private Pane getContent() { + HBox hBox = new HBox(); + hBox.setPrefWidth(350); + hBox.setAlignment(Pos.CENTER); + hBox.setPadding(new Insets(0, 0, 0, 0)); + + // 取消按钮 + Button cancel = new Button(Context.getLanguageBinding("label.cancel").get()); + cancel.setCancelButton(true); + cancel.setOnAction(_ -> dialog.close()); + + // 进度条 TODO 宽度绑定 + ProgressBar progressBar = new ProgressBar(-1); + progressBar.prefWidthProperty().bind(Bindings.createDoubleBinding( + () -> hBox.widthProperty().get() - cancel.widthProperty().get() - 40, + hBox.widthProperty(), cancel.widthProperty() + )); + + hBox.getChildren().add(progressBar); + hBox.getChildren().add(cancel); + return hBox; + } + + public ProgressBuilder onCancel(Runnable run) { + dialog.setOnCloseRequest(_ -> run.run()); + return this; + } +} diff --git a/src/main/java/cn/octopusyan/alistgui/util/alert/TextInputBuilder.java b/src/main/java/cn/octopusyan/alistgui/util/alert/TextInputBuilder.java index cc264fd..b89058f 100644 --- a/src/main/java/cn/octopusyan/alistgui/util/alert/TextInputBuilder.java +++ b/src/main/java/cn/octopusyan/alistgui/util/alert/TextInputBuilder.java @@ -11,6 +11,15 @@ import java.util.Optional; * @author octopus_yan */ public class TextInputBuilder extends BaseBuilder { + + public TextInputBuilder(Window mOwner) { + this(new TextInputDialog(), mOwner); + } + + public TextInputBuilder(Window mOwner, String defaultResult) { + this(new TextInputDialog(defaultResult), mOwner); + } + public TextInputBuilder(TextInputDialog dialog, Window mOwner) { super(dialog, mOwner); }