JSlider 个性化

package com.han;
 
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
 
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JSlider;
import javax.swing.Painter;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.UIManager.LookAndFeelInfo;
 
@SuppressWarnings("serial")
public class JSlider_customized extends JFrame {
 
    public JSlider_customized() {
        // TODO Auto-generated constructor stub
        for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
            if (laf.getName().equals("Nimbus")) {
                try {
                    UIManager.setLookAndFeel(laf.getClassName());
                } catch (ClassNotFoundException | InstantiationException
                        | IllegalAccessException
                        | UnsupportedLookAndFeelException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
 
        JPanel panel = new JPanel(new GridLayout(0, 1, 20, 20));
        JSlider slider = new JSlider(0, 100, 50);
        Container c = getContentPane();
        c.add(panel, BorderLayout.CENTER);
        panel.setBackground(Color.DARK_GRAY);
        panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        panel.add(slider);
        UIDefaults sliderDefaults = new UIDefaults();
        sliderDefaults.put("Slider.thumbWidth", 20);
        sliderDefaults.put("Slider.thumbHeight", 20);
        sliderDefaults.put("Slider:SliderThumb.backgroundPainter",
                new Painter<JComponent>() {
                    public void paint(Graphics2D g, JComponent c, int w, int h) {
                        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
                        g.setStroke(new BasicStroke(2f));
 
                        g.setColor(Color.RED);
                        g.fillOval(1, 1, w - 3, h - 3);
                        g.setColor(Color.WHITE);
                        g.drawOval(1, 1, w - 3, h - 3);
                         Image img = Toolkit.getDefaultToolkit().getImage(
                         JSlider_customized.class
                         .getResource("/images/Luxun.jpg"));
                         
                         g.drawImage(img, 0, 0, w, h, null);
                    }
                });
        sliderDefaults.put("Slider:SliderTrack.backgroundPainter",
                new Painter<JComponent>() {
                    public void paint(Graphics2D g, JComponent c, int w, int h) {
                        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
                        g.setStroke(new BasicStroke(2f));
                        g.setColor(Color.GRAY);
                        g.fillRoundRect(0, 6, w - 1, 8, 8, 8);
                        g.setColor(Color.WHITE);
                        g.drawRoundRect(0, 6, w - 1, 8, 8, 8);
                    }
                });
        slider.putClientProperty("Nimbus.Overrides", sliderDefaults);
        slider.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
 
        JSlider slider2 = new JSlider(0, 100, 50);
        panel.add(slider2);
    }
 
    /**
     * @param args
     */
    public static void main(String[] args) {
 
        // JFrame.setDefaultLookAndFeelDecorated(true);
        JSlider_customized frame = new JSlider_customized();
        // frame.setUndecorated(true);
        // frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
 
        frame.pack();// leaves the frame layout manager in charge of the frame
                        // size, so that all its contents are at or above their
                        // preferred sizes
        // frame.setLocation(100, 100); // set the frame location
        frame.setLocationRelativeTo(null); // centers a frame onscreen
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
 
}

运行结果:

JSlider 个性化_第1张图片

然后用鼠标随便调整下窗口大小,那个设置的图片就出来了:

JSlider 个性化_第2张图片

其中的关键代码是:

JSlider 个性化_第3张图片

如果把null改成JComponent c:

JSlider 个性化_第4张图片

则会抛出异常:

JSlider 个性化_第5张图片

这个ImageObserver在作怪!而我于是去查new Painter<JComponent>() {
public void paint(Graphics2D g, JComponent c, int w, int h)的API,对于JComponent c里面说到:

Generally, to enhance reusability, most standard Painters ignore this parameter. They can thus be reused in any context. The object may be null. Implementations must not throw a NullPointerException if the object parameter is null.

也就是说JComponent c可以为null。所以这种情况该如何是好啊,怎么才能正常的显示drawImage画出的图片啊!!!!

后查明,是Toolkit的getImage的原因。使用 ImageIO的read方法就正常:

JSlider 个性化_第6张图片

package com.han;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Painter;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.UIManager.LookAndFeelInfo;

@SuppressWarnings("serial")
public class JSlider_customized extends JFrame {

	public JSlider_customized() {
		// TODO Auto-generated constructor stub
		for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
			if (laf.getName().equals("Nimbus")) {
				try {
					UIManager.setLookAndFeel(laf.getClassName());
				} catch (ClassNotFoundException | InstantiationException
						| IllegalAccessException
						| UnsupportedLookAndFeelException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		JPanel panel = new JPanel(new GridLayout(0, 1, 20, 20));
		JSlider slider = new JSlider(0, 100, 50);
		Container c = getContentPane();
		c.add(panel, BorderLayout.CENTER);
		panel.setBackground(Color.DARK_GRAY);
		panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
		panel.add(slider);
		UIDefaults sliderDefaults = new UIDefaults();
		sliderDefaults.put("Slider.thumbWidth", 20);
		sliderDefaults.put("Slider.thumbHeight", 20);
		sliderDefaults.put("Slider:SliderThumb.backgroundPainter",
				new Painter<JComponent>() {
					public void paint(Graphics2D g, JComponent c, int w, int h) {
						g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
								RenderingHints.VALUE_ANTIALIAS_ON);
						g.setStroke(new BasicStroke(2f));

						g.setColor(Color.RED);
						g.fillOval(1, 1, w - 3, h - 3);
						g.setColor(Color.WHITE);
						g.drawOval(1, 1, w - 3, h - 3);
						 
						BufferedImage img;
						try {
							img = ImageIO.read(this.getClass() // this --> new Painter()内部类但是也与JSlider_customized在同一文件夹
									 .getResource("/images/Luxun.jpg"));
							g.drawImage(img, 0, 0, w, h, c); // the same for the BufferedImage when using g.drawImage(img, 0, 0, w, h, null);
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
								 
					}
				});
		sliderDefaults.put("Slider:SliderTrack.backgroundPainter",
				new Painter<JComponent>() {
					public void paint(Graphics2D g, JComponent c, int w, int h) {
						g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
								RenderingHints.VALUE_ANTIALIAS_ON);
						g.setStroke(new BasicStroke(2f));
						g.setColor(Color.GRAY);
						g.fillRoundRect(0, 6, w - 1, 8, 8, 8);
						g.setColor(Color.WHITE);
						g.drawRoundRect(0, 6, w - 1, 8, 8, 8);
					}
				});
		slider.putClientProperty("Nimbus.Overrides", sliderDefaults);
		slider.putClientProperty("Nimbus.Overrides.InheritDefaults", false);

		JSlider slider2 = new JSlider(0, 100, 50);
		panel.add(slider2);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		// JFrame.setDefaultLookAndFeelDecorated(true);
		JSlider_customized frame = new JSlider_customized();
		// frame.setUndecorated(true);
		// frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);

		frame.pack();// leaves the frame layout manager in charge of the frame
						// size, so that all its contents are at or above their
						// preferred sizes
		// frame.setLocation(100, 100); // set the frame location
		frame.setLocationRelativeTo(null); // centers a frame onscreen
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}

}

Toolkit 的getImage 都要和MediaTracker搭配使用。BufferedImage在drawImage时是全部Loaded的,此时指定ImageObserver以及设置为null是一样的效果。


你可能感兴趣的:(JSlider 个性化)