3

I am trying to code in a way that when user clicks a button, a new row of jlabel and jtextfield will be added to the the gridlayout of the jframe. like this:

Let's say the JFrame is 800x600, and the height of each row is 50, after I reach the 13th line, I want to add in a vertical scrolling bar. But now I can't seem to add the components correctly as I wished, I have also tried other layouts and apparently not working out.

import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.*;

public class Testing extends JFrame implements ActionListener
{
   public static int x =0;
   JPanel panel;

   public Testing()
   {
      super("Add component on JFrame at runtime");
      setLayout(new BorderLayout());
      panel=new JPanel();
      panel.setPreferredSize(new Dimension(800,600));
      panel.setAutoscrolls(true);
      panel.setLayout(new GridLayout(0,2,0,20));
      add(panel,BorderLayout.CENTER);
      JButton button=new JButton("CLICK HERE");
      add(button,BorderLayout.SOUTH);

      button.addActionListener(this);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setSize(500,500);
      setVisible(true);
      pack();
   }

   public void actionPerformed(ActionEvent evt)
   {
      JLabel jlbl1 = new JLabel("Row"+x);
      JTextField jtf =new JTextField(10);
      jtf.setMaximumSize(new Dimension(400,50));
      jlbl1.setMaximumSize(new Dimension(400,50));
      panel.add(jlbl1);
      panel.add(jtf);
      panel.revalidate();
      x++;

      validate();
   }

   public static void main(String[]args)
   {
      Testing test=new Testing();
   }
}

Edit: Thanks and Props to MadProgrammer for showing guidelines, this is what I wanted, just in case someone else face the same problem as I did:

Thanks to MadProgrammer and Andrew Thompson for showing guidelines. After some tweaks, this is what I wanted.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TableExample {

    public static void main(String[] args) {
        new TableExample();
    }

    public TableExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {
        public GridBagConstraints c = new GridBagConstraints();


        private JPanel fieldsPanel;
        private int row;

        public TestPane() {
            c.gridx =0;
            c.gridy =0;
            c.fill = GridBagConstraints.NONE;
            setLayout(new BorderLayout());

            fieldsPanel = new JPanel(new GridBagLayout());

            add(new JScrollPane(fieldsPanel));

            JButton btn = new JButton("Add");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    fieldsPanel.add(new JLabel("Row " + (++row)),c);
                    c.gridx++;
                    fieldsPanel.add(new JTextField(10),c);
                    fieldsPanel.revalidate();
                    c.gridy++;
                    c.gridx--;
                }
            });
            add(btn, BorderLayout.SOUTH);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
    }

}

1 Answers1

4
  • Use a JTable instead and/or
  • Use a JScrollPane and allow it to take care of it for you...

Update with JTable example

Table

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;

public class TableExample {

    public static void main(String[] args) {
        new TableExample();
    }

    public TableExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private DefaultTableModel model;

        public TestPane() {
            setLayout(new BorderLayout());
            model = new DefaultTableModel(
                    new Object[]{"Row", "Value"}, 
                    0);
            JTable table = new JTable(model);
            add(new JScrollPane(table));

            JButton btn = new JButton("Add");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int count = model.getRowCount();
                    model.addRow(new Object[]{count + 1, ""});
                }
            });
            add(btn, BorderLayout.SOUTH);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
    }

}

Updated with JScrollPane example

fields

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TableExample {

    public static void main(String[] args) {
        new TableExample();
    }

    public TableExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JPanel fieldsPanel;
        private int row;

        public TestPane() {
            setLayout(new BorderLayout());

            fieldsPanel = new JPanel(new GridLayout(0, 2));
            add(new JScrollPane(fieldsPanel));

            JButton btn = new JButton("Add");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    fieldsPanel.add(new JLabel("Row " + (++row)));
                    fieldsPanel.add(new JTextField(10));
                    fieldsPanel.revalidate();
                }
            });
            add(btn, BorderLayout.SOUTH);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
    }

}

