tags:

views:

264

answers:

6

Hi everyone, I have a question about laying out some swing components.

Say, I have a JPanel which contains a JLabel and a JTextField. I want JLabel to be drawn on the left-most side of JPanel, and JTextField to be drawn on the right-most side of JPanel. I tried using BoxLayout and Horizontal Glues, but I couldn't make it work. Can somebody explain how this should be done? And by the way, I also should be able to set the JTextField's size, which will grow from right to left.

EDIT: Here is my class, it's pretty simple.

public class TextField extends JPanel {
    private JLabel label;
    private JTextField textField;
    public TextField(String labelText){
     this.label = new JLabel(labelText);
     this.textField = new JTextField("");
     Box horizontalBox = Box.createHorizontalBox();
     horizontalBox.add(label);
     horizontalBox.add(Box.createHorizontalGlue());
     horizontalBox.add(textField);
     add(horizontalBox);
    }
}
A: 

To use BoxLayout:

public TextField(String labelText){
    this.label = new JLabel(labelText);
    this.textField = new JTextField("");
    this.setLayout( new BoxLayout( this, BoxLayout.X_AXIS ) );
    this.add( label );
    this.add( Box.createHorizontalGlue() );
    this.add( textField );
}

I like to use GridBagLayout for panels that have either complex layouts or components that should "fill" part of the panel.

JPanel panel = new JPanel();
JLabel label = new JLabel( "Enter your text:" );
JTextField textField = new JTextField();
panel.setLayout( new GridBagLayout() );
panel.add( label, 
    new GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0, 
    GridBagConstraints.EAST, GridBagConstraints.NONE,
    new Insets( 0, 0, 0, 0 ), 0, 0 ) );
panel.add( textField, 
    new GridBagConstraints( 1, 0, 1, 1, 1.0, 0.0, 
    GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
    new Insets( 0, 0, 0, 0 ), 0, 0 ) );

You can find a good explanation of how you use GridBagLayout here.

Joseph Gordon
+1  A: 

I tried using BoxLayout and Horizontal Glues, but I couldn't make it work. Can somebody explain how this should be done?

There is no trick to this. Read the Swing tutorial on How to Use Box Layout for a working example.

If it still doesn't work then you need to post your SSCCE because we can't guess what you might be doing wrong.

camickr
+1  A: 

You could also use border layout and add the label using the BorderLayout.WEST option and the TextField using the BorderLayout.EAST option.

broschb
+1, but TextField should do to CENTER
tulskiy
+1  A: 

One of the best ways to debug swing UIs is to add visible borders to your components to get a better idea of what is going on.

Try adding this after you create the horizontalBox:

horizontalBox.setBorder(BorderFactory.createLineBorder(Color.black));

Most likely what you will find is that your TextField is shrunk to the absolute minimum size required to display whatever text you pass to the constructor and the minimum size of the JTextField (which is basically just one visible character space).

Now try adding this to the constructor:

horizontalBox.setPreferredSize(new Dimension(400, 40));

Then try replacing the glue with a strut:

horizontalBox.add(Box.createHorizontalStrut(30));

That said, I think the biggest issue is that you are using a JPanel and then adding a box component to it, which makes resizing of the component problematic.

Try this and see if it works for you:

public TextField(String labelText){
    this.label = new JLabel(labelText);
    this.textField = new JTextField("");
    this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    this.setBorder(BorderFactory.createLineBorder(Color.black));  // debug
    this.add(label);
    this.add(Box.createHorizontalStrut(30));
    this.add(textField);
}

[p.s.]

You really want to reconsider the name of that JPanel extension. Perhaps TextFieldDisplay or TextFieldPanel would be more appropriate.

Thank you for the debugging trick, it was good to know.
Erkan Haspulat
A: 

The problem with the code that you posted isn't so much the BoxLayout, it's the layout that contains it. By default, JPanel uses FlowLayout. When you add a component to a FlowLayout it does not expand to fill all of the available space.

So, instead of adding a Box to the panel, either make the class extend Box or set the panel layout to BoxLayout and add the components directly.

Dan Dyer
A: 

Set your JPanel to use BorderLayout. This, in combination with Box will give you almost any layout you need.

tulskiy