I want to add JTable into JPanel whose layout is null. JPanel contains other components. I have to add JTable at proper position.

15 upvote
  flag
just to emphasize jzd's answer: forget about null layout. That's definitely un-swing'ish - either learn using LayoutManagers or use a different language. – kleopatra

11 Answers 11

Don't use a null layout. Learn to use LayoutManagers:

http://download.oracle.com/javase/tutorial/uiswing/layout/using.html

LayoutManagers allow you to properly handle things window resizing or dynamic component counts. They might seem intimidating at first, but they are worth the effort to learn.

If you are using null layout manager you always need to set the bounds of a component. That is the problem in your case.

You should do what everyone suggest here and go and use some layout manager believe they save time. Go and check out the tutorial in @jzd's post.

Enjoy, Boro.

Nested/Combination Layout Example

The Java Tutorial has comprehensive information on using layout managers. See the Laying Out Components Within a Container lesson for further details.

One aspect of layouts that is not covered well by the tutorial is that of nested layouts, putting one layout inside another to get complex effects.

The following code puts a variety of components into a frame to demonstrate how to use nested layouts. All the layouts that are explicitly set are shown as a titled-border for the panel on which they are used.

Notable aspects of the code are:

  • There is a combo-box to change PLAF (Pluggable Look and Feel) at run-time.
  • The GUI is expandable to the user's need.
  • The image in the bottom of the split-pane is centered in the scroll-pane.
  • The label instances on the left are dynamically added using the button.

Nimbus PLAF

NestedLayoutExample.java

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.border.TitledBorder;

/** A short example of a nested layout that can change PLAF at runtime.
The TitledBorder of each JPanel shows the layouts explicitly set.
@author Andrew Thompson
@version 2011-04-12 */
class NestedLayoutExample {

