0
public class LabelResizing2 {

    public static JPanel createSliderPanel(
            int min, int max, int curr)
    {       
        /*outer panel*/
        final JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 
        panel.setBorder(BorderFactory.createRaisedBevelBorder());       

        final JLabel valueLabel = new JLabel();
        valueLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

        /*set up slider*/
        final JSlider slider = new JSlider(JSlider.VERTICAL, min, max, curr);
        slider.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

        panel.add(valueLabel); 
        panel.add(slider);

        /*slider move event*/
        slider.addChangeListener(new ChangeListener() {

            public void stateChanged(ChangeEvent event) {

                valueLabel.setText(Integer.toString(slider.getValue()));
            }


        });

        valueLabel.setText(Integer.toString(curr));
        return panel; 
    }

    public static void main(String[] args) {
        JFrame gui = new JFrame("Label Resizing");
        gui.setMinimumSize(new Dimension(500, 500));
        gui.add(createSliderPanel(-100, 100, 0)); 
        gui.setVisible(true); 

    }

}

The problem here is that the slider will move all over the place, as the label resizes from '99' to '100' and from '0' to '-1' etc.

Several questions:

  1. Why is it bouncing around?
  2. If I put in

    valueLabel.setSize(100, 100); it does absolutely nothing. Why?

    valueLabel.setMinimumSize(100,100); will stop it bouncing around, but doesn't actually resize the label. Why?

  3. Best solution I've found is to go slider.setAlignmentX(Component.LEFT_ALIGNMENT);Is this a good solution? However, this won't work for CENTER_ALIGNMENT or RIGHT_ALIGNMENT, what's going on here?

  4. If we modify it a bit and put the valueLabel inside a panel.

:

final JPanel labelPanel = new JPanel(); 
final JLabel valueLabel = new JLabel();
valueLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
labelPanel.add(valueLabel); 
labelPanel.setBorder(BorderFactory.createLineBorder(Color.RED));
panel.add(labelPanel); 
panel.add(slider); 

The slider still moves around, even though the labelPanel isn't resizing (the valueLabel is resizing inside it). What's going on here? Is the layout manager also looking at nested components?

dwjohnston
  • 11,163
  • 32
  • 99
  • 194

1 Answers1

1

1 Why is it bouncing around?

That's the nature of this particular layout manager. As the component's preferredSize is changed, the layout manager is updating the layout.

2 If I put in

valueLabel.setSize(100, 100); it does absolutely nothing. Why?
valueLabel.setMinimumSize(100,100); will stop it bouncing around, but doesn't actually resize the label. Why?

Changing the size of a component under the control of a layout manager has no effect because the layout manager will resize the component when it re-lays out it's children.

preferred/minimum/maximumSize are "suggestions" that the layout managers may use to determine how best to perform their individual layouts, they are not obligated to use them in any way.

3 Best solution I've found is to go slider.setAlignmentX(Component.LEFT_ALIGNMENT);. Is this a good solution?

I guess so, but "Be aware that these are hints only and might be ignored by certain layout managers"

4 If we modify it a bit and put the valueLabel inside a panel.

Now, instead of the components begin effected directly by the layout manager, each panel is effect it's parent layout manager, net result, some problem

UPDATED with example

In this case, you can cheat a little...

public class BadLayout03 {

    public static void main(String[] args) {
        new BadLayout03();
    }

    public BadLayout03() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestLayout());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestLayout extends JPanel {

        public TestLayout() {
            setLayout(new GridBagLayout());

            final JLabel valueLabel = new JLabel("000");
            final JSlider slider = new JSlider();

            slider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    StringBuilder sb = new StringBuilder(Integer.toString(slider.getValue()));
                    while (sb.length() < 3) {
                        sb.insert(0, "0");
                    }
                    valueLabel.setText(sb.toString());
                }
            });

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = 0.75;
            gbc.anchor = GridBagConstraints.WEST;
            valueLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
            add(valueLabel, gbc);
            gbc.gridx = 1;
            gbc.weightx = 1;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            add(slider, gbc);
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366