今天继续来Swing LAF的学习, 希望对有兴趣的新的朋友有帮助。我们为什么要学习LAF呢,其实很简单,就是为了能简单快速地给Swing “化一个漂亮的妆”。可能很多新学的朋友,都喜欢Override 组件的paintComponent(Graphics) 或者paint(Graphics)来完成对Swing的"美化"。其实,如果真的这样做了,那么这个组件的重用性变得很低了,而且代码的可读性也变得很差。更头痛的是,这样的组件如何快速方便切换Style呢(就像网页中的皮肤,可以快速切换)?闲话不多说了,下面来回顾上一篇文章。
看完了第一篇《LAF让Swing漂亮起来》的朋友可能会产生了问题:
1) UIManager.put(String sKey, Object oVal) 这种方法只能用来改变某种类型组件的风格。如:UIManager.put("Button.foreground", Colo.red) 改变了整个APP中所有Button的前景色。但是有些朋友会问,如果只是想改变某个Button的风格呢? 好,下面这篇文章中的例子也会解决。
2)上一篇文章中,有些朋友问到如何来改变渐变,在这篇文章中的例子都会解决。
这篇文章主要是如何使用Nimbus LAF来快速定制自己喜欢的组件。闲话不多说了,一切都在代码中,
下面的代码,没有进行过多的整理,为了方便大家运行,我直接在一个类里面写了。
package org.dui.laf; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.LinearGradientPaint; import java.awt.Paint; import java.awt.Point; import java.lang.reflect.Field; import java.lang.reflect.Method; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.UIDefaults; import javax.swing.UIManager; import javax.swing.plaf.ColorUIResource; import javax.swing.plaf.synth.SynthLookAndFeel; import javax.swing.plaf.synth.SynthStyle; /** * <code>LAFDemo01</code> demonstrates how to use <code>Nimbus</code> to custom * your own style. * * @author Jimmy(SZ) * * @since <i>v1.0.0 (Apr 12, 2013)</i> */ public class LAFDemo03 extends JPanel { private static final long serialVersionUID = 1L; { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); } catch (Exception e) { e.printStackTrace(); } } /** * Create an instance */ public LAFDemo03() { initGUI(); } /** * Initial the ui * * @since <i>v1.0.0 (Apr 12,2013)</i> */ public void initGUI() { this.setLayout(new GridLayout(7, 2)); this.add(new JLabel("Button1 : ")); this.add(new JButton("Default style")); this.add(new JLabel("Button2 : ")); this.add(new JButton("Default style")); this.add(new JLabel("Button3 : ")); this.add(new JButton("Default style")); this.add(new JLabel("Button4 : ")); JButton btn = new JButton("My style is changed."); this.add(btn); btn.setBorder(BorderFactory.createLineBorder(new Color(0 , 33, 106))); changeStyle(btn, "Button[Enabled].textForeground", new ColorUIResource(Color.darkGray)); changeStyle(btn, "Button.font", new Font("宋体", Font.BOLD, 16)); changeStyle(btn, "Button[Enabled].backgroundPainter", new GradientPainter(true, new Color(33, 249, 249), new Color(238, 4, 238))); changeStyle(btn, "Button[Focused+Pressed].backgroundPainter", new GradientPainter(true, new Color(238, 4, 238), new Color(33, 249, 249) )); changeStyle(btn, "Button[MouseOver].backgroundPainter", new GradientPainter(true, new Color(238, 4, 238), new Color(33, 249, 249) )); changeStyle(btn, "Button[Focused+MouseOver].backgroundPainter", new GradientPainter(false, Color.cyan, Color.blue)); SwingUtilities.updateComponentTreeUI(btn); } /** * Changed the style of single component specified by <code>oComp</code> * * @param oComp * @param sKey * @param oVal * * @since <i>v1.0.0 (Apr 12,2013)</i> */ private void changeStyle(JComponent oComp, String sKey, Object oVal) { UIDefaults uiDefaults = (UIDefaults) oComp.getClientProperty("Nimbus.Overrides"); if (uiDefaults == null) { uiDefaults = createDefs(); } uiDefaults.put(sKey, oVal); oComp.putClientProperty("Nimbus.Overrides.InheritDefaults", false); oComp.putClientProperty("Nimbus.Overrides", uiDefaults); reloadDefault(oComp); } /** * Refresh the synch style. * @param c * * @since <i>v1.0.0 (Apr 12,2013)</i> */ protected static void reloadDefault(JComponent c) { try { SynthStyle oStyle = SynthLookAndFeel.getStyle(c, SynthLookAndFeel.getRegion(c)); Field oStyleField = oStyle.getClass().getDeclaredField("values"); oStyleField.setAccessible(true); oStyleField.set(oStyle, null); Method oStyleMethod = oStyle.getClass().getDeclaredMethod("validate", new Class<?>[] {}); oStyleMethod.setAccessible(true); oStyleMethod.invoke(oStyle, new Object[] {}); } catch (Exception ex) { ex.printStackTrace(); } } /** * @return * * @since <i>v1.0.0 (Apr 12,2013)</i> * */ private UIDefaults createDefs() { return new UIDefaults(); } /** * Launch the app * * @param args * @since <i>v1.0.0 (Apr 12 ,2013)</i> */ public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame oFrame = new JFrame(); oFrame.setContentPane(new LAFDemo03()); oFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); oFrame.setTitle("LAFDemo01"); oFrame.setSize(400, 400); oFrame.setLocationRelativeTo(null); oFrame.setVisible(true); } }); } /** * Simple GradientPainter * * Note that the performance of <code>GradientPainter</code> is poor. It will be improved in the coming days. * * @author Jimmy(SZ) * * @since <i>v1.0.0 (Apr 12,2013)</i> */ static class GradientPainter extends PainterAdaptor { Paint oPaint; Color[] m_aClr; boolean m_bVertical ; public GradientPainter(boolean bVertical, Color... aClr) { m_aClr = aClr; m_bVertical = bVertical; } @Override public void paint(Graphics2D g, JComponent object, int iW, int iH) { Paint oldPaint = g.getPaint(); int iLen = m_aClr.length; float[] aFra = new float[iLen]; float iAct = (1f / iLen); for (int i = 0; i < iLen; ++i) { aFra[i] = i * iAct; } Point ptEnd = null; if(m_bVertical){ ptEnd = new Point(0 , iH); }else{ ptEnd = new Point(iW , 0); } oPaint = new LinearGradientPaint(new Point(0 , 0),ptEnd , aFra, m_aClr); g.setPaint(oPaint); g.fillRect(0, 0, iW, iH); // restore the old paint g.setPaint(oldPaint); } } } class PainterAdaptor implements com.sun.java.swing.Painter<JComponent> { @Override public void paint(Graphics2D g, JComponent object, int iW, int iH) { } }
运行上面的例子大家可以看到:
看了上面例子,只是仅仅改变了一个Button的style,但是我觉得大家会依葫芦画瓢,其实其他组件也一样的。
总结一下不可缺少的步骤:
1 ) UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
2 ) 通过key-value的方式来改变Nimbus.Overrides的内容
3 ) validate synth style. 如#reloadDefault(JComponent)
4 ) SwingUtilities.updateComponentTreeUI(JComponent);
今天就学习到这里,欢迎来提意见 或者讨论。不懂的朋友可以留言,或者Google。想喷的朋友,也欢迎,毕竟写作能力有限,一个憨厚的程序员Jimmy.huang。
相关推荐
在本文中,我们将深入探讨如何使用Look and Feel(LAF)技术使Swing应用程序看起来更加美观,特别是通过创建一个模拟闪烁的股票行情系统。Swing是Java中的一个GUI工具包,虽然功能强大,但默认的界面风格可能并不...
NULL 博文链接:https://jimmyhr.iteye.com/blog/1845824
然而,Swing的默认LAF可能在视觉效果上显得较为单调,这就是Substance LAF的价值所在——它提供了多样的主题和高度可定制的外观,使Java应用看起来更加现代和专业。 在使用Substance LAF时,开发者可以轻松地切换...
jasmine-gradle-plugin.zip,使用jasmine在现场测试javascript,并作为buildgradle支持运行jasmine javascript规范的一部分。加上jslint
Java提供了多种内置的LAF,如Windows LAF、Motif LAF和Nimbus LAF等。开发者可以根据自己的需求选择不同的LAF,以改变程序的界面风格。Netbeans-dark-laf就是针对NetBeans IDE定制的一款深色LAF,旨在提供更为舒适的...
laf-win10.jar
java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包
《Python库:深入理解laf-fabric-4.5.25》 在Python的世界里,库是构建强大应用程序的基础,它们提供了丰富的功能,让开发者能够高效地完成各种任务。今天我们将聚焦于一个名为“laf-fabric”的库,通过其4.5.25...
Java Swing 是Java提供的一种用于创建桌面应用程序用户界面的库,它允许开发者构建功能丰富的图形用户界面(GUI)。在Swing中,LookAndFeel是一个关键概念,它决定了应用程序的视觉样式,包括控件的外观、颜色、字体...
laf 是云开发平台,提供云函数、云数据库、云存储等开箱即用的应用资源。让开发者快速释放创意。ChatGPT 自动写函数,秒级上线,世界上只有两种 serverless,30 秒上线的 和 30 秒劝退的!
Darklaf-具有主题感的Swing外观 该项目基于Swing的外观。 屏幕截图 用法与 可以在找到所有功能的列表。 LaF与Java> = 1.8兼容(您需要> = 1.9才能获得适当的缩放比例)。 您可以在weisj.github.io/darklaf-docs上...
用于java swing包的美化 里面有配套的四个类 trident-7.3-swing.jar substance-7.3.jar laf-widget-7.3.jar laf-plugin-7.3.jar
Swing样式大全 主题 皮肤包(全56种经典)LookAndFeel 本样式合集共有56种样式,包括使用说明和实例,即装即用 5种经典的Alloy和liquidlnf包 7种另类风格和实例包 20种样式风格包 24种样式合集包
- `javax.swing.plaf`:Swing的外观和感觉(LAF)包,包含不同外观风格的实现,如基本的、金属的、多层的和合成的LAF。 - `javax.swing.table`:用于构建表格数据的组件。 - `javax.swing.text`:用于文本显示和编辑...
使用Laf云平台将ChatGPT接入微信公众号.zip
SwingSet + GenLAF (version 1) 是一个基于Java Swing库的用户界面示例集合,配合GenLAF(Generic Look and Feel)库,用于展示不同外观和感觉(LookAndFeel)的效果。在Java编程中,Swing是用于构建图形用户界面...
Swing框架中的UI Delegate机制是Swing组件能够动态切换外观和感觉(Look and Feel, LAF)的关键。LAF决定了组件的视觉样式和交互行为,让应用程序可以根据不同的平台或用户需求呈现不同的界面风格。Swing提供了默认...
Win10 风格 Swing 的 LookAndFeel(即皮肤),由本人自己开发, 完整版含有3套不同色调win7风格的皮肤和2套不同色调win10风格的皮肤 本次发布的是一个缩减版本,只含一套亮色调Win10风格皮肤 使用方法:在Swing项目...