Updated with GridBagLayout example

GridBagLayout

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TableExample {

    public static void main(String[] args) {
        new TableExample();
    }

    public TableExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JPanel fieldsPanel;
        private JPanel filler;
        private int row;

        public TestPane() {
            setLayout(new BorderLayout());

            filler = new JPanel();
            fieldsPanel = new JPanel(new GridBagLayout());
            add(new JScrollPane(fieldsPanel));

            JButton btn = new JButton("Add");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    fieldsPanel.remove(filler);
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.insets = new Insets(2, 2, 2, 2);
                    gbc.gridx = 0;
                    gbc.gridy = row;
                    gbc.fill = GridBagConstraints.HORIZONTAL;
                    fieldsPanel.add(new JLabel("Row " + (++row)), gbc);
                    gbc.gridx++;
                    gbc.weightx = 1;
                    fieldsPanel.add(new JTextField(10), gbc);

                    gbc.gridy++;
                    gbc.weighty = 1;
                    fieldsPanel.add(filler, gbc);
                    fieldsPanel.revalidate();
                }
            });
            add(btn, BorderLayout.SOUTH);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Holy crap! How can this answer get better? Are you about to make an edit with animated images? ;) – Andrew Thompson Mar 24 '14 at 06:46
  • 2
    @AndrewThompson Unicorns, definitely needs unicorns – MadProgrammer Mar 24 '14 at 06:46
  • Good answer, I can only however mark this as accepted answer in 1 minute, can you also point me the way on how to have certain margins between each row? like top margin, left margin etc... to have better formatting. I've heard of inserting a invisible row, but how about left and right? – user3454220 Mar 24 '14 at 06:50
  • Use layout padding & borders for [white space](http://stackoverflow.com/q/17874717/418556). – Andrew Thompson Mar 24 '14 at 06:51
  • @user3454220 Try using [`GridLayout(rows, cols, hgap, vgap)`](http://docs.oracle.com/javase/7/docs/api/java/awt/GridLayout.html#GridLayout(int, int, int, int)) and/or use a `EmptyBorder` – MadProgrammer Mar 24 '14 at 06:52
  • For the second example, when you insert 1 row, the whole thing scales to take up the whole screen, are there any way to fix this? – user3454220 Mar 24 '14 at 06:53
  • @user3454220 Don't use `GridLayout`, that's how it work. May be try `GridBagLayout` – MadProgrammer Mar 24 '14 at 06:54
  • @MadProgrammer tried that, hgap gives margin between column, vgap gives margin between rows, how to give margin between the 1st row and the Jframe top border, last row and the Jframe btm border, 1st column and the Jframe left border... etc.. – user3454220 Mar 24 '14 at 06:55
  • Oh.. and for tables see [`setRowMargin(int)`](http://docs.oracle.com/javase/7/docs/api/javax/swing/JTable.html#setRowMargin%28int%29).. – Andrew Thompson Mar 24 '14 at 06:55
  • *"how to give margin between the 1st row and the Jframe top border,..?"* Add an `EmptyBorder` to the *container* that you set the `GridLayout` to. – Andrew Thompson Mar 24 '14 at 06:56
  • 1
    *"that's how it work"* If you put the `GridLayout` in a constraining `FlowLayout` it won't be stretched to the size of the **parent** of the `FlowLayout`.. – Andrew Thompson Mar 24 '14 at 06:59
  • @AndrewThompson Shhh, stop giving away the secrets :P – MadProgrammer Mar 24 '14 at 07:01
  • 1
    Most of your questions of @MadProgrammer can be addressed in two links in a comment I often make: Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556), along with layout padding & borders for [white space](http://stackoverflow.com/q/17874717/418556). The first example show how to dynamically add labels to a `GridLayout` .. – Andrew Thompson Mar 24 '14 at 07:02
  • .. **without** stretching them. :) Few.. ran out of limit on that last comment. ;) – Andrew Thompson Mar 24 '14 at 07:03