Hot questions for Using JTextField in layout manager

Top Java Programmings / JTextField / layout manager

Question:

I am trying to make a frame and add a text field inside it. For that I used JTextField. But it's not appearing.

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

class Tst
{
    JFrame f;
    JTextField tf;

    public Tst()
    {
        f=new JFrame();
        tf=new JTextField(10);
        f.setSize(400,400);
        f.add(tf);
        f.setLayout(null);
        f.setVisible(true);
    }

    public static void main(String s[])
    {
        new Tst();
    }
}

Answer:

If you don't want to use a layout manager, you need to set its bounds using JTextField's setBounds(x, y, width, height) method, where x and y are position of the textfield in the JFrame:

tf.setBounds(100 , 100 , 100 , 20 );

First set layout to your frame, then add elements and components to it, like in the full code:

import javax.swing.*;

class Tst
{
    public Tst()
    {
        JTextField tf = new JTextField(10);
        tf.setBounds(100 , 100 , 100 , 20 );

        JFrame f = new JFrame();

        f.setSize(400, 400);
        f.setLayout(null);
        f.setVisible(true);
        f.add(tf);

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String s[])
    {
        new Tst();
    }
}

Question:

I'm using a grid layout for one of my programs and when i try to add JTextFields to the grid It doesn't show at all. If i try adding JButtons instead of JTextFields in the same method it works perfectly.

    package suDUKO;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;

import javax.swing.JTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class Gui_Class {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension blocksize;
    private final  int screenW=(int) (screenSize.getWidth()/2);
    private final  int screenH=(int) (screenSize.getHeight()/2);
    JFrame frame;
    JPanel panel;

        public Gui_Class() {
            frame=new JFrame("Suduko");
            frame.setBounds((int) screenW-500,screenH-500,500,500);
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.setVisible(true);
            panel=new JPanel();
            frame.add(panel);
            panel.setVisible(true);

            panel.setLayout(new GridLayout(9, 9));
            JTextField [][] table = new JTextField[9][9];
            for(int m = 0; m < 9; m++) {
                   for(int n = 0; n < 9; n++) {
                      table[m][n]=new JTextField(m+" "+n);
                      table[m][n].setVisible(true);
                      panel.add(table[m][n]);

                   }
                }
    }
}

Answer:

There are a number of problems with this code. The main ones that you asked about, can be fixed by adding all the components, then calling pack() before finally calling setVisible(true);.

If the code as seen above does those things, the GUI won't be 500 x 500 in size, and will not be centered. Each has it's own best approach.

Firstly, it seems you want the content pane to be square (500 x 500), and that won't happen if the frame is 500 x 500, because it has a title bar and possibly borders to render. Then centering a GUI on screen is as simple as frame.setLocationRelativeTo(null).

You've already marked this correct, but was just preparing an example of what is written above, so here it is!

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

public class Gui_Class {

    JFrame frame;
    JPanel panel;

    public Gui_Class() {
        frame = new JFrame("Suduko");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        panel = new JPanel(new GridLayout(9, 9));
        frame.add(panel);
        //panel.setVisible(true); //unnecessary 

        JTextField[][] table = new JTextField[9][9];
        for (int m = 0; m < 9; m++) {
            for (int n = 0; n < 9; n++) {
                table[m][n] = new SquareTextField(m + " " + n);
                panel.add(table[m][n]);
            }
        }

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            new Gui_Class();
        };
        SwingUtilities.invokeLater(r);
    }
}

class SquareTextField extends JTextField {

    int size = 30;

    SquareTextField(String s) {
        super(s);
        setFont(getFont().deriveFont((float)size));
        int sz = size/6;
        setMargin(new Insets(sz, sz, sz, sz));
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension d = super.getPreferredSize();
        int w = d.width;
        int h = d.height;
        int max = w>h ? w : h;

        return new Dimension(max, max);
    }
}

Question:

