【问题标题】:Why is fillRect with width of one not the same as drawLine为什么宽度为1的fillRect与drawLine不同
【发布时间】:2021-02-07 17:14:20
【问题描述】:

我正在使用 JFrame 上的 Canvas 开发一个 java gui 应用程序。我尝试在 Jframe 上绘制细长的矩形并注意到它们并不总是显示相同的宽度。

这是我写的一个测试类的结果。左侧使用fillRect()绘制,宽度为1,右侧使用drawLine绘制。

这是我的测试类的代码。

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;

public class test {
    public static void main(String[]args){
        new test();
    }

    public test(){
        JWindow frame = new JWindow();
        frame.setSize(500,500);
        frame.setLocation(200,200);

        Canvas c = new Canvas();
        frame.add(c);

        frame.setVisible(true);

        new Thread(() -> {
            while(true) {
                BufferStrategy bs = c.getBufferStrategy();

                if (bs == null) {
                    c.createBufferStrategy(2);
                    bs = c.getBufferStrategy();
                }

                Graphics g = bs.getDrawGraphics();
                Graphics2D g2 = (Graphics2D) g;

                g2.setColor(Color.black);

                for(int i = 0; i < 50; i++){
                    if(i % 4 == 0){
                        g2.fillRect(20 + i, 50, 1, 100);
                    }
                    else if(i % 4 == 1){
                        g2.fillRect(20 + i, 150, 1, 100);
                    }
                    else if(i % 4 == 2){
                        g2.fillRect(20 + i, 250, 1, 100);
                    }
                    else{
                        g2.fillRect(20 + i, 350, 1, 100);
                    }
                }

                for(int i = 0; i < 50; i++){
                    if(i % 4 == 0){
                        g2.drawLine(100 + i, 50, 100 + i, 150);
                    }
                    else if(i % 4 == 1){
                        g2.drawLine(100 + i, 150, 100 + i, 250);
                    }
                    else if(i % 4 == 2){
                        g2.drawLine(100 + i, 250, 100 + i, 350);
                    }
                    else{
                        g2.drawLine(100 + i, 350, 100 + i, 450);
                    }
                }

                g.dispose();
                bs.show();
            }
        }).start();
    }
}

有人知道它是如何工作的,或者甚至有办法解决这个问题吗?

【问题讨论】:

标签: java swing canvas


【解决方案1】:

如果你仔细观察,你会注意到第四组线向右移动了 2 个像素。

我认为您正在进行 125% UI 缩放,因此每 4 个逻辑像素对应 5 个物理像素。发布图像中的线条为 125 像素高这一事实证实了这一点,尽管代码要求线条为 100 像素长。

这意味着当您使用x + 3 (逻辑上) 绘图时,它实际上映射到x + 4 (物理上在监视器上)drawLine() 方法正确地移动了 4 个像素而不是 3 个像素,并且正确地绘制了一条 1 像素宽的线。

drawRect() 将分别计算要填充的框的左侧 (包括) 和右侧 (不包括),因此对于第三组框,右侧是左侧右侧的 2 个像素。然后它会填充 2 像素宽的框。

我们大多数人都没有 UI 缩放,所以我们不会看到您遇到的问题。

【讨论】:

最近更新 更多