diff --git a/core/src/main/java/com/tlcsdm/core/javafx/controlsfx/FxAction.java b/core/src/main/java/com/tlcsdm/core/javafx/controlsfx/FxAction.java index f27426d37..c254fc6a8 100644 --- a/core/src/main/java/com/tlcsdm/core/javafx/controlsfx/FxAction.java +++ b/core/src/main/java/com/tlcsdm/core/javafx/controlsfx/FxAction.java @@ -27,17 +27,15 @@ package com.tlcsdm.core.javafx.controlsfx; -import java.util.function.Consumer; - -import org.controlsfx.control.action.Action; - import com.tlcsdm.core.javafx.dialog.ExceptionDialog; import com.tlcsdm.core.javafx.dialog.SystemSettingDialog; import com.tlcsdm.core.javafx.helper.LayoutHelper; import com.tlcsdm.core.util.I18nUtils; - import javafx.event.ActionEvent; import javafx.scene.Node; +import org.controlsfx.control.action.Action; + +import java.util.function.Consumer; /** * controlsfx Action的初始化封装 @@ -207,4 +205,12 @@ public static Action clear(Consumer eventHandler) { public static Action clear(String text, Consumer eventHandler) { return create(text, eventHandler, "/com/tlcsdm/core/static/icon/clear.png"); } + + public static Action logConsole(Consumer eventHandler) { + return logConsole(I18nUtils.get("core.button.logConsole"), eventHandler); + } + + public static Action logConsole(String text, Consumer eventHandler) { + return create(text, eventHandler, "/com/tlcsdm/core/static/icon/console.png"); + } } diff --git a/core/src/main/java/com/tlcsdm/core/javafx/dialog/LogConsoleDialog.java b/core/src/main/java/com/tlcsdm/core/javafx/dialog/LogConsoleDialog.java new file mode 100644 index 000000000..5e614614a --- /dev/null +++ b/core/src/main/java/com/tlcsdm/core/javafx/dialog/LogConsoleDialog.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2019, 2023 unknowIfGuestInDream + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of unknowIfGuestInDream, any associated website, nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL UNKNOWIFGUESTINDREAM BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.tlcsdm.core.javafx.dialog; + +import com.tlcsdm.core.javafx.FxApp; +import com.tlcsdm.core.javafx.util.JavaFxSystemUtil; +import com.tlcsdm.core.logging.logback.ConsoleLogAppender; +import com.tlcsdm.core.util.I18nUtils; +import javafx.geometry.Insets; +import javafx.scene.Scene; +import javafx.scene.control.TextArea; +import javafx.scene.layout.Priority; +import javafx.scene.layout.VBox; +import javafx.stage.Modality; +import javafx.stage.Stage; + +/** + * 日志输出控制台 + * 配合logback使用 + *

+ *     
+ *         
+ *             %d{HH:mm:ss.SSS} [%-5level] [%thread] %logger{3600} - %msg%n
+ *         
+ *     
+ *
+ *         
+ *         
+ *     
+ * 
+ * + * @author: unknowIfGuestInDream + * @date: 2023/3/27 21:07 + */ +public class LogConsoleDialog { + + public static void addLogConsole() { + TextArea textArea = new TextArea(); + textArea.setFocusTraversable(true); + textArea.setEditable(false); + ConsoleLogAppender.textAreaList.add(textArea); + Stage newStage = new Stage(); + VBox dialogContainer = new VBox(textArea); + VBox.setVgrow(textArea, Priority.ALWAYS); + dialogContainer.setPadding(new Insets(5.0D)); + dialogContainer.setSpacing(5.0D); + double[] screenSize = JavaFxSystemUtil.getScreenSizeByScale(0.5D, 0.54D); + newStage.setTitle(I18nUtils.get("core.dialog.logConsole.title")); + newStage.setScene(new Scene(dialogContainer, screenSize[0], screenSize[1])); + newStage.setResizable(true); + if (FxApp.appIcon != null) { + newStage.getIcons().add(FxApp.appIcon); + } + newStage.initModality(Modality.NONE); + newStage.show(); + newStage.setOnCloseRequest(event1 -> { + ConsoleLogAppender.textAreaList.remove(textArea); + }); + } +} diff --git a/core/src/main/java/com/tlcsdm/core/javafx/util/GetScreenUtil.java b/core/src/main/java/com/tlcsdm/core/javafx/util/GetScreenUtil.java new file mode 100644 index 000000000..a4fb0e658 --- /dev/null +++ b/core/src/main/java/com/tlcsdm/core/javafx/util/GetScreenUtil.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019, 2023 unknowIfGuestInDream + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of unknowIfGuestInDream, any associated website, nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL UNKNOWIFGUESTINDREAM BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.tlcsdm.core.javafx.util; + +import javafx.scene.Node; + +/** + * @author: unknowIfGuestInDream + * @date: 2023/3/26 21:03 + */ +public class GetScreenUtil { + + public static double getScreenX(Node control) { + return control.getScene().getWindow().getX() + control.getScene().getX() + control.localToScene(0.0D, 0.0D).getX(); + } + + public static double getScreenY(Node control) { + return control.getScene().getWindow().getY() + control.getScene().getY() + control.localToScene(0.0D, 0.0D).getY(); + } + + public static double getWidth(Node control) { + return control.getBoundsInParent().getWidth(); + } + + public static double getHeight(Node control) { + return control.getBoundsInParent().getHeight(); + } +} diff --git a/core/src/main/java/com/tlcsdm/core/javafx/util/TooltipUtil.java b/core/src/main/java/com/tlcsdm/core/javafx/util/TooltipUtil.java new file mode 100644 index 000000000..4c98870ac --- /dev/null +++ b/core/src/main/java/com/tlcsdm/core/javafx/util/TooltipUtil.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2019, 2023 unknowIfGuestInDream + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of unknowIfGuestInDream, any associated website, nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL UNKNOWIFGUESTINDREAM BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.tlcsdm.core.javafx.util; + +import com.tlcsdm.core.javafx.dialog.FxNotifications; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.control.Tooltip; +import javafx.stage.Window; +import javafx.util.Duration; +import org.controlsfx.control.Notifications; +import org.controlsfx.tools.Utils; + +import java.util.Timer; +import java.util.TimerTask; + +/** + * 提示组件,可以使用FxNotifications + * + * @author: unknowIfGuestInDream + * @date: 2023/3/26 20:59 + */ +public class TooltipUtil { + + public static void showToast(String message) { + showToast((Node) null, message); + } + + public static void showToast(Node node, String message) { + Window window = Utils.getWindow(node); + double x; + double y; + if (node != null) { + x = GetScreenUtil.getScreenX(node) + GetScreenUtil.getWidth(node) / 2.0D; + y = GetScreenUtil.getScreenY(node) + GetScreenUtil.getHeight(node); + } else { + x = window.getX() + window.getWidth() / 2.0D; + y = window.getY() + window.getHeight(); + } + + showToast(window, message, 3000L, x, y); + } + + public static void showToast(Window window, String message, long time, double x, double y) { + final Tooltip tooltip = new Tooltip(message); + tooltip.setAutoHide(true); + tooltip.setOpacity(0.9D); + tooltip.setWrapText(true); + tooltip.show(window, x, y); + tooltip.setAnchorX(tooltip.getAnchorX() - tooltip.getWidth() / 2.0D); + tooltip.setAnchorY(tooltip.getAnchorY() / 5.0D); + if (time > 0L) { + new Timer().schedule(new TimerTask() { + @Override + public void run() { + Platform.runLater(tooltip::hide); + } + }, time); + } + } + + public static void showToast(String message, Pos pos) { + showToast((String) null, message, (Node) null, 3.0D, pos, (EventHandler) null, (Object) null, true, true); + } + + public static void showToast(String title, String message) { + showToast(title, message, (Node) null, 3.0D, Pos.TOP_CENTER, (EventHandler) null, (Object) null, true, true); + } + + public static void showToast(String title, String message, Pos pos) { + showToast(title, message, (Node) null, 3.0D, pos, (EventHandler) null, (Object) null, true, true); + } + + public static void showToast(String title, String message, Node graphic, double hideTime, Pos pos, EventHandler onAction, Object owner, boolean isHideCloseButton, boolean isDarkStyle) { + Notifications notificationBuilder = FxNotifications.notifications(Duration.seconds(hideTime), pos).title(title).text(message).graphic(graphic).onAction(onAction); + if (owner != null) { + notificationBuilder.owner(owner); + } + + if (isHideCloseButton) { + notificationBuilder.hideCloseButton(); + } + + if (isDarkStyle) { + notificationBuilder.darkStyle(); + } + + Platform.runLater(() -> { + notificationBuilder.show(); + }); + } +} diff --git a/core/src/main/java/com/tlcsdm/core/logging/logback/ConsoleLogAppender.java b/core/src/main/java/com/tlcsdm/core/logging/logback/ConsoleLogAppender.java new file mode 100644 index 000000000..31bfc8d39 --- /dev/null +++ b/core/src/main/java/com/tlcsdm/core/logging/logback/ConsoleLogAppender.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019, 2023 unknowIfGuestInDream + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of unknowIfGuestInDream, any associated website, nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL UNKNOWIFGUESTINDREAM BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.tlcsdm.core.logging.logback; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.OutputStreamAppender; +import javafx.scene.control.TextArea; + +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * 日志打印控制台 + * + * @author: unknowIfGuestInDream + * @date: 2023/3/26 20:56 + */ +public class ConsoleLogAppender extends OutputStreamAppender { + public final static List