如何在JFrame中设置JLabel的边界?

4

我使用JLabelJFrame中查看一张图片。 我使用ImageIcon从文件加载它。

JFrame frame = new JFrame(String);
frame.setLocationByPlatform(true);
frame.setSize(500, 500);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel cpu = new JLabel(new ImageIcon(String));
cpu.setLocation(20, 20);
cpu.setSize(20, 460);
frame.add(cpu);
frame.setVisible(true);

我不能设置JLabel的位置和大小,因为它是自动完成的

由于我想要截断图像(垂直进度条),所以我必须手动设置这些值。


@user1803551 我使用了 String 来表示通用字符串值。 - spongebob
2
标签的大小应该与图像的大小相同。手动设置标签的大小有什么意义呢?图像的绘制不会拉伸/缩小,因此您要么在标签中留有空白空间,要么截断图像。 - camickr
我猜@camickr想说的是删除cpu.setSize(20, 460);这一行。如果你手动添加大小到JLabel,它会截断你的图像或在边框上留下空白(正如camickr已经说过的那样)。 - Frakcool
@Joiner,你能否发布一个 MCVE?我的意思是一个完整的程序,我们可以复制粘贴、编译并看到与你相同的错误,这样我们可以更好地帮助你。 - Frakcool
@Frakcool,我已经发布了相关算法。但在这种特殊情况下,你可以将它复制到public static void main(String[] args) {}中。 - spongebob
显示剩余12条评论
3个回答

5

一种方法是直接绘制图像:

final ImageIcon icon = new ImageIcon(path);
JPanel panel = new JPanel() {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(icon.getImage(), 0, 0, getWidth(), getHeight(), this);
    }
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(500, 500);
    }
};
frame.add(panel); 
drawImage中的getWidth()getHeight()会强制图片拉伸到面板的大小。此外,getPreferredSize()将为面板提供一个大小。
如果要保持面板的大小,请确保其父容器具有将尊重首选大小的布局管理器,例如FlowLayoutGridBagLayout。如果要拉伸面板,请确保其父容器具有忽略首选大小的布局管理器,例如BorderLayoutGridLayout
更多绘图信息请参见自定义绘图。要了解更多有关布局管理器(您应该使用的内容)的信息,请参见在容器内布置组件。另请参见为什么不建议在SWING中使用null布局?Java中Null布局的问题是什么?

我问了关于 JLabel 控件,为什么你在使用 JPanel - spongebob
如果你想的话,可以使用JLabel并做同样的事情。不过我更喜欢在面板上绘制。它们都是容器,工作方式相同。只是JLabel有更多的功能。在代码中,只需将“JPanel”更改为“JLabel”。结果是一样的。如果您使用JLabel,并且想要向其添加组件(就像您会对面板进行的操作一样),请继续,这就是容器的用途。您只需要为标签设置布局管理器即可。 - Paul Samsotha
这不是我的问题:无论我使用 JLabel 还是覆盖 JPanel,都无关紧要。我无法设置控件的大小和位置。 - spongebob
看了你对camickr的评论,看到图片不是问题,你想做的是setSize()。布局管理器由preferredSize驱动。因此,对于像FlowLayout这样的布局管理器,如果可用,则会尊重首选大小。在默认的BorderLayout的情况下,它不会尊重首选大小。您当前看到的是标签被拉伸了,尽管您无法注意到它,因为默认情况下它是_不_不透明的。您看到的只是图像。但实际上标签是被拉伸的。 - Paul Samsotha
对于设置大小(setSize()),确实需要使用 null 布局,但是在 Swing 中(正如我的答案底部所建议的那样),您不应该使用 null 布局。相反,应该利用布局管理器。学习哪些布局管理器将尊重首选大小,哪些不会。如果需要间距,请使用 EmptyBorders。 - Paul Samsotha
显示剩余3条评论

4
您的原始图像大小为(58 x 510)。如果您想将图像以固定尺寸20 x 420显示,则应按比例缩放图像,以避免截断任何部分。一种做法是使用Image.getScaledImage(...) 方法来进行缩放。然后将缩放后的图像添加到标签中即可。
如果您想要将标签从面板左上角(20, 20)处开始定位,则可以向面板或标签添加EmptyBorder
请使用 Swing 的相关功能。
编辑:

我想截取图像。

将您的图像读入BufferedImage中。然后,您可以使用getSubImage(...)方法来获取任意尺寸的子图像。接着,您可以使用该子图像创建您的ImageIcon,并将其添加到标签中。

图像并不重要。我总是无法设置控件的大小和位置。 - spongebob
@Joiner,“我总是无法设置控件的大小和位置。”确切地说,您不应该尝试手动设置组件的大小/位置。让布局管理器来完成这个任务,它将在所有平台上都能正常工作。 - camickr
我想设置这些值。 - spongebob
@Joiner,每个组件都有一个首选大小。您不应该尝试设置大小。如果您错误地设置标签的大小,则可能会截断标签的文本或图像。除了“我想要”之外,您没有给我们任何进一步的信息。那不是一个好理由。如果您告诉我们为什么认为需要这样做,我们可以给您更好的解决方案。我们已经向您提供了有关布局管理器以及如何使用边框的信息。我们无法继续猜测。 - camickr

1

LayoutManager可以自动调整你的组件大小,不允许手动调整大小。

如果你想避免这种情况,你可以关闭LayoutManager

frame.setLayout(null);

请注意,您不应使用null布局。


3
避免使用null布局。相反,使用布局管理器。 - Frakcool
1
这段代码不会调整图像大小,而是截取了图像。您的原始图像尺寸为(58 x 510)。因此,您正在剪切图像的底部部分,这意味着您失去了彩虹的那种颜色。Swing 不是设计用于与 null 布局一起使用的,而且在这里使用 null 布局没有任何理由。 - camickr
@camickr... 我们都喜欢绿色。我测量了相同的尺寸,不过如果我在Windows上用鼠标悬停在文件上,会弹出工具提示说“尺寸:259x194”,不确定它实际测量的是什么。 - user1803551
@user1803551,使用IE浏览器,我只需右键单击问题中发布的图像,然后选择“属性”菜单项即可获取其尺寸。 - camickr
@camickr 我同意,我只是想知道为什么会有矛盾之处。无论如何,这已经偏离了主题。 - user1803551

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接