I can`t add this TextField to the interface, the resulting window is plain without any details on it , altough I tried a lot to find where the problem is.. here is the code: import java.awt.ComponentOrientation; import java.awt.Font;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;

public class Calculator extends JFrame {
    private JTextField display;

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            System.out.println("Could not load system interface\n");
        }
        new Calculator();
    }

    public Calculator() {
        super("Calculator");
        sendDisplay();
        sendUI(this);
    }

    private void sendDisplay() {
        display = new JTextField("0");
        display.setBounds(10, 10, 324, 50);
        display.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        display.setEditable(false);
        display.setFont(new Font("Arial", Font.PLAIN, 30));
        display.setVisible(true);
        add(display);
    }

    private void sendUI(Calculator app) {
        app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        app.setVisible(true);
        app.setSize(400, 600);
        app.setLayout(null);
        app.setResizable(false);
        app.setLocationRelativeTo(null);
    }
}

I would be grateful if someone could find the problem


Answer:

Make setVisible(true) is the last statement of your sendUI method

private void sendUI(Calculator app) {
    app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    app.setSize(400,600);
    app.setLayout(null);
    app.setResizable(false);
    app.setLocationRelativeTo(null);

    app.setVisible(true);               
}

Good Practice

  • Avoid using Absolute Positioning (null layout).

Question:

I simply cannot get my JTextFields to align correctly. Right now the program looks like this: .

Now the Assignment numbers are correctly aligned. However the Mark JTextfield starts under 7 and Weight JTextField starts under the last Mark.

Now what I want is for everything to correctly align. Meaning at Assignment 1 there are Mark and Weight JTextFields under the same row. This should go along all the way down to 7 ( or how many number of rows I choose).

Code:

    public class test{

    private static final Insets normalInsets = new Insets(10,10,0,10);
    private static final Insets finalInsets = new Insets(10,10,10,10);





    private static JPanel createMainPanel(){
        GridBagConstraints gbc = new GridBagConstraints();

        //Adding the JPanels. Panel for instructions
        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());

        int gridy = 0;

        //JLabel for the Instructions
        JTextArea instructionTextArea = new JTextArea(5, 30);
        instructionTextArea.setEditable(false);
        instructionTextArea.setLineWrap(true);
        instructionTextArea.setWrapStyleWord(true);

        JScrollPane instructionScrollPane = new JScrollPane(instructionTextArea);
        addComponent(panel, instructionScrollPane, 0, gridy++, 3, 1, finalInsets, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);

        //JLabels for Assignment
        JLabel label1 = new JLabel("Assignment");
        label1.setHorizontalAlignment(JLabel.CENTER);
        addComponent(panel, label1, 0, gridy, 1, 1, finalInsets,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL);

        //JLabel for Mark
        JLabel label2 = new JLabel("Mark");
        label2.setHorizontalAlignment(JLabel.CENTER);
        addComponent(panel, label2, 1, gridy, 1, 1, finalInsets, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);

        //JLabel for Weight.
        JLabel label3 = new JLabel("Weight");
        label3.setHorizontalAlignment(JLabel.CENTER);
        addComponent(panel, label3, 2, gridy++, 1, 1, finalInsets, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);



        //JLabel Number for the number list of assignments at the side.
        for(int i = 1; i<=7; i++){
            String kok = String.valueOf(i);
        JLabel number = new JLabel(kok);
        number.setHorizontalAlignment(JLabel.CENTER);
        addComponent(panel, number, 0, gridy++, 1, 1, normalInsets, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
        }

        //JTextfield for Mark
        for(int i=0; i<7; i++){
        JTextField mark = new JTextField(20);
        mark.setHorizontalAlignment(JLabel.CENTER);
        addComponent(panel, mark, 1, gridy++, 1, 1, normalInsets, GridBagConstraints.CENTER,GridBagConstraints.NONE);
        }

        //JTextfield for Weight
        for(int i=0; i<7; i++){
        JTextField weight = new JTextField(20);
        weight.setHorizontalAlignment(JLabel.CENTER);
        addComponent(panel, weight, 2, gridy++, 1, 1, normalInsets, GridBagConstraints.CENTER,GridBagConstraints.NONE);
        }

        return panel;

    }

    private static void addComponent(Container container, Component component, int gridx, int gridy, int gridwidth, int gridheight, Insets insets, int anchor, int fill ){
        GridBagConstraints gbc = new GridBagConstraints(gridx, gridy, gridwidth, gridheight, 1.0D,1.0D,anchor,fill,insets,0,0);
        container.add(component,gbc);
    }

    public static void main(String[] args) {    
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createMainPanel());
        frame.pack();
        frame.setVisible(true);
        new test();
    }
}

I'm a terrible new Java programmer so go easy please :).

UPDATE~~~~~

 After running the `for` loops which add the `JLabels` and `JTextFields`, you will need to reset `gbc.gridy = 1`. This way the loop will start adding components from the top row.

//JLabel Number for the number list of assignments at the side.
for(int i = 1; i<=7; i++){
    String kok = String.valueOf(i);
    JLabel number = new JLabel(kok);
    number.setHorizontalAlignment(JLabel.CENTER);
    addComponent(panel, number, 0, gridy++, 1, 1, normalInsets, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
}
gbc.gridy = 1;

//JTextfield for Mark
for(int i=0; i<7; i++){
    JTextField mark = new JTextField(20);
    mark.setHorizontalAlignment(JLabel.CENTER);
    gridy = 1; //The code only partly works when I include this
    addComponent(panel, mark, 1, gridy++, 1, 1, normalInsets, GridBagConstraints.CENTER,GridBagConstraints.NONE);
}
gbc.gridy = 1;

And this is what it looks like:

Only the Weight JTextField properly aligned. When I don't add 'gridy=1' it has the same format error as my original screenshot.


Answer:

After running the for loops which add the JLabels and JTextFields, you will need to reset gbc.gridy = 2. This way the loop will start adding components from the top row. Also, in each use of addComponent(), change gridy++ to gbc.gridy++.

gbc.gridy = 2;

//JLabel Number for the number list of assignments at the side.
for(int i = 1; i<=7; i++){
    String kok = String.valueOf(i);
    JLabel number = new JLabel(kok);
    number.setHorizontalAlignment(JLabel.CENTER);
    addComponent(panel, number, 0, gbc.gridy++, 1, 1, normalInsets, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
}
gbc.gridy = 2;

//JTextfield for Mark
for(int i=0; i<7; i++){
    JTextField mark = new JTextField(20);
    addComponent(panel, mark, 1, gbc.gridy++, 1, 1, normalInsets, GridBagConstraints.CENTER,GridBagConstraints.NONE);
}
gbc.gridy = 2;

//JTextfield for Weight
for(int i=0; i<7; i++){
    JTextField weight = new JTextField(20);
    weight.setHorizontalAlignment(JLabel.CENTER);
    addComponent(panel, weight, 2, gbc.gridy++, 1, 1, normalInsets, GridBagConstraints.CENTER,GridBagConstraints.NONE);
}

This is what the result looks like:

Question:

I am trying to get my JTextField (desc) to under the JSpinner, (dayspinner) but I'm not sure how. If I put the text field in SOUTH, it just goes all the way to the bottom of the window. I would also like to implement whatever solution there is to this problem with my beginning menu with the 3 buttons next to each other, I would much rather them be on top of one another.

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

public class Scheduler {

  JButton VDay, VWeek, Task, Exit;
  JFrame wframe, dframe, tframe;
  JTextField hin, min, desc;
  JLabel time;
  JSpinner dayspinner;

  class ButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      if (e.getSource() == VDay) {
        dframe.setVisible(true);
      } else if (e.getSource() == VWeek) {
        wframe.setVisible(true);
      } else if (e.getSource() == Task) {
        tframe.setVisible(true);
      } else if (e.getSource() == Exit) {
        System.exit(0);
      }
    }
  }

  public String[] getDayStrings() {
    String[] dayStrings = {
      "Sunday",
      "Monday",
      "Tuesday",
      "Wednesday",
      "Thursday",
      "Friday",
      "Saturday",
    };
    return dayStrings;
  }


  public void CreateFrame() {
    JFrame frame = new JFrame("Main Menu");
    frame.setSize(350, 250);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    ButtonListener btnlst = new ButtonListener();
    VDay = new JButton("View Day");
    VWeek = new JButton("View Week");
    Task = new JButton("Assign/Edit Tasks");
    Exit = new JButton("Exit");

    VDay.addActionListener(btnlst);
    VWeek.addActionListener(btnlst);
    Task.addActionListener(btnlst);
    Exit.addActionListener(btnlst);

    JPanel center = new JPanel();
    JPanel south = new JPanel();
    south.add(Exit);
    center.add(Task);
    center.add(VDay);
    center.add(VWeek);
    frame.add(south, BorderLayout.SOUTH);
    frame.add(center, BorderLayout.CENTER);
    frame.setVisible(true);


    dframe = new JFrame("Today's Schedule");
    dframe.setSize(500, 500);
    dframe.setVisible(false);

    wframe = new JFrame("Week's Schedule");
    wframe.setSize(1050, 400);
    wframe.setVisible(false);

    tframe = new JFrame("Edit/Add Tasks");
    tframe.setSize(500, 500);
    tframe.setVisible(false);

    //GUI for tframe
    JPanel tnorth = new JPanel();
    JPanel tcenter = new JPanel();
    JPanel tsouth = new JPanel();
    tframe.add(tnorth, BorderLayout.NORTH);
    tframe.add(tcenter, BorderLayout.CENTER);
    tframe.add(tsouth, BorderLayout.SOUTH);

    //time input
    time = new JLabel("Time (HH:MM): ");
    tnorth.add(time);
    hin = new JTextField(2);
    hin.setColumns(5);
    tnorth.add(hin);
    min = new JTextField(2);
    min.setColumns(5);
    tnorth.add(min);

    //select day
    String[] dayStrings = getDayStrings();
    dayspinner = new JSpinner(new SpinnerListModel(dayStrings));
    dayspinner.setPreferredSize(new Dimension(85, 20));
    tcenter.add(dayspinner);

    //event description
    desc = new JTextField(35);
    desc.setColumns(30);
    tcenter.add(desc);


  }


  public static void main(String[] args) {
    Scheduler scheduler = new Scheduler();
    scheduler.CreateFrame();
  }
}

Answer:

Don't use BorderLayout, it's not designed to do what you want, consider trying to use something like GridBagLayout instead, which is far more flexible

See How to Use GridBagLayout for more details

Question:

I am trying to create 4 JLabel components 4 JTextfield components for my Swing based application. I am adding these lables and text fields in one of the many panels of the application.

The class for this panel is as follows:

public class CustomerInfoPanel extends JPanel implements ActionListener {

        private Car[] carList;
        private CarSalesSystem carSystem;
        private int currentIndex = 0;
        private JLabel headingLabel = new JLabel("Enter your details and let us find a car for you");
        private JLabel ageLabel = new JLabel("Age");
        private JLabel genderLabel = new JLabel("Gender");
        private JLabel incomeLabel = new JLabel("Income");
        private JLabel interestLabel = new JLabel("Age");

        private JButton searchButton = new JButton("Search");
        private JButton resetButton = new JButton("Reset");
        private JButton previousButton = new JButton("Previous");
        private JButton nextButton = new JButton("Next");

        //text fields
        private JTextField ageTextField = new JTextField();
        private JTextField genderTextField = new JTextField();
        private JTextField incomeTextField = new JTextField();
        private JTextField interestTextField = new JTextField();

        private JPanel topPanel = new JPanel();
        private JPanel agePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        private JPanel searchButtonsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        private JPanel navigateButtonsPanel = new JPanel();
        private CarDetailsComponents carComponents = new CarDetailsComponents();

        /**
         * @param carSys links to a CarSalesSystem object
         * @param dest where the panel will be displayed on the main frame
         */
        public CustomerInfoPanel(CarSalesSystem carSys)
        {
            carSystem = carSys;
            Insets currentInsets;
            GridBagConstraints gridBagConstraints;
            setLayout(new BorderLayout(0, 20));
            topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));

            previousButton.addActionListener(this);
            nextButton.addActionListener(this);
            resetButton.addActionListener(this);
            searchButton.addActionListener(this);

            String currentFont = ageLabel.getFont().getName();
            currentInsets =  new Insets(0, 10, 0, 30);

            ageLabel.setFont(new Font(currentFont, Font.BOLD, 12));
            gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.anchor = GridBagConstraints.WEST;
            gridBagConstraints.insets = currentInsets;
            agePanel.add(ageLabel, gridBagConstraints);

            genderLabel.setFont(new Font(currentFont, Font.BOLD, 12));
            gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.gridx = 0;
            gridBagConstraints.gridy = 1;
            gridBagConstraints.anchor = GridBagConstraints.WEST;
            gridBagConstraints.insets = currentInsets;
            agePanel.add(genderLabel, gridBagConstraints);

            incomeLabel.setFont(new Font(currentFont, Font.BOLD, 12));
            gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.gridx = 0;
            gridBagConstraints.gridy = 2;
            gridBagConstraints.anchor = GridBagConstraints.WEST;
            gridBagConstraints.insets = currentInsets;
            agePanel.add(incomeLabel, gridBagConstraints);

            interestLabel.setFont(new Font(currentFont, Font.BOLD, 12));
            gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.gridx = 0;
            gridBagConstraints.gridy = 3;
            gridBagConstraints.anchor = GridBagConstraints.WEST;
            gridBagConstraints.insets = currentInsets;
            agePanel.add(interestLabel, gridBagConstraints);

            gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.gridwidth = GridBagConstraints.RELATIVE;
            gridBagConstraints.anchor = GridBagConstraints.WEST;
            gridBagConstraints.weightx = 1.0;
            agePanel.add(ageTextField, gridBagConstraints);

            gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.gridx = 1;
            gridBagConstraints.gridy = 1;
            gridBagConstraints.gridwidth = GridBagConstraints.RELATIVE;
            gridBagConstraints.anchor = GridBagConstraints.WEST;
            gridBagConstraints.weightx = 1.0;
            agePanel.add(genderTextField, gridBagConstraints);

            gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.gridx = 1;
            gridBagConstraints.gridy = 2;
            gridBagConstraints.gridwidth = GridBagConstraints.RELATIVE;
            gridBagConstraints.anchor = GridBagConstraints.WEST;
            gridBagConstraints.weightx = 1.0;
            agePanel.add(incomeTextField, gridBagConstraints);

            gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.gridx = 1;
            gridBagConstraints.gridy = 3;
            gridBagConstraints.gridwidth = GridBagConstraints.RELATIVE;
            gridBagConstraints.anchor = GridBagConstraints.WEST;
            gridBagConstraints.weightx = 1.0;
            agePanel.add(interestTextField, gridBagConstraints);


            searchButtonsPanel.add(searchButton);
            searchButtonsPanel.add(resetButton);
            navigateButtonsPanel.add(previousButton);
            navigateButtonsPanel.add(nextButton);
            agePanel.setBorder(new javax.swing.border.EmptyBorder(new Insets(0, 5, 0, 0)));
            searchButtonsPanel.setBorder(new javax.swing.border.EmptyBorder(new Insets(0, 5, 0, 0)));

            headingLabel.setAlignmentX(0.5f);

            topPanel.add(Box.createVerticalStrut(10));
            topPanel.add(headingLabel);
            topPanel.add(Box.createVerticalStrut(10));
            topPanel.add(agePanel);
            topPanel.add(searchButtonsPanel);
            topPanel.add(Box.createVerticalStrut(15));
            carComponents.add(navigateButtonsPanel, "Center");
            carComponents.setVisible(false);

            add(topPanel, "North");
            add(carComponents, "Center");
        }

But when I execute the above code, I end up getting the following

As you can clearly see from the image that the text field and labels are not positioned properly. What am I doing wrong here?


Answer:

The agePanel is using a FlowLayout, but you're supplying GridBagConstraints to it when you're adding your components. You need to make up you mind over which layout manager you want to use.

Start by changing the layout manager for agePanel to a GridBagLayout

private JPanel agePanel = new JPanel(new GridBagLayout());

Then supply a column hint the JTextField

private JTextField ageTextField = new JTextField(10);
private JTextField genderTextField = new JTextField(10);
private JTextField incomeTextField = new JTextField(10);
private JTextField interestTextField = new JTextField(10);

Take a closer look at Laying Out Components Within a Container and focus on the differences between the different layout managers