26

I am trying to have several JTextFields on a single row, but I don't want them to have the same width. How can I control the width and make some of them wider than others? I want that they together take up 100% of the total width, so it would be good if I could use some kind of weigthing.

I have tried with .setColumns() but it doesn't make sense.

Here is an example, where I am using three rows with three strings that should appear as in columns:

import java.awt.GridLayout;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class RowTest extends JPanel {

    class Row extends JComponent {
        public Row(String str1, String str2, String str3) {
            this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

            JTextField fld1 = new JTextField(str1);
            JTextField fld2 = new JTextField(str2);
            JTextField fld3 = new JTextField(str3);

            fld1.setColumns(5); // makes no sense

            this.add(fld1);
            this.add(fld2);
            this.add(fld3);
        }
    }

    public RowTest() {
    this.setLayout(new GridLayout(5,0));

    this.add(new Row("Short", "A long text that takes up more space",
        "Short again"));
    this.add(new Row("Longer but short", "Another long string", "Short"));
    this.add(new Row("Hello", "The long field again",
        "Some info"));
    }

    public static void main(String[] args) {
        new JFrame() {{ this.getContentPane().add(new RowTest());
                            this.pack(); this.setVisible(true); }};
    }

}
Jonas
  • 121,568
  • 97
  • 310
  • 388
  • I think you need to not use the BoxLayout for your Row class. Box is pushing everything into, well, Boxes. You need a layout that pushes the elements together. – Yishai May 24 '10 at 14:26
  • @Yishai: Yes, I think the problem can be there. But I don't know what LayoutManager I should use instead... Any suggestions? – Jonas May 24 '10 at 14:45
  • @Jonas, what type of algorithm are you looking for for the actual widths? Your running example (at least for me) has varying widths, so you clearly want to vary them in a different way. What way? – Yishai May 24 '10 at 14:51
  • I find you can't beat a GridBagLayout most (say around 95%). Can be a bit confusing the first few times but well worth getting up to speed with. – vickirk May 24 '10 at 14:53
  • @Yishai: I want the JTextFields in **columns** and would prefer to set the **width** in percent. I.e. `30% 50% 20%`. – Jonas May 24 '10 at 15:13
  • @Jonas, please excuse my obtuseness, but you are saying that you want each label in a given Row to align in an even grid with the label in the Row underneath it? – Yishai May 24 '10 at 15:22
  • @Yishai: Yes, that is correct ;) Sorry for my bad explanation. – Jonas May 24 '10 at 15:27

4 Answers4

52
yourTextField = new JTextField("", 20);

if you start it like this it sets the textfield to be empty and to have 20 collumns

animuson
  • 53,861
  • 28
  • 137
  • 147
  • This should be the accepted answer. "SetPreferredSize()" method mentioned in the competing answer is obvious from the code insight for an JTextField object, and is useless for all practical purposes. – Tegiri Nenashi Jan 24 '20 at 23:30
  • 3
    For other readers: Instead of setting via the ctor, you may also call this `JTextField` method: `void setColumns(int columns)`. – kevinarpe Dec 24 '20 at 09:59
8

Try this:

textfield.setPreferredSize(new Dimension(int width, int height));
Psychosis404
  • 91
  • 1
  • 6
7

All Swing components have a preferred size. The preferred size of a text component is based on the text of the component. So generally the component is painted at its preferred size.

So I don't see the problem with your code snippet. Each text field should have a different preferred size. Also, as the frame is resized the width will be adjusted since the BoxLayout will try to resize each component up to its maximum/minimum size.

If you need more help post your SSCCE that actually demonstrates the sizing problem you are experiencing.

Edit:

Based on the latest requirement you can use the Relative Layout.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • I have updated my example now. It works fine except that I don't get the TextFields in columns since I can't control it's **width** – Jonas May 24 '10 at 14:40
  • If you want the components lined up in columns then you can't use multiple child panels since layout managers work independently of one another. You need to add all the compnents to the same panel and use a layout manager that supports columns. You can try using the SpringLayout or the GridBagLayout. Examples of each layout manager is found in the Swing tutorial on Using Layout Managers: http://java.sun.com/docs/books/tutorial/uiswing/TOC.html. You could also use a GridLayout, but you would need to wrap each text field in a JPanel to prevent the text field from being resized. – camickr May 24 '10 at 14:53
  • I haven't tried it, but Relative Layout seems like the reasonable solution if the panels are to stay with seperate layout managers. Typically such a case is solved by having one panel with one layout for all 9 components. – Yishai May 24 '10 at 18:32
  • Thanks, **RelativeLayout** was exactly what I was looking for! – Jonas May 25 '10 at 06:27
0
// 1. create JTextField
yourTextField = new JTextField();
// 2. store default height
int defaultHeight = yourTextField.getSize().getHeight();
// 3. set custom width and default height
yourTextField.setSize(new Dimension(yourWidth, defaultHeight));
Xorty
  • 18,367
  • 27
  • 104
  • 155
  • Thanks, I can try with that. But I would like to go with the default Height, and not set it. – Jonas May 24 '10 at 14:12
  • @Xorty: This is not working. I think the problem is that the layoutmanager maybe ignore this values. And I would prefere a solution where I don't have to set the Height manually. – Jonas May 24 '10 at 14:24
  • -1, No, you should never use setSize(). The layout manager uses -information from the preferred size, maximum size and minumum size (in some cases) to determine the size the component will be painted at. Read the section from the Swing tutorial on "Using Layout Managers" - http://java.sun.com/docs/books/tutorial/uiswing/TOC.html – camickr May 24 '10 at 14:26
  • @Jonas so use some nice IDE like NetBeans with Swing GUI builder and set it in properties ... either this way, or way I suggested - programatically – Xorty May 24 '10 at 14:26
  • @camickr : I've been recently building rather large Swing applications, and it worked perfectly - tested with multiple managers and even multiple system managers for different operating systems :O – Xorty May 24 '10 at 14:28
  • When using a layout manager setSize() does NOT work. Read the tutorial. This is the whole reason layout managers exist. Based on the rules of the layout manager the size and location of a component is calculated. You can set the size but it will be ignored. – camickr May 24 '10 at 14:35
  • @camickr - I am sorry, you are right. I just checked our sources, and we do not user layout manager(null), that it is probably reason why it works (with JLabels setSize in our code works good) – Xorty May 24 '10 at 14:44