`

LAF让Swing漂亮起来02 - Nimbus LAF(进阶篇)

阅读更多

      今天继续来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。

  • 大小: 31.2 KB
1
0
分享到:
评论

相关推荐

    LAF让Swing漂亮起来03 (模拟闪烁的股票行情系統)

    在本文中,我们将深入探讨如何使用Look and Feel(LAF)技术使Swing应用程序看起来更加美观,特别是通过创建一个模拟闪烁的股票行情系统。Swing是Java中的一个GUI工具包,虽然功能强大,但默认的界面风格可能并不...

    LAF让Java Swing漂亮起来

    NULL 博文链接:https://jimmyhr.iteye.com/blog/1845824

    substance7.1(全) Swing LAF

    然而,Swing的默认LAF可能在视觉效果上显得较为单调,这就是Substance LAF的价值所在——它提供了多样的主题和高度可定制的外观,使Java应用看起来更加现代和专业。 在使用Substance LAF时,开发者可以轻松地切换...

    laf-plugin-6.3.zip

    jasmine-gradle-plugin.zip,使用jasmine在现场测试javascript,并作为buildgradle支持运行jasmine javascript规范的一部分。加上jslint

    netbeans-dark-laf:netbeans-dark-laf

    Java提供了多种内置的LAF,如Windows LAF、Motif LAF和Nimbus LAF等。开发者可以根据自己的需求选择不同的LAF,以改变程序的界面风格。Netbeans-dark-laf就是针对NetBeans IDE定制的一款深色LAF,旨在提供更为舒适的...

    laf-win10.jar

    laf-win10.jar

    a03-laf-jdk5-1.1.1.jar

    java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包java皮肤包

    Python库 | laf-fabric-4.5.25.tar.gz

    《Python库:深入理解laf-fabric-4.5.25》 在Python的世界里,库是构建强大应用程序的基础,它们提供了丰富的功能,让开发者能够高效地完成各种任务。今天我们将聚焦于一个名为“laf-fabric”的库,通过其4.5.25...

    laf 是开源的云开发平台,提供云函数、云数据库、云存储等开箱即用的应用资源 让开发者专注于业务开发,无需折腾服务器,快速释放创

    laf 是云开发平台,提供云函数、云数据库、云存储等开箱即用的应用资源。让开发者快速释放创意。ChatGPT 自动写函数,秒级上线,世界上只有两种 serverless,30 秒上线的 和 30 秒劝退的!

    java swing Mac风格的LookAndFeel

    Java Swing 是Java提供的一种用于创建桌面应用程序用户界面的库,它允许开发者构建功能丰富的图形用户界面(GUI)。在Swing中,LookAndFeel是一个关键概念,它决定了应用程序的视觉样式,包括控件的外观、颜色、字体...

    darklaf:Darklaf-基于Darcula-Laf的主题化Swing外观

    Darklaf-具有主题感的Swing外观 该项目基于Swing的外观。 屏幕截图 用法与 可以在找到所有功能的列表。 LaF与Java&gt; = 1.8兼容(您需要&gt; = 1.9才能获得适当的缩放比例)。 您可以在weisj.github.io/darklaf-docs上...

    substance7.3

    用于java swing包的美化 里面有配套的四个类 trident-7.3-swing.jar substance-7.3.jar laf-widget-7.3.jar laf-plugin-7.3.jar

    Swing样式大全 主题 皮肤包(全56种经典)LookAndFeel

    Swing样式大全 主题 皮肤包(全56种经典)LookAndFeel 本样式合集共有56种样式,包括使用说明和实例,即装即用 5种经典的Alloy和liquidlnf包 7种另类风格和实例包 20种样式风格包 24种样式合集包

    The Java Swing tutorial.pdf

    - `javax.swing.plaf`:Swing的外观和感觉(LAF)包,包含不同外观风格的实现,如基本的、金属的、多层的和合成的LAF。 - `javax.swing.table`:用于构建表格数据的组件。 - `javax.swing.text`:用于文本显示和编辑...

    LookAndFeel换肤

    3. Liquid Look and Feel(liquidlnf.jar):LiquidLNF提供了一种独特的、流畅的界面风格,让Swing应用看起来更为现代和时尚。 4. NimbusLookAndFeel(nimrodlf-1.0b.jar):Nimbus是Java 6引入的一种新的LAF,具有...

    使用Laf云平台将ChatGPT接入微信公众号.zip

    使用Laf云平台将ChatGPT接入微信公众号.zip

    界面 SwingSet + GenLAF (version 1).rar

    SwingSet + GenLAF (version 1) 是一个基于Java Swing库的用户界面示例集合,配合GenLAF(Generic Look and Feel)库,用于展示不同外观和感觉(LookAndFeel)的效果。在Java编程中,Swing是用于构建图形用户界面...

    swing框架之uidelegate之一.doc

    Swing框架中的UI Delegate机制是Swing组件能够动态切换外观和感觉(Look and Feel, LAF)的关键。LAF决定了组件的视觉样式和交互行为,让应用程序可以根据不同的平台或用户需求呈现不同的界面风格。Swing提供了默认...

    win10laf.jar

    Win10 风格 Swing 的 LookAndFeel(即皮肤),由本人自己开发, 完整版含有3套不同色调win7风格的皮肤和2套不同色调win10风格的皮肤 本次发布的是一个缩减版本,只含一套亮色调Win10风格皮肤 使用方法:在Swing项目...

Global site tag (gtag.js) - Google Analytics