2012-05-30 108 views
0

爲我的項目,我想創建自定義形狀的按鈕。我已經有了創建圓形按鈕的代碼,經過大量研究,我設法找到了一些代碼,我可以使用它來從具有透明度的PNG圖像生成形狀(區域),以便我可以使用代碼並將其放入進入我的自定義按鈕程序。但是,創建形狀的過程是耗費CPU的,創建每個形狀需要相當長的時間。這是我的用於從圖像生成一形狀代碼:Java - 從PNG圖像創建形狀(NullPointerException)

import java.awt.Rectangle; 
import java.awt.geom.Area; 
import java.awt.image.BufferedImage; 

public class CreateShapeClass { 
    public static Area createArea(BufferedImage image, int maxTransparency) { 
     Area area = new Area(); 
     Rectangle rectangle = new Rectangle(); 
     for (int x = 0; x < image.getWidth(); x++) { 
      for (int y = 0; y < image.getHeight(); y++) { 
       int rgb = image.getRGB(x, y); 
       rgb = rgb >>> 24; 
       if (rgb >= maxTransparency) { 
        rectangle.setBounds(x, y, 1, 1); 
        area.add(new Area(rectangle)); 
       } 
      } 
     } 
     return area; 
    } 
} 

通過使用上面的代碼,就會出現NullPointerException錯誤。這裏的堆棧跟蹤:

java.lang.NullPointerException 
at CreateShapeClass.createArea(CreateShapeClass.java:10) 
at CustomButton.initShape(CustomButton.java:95) 
at CustomButton.paintBorder(CustomButton.java:102) 
at javax.swing.JComponent.printBorder(Unknown Source) 
at javax.swing.JComponent.paint(Unknown Source) 
at javax.swing.JComponent.print(Unknown Source) 
at javax.swing.JComponent.paintChildren(Unknown Source) 
at javax.swing.JComponent.printChildren(Unknown Source) 
at javax.swing.JComponent.paint(Unknown Source) 
at javax.swing.JComponent.print(Unknown Source) 
at javax.swing.JComponent.paintChildren(Unknown Source) 
at javax.swing.JComponent.printChildren(Unknown Source) 
at javax.swing.JComponent.paint(Unknown Source) 
at javax.swing.JLayeredPane.paint(Unknown Source) 
at javax.swing.JComponent.print(Unknown Source) 
at javax.swing.JComponent.paintChildren(Unknown Source) 
at javax.swing.JComponent.printChildren(Unknown Source) 
at javax.swing.JComponent.paint(Unknown Source) 
at javax.swing.JComponent.print(Unknown Source) 
at java.awt.GraphicsCallback$PrintCallback.run(Unknown Source) 
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source) 
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source) 

這裏是我的CustomButtonClass:

import java.awt.*; 
import java.awt.geom.*; 
import java.awt.image.BufferedImage; 
import java.io.*; 
import java.util.Iterator; 

import javax.imageio.ImageIO; 
import javax.imageio.ImageReadParam; 
import javax.imageio.ImageReader; 
import javax.imageio.stream.ImageInputStream; 
import javax.swing.*; 

public class CustomButton extends JButton { 
    protected Shape shape, base; 
    protected BufferedImage image; 
    protected String imagePath; 

    private static final long serialVersionUID = 1L; 
    public CustomButton() { 
     this(null, null); 
    } 
    //takes in an icon 
    public CustomButton(Icon icon) { 
     this(null, icon); 
    } 
    //takes in a text string for button 
    public CustomButton(String text) { 
     this(text, null); 
    } 

    //takes in a text string for button 
    public CustomButton(Icon icon, String imagePath, boolean useless) { 
     this(null, icon); 
     this.imagePath = imagePath; 
    } 
    //takes in an action for the button press event 
    public CustomButton(Action a) { 
     this(); 
     setAction(a); 
    } 
    //takes in text and icon image 
    public CustomButton(String text, Icon icon) { 
     setModel(new DefaultButtonModel()); 
     init(text, icon); 
     if(icon==null) { 
      return; 
     } 
     setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); 
     setBackground(Color.BLACK); 
     setContentAreaFilled(false); 
     setFocusPainted(false); 
     //setVerticalAlignment(SwingConstants.TOP); 
     setAlignmentY(Component.TOP_ALIGNMENT); 
     initShape(); 
    } 

    //creates a method for retrieving preferred size of the button (the image) 
    @Override public Dimension getPreferredSize() { 
     Icon icon = getIcon(); 
     Insets i = getInsets(); 
     if (icon == null){ 
      return super.getPreferredSize(); 
     } 
     else { 
      return new Dimension(icon.getIconWidth(), icon.getIconHeight()); 
     } 
    } 

    //creates the shape of the button from the image 
    protected void initShape() { 
     if(!getBounds().equals(base)) { 
      Dimension s = getPreferredSize(); 
      base = getBounds(); 
      if (image == null){ 
       try { 
        image = ImageIO.read(new File("Untitled1.png")); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      shape = CreateShapeClass.createArea(image, 25); 
      System.out.println(shape.getBounds()); 
     } 
    } 

    //creates the border of the button 
    @Override protected void paintBorder(Graphics g) { 
     initShape(); 
     Graphics2D g2 = (Graphics2D)g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setColor(getBackground()); 
     g2.setStroke(new BasicStroke(1.0f)); 
     g2.draw(shape); 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); 
    } 
    @Override public boolean contains(int x, int y) { 
     initShape(); 
     return shape.contains(x, y); 
    } 
} 

因此,任何人都可以指導我在哪裏,我去錯誤的代碼?並且有什麼方法可以將生成的形狀保存到某種文件中,以便在程序運行時不必總是重新生成形狀?或者有什麼辦法來預備形狀。

+0

檢查'image'是否爲空。 –

+0

感謝它解決了這個問題:D – csharpnewbie

回答

1

如果image參數爲null,則不檢查。看看你的調用方法initShape如果無法讀取「Untitled1.png」,你可以得到一個空指針。

+0

謝謝,通過添加一個檢查圖像是否爲空,解決了這個問題。 – csharpnewbie