JDialog不尊重子组件的尺寸 [英] JDialog doesn't respect dimensions of child components

查看:53
本文介绍了JDialog不尊重子组件的尺寸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个通常可以使用的设置,但是我现在觉得有点痛苦.

我有一个JDialog(以前是JFrame,但是我最近更改了UI流程以删除多余的JFrames)设置为BorderLayout,其中包含三个主要的JPanels,页眉,内容和页脚. /p>

标头JPanel的背景图片可以很好地加载.但是,我以各种方式调用setMinimumSize/setPreferredSize/etc(出于绝望,我什至尝试了setSizesetBounds),并且JPanel的大小没有正确设置.该组件的布局为BoxLayout,孩子们可以舒适地坐在其中,但这不应影响我要使用标题面板本身做的事情.

唯一有效的方法是在父级JDialog上设置大小.但是我不想这样做/从我读到的内容来看,这似乎是一个糟糕的设计.我还必须算出所有孩子的潜在宽度/高度,加上边距,等等.

建议我正在寻找:使用其他LayoutManager."

想要了解是否有理由不尊重子组件.

我可以提供代码,但是鉴于我要处理的互锁系统数量众多,要隔离出一个小的可运行段是困难的.这是设置JPanel大小的相关代码段.图片尺寸为480 * 96.

public JPanelThemed(BufferedImage image) {
    super();
    this.backgroundImage = image;
    setAllSimilarConstraints(new Dimension(image.getWidth(), image.getHeight()));
    setOpaque(false);
}

// for use with BoxLayout as it requires explicit bounds to be set
public void setAllSimilarConstraints(Dimension dim) {
    setPreferredSize(dim);
    setMinimumSize(dim);
    setMaximumSize(dim);
}

解决方案

如果我没有定义尺寸,如何确保显示正在绘制的整个背景?

您可以使用JLabel显示ImageIcon.标签的大小将是图像的大小.然后,设置标签的布局管理器,以便可以向其中添加组件.

您知道为什么在用Java绘制背景时为什么通常建议将其子类化为JPanel吗?

使用JPanel时,面板的大小取决于添加到面板中的组件和所使用的布局管理器.然后,您的自定义绘画代码需要按照所需的方式绘画图像.也就是说,您可以从(0,0)绘制图像,或者可以将图像居中放置在面板上,可以缩放图像以使其适合窗格,但是该图像决不能控制面板的大小,除非您可以覆盖面板的getPreferredSize()方法,以使用自定义代码来确定较大的组件或图像的大小.因此,您完全可以控制.

使用此处建议的JLabel方法时,标签的大小始终是图像的大小.然后,将基于布局管理器定位组件,但是如果图像小于组件所需的空间,则可以将其截断.

因此,根据您的需要来确保显示整个图像,我建议使用JLabel方法,因为您无需编写任何自定义代码.使用弹出式不可调整大小的对话框来显示背景图像以及一些组件和按钮来关闭对话框时,我发现这是一种简单的方法.

您还可以查看背景面板,其中提供了以下常见信息在可重用的类中绘画功能.

I have a setup that usually works, but I'm finding it a bit of a pain at the moment.

I have a JDialog (formerly a JFrame, but I've changed the UI flow recently to remove redundant JFrames) set to BorderLayout that contains three main JPanels, header, content and footer.

The header JPanel has a background image that is loading fine. However, I'm calling all manner of setMinimumSize / setPreferredSize / etc (I even tried setSize and setBounds out of desperation) and the JPanel isn't being sized correctly. The layout for that component is BoxLayout, and the children sit comfortably within it, but that shouldn't affect what I'm trying to do with the header panel itself.

The only thing that works is setting a size on the parent JDialog. But I don't want to do that / from what I've read it seems like bad design. I'd also have to maths out the potential width / height of all the children, add the margins, etc.

Advice I am not looking for: "use a different LayoutManager."

I want to understand if there's a reason for the child components not being respected.

I can provide code, but isolating a small, runnable segment is difficult given the amount of interlocked systems I'm juggling. Here is the relevant snippet to set the size of the JPanel. The image dimensions are 480 * 96.

public JPanelThemed(BufferedImage image) {
    super();
    this.backgroundImage = image;
    setAllSimilarConstraints(new Dimension(image.getWidth(), image.getHeight()));
    setOpaque(false);
}

// for use with BoxLayout as it requires explicit bounds to be set
public void setAllSimilarConstraints(Dimension dim) {
    setPreferredSize(dim);
    setMinimumSize(dim);
    setMaximumSize(dim);
}

解决方案

If I don't define dimensions, how do I ensure the whole background I'm painting is displayed?

You could use a JLabel to display the ImageIcon. The size of the label will be the size of the image. You then set the layout manager of the label so you can add components to it.

Edit:

do you know why it's commonly-recommended to subclass JPanel when painting backgrounds in Java

When you use a JPanel the size of the panel is based on the components added to the panel and the layout manager you are using. Your custom painting code then needs to paint the image the way your want. That is you can paint the image from (0, 0), or you can center the image on the panel, you can scale the image to make it fit the pane, but the image in no way controls the size of the panel, unless you override the getPreferredSize() method of the panel to use custom code to base the size of the larger of the components or the image. So you are in full control.

When you use the JLabel approach suggested here, the size of the label is always the size of the image. Then components will be positioned based on the layout manager but can be truncated if the image is smaller than the space required by the components.

So based on your requirement that you want to make sure the entire image is displayed, I suggested the JLabel approach, since you don't need to write any custom code. I find this a simple approach when using popup non-resizable dialogs to display a background image and a few components and buttons to close the dialog.

You can also check out Background Panel which provides these common painting features in a reusable class.

这篇关于JDialog不尊重子组件的尺寸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