引入统一 Feather 图标系统

This commit is contained in:
张家训
2026-08-01 13:37:16 +08:00
parent 06667475b8
commit e8cf4e42ea
4 changed files with 99 additions and 0 deletions
+12
View File
@@ -27,6 +27,7 @@
<javafx.version>17.0.15</javafx.version>
<!-- AtlantaFX 版本 -->
<atlantafx.version>2.0.1</atlantafx.version>
<ikonli.version>12.4.0</ikonli.version>
<!-- 指定 JDK 17 路径(系统默认 JDK 8 时启用) -->
<jdk17.home>C:\Program Files\Java\jdk-17</jdk17.home>
</properties>
@@ -171,6 +172,17 @@
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-javafx</artifactId>
<version>${ikonli.version}</version>
</dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-feather-pack</artifactId>
<version>${ikonli.version}</version>
</dependency>
<!-- ==================== AtlantaFX 现代 UI 主题 ==================== -->
<dependency>
<groupId>io.github.mkpaz</groupId>
@@ -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;
}
}
@@ -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;
}
}
@@ -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"));
}
}