提问者:小点点

图形/JPanel尺寸不是以像素为单位吗?


当我在JFrame内的JPanel上绘制一个矩形时,它的宽度为例如500,它实际上比我屏幕上的500像素宽。这是如何测量的?

在处理JPanel上的绘图矩形和JFrame的大小时,我认识到,当涉及到JFrame和JPanel时,500个“宽度”是不同的。一个宽度为1920像素的JFrame正好是1920像素宽,意味着与我的屏幕(1920x1080)一样宽。如果我在JPanel上绘制一个宽度为1920的矩形,也就是在JFrame内部,它正好将我的屏幕扩展了385个像素。分别:与我的屏幕一样宽的绘制矩形需要1535的宽度。

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

public class Main {

    public static void main(String[] args){

        JFrame window = new JFrame();
        window.setSize(1920,1080);     //Window as wide as the screen
        window.add(new Canvas());
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);

    }

}

public class Canvas extends JPanel {

    @Override
    protected void paintComponent(Graphics g){

        super.paintComponent(g);
        g.drawRect(0, 0, 1920, 500); //Paints a rectangle on the JPanel

    }
}

打开的窗口和我的屏幕一样宽,但是里面的矩形扩展了它。如果我将矩形的宽度更改为1535[DramRect(0,0,1535,500)],它就和JFrame/屏幕一样宽。为什么?

编辑:由于Windows 10框架的侧面没有装饰,只有顶部的标准菜单栏,我不认为这是问题所在(据我所知装饰)。


共1个答案

匿名用户

简短的回答是:是的。

解释:让我们更深入地看看!

在MacOS上运行JavaSwing(使用Metal LAF进行测试),JFrame的左右插入值为零。这类似于Windows 10上某些主题的渲染。我在下面包含了代码;内容窗格和面板填充矩形之间的间隙应该保持8像素。当程序运行时,调整它的大小,并自行检查。如果这不是您体验到的行为,请随时发表评论。

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        final String name;
        name = javax.swing.plaf.metal.MetalLookAndFeel.class.getName();
        try {
            UIManager.setLookAndFeel(name);
        }
        catch (Throwable e) {
            e.printStackTrace();
        }

        createAndShowWindow();
    });
}

private static void createAndShowWindow() {
    final int width = 1920;
    final int height = 800;
    final int padding = 8;

    JFrame window = new JFrame();
    window.setTitle("Hello World.");
    window.setPreferredSize(new Dimension(width, height));
    window.setSize(width, height);     //Window as wide as the screen
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Canvas canvas = new Canvas(padding);
    window.add(canvas, BorderLayout.CENTER);

    window.pack();
    window.setVisible(true);

    System.out.println("w: " + window.getSize());
    System.out.println("c: " + window.getContentPane().getSize());
    System.out.println("p: " + canvas.getSize());
    System.out.println("i: " + window.getInsets());
}

public static class Canvas extends JPanel {

    private final int padding;

    public Canvas(int padding) {
        this.padding = padding;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(new Color(180, 120, 16));
        //Paints a rectangle on the JPanel
        int x = padding;
        int y = padding;
        int w = getWidth() - 2 * padding;
        int h = getHeight() - 2 * padding;
        g.fillRect(x, y, w, h);
    }
}