Search code examples
javaswingjtablejtableheaderjide

synchronize view of two JTable


I have two JTables one in main viewport and one in footer viewport, using JideScrollPane. the problem is when the main JTable's view is customized, the footer JTable remains the same, is there any way to synchronize their view?

thanks.

unsynch


Solution

  • EDIT: Here's a demo that will synch up the resizing of two tables that have similar columns. The idea is:

    • Create a custom TableColumnModelListener for each table's column model.
    • Upon resize, sync up the column widths. You'll have to disable the other listener temporarily, while this is happening.
    • For moving of columns, implement that logic in columnMoved(...) [left as an exercise]

    This shows two-way synching:

    import java.awt.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    
    public class JTableResizeColumnsDemo implements Runnable
    {
      JTable table1, table2;
      TableColumnModelListener columnListener1, columnListener2;
      Map<JTable, TableColumnModelListener> map;
    
      public static void main(String[] args)
      {
        SwingUtilities.invokeLater(new JTableResizeColumnsDemo());
      }
    
      public void run()
      {
        Vector<String> names = new Vector<String>();
        names.add("One");
        names.add("Two");
        names.add("Three");
    
        table1 = new JTable(null, names);
        table2 = new JTable(null, names);
    
        columnListener1 = new ColumnChangeListener(table1, table2);
        columnListener2 = new ColumnChangeListener(table2, table1);
    
        table1.getColumnModel().addColumnModelListener(columnListener1);
        table2.getColumnModel().addColumnModelListener(columnListener2);
    
        map = new HashMap<JTable, TableColumnModelListener>();
        map.put(table1, columnListener1);
        map.put(table2, columnListener2);
    
        JPanel p = new JPanel(new GridLayout(2,1));
        p.add(new JScrollPane(table1));
        p.add(new JScrollPane(table2));
    
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(p);
        frame.setSize(300, 200);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    
      class ColumnChangeListener implements TableColumnModelListener
      {
        JTable sourceTable;
        JTable targetTable;
    
        public ColumnChangeListener(JTable source, JTable target)
        {
          this.sourceTable = source;
          this.targetTable = target;
        }
    
        public void columnAdded(TableColumnModelEvent e) {}
        public void columnSelectionChanged(ListSelectionEvent e) {}
        public void columnRemoved(TableColumnModelEvent e) {}
        public void columnMoved(TableColumnModelEvent e) {}
    
        public void columnMarginChanged(ChangeEvent e)
        {
          TableColumnModel sourceModel = sourceTable.getColumnModel();
          TableColumnModel targetModel = targetTable.getColumnModel();
          TableColumnModelListener listener = map.get(targetTable);
    
          targetModel.removeColumnModelListener(listener);
    
          for (int i = 0; i < sourceModel.getColumnCount(); i++)
          {
            targetModel.getColumn(i).setPreferredWidth(sourceModel.getColumn(i).getWidth());
          }
    
          targetModel.addColumnModelListener(listener);
        }
      }
    }