0

Setup:

  • On the right side of the screen, there is a list from top to bottom.
  • On the left side of the screen, there are manipulators for this list;
    • one manipulator consists of two elements, one beside the other.
    • at first only one manipulator exists, but further ones may appear;
      • those would then be placed below each other.

Here, the manipulators' elements are JComboBoxes: sourceAMask and sourceBMask.

To ensure that they appear side by side, I enclosed them in the Box mask_initialPair laid out along the BoxLayout.X_AXIS. They should appear left-aligned, so I padded the right with a Box.createHorizontalGlue.

To allow mask_initialPair to be vertically unstretched, I enclosed that in the Box maskPairs laid out along the BoxLayout.Y_AXIS and added a Box.createVerticalGlue below it.

To put this vertical list beside the other one, targetScroller, I enclosed both in the Box maskPage laid out along the BoxLayout.X_AXIS. This construct should appear centered, so I padded both left and right with Box.createHorizontalGlue.

My (ideal) assumptions:

  1. sourceAMask and sourceBMask are left-aligned and of minimal width necessary (as per greatest length from source[A|B]Package), as the horizontal glue to the right takes up all further space assigned to maskPairs.
  2. mask_initialPair (and all further pairs) has the minimal height necessary (as per current size of font used), as the vertical glue below takes up all further space.
  3. The left and right margins of maskPage are of equal width.
  4. maskPairs and targetScroller are of equal width.

Only 3 holds.

4 is violated as maskPairs is far wider than targetScroller, because (violating 1), the horizontal glue within mask_initialPair receives equal width to the glues in maskPage, as if inserted between maskPairs and targetScroller, instead of as part of maskPairs.

2 is violated as mask_initialPair has equal height to the glue below it.

Example

Question:

  • I understand how the horizontal misalignment happens.
  • I do not understand why the stretching (in both dimensions) of visible components happens, despite there always being glue to take up the excess space.

In both cases: How can I fix it?
Ideally without overriding all the classes and inflating my code by its size again.

import javax.swing.*;

class Test
{
  public static void main(String[] args)
  {
    String[] sourceAPackage = { "A::entry1", "A::entry2", "A::entry3" };
    String[] sourceBPackage = { "B::entry1", "B::entry2" };
    String[] targetPackage = {};

    JList<String> targetList = new JList<String>(targetPackage);
    JScrollPane targetScroller = new JScrollPane(targetList);

    JComboBox sourceAMask = new JComboBox<String>(sourceAPackage);
    JComboBox sourceBMask = new JComboBox<String>(sourceBPackage);
    sourceAMask.setEditable(true);
    sourceBMask.setEditable(true);

    Box mask_initialPair = new Box(BoxLayout.X_AXIS);
    mask_initialPair.add(sourceAMask);
    mask_initialPair.add(sourceBMask);
    mask_initialPair.add(Box.createHorizontalGlue());

    Box maskPairs = new Box(BoxLayout.Y_AXIS);
    maskPairs.add(mask_initialPair);
    maskPairs.add(Box.createVerticalGlue());

    Box maskPage = new Box(BoxLayout.X_AXIS);
    maskPage.add(Box.createHorizontalGlue());
    maskPage.add(maskPairs);
    maskPage.add(targetScroller);
    maskPage.add(Box.createHorizontalGlue());

    JFrame frame = new JFrame();
    frame.add(maskPage);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }
}
Zsar
  • 443
  • 3
  • 14
  • can you paste in a screenshot? Hard to answer without anything visual – Oliver Watkins Dec 15 '15 at 15:29
  • Note: I read in a few other topics, e.g. in various comments on [this topic](http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi) that `JComboBox`, which I use here, does not correctly calculate its preferred size (as equal maximum size?). That would be a source of the undesired behaviour observed in the example; is there a way to override its method to correctly return the size needed (height according to font, width according to widest element)? – Zsar Dec 15 '15 at 15:38
  • @OliverWatkins : Oops, forgot about that. Done. – Zsar Dec 15 '15 at 15:43
  • I would not use BoxLayout or GridLayout for things like combos because they tend to stretch things out. Why not use a FlowLayout for the combos? Or you could use GridBagLayout. I would have BorderLayout, and have the List to the east, and a panel in the center. In the panel i would set to flowlayout (default) and then add the combos. – Oliver Watkins Dec 15 '15 at 15:50
  • @OliverWatkins : Using FlowLayout raises the new problem of having to prevent linebreaks. Which, looking at its API entry, seems to be impossible. – Zsar Dec 15 '15 at 16:09
  • @OliverWatkins : BorderLayout assigns to CENTER more width than to EAST and WEST, even if components in CENTER require much less space. Again, I see no methods to change this behaviour. – Zsar Dec 15 '15 at 16:16
  • Yes Flowlayout creates linebreaks. An easy way to prevent the combos being stretched is to add them to a panel, and then add the panel. Ie. the BoxLayout would then stretch out the panel, but the combos would just float normally inside the panel – Oliver Watkins Dec 16 '15 at 08:18

0 Answers0