From e8cf4e42eaf35fbd7ec6868dbd15c3aede81c5e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=AE=B6=E8=AE=AD?= Date: Sat, 1 Aug 2026 13:37:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=95=E5=85=A5=E7=BB=9F=E4=B8=80=20Feather?= =?UTF-8?q?=20=E5=9B=BE=E6=A0=87=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 12 +++++++ .../workutils/system/ui/icon/AppIcon.java | 31 +++++++++++++++++++ .../workutils/system/ui/icon/IconFactory.java | 25 +++++++++++++++ .../system/ui/icon/IconFactoryTest.java | 31 +++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 src/main/java/com/example/workutils/system/ui/icon/AppIcon.java create mode 100644 src/main/java/com/example/workutils/system/ui/icon/IconFactory.java create mode 100644 src/test/java/com/example/workutils/system/ui/icon/IconFactoryTest.java diff --git a/pom.xml b/pom.xml index b5394f4..d1a2753 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,7 @@ 17.0.15 2.0.1 + 12.4.0 C:\Program Files\Java\jdk-17 @@ -171,6 +172,17 @@ ${javafx.version} + + org.kordamp.ikonli + ikonli-javafx + ${ikonli.version} + + + org.kordamp.ikonli + ikonli-feather-pack + ${ikonli.version} + + io.github.mkpaz diff --git a/src/main/java/com/example/workutils/system/ui/icon/AppIcon.java b/src/main/java/com/example/workutils/system/ui/icon/AppIcon.java new file mode 100644 index 0000000..f1f467d --- /dev/null +++ b/src/main/java/com/example/workutils/system/ui/icon/AppIcon.java @@ -0,0 +1,31 @@ +package com.example.workutils.system.ui.icon; + +import org.kordamp.ikonli.Ikon; +import org.kordamp.ikonli.feather.Feather; + +public enum AppIcon { + MENU(Feather.MENU), + SETTINGS(Feather.SETTINGS), + CHEVRON_LEFT(Feather.CHEVRON_LEFT), + CHEVRON_RIGHT(Feather.CHEVRON_RIGHT), + GIT_SYNC(Feather.REFRESH_CW), + GIT_REVIEW(Feather.GIT_BRANCH), + DIFF(Feather.COLUMNS), + SQL_EXPORT(Feather.DATABASE), + MYBATIS_GENERATOR(Feather.CODE), + SCANNER(Feather.SEARCH), + API_DOC(Feather.FILE_TEXT), + EXPORT(Feather.DOWNLOAD), + CANCEL(Feather.X), + APP(Feather.TOOL); + + private final Feather glyph; + + AppIcon(Feather glyph) { + this.glyph = glyph; + } + + public Ikon glyph() { + return glyph; + } +} diff --git a/src/main/java/com/example/workutils/system/ui/icon/IconFactory.java b/src/main/java/com/example/workutils/system/ui/icon/IconFactory.java new file mode 100644 index 0000000..de06cf0 --- /dev/null +++ b/src/main/java/com/example/workutils/system/ui/icon/IconFactory.java @@ -0,0 +1,25 @@ +package com.example.workutils.system.ui.icon; + +import org.kordamp.ikonli.javafx.FontIcon; + +import java.util.Objects; + +public final class IconFactory { + private static final int BUTTON_ICON_SIZE = 16; + private static final String ICON_STYLE_CLASS = "app-icon"; + + private IconFactory() { + } + + public static FontIcon create(AppIcon icon, int size) { + FontIcon node = FontIcon.of(Objects.requireNonNull(icon, "icon must not be null").glyph(), size); + node.getStyleClass().add(ICON_STYLE_CLASS); + return node; + } + + public static FontIcon createButtonIcon(AppIcon icon, String accessibleText) { + FontIcon node = create(icon, BUTTON_ICON_SIZE); + node.setAccessibleText(Objects.requireNonNull(accessibleText, "accessibleText must not be null")); + return node; + } +} diff --git a/src/test/java/com/example/workutils/system/ui/icon/IconFactoryTest.java b/src/test/java/com/example/workutils/system/ui/icon/IconFactoryTest.java new file mode 100644 index 0000000..3cc234f --- /dev/null +++ b/src/test/java/com/example/workutils/system/ui/icon/IconFactoryTest.java @@ -0,0 +1,31 @@ +package com.example.workutils.system.ui.icon; + +import org.junit.jupiter.api.Test; +import org.kordamp.ikonli.feather.Feather; +import org.kordamp.ikonli.javafx.FontIcon; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class IconFactoryTest { + + @Test + void mapsEverySemanticIconToFeatherAndCreatesAccessibleNodes() { + for (AppIcon icon : AppIcon.values()) { + assertInstanceOf(Feather.class, icon.glyph()); + + FontIcon node = IconFactory.createButtonIcon(icon, "系统设置"); + assertEquals(16, node.getIconSize()); + assertEquals("系统设置", node.getAccessibleText()); + } + } + + @Test + void createsSemanticIconWithRequestedSizeAndSharedStyle() { + FontIcon node = IconFactory.create(AppIcon.MENU, 20); + + assertEquals(20, node.getIconSize()); + assertTrue(node.getStyleClass().contains("app-icon")); + } +}