Search code examples
javaswingjtablegridbaglayout

How to set size to Jtable using GridBagLayOut


I am using GridBagLayout to position GUI components. I have used a Jtable inside a JFrame. But the table is not fitting to the frame. It appears as follows. When I drag the frame it shows the table.

enter image description here

Here is my code. I used this as a pop up Jframe to a button listner.

public class ViewPrescriptionHistory extends JFrame{

    private GridBagConstraints gridbBagConstraints;
    private JTable drugDetailsTable;
    HistroyTableModel drugDetailsTabelModel = new HistroyTableModel();

    public ViewPrescriptionHistory() {
        this.setLayout(new GridBagLayout());
        this.setSize(500, 500);

        this.pack();
        initialize();
    }

    private void initialize() {
        gridbBagConstraints = new GridBagConstraints();
        gridbBagConstraints.insets = new Insets(10, 0, 10, 0);
        gridbBagConstraints.ipady = 10;
        gridbBagConstraints.ipadx = 10;

        drugDetailsTable = new JTable(drugDetailsTabelModel);
        drugDetailsTable.setPreferredScrollableViewportSize(new Dimension(600, 100));
        drugDetailsTable.setFillsViewportHeight(true);

        JScrollPane scrollPane = new JScrollPane(drugDetailsTable);
        scrollPane.setBounds(5, 218, 884, 194);


        this.add(scrollPane);

    }
}

Here is my table model. I used Abstract Table model.

    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.table.AbstractTableModel; 
    import assignment3.prescriptionsystem.model.HistoryModel;

    public class HistroyTableModel extends AbstractTableModel{

        private String[] columnNames = { "Doctor Name", "Date", "Drug Name", "Form" , "Dosage" };
        List<HistoryModel> historyList = new ArrayList<HistoryModel>();

        public String getColumnName(int column) {
            return columnNames[column];

        }

        public int getColumnCount() {

            return columnNames.length;
        }

        public int getRowCount() {

            return historyList.size();
        }

        public void reloadDrugList(List<HistoryModel> drugsData) {
            historyList= drugsData;
            fireTableDataChanged();
        }

        public Object getValueAt(int rowIndex, int columnIndex) {
            HistoryModel drugData = historyList.get(rowIndex);
            switch (columnIndex) {
            case 0:
                return drugData.getDocName();
            case 1:
                return drugData.getDate();
            case 2:
                return drugData.getDrugName();
            case 3:
                return drugData.getFrom();
            case 4:
                return drugData.getDosage();
            default:
                return null;

            }

        }


}

Here is my model class

public class HistoryModel {
    String docName;
    String date;
    String drugName;
    String dosage;
    String from;
    public String getDocName() {
        return docName;
    }
    public void setDocName(String docName) {
        this.docName = docName;
    }
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
    public String getDrugName() {
        return drugName;
    }
    public void setDrugName(String drugName) {
        this.drugName = drugName;
    }
    public String getDosage() {
        return dosage;
    }
    public void setDosage(String dosage) {
        this.dosage = dosage;
    }
    public String getFrom() {
        return from;
    }
    public void setFrom(String from) {
        this.from = from;
    }
}

How to fix this issue?


Solution

  • Firstly you should be adding your components to, and setting the GridBagLayout on, the JFrame's content pane, rather than the JFrame itself. Consider this image of the containment hierarchy taken from an Oracle tutorial:

    Container heirarchy

    You should also be calling pack() after you have added your components, not before:

    The pack method sizes the frame so that all its contents are at or above their preferred sizes. An alternative to pack is to establish a frame size explicitly by calling setSize or setBounds (which also sets the frame location). In general, using pack is preferable to calling setSize, since pack leaves the frame layout manager in charge of the frame size, and layout managers are good at adjusting to platform dependencies and other factors that affect component size.

    Because pack() handles the sizing of the JFrame, you do not need to explicitly call setSize()

    So your code should look like:

    getContentPane().setLayout(new GridBagLayout()); // Set the layout on the content pane rather than the JFrame
    
    gridbBagConstraints = new GridBagConstraints();
    gridbBagConstraints.insets = new Insets(10, 0, 10, 0);
    gridbBagConstraints.ipady = 10;
    gridbBagConstraints.ipadx = 10;
    
    drugDetailsTable = new JTable(drugDetailsTabelModel);
    drugDetailsTable.setPreferredScrollableViewportSize(new Dimension(600, 100));
    drugDetailsTable.setFillsViewportHeight(true);
    
    JScrollPane scrollPane = new JScrollPane(drugDetailsTable);
    scrollPane.setBounds(5, 218, 884, 194);
    
    getContentPane().add(scrollPane); // Add the scroll pane to the content pane rather than the JFrame
    
    pack(); // Call pack at the end
    

    And the resulting GUI looks like:

    GUI result