I have a custom Icon
which uses a TexturePaint
as paint and calls fillPolygon
on a Graphics2D
object.
This code works fine on JDK6 and JDK7, but fails under JDK8 with 64bit Linux (tried most recent JDK1.8 on 64bit Linux). On Windows, this runs fine with JDK8.
Output of the java -version
command for the JDK used to reproduce the issue.
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
Code to reproduce the issue:
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
public class TexturePaintIconTest {
private static class CustomIcon implements Icon{
private static final int[] sXArray = new int[]{2, 5, 7, 12, 12, 4, 1, 1, 2};
private static final int[] sYArray = new int[]{4, 4, 2, 2, 11, 11, 8, 5, 4};
private static final int sNumberOfPoints = 9;
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.translate(x,y);
Graphics2D g2d = (Graphics2D) g;
Color fillColor = new Color( 140, 25, 25, 35);
g2d.setPaint(createPatternPaint(fillColor));
g2d.fillPolygon(sXArray, sYArray, sNumberOfPoints);
g.translate(-x, -y);
}
private Paint createPatternPaint(Color color ){
int[] colors = new int[]{color.getRGB(), 0};
IndexColorModel colorModel = new IndexColorModel(1, 2, colors, 0, true, -1, DataBuffer.TYPE_BYTE);
BufferedImage image = new BufferedImage(2, 2, BufferedImage.TYPE_BYTE_INDEXED, colorModel);
DataBufferByte dataBuffer = (DataBufferByte) image.getRaster().getDataBuffer();
byte[] data = dataBuffer.getData();
data[0] = 0;
data[1] = 1;
data[2] = 1;
data[3] = 0;
return new TexturePaint(image, new Rectangle(2, 2));
}
@Override
public int getIconWidth() {
return 16;
}
@Override
public int getIconHeight() {
return 16;
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame testFrame = new JFrame("TestFrame");
JLabel label = new JLabel("Label with icon", new CustomIcon(), SwingConstants.LEFT);
testFrame.add(label);
testFrame.pack();
testFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
testFrame.setVisible(true);
}
});
}
}
Running the main
method results in the following error
Exception in thread "AWT-EventQueue-0" java.lang.InternalError: Surface not cachable
at sun.java2d.xr.XRPaints$XRTexture.getAccSrcSurface(XRPaints.java:211)
at sun.java2d.xr.XRPaints$XRTexture.isPaintValid(XRPaints.java:224)
at sun.java2d.xr.XRPaints.isValid(XRPaints.java:75)
at sun.java2d.xr.XRSurfaceData.getMaskFill(XRSurfaceData.java:205)
at sun.java2d.SurfaceData.validatePipe(SurfaceData.java:675)
at sun.java2d.xr.XRSurfaceData.validatePipe(XRSurfaceData.java:123)
at sun.java2d.SunGraphics2D.validatePipe(SunGraphics2D.java:446)
at sun.java2d.pipe.ValidatePipe.validate(ValidatePipe.java:55)
at sun.java2d.pipe.ValidatePipe.fillPolygon(ValidatePipe.java:147)
at sun.java2d.SunGraphics2D.fillPolygon(SunGraphics2D.java:2389)
at com.luciad.internal.lucy.map.TexturePaintIconTest$CustomIcon.paintIcon(TexturePaintIconTest.java:22)
I already searched in the Java bug database (official one and the openjdk one) but found no bug report which could explain this. Am I doing something wrong with my custom icon, or did I stumble upon a JDK bug ?