    public static void main(String[] args) {

        Runnable r = new Runnable() {

            public void run() {
                final JFrame frame = new JFrame("Nested Layout Example");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                final JPanel gui = new JPanel(new BorderLayout(5,5));
                gui.setBorder( new TitledBorder("BorderLayout(5,5)") );

                //JToolBar tb = new JToolBar();
                JPanel plafComponents = new JPanel(
                    new FlowLayout(FlowLayout.RIGHT, 3,3));
                plafComponents.setBorder(
                    new TitledBorder("FlowLayout(FlowLayout.RIGHT, 3,3)") );

                final UIManager.LookAndFeelInfo[] plafInfos =
                    UIManager.getInstalledLookAndFeels();
                String[] plafNames = new String[plafInfos.length];
                for (int ii=0; ii<plafInfos.length; ii++) {
                    plafNames[ii] = plafInfos[ii].getName();
                }
                final JComboBox plafChooser = new JComboBox(plafNames);
                plafComponents.add(plafChooser);

                final JCheckBox pack = new JCheckBox("Pack on PLAF change", true);
                plafComponents.add(pack);

                plafChooser.addActionListener( new ActionListener(){
                    public void actionPerformed(ActionEvent ae) {
                        int index = plafChooser.getSelectedIndex();
                        try {
                            UIManager.setLookAndFeel(
                                plafInfos[index].getClassName() );
                            SwingUtilities.updateComponentTreeUI(frame);
                            if (pack.isSelected()) {
                                frame.pack();
                                frame.setMinimumSize(frame.getSize());
                            }
                        } catch(Exception e) {
                            e.printStackTrace();
                        }
                    }
                } );

                gui.add(plafComponents, BorderLayout.NORTH);

                JPanel dynamicLabels = new JPanel(new BorderLayout(4,4));
                dynamicLabels.setBorder(
                    new TitledBorder("BorderLayout(4,4)") );
                gui.add(dynamicLabels, BorderLayout.WEST);

                final JPanel labels = new JPanel(new GridLayout(0,2,3,3));
                labels.setBorder(
                    new TitledBorder("GridLayout(0,2,3,3)") );

                JButton addNew = new JButton("Add Another Label");
                dynamicLabels.add( addNew, BorderLayout.NORTH );
                addNew.addActionListener( new ActionListener(){

                    private int labelCount = 0;

                    public void actionPerformed(ActionEvent ae) {
                        labels.add( new JLabel("Label " + ++labelCount) );
                        frame.validate();
                    }
                } );

                dynamicLabels.add( new JScrollPane(labels), BorderLayout.CENTER );

                String[] header = {"Name", "Value"};
                String[] a = new String[0];
                String[] names = System.getProperties().
                    stringPropertyNames().toArray(a);
                String[][] data = new String[names.length][2];
                for (int ii=0; ii<names.length; ii++) {
                    data[ii][0] = names[ii];
                    data[ii][1] = System.getProperty(names[ii]);
                }
                DefaultTableModel model = new DefaultTableModel(data, header);
                JTable table = new JTable(model);
                try {
                    // 1.6+
                    table.setAutoCreateRowSorter(true);
                } catch(Exception continuewithNoSort) {
                }
                JScrollPane tableScroll = new JScrollPane(table);
                Dimension tablePreferred = tableScroll.getPreferredSize();
                tableScroll.setPreferredSize(
                    new Dimension(tablePreferred.width, tablePreferred.height/3) );

                JPanel imagePanel = new JPanel(new GridBagLayout());
                imagePanel.setBorder(
                    new TitledBorder("GridBagLayout()") );

                BufferedImage bi = new BufferedImage(
                    200,200,BufferedImage.TYPE_INT_ARGB);
                Graphics2D g = bi.createGraphics();
                GradientPaint gp = new GradientPaint(
                    20f,20f,Color.red, 180f,180f,Color.yellow);
                g.setPaint(gp);
                g.fillRect(0,0,200,200);
                ImageIcon ii = new ImageIcon(bi);
                JLabel imageLabel = new JLabel(ii);
                imagePanel.add( imageLabel, null );

                JSplitPane splitPane = new JSplitPane(
                    JSplitPane.VERTICAL_SPLIT,
                    tableScroll,
                    new JScrollPane(imagePanel));
                gui.add( splitPane, BorderLayout.CENTER );

                frame.setContentPane(gui);

                frame.pack();

                frame.setLocationRelativeTo(null);
                try {
                    // 1.6+
                    frame.setLocationByPlatform(true);
                    frame.setMinimumSize(frame.getSize());
                } catch(Throwable ignoreAndContinue) {
                }

                frame.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

Other Screen Shots

Windows PLAF

Mac OS X Aqua PLAF

Ubuntu GTK+ PLAF

As I can remember, the null layout means an absolute position so it will be pretty hard you to count the X point for your JTable left upper corner location. But if you just want to have all panel components one by one you can use FlowLayout() manager as

JPanel panel=new JPanel(new FlowLayout());
panel.add(new aComponent());
panel.add(new bComponent());
panel.add(new JTable());

or if you need to fill the panel you should use GridLayout() as...

int x=2,y=2;
JPanel panel=new JPanel(new GridLayout(y,x));
panel.add(new aComponent());
panel.add(new bComponent());
panel.add(new JTable());

Good luck

You can make use of the following code. To add JTable to JPanel.

JPanel panel = new JPanel();
this.setContentPane(panel);
panel.setLayout(null);
String data[][] = {{"1.", "ABC"}, {"2.", "DEF"}, {"3.", "GHI" }};
String col[] = {"Sr. No", "Name"};
JTable table = new JTable(data,col);
table.setBounds(100, 100, 100, 80);
panel.add(table);
setVisible(true);
setSize(300,300);

JTable should be added into the JScrollPane which actually should be added into the JPanel.

The JPanel should have some layout manager.

If you don't care about the precision of components size you can use pure BorderLayout and combine it with FlowLayout and GridLayout. if you need precision - use jgoodies FormLayout.

The FormLayout is really tricky one, but you can play a little with WindowBuilder (which is embedded into Eclipse) and a look at the code it generates. It may look complicated but it is just an ignorance.

Good luck.

JPanel panel = new JPanel();
JTable table = new JTable(rowData, colData);
JScrollPane scrollPane = new JScrollPane(table);
panel.add(scrollPane, BorderLayout.CENTER);
panel.setSize(800, 150);
panel.add(table);
panel.setLocationRelativeTo(null);
panel.setVisible(true);

Hope this helps.

upvote
  flag
no ... three errors in three consecutive lines and not solving the (bad as it is) requirement – kleopatra
upvote
  flag
use frame instead of panel and try. – Leo
upvote
  flag
you didn't even try to find your errors, did you? Sometimes (like now) I really would like to have as many downvotes as there are errors in the code/answer .. – kleopatra
upvote
  flag
which three lines? rowdata and coldata you have to add. – Leo
upvote
  flag
4, 5, 6 (and the last) – kleopatra
upvote
  flag
Sorry boss, it doesn't give any error for me. As I told you have to give your rowdata and coldata and import proper package. – Leo
upvote
  flag
A: take it for granted that there is something wrong with those lines. B: find out what it is (no rocket science, just a bit of searching). C: you improved your skills and your knowledge. Or refuse to learn, your choice obviously ;-) Bye. – kleopatra
JFrame frame = new JFrame("Sample Frame");
frame.setSize(600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel panel = new JPanel();
        DefaultTableModel dfm = new DefaultTableModel(data, columnNames);
        JTable table = new JTable(dfm);
        JScrollPane scrollPane = new JScrollPane(table);
    panel.add(scrollPane);
frame.add(panel);
frame.setVisible(true);

table model depends on your requirement

this.setTitle("Sample");
        JPanel p = new JPanel(new BorderLayout());
        WindowEvent we = new WindowEvent(this, WindowEvent.WINDOW_CLOSED);
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                System.exit(0);
            }
        }); 
        // Create columns names
        String columnNames[] = { "FirstCol", "SecondCol",
                "ThirdCol", "FourthCol" };
        dataModel = new DefaultTableModel();
        for (int col = 0; col < columnNames.length; col++) {
            dataModel.addColumn(columnNames[col]);
        }
        // Create a new table instance
        table = new JTable(dataModel);
        table.setPreferredScrollableViewportSize(new Dimension(200, 120));
        table.setFillsViewportHeight(true);
        table.setShowGrid(true);
        table.setAutoscrolls(true);

