- 桌面应用
- UI组件
【免费下载链接】FlatLaf
FlatLaf - Swing Look and Feel (with Darcula/IntelliJ themes support)
FlatLaf 的 IntelliJ Themes Pack(flatlaf-intellij-themes)是一个官方附加组件,它把 JetBrains Plugin Repository 中大量流行的开源第三方主题(Arc、Dracula、Nord、One Dark、Material Theme UI Lite 等)打包进一个 JAR,并对外提供可直接调用的 Java 类。本文将以该模块的 README 为骨架,结合仓库源码讲解如何引入依赖、通过setup()一行代码启用主题、如何借助FlatAllIJThemes.INFOS构建主题切换器,并深入剖析这些主题类背后的加载与解析原理,读完即可在自己的 Swing 应用中复刻 IntelliJ IDEA 风格的界面。
一、模块定位:它解决了什么问题
FlatLaf 核心自带 FlatLightLaf.java、FlatDarkLaf.java、FlatIntelliJLaf.java、FlatDarculaLaf.java 四套内置外观,视觉风格深受 IntelliJ IDEA 2019.2+ 的 IntelliJ/Darcula 主题影响。而IntelliJ Themes Pack则更进一步:它把 JetBrains 插件生态中由第三方作者维护的.theme.json主题文件"翻译"成 FlatLaf 可以直接渲染的 Look and Feel,让桌面应用一键获得与 JetBrains IDE 插件完全一致的配色方案。
从源码结构看,该模块的组织非常清晰:
flatlaf-intellij-themes/src/main/java/com/formdev/flatlaf/intellijthemes/:29 个普通主题类,每个主题一个FlatXxxIJTheme.java;flatlaf-intellij-themes/src/main/java/com/formdev/flatlaf/intellijthemes/materialthemeuilite/:17 个 Material Theme UI Lite 系列主题类(类名前缀FlatMT);FlatAllIJThemes.java:集中登记全部 46 个主题的元信息(名称、类名、明暗标志);Utils.java:负责从 JAR 内读取.theme.json资源并构造IntelliJTheme对象。
这些主题类全部由代码生成器自动产出(每个文件头部都标注了Generated with com.formdev.flatlaf.demo.intellijthemes.IJThemesClassGenerator,见 IJThemesClassGenerator.java),因此结构高度一致,维护成本极低。
二、获取方式:Maven / Gradle 依赖坐标
官方 README 明确说明,该模块的二进制制品发布在Maven Central。使用 Maven 或 Gradle 时,在构建脚本中声明以下坐标即可:
| 项 | 值 |
|---|---|
| groupId | com.formdev |
| artifactId | flatlaf-intellij-themes |
| version | 以 Maven Central 实际发布版本为准 |
以仓库当前 gradle.properties 中flatlaf.releaseVersion = 3.7.2作为版本参考,Gradle 的依赖写法如下:
dependencies { implementation 'com.formdev:flatlaf:3.7.2' // 核心库 implementation 'com.formdev:flatlaf-intellij-themes:3.7.2' // 主题包 }Maven 写法:
<dependency> <groupId>com.formdev</groupId> <artifactId>flatlaf-intellij-themes</artifactId> <version>3.7.2</version> </dependency>注意:主题包运行期强依赖
com.formdev:flatlaf核心库,因此核心依赖也需要一并引入;具体版本号请以 Maven Central 上对应 artifact 的最新发布版本为准,不要机械照搬示例中的数字。
三、快速上手:一行setup()启用主题
这是官方 README 给出的核心用法:选定一个主题(见下文完整清单),调用它的静态setup()方法。例如启用 Arc - Orange 主题:
FlatArcOrangeIJTheme.setup();在真实应用中,完整的最小示例是:
import com.formdev.flatlaf.intellijthemes.FlatArcOrangeIJTheme; public class Main { public static void main(String[] args) { // 必须在 Swing 组件创建之前调用 FlatArcOrangeIJTheme.setup(); javax.swing.SwingUtilities.invokeLater(() -> { JFrame frame = new JFrame("FlatLaf IntelliJ Theme Demo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(800, 600); frame.setVisible(true); }); } }以 FlatArcOrangeIJTheme.java 为样本,每个主题类都遵循同一套模板,包含四个关键成员:
public class FlatArcOrangeIJTheme extends IntelliJTheme.ThemeLaf { public static final String NAME = "Arc - Orange"; // 主题显示名 // 1. 一键启用:创建实例并交给 FlatLaf.setup() public static boolean setup() { try { return setup(new FlatArcOrangeIJTheme()); } catch (RuntimeException ex) { return false; } } // 2. 注册到 UIManager,便于通过类名切换 public static void installLafInfo() { installLafInfo(NAME, FlatArcOrangeIJTheme.class); } // 3. 构造器:从 JAR 资源加载 .theme.json public FlatArcOrangeIJTheme() { super(Utils.loadTheme("arc-theme-orange.theme.json")); } @Override public String getName() { return NAME; } }关键点解读:
setup()返回boolean:内部调用的是FlatLaf.setup(LookAndFeel),其实现(见 FlatLaf.java)本质是UIManager.setLookAndFeel()的包装,失败时记录 severe 日志并返回false;installLafInfo()可选:其底层调用UIManager.installLookAndFeel()(见 FlatLaf.java),调用后主题会出现在UIManager.getInstalledLookAndFeels()的列表中,适合用类名字符串(而非直接引用类)做切换的场景;- 主题文件是资源而非代码:构造器通过
Utils.loadTheme()从 classpath 读取 JSON,主题数据全部在src/main/resources(打包后位于 JAR 的/com/formdev/flatlaf/intellijthemes/themes/目录下),Java 类只是薄封装。
四、内置主题完整清单
该模块内置的主题分为两组:普通主题与 Material Theme UI Lite 主题。以下清单完整继承自官方 README,类名即真实存在的源码文件。
4.1 普通主题(29 个)
位于包com.formdev.flatlaf.intellijthemes:
| 主题名称 | 类名 |
|---|---|
| Arc | com.formdev.flatlaf.intellijthemes.FlatArcIJTheme |
| Arc - Orange | com.formdev.flatlaf.intellijthemes.FlatArcOrangeIJTheme |
| Arc Dark | com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme |
| Arc Dark - Orange | com.formdev.flatlaf.intellijthemes.FlatArcDarkOrangeIJTheme |
| Carbon | com.formdev.flatlaf.intellijthemes.FlatCarbonIJTheme |
| Cobalt 2 | com.formdev.flatlaf.intellijthemes.FlatCobalt2IJTheme |
| Cyan light | com.formdev.flatlaf.intellijthemes.FlatCyanLightIJTheme |
| Dark Flat | com.formdev.flatlaf.intellijthemes.FlatDarkFlatIJTheme |
| Dark purple | com.formdev.flatlaf.intellijthemes.FlatDarkPurpleIJTheme |
| Dracula | com.formdev.flatlaf.intellijthemes.FlatDraculaIJTheme |
| Gradianto Dark Fuchsia | com.formdev.flatlaf.intellijthemes.FlatGradiantoDarkFuchsiaIJTheme |
| Gradianto Deep Ocean | com.formdev.flatlaf.intellijthemes.FlatGradiantoDeepOceanIJTheme |
| Gradianto Midnight Blue | com.formdev.flatlaf.intellijthemes.FlatGradiantoMidnightBlueIJTheme |
| Gradianto Nature Green | com.formdev.flatlaf.intellijthemes.FlatGradiantoNatureGreenIJTheme |
| Gray | com.formdev.flatlaf.intellijthemes.FlatGrayIJTheme |
| Gruvbox Dark Hard | com.formdev.flatlaf.intellijthemes.FlatGruvboxDarkHardIJTheme |
| Hiberbee Dark | com.formdev.flatlaf.intellijthemes.FlatHiberbeeDarkIJTheme |
| High Contrast | com.formdev.flatlaf.intellijthemes.FlatHighContrastIJTheme |
| Light Flat | com.formdev.flatlaf.intellijthemes.FlatLightFlatIJTheme |
| Material Design Dark | com.formdev.flatlaf.intellijthemes.FlatMaterialDesignDarkIJTheme |
| Monocai | com.formdev.flatlaf.intellijthemes.FlatMonocaiIJTheme |
| Monokai Pro | com.formdev.flatlaf.intellijthemes.FlatMonokaiProIJTheme |
| Nord | com.formdev.flatlaf.intellijthemes.FlatNordIJTheme |
| One Dark | com.formdev.flatlaf.intellijthemes.FlatOneDarkIJTheme |
| Solarized Dark | com.formdev.flatlaf.intellijthemes.FlatSolarizedDarkIJTheme |
| Solarized Light | com.formdev.flatlaf.intellijthemes.FlatSolarizedLightIJTheme |
| Spacegray | com.formdev.flatlaf.intellijthemes.FlatSpacegrayIJTheme |
| Vuesion | com.formdev.flatlaf.intellijthemes.FlatVuesionIJTheme |
| Xcode-Dark | com.formdev.flatlaf.intellijthemes.FlatXcodeDarkIJTheme |
4.2 Material Theme UI Lite(17 个)
位于子包com.formdev.flatlaf.intellijthemes.materialthemeuilite,类名前缀统一为FlatMT:
| 主题名称 | 类名 |
|---|---|
| Arc Dark (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTArcDarkIJTheme |
| Atom One Dark (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTAtomOneDarkIJTheme |
| Atom One Light (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTAtomOneLightIJTheme |
| Dracula (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTDraculaIJTheme |
| GitHub (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTGitHubIJTheme |
| GitHub Dark (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTGitHubDarkIJTheme |
| Light Owl (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTLightOwlIJTheme |
| Material Darker (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMaterialDarkerIJTheme |
| Material Deep Ocean (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMaterialDeepOceanIJTheme |
| Material Lighter (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMaterialLighterIJTheme |
| Material Oceanic (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMaterialOceanicIJTheme |
| Material Palenight (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMaterialPalenightIJTheme |
| Monokai Pro (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMonokaiProIJTheme |
| Moonlight (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMoonlightIJTheme |
| Night Owl (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTNightOwlIJTheme |
| Solarized Dark (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTSolarizedDarkIJTheme |
| Solarized Light (Material) | com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTSolarizedLightIJTheme |
Material 系列的主题文件存放于资源目录themes/material-theme-ui-lite/下,这一点可以从 materialthemeuilite/Utils.java 的资源路径中确认。以 FlatMTArcDarkIJTheme.java 为例,它加载的资源是"Arc Dark.theme.json",显示名为"Arc Dark (Material)"——即命名冲突时通过(Material)后缀区分。
五、源码级原理剖析
5.1 资源加载:Utils.loadTheme()
普通主题的 Utils.java 实现非常精简:
static IntelliJTheme loadTheme(String name) { try { return new IntelliJTheme(Utils.class.getResourceAsStream( "/com/formdev/flatlaf/intellijthemes/themes/" + name)); } catch (IOException ex) { String msg = "FlatLaf: Failed to load IntelliJ theme '" + name + "'"; LoggingFacade.INSTANCE.logSevere(msg, ex); throw new RuntimeException(msg, ex); } }它通过 classpath 资源路径定位.theme.json文件;加载失败时先通过 LoggingFacade 记录 severe 日志,再抛出RuntimeException——这正是主题类setup()中catch (RuntimeException ex)捕获并返回false的来源。
5.2 JSON 解析与属性映射:IntelliJTheme
核心解析逻辑位于 IntelliJTheme.java。构造器(约 L120-L137)把.theme.json用 UTF-8 读取并交给com.formdev.flatlaf.json.Json.parse()解析,然后抽取五个顶层节点:
name:主题名称;dark:布尔字符串,决定明暗主题;author:作者信息;colors:命名字典,映射到 FlatLaf 的命名颜色(@xxx变量);ui:组件级 UI 键值,逐条转换为 Swing UI 属性;icons:图标配色信息(如ColorPalette)。
随后applyProperties()(约 L139 起)完成大量"翻译"工作,例如:
- 写入
Component.isIntelliJTheme = true标记; - 根据明暗主题设置按钮阴影宽度(
Button.shadowWidth,暗色为 2、亮色为 1); - 把
@accentBaseColor映射到ColorPalette.accent、ColorPalette.accentColor、ProgressBar.foreground、*.selectionBackground等多个 FlatLaf 键(见 L162-L166),以兼容不同主题作者的命名习惯; - 将
TextField.background扩散到EditorPane、FormattedTextField、PasswordField、TextArea、TextPane等文本组件,弥补 IntelliJ 主题只定义部分组件的空缺; - 处理
*.前缀的通配属性替换(L248-L263); - 对
Button的 start/end 渐变背景做fixStartEnd()修正,还原 FlatLaf 的按钮渲染习惯。
这些适配逻辑正是"第三方 IntelliJ 主题能无缝工作在 Swing 上"的关键——它并不是简单地套用颜色,而是把 IntelliJ 平台的属性语义映射到 Swing 组件属性语义上。
5.3 明暗判定与默认值来源:IntelliJTheme.ThemeLaf
每个主题类都继承IntelliJTheme.ThemeLaf(定义于 IntelliJTheme.java),它本身继承FlatLaf:
public static class ThemeLaf extends FlatLaf { @Override public String getName() { return theme.name; } @Override public boolean isDark() { return theme.dark; } @Override void applyAdditionalProperties(Properties properties) { theme.applyProperties(properties); } @Override protected ArrayList<Class<?>> getLafClassesForDefaultsLoading() { ArrayList<Class<?>> lafClasses = UIDefaultsLoader.getLafClassesForDefaultsLoading(getClass()); lafClasses.add(1, theme.dark ? FlatDarkLaf.class : FlatLightLaf.class); lafClasses.add(2, theme.dark ? FlatDarculaLaf.class : FlatIntelliJLaf.class); return lafClasses; } }这段代码揭示了两个重要事实:
isDark()直接由 JSON 中的dark字段决定,因此主题列表、图标渲染、系统托盘明暗适配等都能自动跟随;- 默认值加载是分层叠加的:主题自身属性优先,随后回落到
FlatDarkLaf/FlatLightLaf,再回落到FlatDarculaLaf/FlatIntelliJLaf,最后是 FlatLaf 基础默认值。这保证了主题 JSON 未覆盖到的组件也能获得风格统一的兜底外观。
5.4 元信息清单:FlatAllIJThemes.INFOS
FlatAllIJThemes.java 用静态数组集中登记全部主题:
public static final FlatIJLookAndFeelInfo[] INFOS = { new FlatIJLookAndFeelInfo("Arc", "com.formdev.flatlaf.intellijthemes.FlatArcIJTheme", false), new FlatIJLookAndFeelInfo("Arc - Orange", "com.formdev.flatlaf.intellijthemes.FlatArcOrangeIJTheme", false), new FlatIJLookAndFeelInfo("Arc Dark", "com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme", true), // ... 共 46 项 };FlatIJLookAndFeelInfo继承自javax.swing.UIManager.LookAndFeelInfo,第三个参数dark用于标记明暗属性。该数组同样由 IJThemesClassGenerator.java 自动生成,与主题类一一对应,任何新增/移除主题都会同步反映在清单中。基于它,应用可以轻松构建"主题选择下拉框"。
六、进阶实战
6.1 用FlatAllIJThemes.INFOS构建主题切换器
不需要为每个主题手写分支,遍历INFOS即可生成候选列表:
import com.formdev.flatlaf.IntelliJTheme; import com.formdev.flatlaf.intellijthemes.FlatAllIJThemes; import javax.swing.*; JComboBox<FlatAllIJThemes.FlatIJLookAndFeelInfo> combo = new JComboBox<>(); for (FlatAllIJThemes.FlatIJLookAndFeelInfo info : FlatAllIJThemes.INFOS) combo.addItem(info); combo.addActionListener(e -> { FlatAllIJThemes.FlatIJLookAndFeelInfo info = (FlatAllIJThemes.FlatIJLookAndFeelInfo) combo.getSelectedItem(); try { // 通过类名字符串切换 Look and Feel UIManager.setLookAndFeel(info.getClassName()); } catch (Exception ex) { ex.printStackTrace(); } });配合FlatAnimatedLafChange.showSnapshot()与hideSnapshotWithAnimation()(见 FlatAnimatedLafChange.java)可实现丝滑的明暗主题过渡动画。仓库的 FlatLaf Demo 正是这样实现的:主题列表、明暗筛选(all/light/dark)与插件/源码跳转按钮都在 IJThemesPanel.java 中,切换后调用FlatLaf.updateUI()统一刷新所有已创建组件。
6.2 在 FlatLaf Demo 中体验全部主题
官方 README 推荐直接使用 FlatLaf Demo 试用这些主题。Demo 的 FlatLafDemo.java 提供完整的主题浏览界面,支持:
- 按明暗过滤主题列表;
- 一键跳转到主题的插件主页与源码仓库;
- 加载当前工作目录下的自定义
.theme.json/.properties主题文件(对应 IJThemesManager.java 中的loadThemesFromDirectory(),它扫描工作目录下以.theme.json或.properties结尾的文件)。
6.3 加载自定义 IntelliJ 主题文件
该模块内置主题是静态打包的;如果你从 JetBrains 插件市场拿到了新的.theme.json,不必改代码,可以用核心库的IntelliJThemeAPI 动态加载:
import com.formdev.flatlaf.IntelliJTheme; import java.io.FileInputStream; IntelliJTheme.setup(new FileInputStream("my-theme.theme.json"));IntelliJTheme.setup(InputStream)(见 IntelliJTheme.java)会解析流、创建ThemeLaf实例并完成安装;输入流会自动关闭。也可以先IntelliJTheme.createLaf(in)拿到FlatLaf实例,再自行决定FlatLaf.setup(laf)或UIManager.setLookAndFeel(laf)。
6.4 运行期安装多个主题供用户挑选
调用每个主题类的installLafInfo(),可把多个主题注册进UIManager,之后就能用字符串类名在任意时刻切换:
FlatArcIJTheme.installLafInfo(); FlatDraculaIJTheme.installLafInfo(); FlatNordIJTheme.installLafInfo(); UIManager.setLookAndFeel("com.formdev.flatlaf.intellijthemes.FlatDraculaIJTheme");七、Java 模块化(JPMS)支持
该模块声明了标准 Java 模块com.formdev.flatlaf.intellijthemes(见 module-info.java):
module com.formdev.flatlaf.intellijthemes { requires java.desktop; requires com.formdev.flatlaf; exports com.formdev.flatlaf.intellijthemes; exports com.formdev.flatlaf.intellijthemes.materialthemeuilite; }在模块化应用(如flatlaf-testing-modular-app)中,只需在module-info.java里添加requires com.formdev.flatlaf.intellijthemes;即可使用;两个包均已导出,普通类路径(classpath)使用则无需任何额外配置。
八、使用建议与注意事项
- 在组件创建之前调用
setup():Look and Feel 必须在任何 Swing 组件实例化之前安装,否则已创建组件的 UI 不会自动更新(需要手动SwingUtilities.updateComponentTreeUI())。 setup()返回false时不要静默忽略:通常是主题资源缺失或 JSON 解析失败,可结合LoggingFacade输出的 severe 日志排查;请确认 JAR 完整打入依赖,且资源目录未被排除。- 明暗属性已自动处理:
ThemeLaf.isDark()来自 JSON 的dark字段,如需在应用内做主题感知逻辑(如图标切换),直接判断((FlatLaf)UIManager.getLookAndFeel()).isDark()即可。 - 主题文件资源路径是固定的:普通主题在
/com/formdev/flatlaf/intellijthemes/themes/,Material 系列在themes/material-theme-ui-lite/子目录,不要自行移动或重命名 JAR 内资源。 - 与核心库版本保持同步:主题包与核心库通常同版本发布,混用跨版本依赖可能导致属性映射差异,建议二者使用相同版本。
九、小结
FlatLaf IntelliJ Themes Pack 以极低的使用成本(一个依赖 + 一行setup())把 JetBrains 生态中最受欢迎的第三方主题引入 Swing 应用。其底层由 IntelliJTheme 负责.theme.json的解析与属性映射,由模板化生成的 46 个主题类提供统一 API,由 FlatAllIJThemes 提供可枚举的元信息清单——理解这三层结构,你就能在应用中轻松实现主题选择、动态切换乃至自定义 IntelliJ 主题加载,让桌面软件拥有 JetBrains 级别的现代观感。
- 桌面应用
- UI组件
【免费下载链接】FlatLaf
FlatLaf - Swing Look and Feel (with Darcula/IntelliJ themes support)
相关推荐
FlatLaf 字体包使用指南:在 Swing 应用中集成 JetBrains Mono 等宽字体
FlatLaf 字体包使用指南:在 Swing 应用中集成 JetBrains Mono 等宽字体 导读 JetBrains Mono 是 JetBrains
桌面应用UI组件FlatLaf与IntelliJ平台主题的完美集成:打造现代化Java Swing应用的终极指南
FlatLaf与IntelliJ平台主题的完美集成:打造现代化Java Swing应用的终极指南 FlatLaf是一款功能强大的Swing外观组件库,它能够帮助
桌面应用UI组件FlatLaf Fonts 字体包使用指南:在 Swing 应用中集成 Inter、JetBrains Mono、Roboto 与 Roboto Mono
FlatLaf Fonts 字体包使用指南:在 Swing 应用中集成 Inter、JetBrains Mono、Roboto 与 Roboto Mono 本篇
桌面应用UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考