0

I'm writing a Java program (minimum compilable example below), and I'm trying to pretty up the user interface by making some elements line up. If you run this, you can see that d_ip and d_pword would look a lot better if I could make them the same size. And I want them to dynamically stay the same size even when you resize the window.

GroupLayout has a linkSize() method that lets you link the sizes of unrelated objects. This works great with buttons and labels. But with JTextField, it's a disaster. Even if I set the minimum size on one of them to something large, it still insists on setting the sizes to zero.

I've also tried things like telling GroupLayout that the horizontal min and preferred sizes are GroupLayout.DEFAULT_SIZE or GroupLayout.PREFERRED_SIZE to no avail. Can anyone tell me if there is any way I can coerce JTextField to work properly with linkSize?

Note that to turn on the linkSize, there is a line, labeled with a comment, that you need to uncomment. When you do that, the JTextField widths get messed up. Also, try adding d_username to the list of linked objects. Now, even though theres 'tension,' you might say, to make the username/password row horizontally the width of the window, the fields go to zero size and won't resize.

Thanks!

package textfield;

import java.awt.Container;
import java.awt.Dimension;
import javax.swing.ButtonGroup;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.UIManager;

public class TextField extends JFrame {
    JTextField d_mount, d_ip, d_share, d_username, d_pword;
    JRadioButton nfs, smb;
    JButton save, revert;

    TextField() {
        Container pane = this.getContentPane();

        JLabel lmount = new JLabel("Mount Point:");
        JLabel ltype = new JLabel("Share Type:");
        JLabel lip = new JLabel("IP Address:");
        JLabel lshare = new JLabel("Remote Share:");
        JLabel lusername = new JLabel("Username:");
        JLabel lpassword = new JLabel("Password:");

        d_mount = new JTextField();
        nfs = new JRadioButton("NFS");
        smb = new JRadioButton("SMB");
        ButtonGroup group = new ButtonGroup();
        group.add(nfs);
        group.add(smb);
        d_ip = new JTextField();
        d_share = new JTextField();
        d_username = new JTextField();
        d_pword = new JTextField();

        d_ip.setMinimumSize(new Dimension(200, 0));

        save = new JButton("Save");
        revert = new JButton("Revert");

        GroupLayout layout = new GroupLayout(pane);
        pane.setLayout(layout);

        layout.setVerticalGroup(
            layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(lmount)
                    .addComponent(d_mount)
                    )
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(ltype)
                    .addComponent(nfs)
                    .addComponent(smb)
                //    )
                //.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(lip)
                    .addComponent(d_ip)
                    )
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(lshare)
                    .addComponent(d_share)
                    )
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE, true)
                    .addComponent(lusername)
                    .addComponent(d_username)
                    .addComponent(lpassword)
                    .addComponent(d_pword)
                )
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(revert)
                    .addComponent(save)
                )
            );
        layout.setHorizontalGroup(
            layout.createParallelGroup()
                .addGroup(layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                        .addComponent(lmount)
                        .addComponent(ltype)
                        .addComponent(lshare)
                        .addComponent(lusername)
                        )
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(d_mount)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(nfs)
                            .addComponent(smb)
                            .addGap(20, 20, Integer.MAX_VALUE)
                            .addComponent(lip)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(d_ip, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            )
                        .addComponent(d_share)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(d_username, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                            .addComponent(lpassword)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(d_pword, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            )
                        )
                    )
                .addGroup(layout.createSequentialGroup()
                    .addGap(0, 0, Integer.MAX_VALUE)
                    .addComponent(revert)
                    .addComponent(save)
                    )
            );


        // ****** ADD THIS LINE BACK IN ******
        //layout.linkSize(SwingConstants.HORIZONTAL, d_pword, d_ip);

        pack();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        try {         
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());     
        }      catch (Exception e) {        
        }

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TextField().setVisible(true);
            }
        });
    }
}
Filburt
  • 17,626
  • 12
  • 64
  • 115
Timothy Miller
  • 1,527
  • 4
  • 28
  • 48

2 Answers2

3

The immediate solution is to suggest a size in columns. Viz.

d_pword = new JTextField(15);

Notes:

  • I disagree that the GUI looks best when those two fields are aligned. There is no logical connection between them, so linking the size seems irrelevant & misleading.
  • The d_pword field should be a JPasswordField.
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1
    See also this possibly related [example](http://stackoverflow.com/a/8504753/230513). – trashgod Jun 04 '12 at 02:06
  • @trashgod Agreed. That GUI also seems to be suggesting component sizes by the natural means (column size etc.) - a basic principal for using most components in most layouts, really. – Andrew Thompson Jun 04 '12 at 02:11
  • I voted for your answer but didn't accept it. Adding the 15 HELPS, but it doesn't solve the underlying problem of JTextField widgets being non-resizable when `linkSize` is used. Irregardless of the HCI guideline I may be violating in order to make this UI more compact (and indeed it's still very much in an early design phase), I can find no way to make JTextField widgets both resizable AND linked. – Timothy Miller Jun 04 '12 at 15:12
0

The underlying problem may be that it is if you linkSize two objects, both become inherently un-resizable.

That is if what this book says is true:

http://books.google.com/books?id=kELcexu0pAcC&pg=PA67&lpg=PA67&dq=grouplayout+linksize+resIzable&source=bl&ots=Syy_LnNd4W&sig=cLGV96RAJeYEeV2ZDt_bmeBZqCM&hl=en&sa=X&ei=bdDMT9mMJMms2gW8m6z1DA&ved=0CFMQ6AEwAw#v=onepage&q=grouplayout%20linksize%20resIzable&f=false

Timothy Miller
  • 1,527
  • 4
  • 28
  • 48
  • The same thing is said here in the section on linkSize: http://www.docjar.org/docs/api/javax/swing/GroupLayout.html#linkSize(int,%20Component) – Timothy Miller Jun 04 '12 at 15:18