miglayout icon indicating copy to clipboard operation
miglayout copied to clipboard

Limit size of child to bounds of parent when applying visualPadding

Open weisJ opened this issue 1 year ago • 1 comments

If child components have e.g. the fillx constraint and also visualPaddings specified the child may be layed out outside the parents bounds. This results in e.g. focus rings not be painted on those side.

Here is a small example that demonstrated the problem:

SwingUtilities.invokeLater(() -> {
    JFrame frame = new JFrame("Test");

    JPanel titlePanel = new JPanel(new MigLayout("fillx, insets 0", "[fill]"));

    JPanel overflowing = new JPanel();
    overflowing.setMinimumSize(new Dimension(50, 50));
    int thickness = 5;
    overflowing.setBorder(new LineBorder(Color.MAGENTA, thickness));
    overflowing.putClientProperty("visualPadding", new Insets(thickness, thickness, thickness, thickness));

    titlePanel.add(overflowing);

    JPanel panel = new JPanel(new BorderLayout());
    panel.setBorder(new CompoundBorder(
            new EmptyBorder(30, 30, 30, 30),
            new LineBorder(Color.BLACK)
    ));
    panel.add(titlePanel, BorderLayout.NORTH);
    panel.add(new JPanel(), BorderLayout.CENTER);

    frame.setContentPane(panel);

    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
});

Without the patch the magenta border will be invisible.

I am not fully sure it is the correct approach. Maybe there is some scenario where one would actually want a child to extend outside the parent. But I wasn't able to track down the code where fill constraints are evaluated to patch it at that point already.

Any feedback is highly appreciated.

weisJ avatar May 04 '23 19:05 weisJ

I'm also interested in a solution for this problem. It occurs often when nesting panels.

Here is a screenshot that shows the problem (cut-off focus border if nested panel uses insets 0 in layout constraints):

image

This PR works, it simply reduces the size of the components if they are outside of the container. But there are some problems with this approach.

The components no longer have their preferred sizes.

Here is an example that shows that button height gets too small (left is without this PR, right is with this PR):

image

Another problem is that if components are "intentionally" placed partly (or fully) outside of the container, then this PR "forces" them into the container bounds.

A "manual" fix for the issue would be to increase the layout insets for the nested panels where necessary (e.g. change layout constraints from insets 0 to insets 3 0 3 3). But this is error-prone and it does not work if the application also supports L&Fs that do not provide visualPaddings or where visualPadding is always 0,0,0,0.

It would be great to find a solution that automatically increases the container insets, but only on those sides where it is necessary. This should also increase the preferred size of the container.

But have no idea where and how to implement this. I think it has to be done very late in the layout calculation because the bounds of the container and of all children is needed to find out whether a component is located at one of the four sides.

DevCharly avatar May 04 '23 22:05 DevCharly