Java GUI美化 Swing使用FlatLaf主题 解决FlatDarkLaf主题不生效的问题
常见设置Java Swing LookAndFeel方式
一般使用UIManager.setLookAndFeel()方法来设置外观,如下所示:
1 | // 设置外观 |
经过我的测试,发现这种方式可以设置两种类型的外观。
一种是跨平台的外观,这是默认的外观。如果想使用这种方式,可以不设置。
1 | UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); |
跨平台的外观如下图所示:
另一种就是和系统一样的外观:
1 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); |
如下图所示:
这种方式比上面的跨平台外观要好看一些。
如果你想要界面更加美观,可以使用FlatLaf主题。
FlatLaf主题
下载FlatLaf主题
到maven仓库下载:https://mvnrepository.com/artifact/com.formdev/flatlaf/1.5
如何使用
导入jar
Getting started
https://www.formdev.com/flatlaf/
To enable FlatLaf, add following code to your main method before you create any Swing component:
1
2 FlatLightLaf.install();
// create UI here...or
1
2
3
4
5
6 try {
UIManager.setLookAndFeel( new FlatLightLaf() );
} catch( Exception ex ) {
System.err.println( "Failed to initialize LaF" );
}
// create UI here...
需要注意的是,如果你使用的是第一种方式FlatLightLaf.install();
。install方法已经不适用了,应该使用setup()
方法.也就是改成:
1 | FlatLightLaf.setup(); |
外观不生效或部分生效的问题
还有就是,如果光写这条语句而已,可能只是部分组件起作用的,有些组件还是原来的外观。还需要给所有的组件都设置上该主题。
这是因为你先创建了组件,然后才使用这条语句来设置外观,造成的。
方案1:先设置外观再创建组件
应该先设置外观,然后再创建组件
把FlatLightLaf.setup();
写到静态代码块中,并把这个静态代码块定义在类的前面。
因为静态代码块最先加载,从而保证在创建UI组件时,外观已经设置好了,组件将会以我们事先创建好的外观显示。
完美的使用FlatLaf外观方式
如下所示:
1 | public class MainFrom { |
美化后的外观如下
这种方式比系统默认的要更加美观一些。
方案2:先创建组件再更改外观 不推荐使用这种方式
https://www.docs4dev.com/docs/zh/java/java8/tutorials/uiswing-lookandfeel-plaf.html
即使程序的 GUI 可见,您也可以使用setLookAndFeel更改 L&F。要使现有组件反映新的 L&F,请对每个顶级容器调用一次SwingUtilities updateComponentTreeUI方法。然后,您可能希望调整每个顶级容器的大小,以反映其包含的组件的新大小。例如:
1
2
3 UIManager.setLookAndFeel(lnfName);
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
代码示例
我测试有效的方式如下:
在main方法中写上如下代码:
public static void main(String[] args) { MainFrom mainFrom = new MainFrom(); JFrame frame = new JFrame("MainFrom"); // 设置面板到窗体上 frame.setContentPane(mainFrom.panel); // // 设置关闭按钮功能 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // frame.setType(Window.Type.NORMAL); // frame.setType(Window.Type.POPUP); // 不显示任务栏 frame.setType(Window.Type.UTILITY); // 不显示标题栏,最小化,关闭按钮 frame.setUndecorated(true); // 永远置顶 frame.setAlwaysOnTop(true); // 设置初始界面 mainFromSetting(mainFrom, frame); // 设置主题 // FlatLightLaf.setup(); FlatDarkLaf.setup(); // 给所有的组件都使用该主题 SwingUtilities.updateComponentTreeUI(frame); // 最合适的方式显示 frame.pack(); // 显示窗体 frame.setVisible(true); }
成果示例
使用暗色主题成功效果:
如果你没有写SwingUtilities.updateComponentTreeUI(frame);
,虽然你使用的是暗色的主题,但是运行结果不会显示暗色主题,默认使用的是亮色的主题
public static void main(String[] args) { ...... // 设置主题 FlatDarkLaf.setup(); // FlatLightLaf.setup(); // 给所有的组件都使用该主题 // SwingUtilities.updateComponentTreeUI(frame); // 最合适的方式显示 frame.pack(); // 显示窗体 frame.setVisible(true); }
此时显示的效果如下图所示:
为什么不推荐先创建组件再更改外观
先创建组件,然后再更改外观,可能会造成其他的奇奇怪怪的问题。
java.awt.IllegalComponentStateException: component must be showing on the screen to determine its location
这是使用这种方式造成的问题:
1 | Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: component must be showing on the screen to determine its location |
解决方案
使用第一种方案,也就是先设置外观,再创建UI组件,这样就不会有这样的问题。
参考资料
https://www.docs4dev.com/docs/zh/java/java8/tutorials/uiswing-lookandfeel-plaf.html
https://github.com/JFormDesigner/FlatLaf
https://mvnrepository.com/artifact/com.formdev/flatlaf/1.5