Java-从PNG图像创建形状(NullPointerException)
对于我的项目,我想创建自定义形状的按钮。我已经有了创建圆形按钮的代码,经过大量研究,我找到了一些代码,可以用来从一个透明的PNG图像生成一个形状(区域),这样我就可以使用这些代码并将其放入我的自定义按钮程序中。但是,创建形状的过程需要cpu,并且创建每个形状需要相当长的时间。以下是我从图像生成形状的代码:Java-从PNG图像创建形状(NullPointerException),java,nullpointerexception,draw,shape,area,Java,Nullpointerexception,Draw,Shape,Area,对于我的项目,我想创建自定义形状的按钮。我已经有了创建圆形按钮的代码,经过大量研究,我找到了一些代码,可以用来从一个透明的PNG图像生成一个形状(区域),这样我就可以使用这些代码并将其放入我的自定义按钮程序中。但是,创建形状的过程需要cpu,并且创建每个形状需要相当长的时间。以下是我从图像生成形状的代码: import java.awt.Rectangle; import java.awt.geom.Area; import java.awt.image.BufferedImage; publ
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;
}
}
这是我的自定义按钮类:
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);
}
}
那么,有人能告诉我代码哪里出了问题吗?有没有办法将生成的形状保存到某种文件中,这样在程序运行时就不必总是重新生成形状?或者是否有任何方法来预切形状。您没有检查
图像
参数是否为空
。查看您的调用方法initShape
如果无法读取“Untitled1.png”,您可以得到一个空指针。谢谢,它解决了问题:感谢您,通过添加检查图像是否为空,解决了问题。
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);
}
}