9

I am displaying a list of key value pairs in a swing JPanel. The key is displayed in a JLabel and the Value is displayed in a JTextField. There is enough room on the panel to display 1 or 2 columns of the key value pairs depending on how big the parent JFrame is. I would like to display 2 columns of key value pairs unless the panel gets too small. Then I want to switch to one column. Is this possible in Swing without writing my own custom layout manager?

Putting each key value pair on it's own panel and adding the panels to a Flow Layout would do what I want to do except that labels would not be aligned with each other and text fields would not align with each other so it would look terrible. Is there a better way to do this?

Edit:

Here is what it would look like. If the panel is big enough, show two columns. Otherwise show one column.

2 Columns:

   Some Key _______________                Key 2 ________________ 
Another Key _______________      Yet Another Key ________________
      Key 5 _______________                Key 6 ________________

1 Column

       Some Key _______________                
          Key 2 _______________ 
    Another Key _______________      
Yet Another Key _______________
          Key 5 _______________                
          Key 6 ________________
Jay Askren
  • 10,282
  • 14
  • 53
  • 75
  • 1) Provide ASCII art of the GUI as it should appear in smallest size and (if resizable) with extra width/height. 2) See the [Nested Layout Example](http://stackoverflow.com/a/5630271/418556) for ideas about how to *combine* layouts to create the required layout. – Andrew Thompson Nov 20 '13 at 20:44
  • @Andrew Thompson The example I gave in the question was an example of combining layouts. – Jay Askren Nov 20 '13 at 21:10
  • You might use a `GroupLayout` as seen in [this answer](http://stackoverflow.com/a/16353404/418556). There are other solutions pre `GroupLayout`, but look at that first. – Andrew Thompson Nov 20 '13 at 21:50

1 Answers1

3

You could use your FlowLayout idea and still make the labels/textfields lineup. Add a strut to each key/value panel that's the size of your longest label to force the textfield out to the right the same amount on each panel. Something like:

import java.awt.*;
import javax.swing.*;

public class Test implements Runnable
{
  private String[] keys = {"One", "Twoooooo", "Three", "Four",
                           "Five", "Six", "Seven", "Eight",
                           "Nine", "Ten", "Eleven", "Twelve"};
  private String[] values = {"Apple", "Boy", "Cat", "Denmark",
                             "Elephant", "Foo", "Hello", "Igloo",
                             "Jug", "Kangaroo", "Lip", "Now"};

  public static void main(String[] args)
  {
    SwingUtilities.invokeLater(new Test());
  }

  public void run()
  {
    JPanel panel = new JPanel(new FlowLayout());
    GridBagConstraints gbc;
    JTextField textField = null;
    int maxWidth = 0;
    JLabel[] labels = new JLabel[keys.length];

    for (int i = 0; i < keys.length; i++)
    {
      labels[i] = new JLabel(keys[i]);
      maxWidth = Math.max(labels[i].getPreferredSize().width, maxWidth);
    }

    JPanel[] panels = new JPanel[keys.length];

    for (int i = 0; i < keys.length; i++)
    {
      panels[i] = new JPanel(new GridBagLayout());

      gbc = new GridBagConstraints();
      gbc.gridx = 0;
      gbc.gridy = 0;
      gbc.anchor = GridBagConstraints.EAST;
      gbc.insets = new Insets(1,1,1,1);
      panels[i].add(Box.createHorizontalStrut(maxWidth), gbc);

      gbc.gridy = 1;
      panels[i].add(labels[i], gbc);

      textField = new JTextField(10);
      textField.setText(values[i]);
      gbc.gridx = 1;
      panels[i].add(textField, gbc);

      panel.add(panels[i]);
    }

    JFrame frame = new JFrame("Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(panel);
    frame.setSize(240, 400);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}
splungebob
  • 5,357
  • 2
  • 22
  • 45
  • I haven't done Swing development for a couple of years, so there may be something more current, but MigLayout - http://www.miglayout.com makes some of this a lot easier. – GreyBeardedGeek Nov 20 '13 at 22:05
  • @GreyBeardedGeek Not a big fan of the Mig. I'm aware that some gurus here swear by it, so I'm sure it has its merits. Normally if I do GBL code, I use some helper classes that I wrote that would eliminate most of the GBL code you see here. – splungebob Nov 21 '13 at 14:25