Monday, December 16, 2013

JTable freezing/fixing columns when scrolling

Following is the sample code for freezing one or more table columns while scrolling through the other columns.

import java.awt.Dimension;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

public class TestClass extends javax.swing.JFrame {
    private DefaultTableModel tableModel;
    private javax.swing.JScrollPane jScrollPane;
    private javax.swing.JTable jTable;
    private javax.swing.JTable freezeTable;
    private int fixedColumns = 1;//number of colums to be freezed
 
    public TestClass() {
        jScrollPane = new javax.swing.JScrollPane();
        jTable = new javax.swing.JTable();
        jScrollPane.setViewportView(jTable);
        getContentPane().add(jScrollPane);
     
        setPreferredSize(new Dimension(300,200));  
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
     
        Object[][] data = {{"Item1", "Papaya", "Letus", "Cashew", "Pine"},
                             {"Item2", "Orange", "Carrot", "Pine nut", "Oak"},
                             {"Item3", "Apple", "Pepper", "Pistacho", "Cypress"}};
        Object[] headers = {"Item", "Fruit", "Vegetable", "Nuts", "Tree"};
        tableModel = new DefaultTableModel(data, headers);
        jTable.setModel(tableModel);
     
        jTable.setAutoCreateColumnsFromModel( false );
        for (int i=0; i<jTable.getColumnCount(); i++){
            jTable.getColumnModel().getColumn(i).setMinWidth(100);
        }
        jTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        jTable.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent e) {
                //  Keep freezeTable in sync with the jTable
                if ("selectionModel".equals(e.getPropertyName())) {
                    freezeTable.setSelectionModel(jTable.getSelectionModel());
                }

                if ("dataModel".equals(e.getPropertyName())) {
                    freezeTable.setModel(jTable.getModel());
                }
            }
        });
     
        freezeTable = new javax.swing.JTable();
        freezeTable.setAutoCreateColumnsFromModel(false);
        freezeTable.setModel(tableModel);
        freezeTable.setSelectionModel(jTable.getSelectionModel());
        freezeTable.setFocusable(false);
     
        for (int i = 0; i < fixedColumns; i++) {
            TableColumnModel colModel = jTable.getColumnModel();
            TableColumn column = colModel.getColumn(0);
            colModel.removeColumn(column);
            freezeTable.getColumnModel().addColumn(column);
        }

        //Synchronize sorting of freezeTable with jTable
        jTable.setAutoCreateRowSorter(true);
        freezeTable.setRowSorter(jTable.getRowSorter());
        jTable.setUpdateSelectionOnSort(true);
        freezeTable.setUpdateSelectionOnSort(false);

        //  Add the fixed table to the scroll pane
        freezeTable.setPreferredScrollableViewportSize(freezeTable.getPreferredSize());
        jScrollPane.setRowHeaderView(freezeTable);
        jScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, freezeTable.getTableHeader());

        // Synchronize scrolling of the row header with the jTable
        jScrollPane.getRowHeader().addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                //  Sync the scroll pane scrollbar with the row header
                JViewport viewport = (JViewport) e.getSource();
                jScrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
            }
        });
        pack();
    }
 
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new TestClass().setVisible(true);
            }
        });
    }
}

See also
JTable Freezing/Fixing column headers while scrolling

--------------------------------------------------------------------------------------------------------------

                        
If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

7 comments:

  1. Hi I need your help. Do you know how to fix a row in Jtable. I need to fix the top and bottom row of Table.

    ReplyDelete
    Replies
    1. Aqeel,

      Please refer to this link about how to create fixed rows in JTable.

      https://community.oracle.com/thread/3585005

      Hope that it helps

      Delete
  2. Hello ! I need to be both tables focusable. My problem is when i move cursor from freezeTable to jTable(by mouse) and vice versa, i do not get any events.
    Thank you in advance

    ReplyDelete
    Replies
    1. I think what you really want is to put your two tables in a JSplitPane.

      Delete
    2. Hello, I have almost made my Table, which consists of two JTable like yours, but i have a problem, how both tables is synchronized by sorting?

      Thank you in advance

      Delete
    3. You may add a RowSorterListener to your main JTable to sort your freezed table accordingly when the main table is sorted.

      jtable.getRowSorter.addRowSorterListener(
      new RowSorterListener() {
      public void sorterChanged(RowSorterEvent e){
      //code to sort the freezed table
      }
      }
      );

      Delete
    4. If your two tables share the same table model, you can create your own table sorter and add the same table sorter to both of your tables.

      TableRowSorter sorter = new TableRowSorter(yourTableModel);

      jtable.addRowSorter(sorter);
      frozenTable.addRowSorter(sorter);

      Delete