`

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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics