0

I have a JTable which would be populated dynamically and I want the table to always resize to fit the number of rows. I don't want any scrolling because the table is in a panel and the contents of the panel needs to be printed. I've tried this:

Dimension d = itemsTable.getPreferredSize();
    //scrollPane.setPreferredSize(new Dimension(d.width,itemsTable.getRowHeight()*itemsTable.getRowCount()+10));
    itemsTable.setPreferredScrollableViewportSize(new Dimension(d.width,itemsTable.getRowHeight()*itemsTable.getRowCount()+1))

But it doesn't seem to work.

public void getDetails(PosView pv){
    Connection con = con();
    DefaultTableModel model = (DefaultTableModel)pv.getItemsTable().getModel();
    String date = null;
    double total = 0.0, paid = 0.0;
    try{
        ps = con.prepareStatement("SELECT DISTINCT AMOUNT_PAYABLE, AMOUNT_PAID, BALANCE, DATE FROM SALES WHERE PAYMENT_ID = ?");
        ps.setString(1, paymentId);
        rs = ps.executeQuery();
        while(rs.next()){
            total = (rs.getDouble(1));
            paid += (rs.getDouble(2));
            date = rs.getString(4);
        }
        double balance = total - paid;
        pv.setDate(date);
        pv.setPaymentId(paymentId);

        ps = con.prepareStatement("SELECT QUANTITY, ITEM_NAME, SELLING_PRICE, TOTAL FROM ITEMS_BOUGHT WHERE ID = ?");
        ps.setString(1, paymentId);
        rs = ps.executeQuery();
        while(rs.next()){
            Object data[] = {rs.getInt(1), rs.getString(2), rs.getDouble(3),rs.getDouble(4)};
            model.addRow(data);
        }

        logActivity(userId, "PAYMENT RECEIPT "+ paymentId +" GENERATED", con);
        pv.setTotal(total);
        pv.setPaid(paid);
        pv.setBalance(balance);
    }catch(SQLException e){
        showMessageDialog(null, e.getMessage());
    }finally{
        try {
            if(ps!=null)
                ps.close();
            con.close();
        }catch(Exception e){}
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Charles
  • 112
  • 11
  • 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) *"But it doesn't seem to work."* What exactly does happen? – Andrew Thompson May 20 '16 at 08:17
  • It doesn't resize the table. Like nothing happens – Charles May 20 '16 at 08:19
  • OK.. where is the MCVE? – Andrew Thompson May 20 '16 at 08:21
  • See also [this mcve](http://stackoverflow.com/a/6175860/418556) .. – Andrew Thompson May 20 '16 at 08:23
  • Can't seem to understand the MCVE in your link. But would look at it again. For my own MCVE, I just created the JTable using NetBeans GUI. Just tried using the code above to adjust the height but nothing happened – Charles May 20 '16 at 08:26
  • *"..in your link.."* Which link? One of the two in 1st comment, or one in later comment? BTW - now is a good time for more details, rather than less. I don't enjoy playing '20 questions'.. – Andrew Thompson May 20 '16 at 08:28
  • *"For my own MCVE,"* ...OK. Don't keep it to yourself, post it here! – Andrew Thompson May 20 '16 at 08:30
  • Sorry I mean the link u said _'see also this mcve'_ And I've edited the question to add the code I use in populating the table – Charles May 20 '16 at 08:36
  • I am just assuming that you are not having your table in scrollpane. If that is the case you need to set the size of the container where you place the table. Something like `this.setSize(this.getWidth(), itemsTable.getRowHeight()*itemsTable.getRowCount()+1);` – Beniton Fernando May 20 '16 at 08:51
  • 2
    I think you're wasting your time, `JTable` has a [printing API](https://docs.oracle.com/javase/tutorial/uiswing/components/table.html#printing) and it doesn't care about the `JScrollPane` and handles page breaks, headers and footers – MadProgrammer May 20 '16 at 08:59
  • 1
    For [example](http://stackoverflow.com/questions/26580954/how-to-print-selected-rows-jtable/26581137#26581137), [example](http://stackoverflow.com/questions/34742195/printing-selected-rows-from-jtable/34742430#34742430), [example](http://stackoverflow.com/questions/34086377/printing-a-jpanel-with-scrollable-jtable-on-it/34114959#34114959), [example](http://stackoverflow.com/questions/29788505/cant-generate-complete-data-to-pdf-file-in-java/29792374#29792374), [example](http://stackoverflow.com/questions/24977871/printing-selected-component-of-jframe-to-printer/24978159#24978159) – MadProgrammer May 20 '16 at 09:02
  • @Beniton The table is in a scroll pane. – Charles May 20 '16 at 09:10
  • @MadProgrammer. It's just not about headers and footers, there are other details that needs to be formatted properly. But I'll check your examples – Charles May 20 '16 at 09:11
  • @Charles if the table is in the scrollpane then you may need to resize the scrollpane and the containter which contains the scrollpane to display the entire content. – Beniton Fernando May 20 '16 at 09:13
  • @MadProgrammer l've looked at the examples. None were useful – Charles May 20 '16 at 09:16
  • how do I do that? @Beniton – Charles May 20 '16 at 09:17
  • @Charles I have put the code in the answer. – Beniton Fernando May 20 '16 at 09:23
  • Then use JasperReports, for [example](http://stackoverflow.com/questions/34086377/printing-a-jpanel-with-scrollable-jtable-on-it/34146067#34146067), also, the preferredSize of the JTable will include all the rows, so you need to setup your container with a layout manager that can support it – MadProgrammer May 20 '16 at 09:58

2 Answers2

5

Override getPreferredScrollableViewportSize() to return a multiple of the product of line height and row count. Each time a row is added, pack() the enclosing window.

image

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

/**
 * @see http://stackoverflow.com/a/37343900/230513
 * @see http://stackoverflow.com/a/37318673/230513
 */
public class Test {

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        class MyTableModel extends AbstractTableModel {

            private int n = 8;

            private void addRow() {
                n++;
                fireTableRowsInserted(n - 1, n - 1);
            }

            @Override
            public int getRowCount() {
                return n;
            }

            @Override
            public int getColumnCount() {
                return 4;
            }

            @Override
            public Object getValueAt(int rowIndex, int colIndex) {
                return "R" + rowIndex + ":C" + colIndex;
            }
        };
        MyTableModel model = new MyTableModel();
        JTable table = new JTable(model) {
            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(super.getPreferredSize().width,
                    getRowHeight() * getRowCount());
            }
        };
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        f.add(new JScrollPane(table));
        f.add(new JButton(new AbstractAction("Add Row") {
            @Override
            public void actionPerformed(ActionEvent e) {
                model.addRow();
                f.pack();
            }
        }), BorderLayout.SOUTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Test()::display);
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
0

I don't think this is the best way. But as you insist i have put the code below.

import javax.swing.RowFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;

/**
 *
 * @author user
 */
public class MyFrame extends javax.swing.JFrame {

    private DefaultTableModel model = null;

    TableRowSorter<DefaultTableModel> sorter = null;

    /**
     * Creates new form MyFrame
     */
    public MyFrame() {
        initComponents();
        model = new DefaultTableModel(null, new String[]{
            "Name", "age", "salary"
        });
        jTable1.setModel(model);
        for (int i = 0; i < 10; i++) {
            model.addRow(new Object[]{"Beniton", 34, 10000});
            model.addRow(new Object[]{"Joema", 33, 10000});
        }
        sorter = new TableRowSorter<DefaultTableModel>(model);
        jTable1.setRowSorter(sorter);
        int rowCount = model.getRowCount();
        this.setSize(this.getWidth(), 50+ (jTable1.getRowHeight()*(rowCount+1)));
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jLabel1 = new javax.swing.JLabel();
        searchBox = new javax.swing.JTextField();
        jTable1 = new javax.swing.JTable();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new java.awt.GridBagLayout());

        jLabel1.setText("Search");
        getContentPane().add(jLabel1, new java.awt.GridBagConstraints());

        searchBox.setMaximumSize(new java.awt.Dimension(150, 20));
        searchBox.setMinimumSize(new java.awt.Dimension(150, 20));
        searchBox.setName("searchField"); // NOI18N
        searchBox.setPreferredSize(new java.awt.Dimension(150, 20));
        searchBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchBoxActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        getContentPane().add(searchBox, gridBagConstraints);
        searchBox.getAccessibleContext().setAccessibleName("");

        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        getContentPane().add(jTable1, gridBagConstraints);

        pack();
    }// </editor-fold>                        

    private void searchBoxActionPerformed(java.awt.event.ActionEvent evt) {                                          
        if (searchBox.getText().length() > 0) {
            Integer value = Integer.parseInt(searchBox.getText());
            // Checking the age as Index is 1
            RowFilter<DefaultTableModel, Integer> rf = RowFilter.numberFilter(RowFilter.ComparisonType.BEFORE, value, 1);
            sorter.setRowFilter(rf);
        } else {
            sorter.setRowFilter(null);
        }
    }                                         

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MyFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JLabel jLabel1;
    private javax.swing.JTable jTable1;
    private javax.swing.JTextField searchBox;
    // End of variables declaration                   
}
Beniton Fernando
  • 1,533
  • 1
  • 14
  • 21
  • Well I used your line of code `this.setSize(this.getWidth(), 50+ (jTable1.getRowHeight()*(rowCount+1)));` Wondering why I didn't think of this earlier. Just modified it to suit what I wanted. Thanks – Charles May 24 '16 at 13:58