4

カスタム レンダリングを使用してプログラムを作成していて、境界線のある四角形をレンダリングする必要がありました。私は単純に graphics2D.fillRect() を呼び出し、境界線の色に切り替えて、graphics2D.drawRect() を呼び出すことにしました。ただし、これらの呼び出しを同じ座標とサイズで連続して行っても、描画している色が半透明 (アルファがある) の場合、fillRect() は常に drawRect に含まれる領域全体を塗りつぶすわけではありません。さらに、fillRect() によって描画される領域は、drawRect() によって含まれる領域の外側にある場合があります。異なる色を指定すると、これら 2 つの方法で異なる場所に描画されるのはなぜですか?

問題を示す例を次に示します。ウィンドウ内でマウスをクリックすると、塗りつぶしの描画がアルファありとなしで切り替わります。アルファを使用して描画すると、四角形の下部に白いピクセルの行がありますが、アルファを使用せずに描画すると、そのピクセルの行は存在しないことに注意してください。

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

1 に答える 1