开发者

How to have multiple JTable headers synchronize their column widths, sorting, etc?

I have an interface that has multiple small JTables stacked on top of each other. I would like their column sizes, sorting, filtering, etc to stay in sync. Is there a straightforward way to do this?

For the column widths, I tried having them share a common TableHeaderModel but this seemed to pose unexpected problems such as only being able to resize using the last table added. I could live with just having their column widths stay in sync while being able to resize using any of the tables if someone has a solution to that.

I have posted a code example below. When run you notice that you can not resize the first or second table headers, but the third one resizes them all. I want the behavior of the third table, but from any of the table headers.

Thank you.

package javaapplication5;

public class NewJFrame extends javax.swing.JFrame {

  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JScrollPane jScrollPane2;
  private javax.swing.JScrollPane jScrollPane3;
  private javax.swing.JTable jTable1;
  private javax.swing.JTable jTable2;
  private javax.swing.JTable jTable3;

  public NewJFrame() {
      initComponents();

      jTable2.setColumnModel(jTable1.getColumnModel());
      jTable3.setColumnModel(jTable1.getColumnModel());        
  }

  private void initComponents() {

      jScrollPane1 = new javax.swing.JScrollPane();
      jTable1 = new javax.swing.JTable();
      jScrollPane2 = new javax.swing.JScrollPane();
      jTable2 = new javax.swing.JTable();
      jScrollPane3 = new javax.swing.JScrollPane();
      jTable3 = new javax.swing.JTable();

      setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
      getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(),             
          javax.swing.BoxLayout.Y_AXIS));

      jTable1.setModel(new javax.swing.table.DefaultTableModel(
          new Object [][] {
            {"a", "b", "c", "d"},
            {"e", "f", "g", "h"},
            {"i", "j", "k", "l"},
            {"m", "n", "o", "p"}
          },
          new String [] {
            "Title 1", "Title 2", "Title 3", "Title 4"
          }
      ));
      jScrollPane1.setViewportView(jTable1);

      getContentPane().add(jScrollPane1);

      jTable2.setModel(new javax.swing.table.DefaultTableModel(
          new Object [][] {
            {"q", "r", "s", "t"},
            {"u", "v", "w", "x"},
            {"y", "z", "1", "2"},
            {"3", "4", "5", "6"}
          },
          new String [] {
            "Title 1", "T开发者_StackOverflowitle 2", "Title 3", "Title 4"
          }
      ));
      jScrollPane2.setViewportView(jTable2);

      getContentPane().add(jScrollPane2);

      jTable3.setModel(new javax.swing.table.DefaultTableModel(
        new Object [][] {
            {"7", "8", "9", "10"},
            {"11", "12", "13", "14"},
            {"15", "16", "17", "18"},
            {"19", "20", "21", "22"}
        },
        new String [] {
            "Title 1", "Title 2", "Title 3", "Title 4"
        }
      ));
      jScrollPane3.setViewportView(jTable3);

      getContentPane().add(jScrollPane3);

      pack();
  }

  public static void main(String args[]) {
      java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
              new NewJFrame().setVisible(true);
          }
      });
  }
}


While waiting for an answer, I stumbled upon a fix to my problem. It is apparently a known bug. I used the solution posted here, with a change in the comments below it.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4816146


import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;

class Application extends JFrame
{
    public Application()
    {
        this.setBounds(100,100,500,200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        String data[][] = {{"a1","b1","c1"},{"a2","b2","c2"},{"a3","b3","c3"}};
        String columnNames[] = {"a","b","c"};

        JTable jtable = new JTable(new DefaultTableModel(data,columnNames));

        JScrollPane jscrollPane = new JScrollPane(jtable,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        jscrollPane.setBorder(new CompoundBorder(new MatteBorder(0,0,1,0,Color.gray),new EmptyBorder(0,0,0,0)));

        this.add(jscrollPane,BorderLayout.CENTER);


        JTable jtable_footer = new JTable(new DefaultTableModel(3,columnNames.length),jtable.getColumnModel());

        SyncListener syncListener = new SyncListener(jtable,jtable_footer);

        this.add(jtable_footer,BorderLayout.SOUTH);
    }

    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                Application application = new Application();

                application.setVisible(true);
            }
        });
    }
}

class SyncListener implements TableColumnModelListener
{
    JTable jtable_data;
    JTable jtable_footer;

    public SyncListener(JTable main, JTable footer)
    {
        jtable_data = main;
        jtable_footer = footer;

        DefaultTableColumnModel dtcm = (DefaultTableColumnModel)jtable_data.getColumnModel();

        // this is the listener causing resize problems
        dtcm.removeColumnModelListener(dtcm.getColumnModelListeners()[1]); 
        dtcm.addColumnModelListener(this);
    }

    public void columnMarginChanged(ChangeEvent changeEvent)
    {
        for (int column = 0; column < jtable_data.getColumnCount(); column++)
        {
            jtable_footer.getColumnModel().getColumn(column).setWidth(jtable_data.getColumnModel().getColumn(column).getWidth());
        }

        jtable_footer.repaint();
    }

    public void columnAdded(TableColumnModelEvent e){}
    public void columnMoved(TableColumnModelEvent e){}
    public void columnRemoved(TableColumnModelEvent e){}
    public void columnSelectionChanged(ListSelectionEvent e){}
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