Java graphics2D fillRect不能在半透明颜色下正常工作

Java graphics2D fillRect不能在半透明颜色下正常工作,java,swing,awt,java-2d,graphics2d,Java,Swing,Awt,Java 2d,Graphics2d,我正在编写一个带有自定义渲染的程序,需要渲染一个带边框的矩形。我决定只调用graphics2D.fillRect(),切换到边框颜色,然后调用graphics2D.drawRect()。但是,即使我使用相同的坐标和大小背对背地调用,当我正在绘制的颜色是半透明的(具有alpha)时,fillRect()并不总是填充drawRect包含的整个区域。此外,fillRect()绘制的区域有时位于drawRect()包含的区域之外。为什么这两种方法在给不同的颜色时会在不同的地方画东西 下面是一个例子来说明

我正在编写一个带有自定义渲染的程序,需要渲染一个带边框的矩形。我决定只调用graphics2D.fillRect(),切换到边框颜色,然后调用graphics2D.drawRect()。但是,即使我使用相同的坐标和大小背对背地调用,当我正在绘制的颜色是半透明的(具有alpha)时,fillRect()并不总是填充drawRect包含的整个区域。此外,fillRect()绘制的区域有时位于drawRect()包含的区域之外。为什么这两种方法在给不同的颜色时会在不同的地方画东西

下面是一个例子来说明这个问题。在窗口中单击鼠标将在使用alpha和不使用alpha绘制填充之间切换。请注意,在使用alpha绘制时,矩形底部有一行像素是白色的,但在不使用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);

}
}

放弃那个答案,我重读了你的问题,复制了你的代码,找到了你在说什么。这条小白线是由于绘画中的舍入误差造成的。非常有趣的小问题。在创建图形2D后添加此项

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

渲染提示告诉绘画类您希望某些过程如何工作。我不知道为什么在颜色上增加透明度会使舍入变得不同。我想这一定与多个渲染提示(如抗锯齿)结合在一起有关

这是关于alpha合成的有用信息,但不幸的是,它并不能解决我的问题。我想我的想法是使用alpha合成,而不是使用alpha颜色来实现透明度。它不起作用,或者这对你来说不是一个可行的解决办法?@lbalazscs它不起作用。当hasAlpha为真时,我在矩形底部看到了相同的未填充像素线。它修复了未填充像素的问题,但是它有一个负面的副作用,即使边框的左侧比其他3个边薄1个像素。我怀疑这是因为我使用的笔划与像素不对齐。我想我可以调整笔划的宽度,使其与像素对齐,这样我就可以看到它是否能像那样工作。这似乎是Java 2D中的一个bug。