【问题标题】:Aren't Graphics/JPanel dimensions measured in pixels?图形/JPanel 尺寸不是以像素为单位测量的吗?
【发布时间】:2019-09-25 16:26:18
【问题描述】:

当我在 JFrame 内的 JPanel 上绘制 [drawRect(x, y, width, height)] 一个矩形时,其宽度为500,它实际上比我屏幕上的 500 像素宽。这是如何测量的?

虽然在 JPanel 上绘制矩形和围绕它的 JFrame 的大小搞砸了,但我认识到,当涉及到 JFrame 和 JPanel 时,500“宽度”是不同的东西。 创建的宽度为 1920 像素的 JFrame 的宽度正好是 1920 像素,也就是说,与我的屏幕 (1920x1080) 一样宽。 如果我在 JFrame 内的 JPanel 上绘制一个宽度为 1920 的矩形,它会将我的屏幕恰好扩展 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 [drawRect(0, 0, 1535, 500)],它与 JFrame/screen 一样宽。这是为什么呢?

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

【问题讨论】:

  • 我现在不能测试,但是你打电话给super.paintComponentS(g);而不是super.paintComponent(g);(注意S)。
  • @Frakcool 谢谢!那是笔误,我更正了。但是对于这个问题,它没有任何区别。
  • 区别在于框架装饰。见stackoverflow.com/a/57042907/11595728
  • @SDJ 我已经阅读了有关装饰品的信息(我完全相信这篇文章)。但是 Windows 10 框架的侧面没有任何装饰。
  • 我会运行帖子中的代码来确定。在我的win10盒子上,边框左右各有8个像素的边框装饰(共16个)。用肉眼可能很难看到,但它们肯定存在。

标签: java swing jpanel


【解决方案1】:

简短的回答:是的。

解释:让我们深入了解一下!

在 MacOS 上运行 Java Swing(使用 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);
    }
}

【讨论】:

  • 打开的窗口看起来和你描述的完全一样,全屏,一个橙色的矩形,每边有 8 个像素的间隙。但是控制台的输出让我感到困惑: w: java.awt.Dimension[width=1554,height=800] c: java.awt.Dimension[width=1906,height=763] p: java.awt.Dimension[width =1906,height=763] i: java.awt.Insets[top=30,left=7,bottom=7,right=7] 为什么内容窗格现在比框架宽?为什么它告诉框架比我的屏幕小得多?
  • 感谢您的回复!您的结果解释了为什么您对 JSwing 是否使用像素感到困惑。有了你提供的数据,我也很困惑。我的建议是对代码进行一些修改,看看你是否能解决这个问题。这似乎是您正在运行的机器/操作系统/软件特有的问题。如果您发现了什么,请告诉我们!
猜你喜欢
  • 2015-04-12
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多