如何让多个JTable标题同步它们的列宽,排序等?

时间:2010-07-09 17:13:51

标签: java swing jtable

我有一个接口,它有多个小的JTable堆叠在一起。我希望他们的列大小,排序,过滤等保持同步。有一种直截了当的方法吗?

对于列宽,我尝试让它们共享一个常见的TableHeaderModel,但这似乎会带来意想不到的问题,例如只能使用添加的最后一个表来调整大小。如果有人有解决方案,我可以忍受他们的列宽保持同步,同时能够使用任何表调整大小。

我在下面发布了一个代码示例。运行时,您会注意到您无法调整第一个或第二个表标题的大小,但第三个表标题会调整大小。我想要第三个表的行为,但是需要来自任何表头。

谢谢。

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", "Title 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);
          }
      });
  }
}

2 个答案:

答案 0 :(得分:4)

在等待答案时,我偶然发现了我的问题。这显然是一个已知的bug。我使用了此处发布的解决方案,并对其下方的评论进行了更改。

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

答案 1 :(得分:1)

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){}
}