Sridhar
Sridhar

Reputation: 1962

JTable does not fill JScrollPane which is added to JPanel using GridBagLayout

I have a JPanel with GridBagLayout. The panel contains 2 rows, first row has a JLabel and second row has a JScrollPane with JTable inside. The table does not fill 100% of the scrollpane. Even I resize my frame, the scrollpane resizes but the table inside always has fixed width.

JTable table=new JTable(myModel);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
JScrollPane scroll=new JScrollPane(table);

JPanel panel=new JPanel(new GridBagLayout());
// component add details skipped

And the following are the grid bag constraints applied to scroll pane while adding to panel.

GridBagConstraints gbc=new GridBagConstraints();
gbc.gridx=0; // first column
gbc.gridy=1; // second row
gbc.gridwidth=1;
gbc.gridheight=1;
gbc.fill=GridBagConstraints.BOTH;
gbc.anchor=GridBagConstraints.NORTHEAST;
gbc.weightx=1.0;
gbc.weighty=1.0;

What went wrong? Problem is with scroll pane or table?

Upvotes: 2

Views: 8726

Answers (3)

Sridhar
Sridhar

Reputation: 1962

Thanks for giving valuable suggestions. I found the exact solution for this problem. Size the table at its preferred size or view port size whichever is greater. Regardless of whatever layout manager you use it is working fine!

The solution is have table defined with getScrollableTracksViewportWidth() method, as example given below:

JTable table=new JTable(myModel){
 public boolean getScrollableTracksViewportWidth() {
   return getPreferredSize().width < getParent().getWidth();
 }
};
JScrollPane scroll=new JScrollPane(table);

Upvotes: 3

mKorbel
mKorbel

Reputation: 109813

I think that only (notice rows never will be resized by using any of LayoutManager, only columns)

c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 0;

GBC isn't proper LayoutManager for JComponents implements Scrollable, use BorderLayout(ev GridLayout) for these JComponents

for example

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

public class JTableAndGBC {

    private String[] columnNames = {"Source", "Hit", "Last", "Ur_Diff"};
    private JTable table;
    private Object[][] data = {{"Swing Timer", 2.99, 5, 1.01},
        {"Swing Worker", 7.10, 5, 1.010}, {"TableModelListener", 25.05, 5, 1.01}};
    private DefaultTableModel model = new DefaultTableModel(data, columnNames);

    public JTableAndGBC() {
        JPanel panel = new JPanel(new GridBagLayout());
        table = new JTable(model);
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.weightx = 1.0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        panel.add(table, gbc);
        JFrame frame = new JFrame();
        frame.add(panel, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String args[]) throws Exception {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JTableAndGBC();
            }
        });
    }
}

EDIT 1

  • JTable, JScollPane, JComboBox can't returns reasonable PreferredSize, see my code in the edit, then wokrs for all LayoutManagers,

  • notice carefully with table.setPreferredScrollableViewportSize(table.getPreferredSize());, I'd suggest to test if Dimension overload desired coordinates or screen resolution or not overload :-),

  • otherwise to shrink with new Dimension(int, int) instead of table.getPreferredSize()

.

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

public class JTableAndGBC {

    private String[] columnNames = {"Source", "Hit", "Last", "Ur_Diff"};
    private JTable table;
    private Object[][] data = {{"Swing Timer", 2.99, 5, 1.01},
        {"Swing Worker", 7.10, 5, 1.010}, {"TableModelListener", 25.05, 5, 1.01}};
    private DefaultTableModel model = new DefaultTableModel(data, columnNames);

    public JTableAndGBC() {
        JPanel panel = new JPanel(new GridBagLayout());
        table = new JTable(model);
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.weightx = 1.0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        JScrollPane pane = new JScrollPane(table);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        panel.add(pane, gbc);
        JFrame frame = new JFrame();
        frame.add(panel, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String args[]) throws Exception {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JTableAndGBC();
            }
        });
    }
}

EDIT 2

I'm strongly to suggest to use BorderLayout, GridLayout

enter image description here

.

enter image description here

instead of GBC (JTable, JScollPane, JComboBox can't returns reasonable PreferredSize, required to override GBC, brrrr, not why bothering)

enter image description here . enter image description here

code for BorderLayout

import java.awt.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

public class JTableAndGBC {

    private String[] columnNames = {"Source", "Hit", "Last", "Ur_Diff"};
    private JTable table;
    private Object[][] data = {{"Swing Timer", 2.99, 5, 1.01},
        {"Swing Worker", 7.10, 5, 1.010}, {"TableModelListener", 25.05, 5, 1.01}};
    private DefaultTableModel model = new DefaultTableModel(data, columnNames);

    public JTableAndGBC() {
        JPanel panel = new JPanel(new BorderLayout()/*(new GridBagLayout()*/);
        table = new JTable(model);
        //GridBagConstraints gbc = new GridBagConstraints();
        //gbc.weightx = 1.0;
        //gbc.fill = GridBagConstraints.HORIZONTAL;
        JScrollPane pane = new JScrollPane(table, 
                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        /*TableColumn firstColumn = table.getColumnModel().getColumn(0);
        firstColumn.setMinWidth(150);
        firstColumn.setMaxWidth(200);
        TableColumn secondColumn = table.getColumnModel().getColumn(1);
        secondColumn.setMinWidth(200);
        secondColumn.setMaxWidth(250);
        TableColumn thirdColumn = table.getColumnModel().getColumn(1);
        thirdColumn.setMinWidth(50);
        thirdColumn.setMaxWidth(100);   */     
        table.setRowHeight(30);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        panel.add(pane/*, gbc*/);
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String args[]) throws Exception {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JTableAndGBC();
            }
        });
    }
}

Upvotes: 8

makasprzak
makasprzak

Reputation: 5220

Remove the

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 

line. It causes the fixed table size.

Upvotes: 1

Related Questions