        // Add the table to a scrolling pane
        scrollPane = new JScrollPane(table,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setPreferredSize(new Dimension(700, 700));
        JPanel jpResultPanel = new JPanel();
        jpResultPanel.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createEtchedBorder(), "Result",
                TitledBorder.CENTER, TitledBorder.TOP));
        jpResultPanel.add(scrollPane);
        add(jpResultPanel);
        pack();
        setSize(720, 720);
        setVisible(true);

Try this.

When a component have a "null" layout, you have to manage the layout by yourself, that means you have to calculate the dimensions and locations for the children of the component to decide where they are drawn. Quite tedious unless it is absolutely necessary.

If you really want that fine-grained control, maybe try GridBagLayout first before going mudding with the UI arrangement.

First, you should seriously consider other Layout managers, for example the BorderLayoutManager (new JPanel(new BorderLayout())) is a good start.

Also when designing your dialog, remember that you can and should nest your layouts: one JPanel inside another JPanel (e.g. a GridLayout inside a BorderLayout). Please note: a 'good' dialog should resize properly, so that if the user resizes your Frame, you want to automatically extend your information objects such as your table, and not show large areas of JPanel background. That's something you cannot achieve with a NullLayout.

But there are probably cases - somewhere in this big world - where a NullLayout is just the thing. So here's an example:

import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class JTableInNullLayout
{
  public static void main(String[] argv) throws Exception {

      DefaultTableModel model = new DefaultTableModel(
          new String[][] { { "a", "123"} , {"b", "456"} }, 
          new String[] { "name", "value" } );

      JTable t = new JTable(model);

      JPanel panel = new JPanel(null);

      JScrollPane scroll = new JScrollPane(t);
      scroll.setBounds( 0, 20, 150, 100 ); // x, y, width, height
      panel.add(scroll);

      JFrame frame = new JFrame();
      frame.add(panel);
      frame.setPreferredSize( new Dimension(200,200));
      frame.pack();
      frame.setVisible(true);
  }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.