Java graphics2D fillRect not working properly with translucent colors

I wrote a program using some custom rendering and had to display a rectangle with a frame. I decided to just call graphics2D.fillRect (), switch to the border color and call graphics2D.drawRect (). However, despite the fact that these calls are repeated with the same coordinates and sizes, fillRect () does not always fill the entire area contained in drawRect when the color I draw is translucent (has alpha). In addition, the area colored by fillRect () is sometimes outside the area containing drawRect (). Why do these two methods paint things in different places with different colors?

Here is an example of a problem demonstration. A mouse click in the window will switch between drawing an alpha fill and without. Note that there is a white line at the bottom of the rectangle when drawing with alpha, but this line of pixels is missing when drawing without alpha.

import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.geom.AffineTransform; import javax.swing.JFrame; import javax.swing.JPanel; public class ColorWithAlpha extends JPanel { private boolean hasAlpha = true; private static final long serialVersionUID = 1L; /** * @param args */ public static void main(String[] args) { // setup a basic frame with a ColorWithAlpha in it JFrame frame = new JFrame(); JPanel panel = new ColorWithAlpha(); panel.setPreferredSize(new Dimension(500, 500)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(panel); frame.pack(); frame.show(); } public ColorWithAlpha() { super(); setBackground(Color.WHITE); this.addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent arg0) { // when the user clicks their mouse, toggle whether we are drawing a color with alhpa or without. hasAlpha = !hasAlpha; ColorWithAlpha.this.repaint(); } @Override public void mouseEntered(MouseEvent arg0) {} @Override public void mouseExited(MouseEvent arg0) {} @Override public void mousePressed(MouseEvent arg0) {} @Override public void mouseReleased(MouseEvent arg0) {} }); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Color color = new Color(100, 100, 250);// this color doesnt have an alpha component // some coordinates that demonstrate the bug. Not all combinations of x,y,width,height will show the bug int x = -900; int y = 1557; int height = 503; int width = 502; if (hasAlpha) { // toggle between drawing with alpha and without color = new Color(200, 100, 250, 100); } Graphics2D g2 = (Graphics2D) g; // this is the transform I was using when I found the bug. g2.setTransform(new AffineTransform(0.160642570281124, 0.0, 0.0, -0.160642570281124, 250.0, 488.0)); g2.setColor(color); g2.fillRect(x, y, width, height); g2.setColor(Color.DARK_GRAY); g2.setStroke(new BasicStroke(8f)); g2.drawRect(x, y, width, height); } } 
+4
source share
1 answer

Drop this answer, I will re-read your question and copy your code and find what you are talking about. A small white line is associated with a rounding error in the picture. Very interesting little problem. Add this after creating Graphics2D

 g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); 

Rendering tips tells the painting class how you want certain procedures to work. I have no idea why adding transparency to color would make rounding different. I believe this should be due to several rendering hints coming together as smoothing.

+3
source

All Articles