0

I am trying to write Swing by hand (yeah crazy, I know) and for some reason this part panel I create here:

private JPanel createColorSliderPanel() {
    JPanel colorSliderPanel = new JPanel(new GridLayout(3, 1, 0, 5));

    JPanel redSliderPanel = new JPanel(new BorderLayout());
    JPanel greenSliderPanel = new JPanel(new BorderLayout());
    JPanel blueSliderPanel = new JPanel(new BorderLayout());

    GridLayout grid = (GridLayout) colorSliderPanel.getLayout();


    redSlider = new JSlider();
    greenSlider = new JSlider();
    blueSlider = new JSlider();

    redField = new JTextField();
    greenField = new JTextField();
    blueField = new JTextField();

    redField.setEditable(false);
    greenField.setEditable(false);
    blueField.setEditable(false);

    JLabel redLabel = new JLabel("Red");
    JLabel greenLabel = new JLabel("Green");
    JLabel blueLabel = new JLabel("Blue");

    redLabel.setPreferredSize(new Dimension(64, 16));
    redField.setPreferredSize(new Dimension(32, 16));
    redSliderPanel.add(redLabel, BorderLayout.WEST);
    redSliderPanel.add(redSlider, BorderLayout.CENTER);
    redSliderPanel.add(redField, BorderLayout.EAST);

    greenLabel.setPreferredSize(new Dimension(64, 16));
    greenField.setPreferredSize(new Dimension(32, 16));
    greenSliderPanel.add(redLabel, BorderLayout.WEST);
    greenSliderPanel.add(redSlider, BorderLayout.CENTER);
    greenSliderPanel.add(redField, BorderLayout.EAST);

    blueLabel.setPreferredSize(new Dimension(64, 16));
    blueField.setPreferredSize(new Dimension(32, 16));
    blueSliderPanel.add(redLabel, BorderLayout.WEST);
    blueSliderPanel.add(redSlider, BorderLayout.CENTER);
    blueSliderPanel.add(redField, BorderLayout.EAST);


    colorSliderPanel.add(redSliderPanel);
    colorSliderPanel.add(greenSliderPanel);
    colorSliderPanel.add(blueSliderPanel);

    return colorSliderPanel;
}

doesn't work as intended:

pic

It's supposed to stack the three panels I make on top of each other. I add it to my JFrame like this:

JPanel sliderPanel = createColorSliderPanel();
...
contentPane.add(sliderPanel, BorderLayout.SOUTH);

Any clue why it doesn't display properly?

OmniOwl
  • 5,477
  • 17
  • 67
  • 116
  • 1
    Wring Swing by hand is not crazy at all.......It's just cooler and way better (and also, the oNLY way to understand how layouts are actually working in your GUI).....look into WindowBuilder once you're bored with the adventure. – ha9u63a7 Mar 18 '15 at 21:07
  • Don't stuff around with setPreferred/Minimum/MaximumSize. See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi) for more details – MadProgrammer Mar 18 '15 at 21:09
  • Okay, but that doesn't really solve my issue. – OmniOwl Mar 18 '15 at 21:12
  • @Vipar That's why its a comment – MadProgrammer Mar 18 '15 at 21:16
  • @MadProgrammer Damn you and your reasonable logic! – OmniOwl Mar 18 '15 at 21:18

1 Answers1

2

The problem is, you only adding the redSlider/Field/Label to all of the other panels

redSliderPanel.add(redLabel, BorderLayout.WEST);
redSliderPanel.add(redSlider, BorderLayout.CENTER);
redSliderPanel.add(redField, BorderLayout.EAST);

greenSliderPanel.add(redLabel, BorderLayout.WEST);
greenSliderPanel.add(redSlider, BorderLayout.CENTER);
greenSliderPanel.add(redField, BorderLayout.EAST);

blueSliderPanel.add(redLabel, BorderLayout.WEST);
blueSliderPanel.add(redSlider, BorderLayout.CENTER);
blueSliderPanel.add(redField, BorderLayout.EAST);

Doing this, will remove the redSlider, redField and redLabel from the container it was previous added to meaning that it will only appear on the blueSliderPanel.

Don't use setPreferred/Minimum/MaximumSize, you don't control the metrics by which a component measures it's required sizes. Provide sizing hints to the components so that they can make better decisions.

redField = new JTextField(4);
greenField = new JTextField(4);
blueField = new JTextField(4);

Layout

Then don't add the fields to sub panels first

Then don't add your fields to separate panels first, but, you might find that something like GridBagLayout makes a better choice...

GridBagConstraints

JPanel colorSliderPanel = new JPanel(new GridBagLayout());

redSlider = new JSlider();
greenSlider = new JSlider();
blueSlider = new JSlider();

redField = new JTextField(4);
greenField = new JTextField(4);
blueField = new JTextField(4);

redField.setEditable(false);
greenField.setEditable(false);
blueField.setEditable(false);

JLabel redLabel = new JLabel("Red");
JLabel greenLabel = new JLabel("Green");
JLabel blueLabel = new JLabel("Blue");

addTo(colorSliderPanel, redLabel, redSlider, redField, 0);
addTo(colorSliderPanel, greenLabel, greenSlider, greenField, 1);
addTo(colorSliderPanel, blueLabel, blueSlider, blueField, 2);

And the addTo method...

protected void addTo(JPanel parent, JLabel label, JSlider slider, JTextField field, int gridY) {

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.anchor = GridBagConstraints.WEST;
    gbc.gridx = 0;
    gbc.gridy = gridY;
    parent.add(label, gbc);

    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.gridx++;
    gbc.weightx = 1;
    parent.add(slider, gbc);

    gbc.gridx++;
    gbc.weightx = 0;
    parent.add(field, gbc);

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • But now the UI is not uniform. I'd like the labels to take up equal amounts of space. – OmniOwl Mar 18 '15 at 21:20
  • One of things I noticed when I ran the code was that there was space above the label/sider/field, which suggested, something was been added, it was just working out why the fields you were expecting weren't :P – MadProgrammer Mar 18 '15 at 21:21
  • @Vipar Then don't add the fields to sub panels first – MadProgrammer Mar 18 '15 at 21:22
  • 1
    but how does that help the problem..? Doesn't that just mean that each label will take out 1/3 of the space? That's way too much. The Labels just needs to take as much space as the Green Label as it's the longest label. – OmniOwl Mar 18 '15 at 21:23
  • 1
    @Vipar Yes, but now they are the same size. You might consider using something like `GridBagLayout` instead, which provides you with more control over the space that each component is allocated, see update – MadProgrammer Mar 18 '15 at 21:32