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); } }
运行结果:
然后用鼠标随便调整下窗口大小,那个设置的图片就出来了:
其中的关键代码是:
如果把null改成JComponent c:
则会抛出异常:
这个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方法就正常:
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是一样的效果。