JDialog doesn't respect dimensions of child components

坚强是说给别人听的谎言 提交于 2019-12-26 15:29:43

问题


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);
}

回答1:


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.




回答2:


I would implement it a bit another way - to ensure that preferred/min/max/Size can not be changed from elsewhere:

public JPanelThemed(BufferedImage image) {
    this.backgroundImage = image;
    setOpaque(false);
}

public Dimension getPreferredSize() {
    return new Dimension(this.backgroundImage.getWidth(), this.backgroundImage.getHeight());
}


来源:https://stackoverflow.com/questions/31165732/jdialog-doesnt-respect-dimensions-of-child-components

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!