Search code examples
javaswingjframeheightjdialog

What's the best rule for fitting a dynamic JTable inside a dialog or a frame?(height issue)


I want to calculate the height of a dialog that contain only a table depending on how many rows that table it has so I'm using the cross multiplication rule.For example i check initially that my table is well fitting into the dialog(Without space at the bottom) for some value and after that i use the cross multiplication rule because data are dynamic.But unfortunately this rule does not solve the problem.What's the best rule for fitting a dynamic table inside a dialog or a frame? Here is my code

public class FlowLayoutChangingGap {
    public static void main(String[] args) {
        // just for testing perpose but data are getting from database and it's dynamic
        Object[][] data = {
                {"Kathy", "Smith", "Snowboarding", new Integer(5)},
                {"John", "Doe", "Rowing", new Integer(3)},
                {"Sue", "Black", "Knitting", new Integer(2)},
                {"Jane", "White", "Speed reading", new Integer(20)},
                {"Joe", "Brown", "Pool", new Integer(10)}};

        Object[] columnNames = {"firstname", "lastname", "age"};
        final JTable table = new JTable(data, columnNames);
        JFrame aWindow = new JFrame("This is a Test");
        aWindow.setBounds(50, 50, 500, 500);
        aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        FlowLayout flow = new FlowLayout(FlowLayout.LEFT, 20, 30);
        Container content = aWindow.getContentPane();
        content.setLayout(flow);
        JButton jButton = new JButton("Press Me");
        ActionListener l = new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                JPanel jPanel = new JPanel();
                jPanel.setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.anchor = GridBagConstraints.NORTHWEST;
                gbc.fill = GridBagConstraints.BOTH;
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.weightx = 1.0;
                gbc.weighty = 1.0;
                jPanel.add(table, gbc);
                JDialog jdialog = new JDialog();
                jdialog.setContentPane(jPanel);

                jdialog.setLocationRelativeTo(null);
                int height = table.getModel().getRowCount() * 25;
                jdialog.setSize(400, height);
                jdialog.setVisible(true);

            }
        };
        jButton.addActionListener(l);
        content.add(jButton);
        aWindow.setVisible(true);
    }
}

Solution

  • Here is a way to fix the number of rows displayed in the scroll-pane.

    enter image description here

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.EmptyBorder;
    
    class FlowLayoutChangingGap {
    
        public static final int ROWS = 3;
    
        FlowLayoutChangingGap() {
            // just for testing perpose but data are getting from database and it's dynamic
            Object[][] data = {
                {"Kathy", "Smith", "Snowboarding", new Integer(5)},
                {"John", "Doe", "Rowing", new Integer(3)},
                {"Sue", "Black", "Knitting", new Integer(2)},
                {"Jane", "White", "Speed reading", new Integer(20)},
                {"Joe", "Brown", "Pool", new Integer(10)}};
            Object[] columnNames = {"firstname", "lastname", "age"};
            final JTable table = new JTable(data, columnNames) {
    
                @Override
                public Dimension getPreferredScrollableViewportSize() {
                    Dimension d = getPreferredSize();
                    // Note: margin is included in rowHeight
                    int n = getRowHeight(); // + getRowMargin();
                    // tbd: insets? we are one-off here
                    return new Dimension(d.width, (n * ROWS));
                }
            };
            JPanel jPanel = new JPanel();
            jPanel.setBorder(new EmptyBorder(6, 6, 6, 6));
            jPanel.setLayout(new GridLayout());
            JScrollPane sp = new JScrollPane(table);
            //sp.getViewport().
            jPanel.add(sp);
            JDialog jdialog = new JDialog();
            jdialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            jdialog.setContentPane(jPanel);
    
            jdialog.setLocationRelativeTo(null);
            jdialog.pack();
            jdialog.setVisible(true);
        }
    
        public static void main(String[] args) {
            Runnable r = new Runnable() {
    
                @Override
                public void run() {
                    new FlowLayoutChangingGap();
                }
            };
            // Swing GUIs should be created and updated on the EDT
            // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
            SwingUtilities.invokeLater(r);
        }
    }