2011-07-22 71 views
4

我有一個類;將列添加到現有的TableModel中

public class A extends AbstractTableModel 
{ 
... 
} 

使用ResultSetMetaData我構建TableModel以匹配數據庫中的結果集。

public class B extends JPanel 
{ 
... 
} 

B類,我繼承JPanel,並添加A級顯示我的表。 我希望能夠根據條件向表模型添加新列。我試過Google搜索,但大多數例子都是基於DefaultTableModel而不是AbstractTableModel

有誰知道如何做到這一點?

回答

3

只是延長的DefaultTableModel,然後您可以訪問它的所有方法。 DefaultTableModel還擴展了AbstractTableModel,因此在代碼的其他部分對AbstractTableModel的引用不會中斷。

2

當然DefaultTableModel更方便,但AbstractTableModel提供了更大的靈活性和更少的開銷。有示出含有List<Value>,其中ValuePOJO一個模型的示例here。更多的例子可以在here找到。

+0

參見[JDBCAdapter](http://www.koders.com/java/fidA9D583712A2FDE1DC40C4C96F137BE9DF67C5BE0.aspx?s=drivermanager+sqlexception#L66),其將所述JDBC接口到'TableModel'接口的適配器。 – trashgod

+0

使用'AbstractTableModel'參見此[示例](http://stackoverflow.com/a/13500910/230513)。 – trashgod

14

例如

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

public class TableColumnHider { 

    private JTable table; 
    private TableColumnModel tcm; 
    private Map hiddenColumns; 

    public TableColumnHider(JTable table) { 
     this.table = table; 
     tcm = table.getColumnModel(); 
     hiddenColumns = new HashMap(); 
    } 

    public void hide(String columnName) { 
     int index = tcm.getColumnIndex(columnName); 
     TableColumn column = tcm.getColumn(index); 
     hiddenColumns.put(columnName, column); 
     hiddenColumns.put(":" + columnName, new Integer(index)); 
     tcm.removeColumn(column); 
    } 

    public void show(String columnName) { 
     Object o = hiddenColumns.remove(columnName); 
     if (o == null) { 
      return; 
     } 
     tcm.addColumn((TableColumn) o); 
     o = hiddenColumns.remove(":" + columnName); 
     if (o == null) { 
      return; 
     } 
     int column = ((Integer) o).intValue(); 
     int lastColumn = tcm.getColumnCount() - 1; 
     if (column < lastColumn) { 
      tcm.moveColumn(lastColumn, column); 
     } 
    } 

    public static void main(String[] args) { 
     String[] columnNames = {"Name", "Size", "Type", "Date Modified", "Permissions"}; 
     String[][] data = { 
      {"bin", "2", "dir", "Jun 9", "drwxr-xr-x"}, 
      {"boot", "3", "dir", "Jun 9", "drwxr-xr-x"}, 
      {"dev", "6", "dir", "Jul 12", "drwxr-xr-x"}, 
      {"etc", "34", "dir", "Jul 12", "drwxr-xr-x"},}; 
     JTable table = new JTable(data, columnNames); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     JScrollPane scrollPane = new JScrollPane(table); 
     final TableColumnHider hider = new TableColumnHider(table); 
     JPanel checkBoxes = new JPanel(); 
     for (int i = 0; i < columnNames.length; i++) { 
      JCheckBox checkBox = new JCheckBox(columnNames[i]); 
      checkBox.setSelected(true); 
      checkBox.addActionListener(new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent evt) { 
        JCheckBox cb = (JCheckBox) evt.getSource(); 
        String columnName = cb.getText(); 

        if (cb.isSelected()) { 
         hider.show(columnName); 
        } else { 
         hider.hide(columnName); 
        } 
       } 
      }); 
      checkBoxes.add(checkBox); 
     } 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(scrollPane); 
     frame.getContentPane().add(checkBoxes, BorderLayout.SOUTH); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+2

+1我無法抗拒這個令人高興的例子[泛型變化](http://stackoverflow.com/questions/6793257/add-column-to-exiting-tablemodel/6798013#6798013)。 – trashgod

10

只是爲了好玩,這裏是@ mKorbel的TableColumnHider的一個仿製版本。

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

/** @see https://stackoverflow.com/questions/6796673 */ 
public class TableColumnHider { 

    private JTable table; 
    private TableColumnModel tcm; 
    private Map<String, IndexedColumn> hidden = 
     new HashMap<String, IndexedColumn>(); 

    public TableColumnHider(JTable table) { 
     this.table = table; 
     this.tcm = table.getColumnModel(); 
    } 

    public void hide(String columnName) { 
     int index = tcm.getColumnIndex(columnName); 
     TableColumn column = tcm.getColumn(index); 
     IndexedColumn ic = new IndexedColumn(index, column); 
     if (hidden.put(columnName, ic) != null) { 
      throw new IllegalArgumentException("Duplicate column name."); 
     } 
     tcm.removeColumn(column); 
    } 

    public void show(String columnName) { 
     IndexedColumn ic = hidden.remove(columnName); 
     if (ic != null) { 
      tcm.addColumn(ic.column); 
      int lastColumn = tcm.getColumnCount() - 1; 
      if (ic.index < lastColumn) { 
       tcm.moveColumn(lastColumn, ic.index); 
      } 
     } 
    } 

    private static class IndexedColumn { 

     private Integer index; 
     private TableColumn column; 

     public IndexedColumn(Integer index, TableColumn column) { 
      this.index = index; 
      this.column = column; 
     } 
    } 

    public static void main(String[] args) { 
     String[] columnNames = { 
      "Name", "Size", "Type", "Date Modified", "Permissions" 
     }; 
     String[][] data = { 
      {"bin", "2", "dir", "Jun 9", "drwxr-xr-x"}, 
      {"boot", "3", "dir", "Jun 9", "drwxr-xr-x"}, 
      {"dev", "6", "dir", "Jul 12", "drwxr-xr-x"}, 
      {"etc", "34", "dir", "Jul 12", "drwxr-xr-x"} 
     }; 
     JTable table = new JTable(data, columnNames); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     JScrollPane scrollPane = new JScrollPane(table); 
     final TableColumnHider hider = new TableColumnHider(table); 
     JPanel checkBoxes = new JPanel(); 
     for (int i = 0; i < columnNames.length; i++) { 
      JCheckBox checkBox = new JCheckBox(columnNames[i]); 
      checkBox.setSelected(true); 
      checkBox.addActionListener(new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent evt) { 
        JCheckBox cb = (JCheckBox) evt.getSource(); 
        String columnName = cb.getText(); 

        if (cb.isSelected()) { 
         hider.show(columnName); 
        } else { 
         hider.hide(columnName); 
        } 
       } 
      }); 
      checkBoxes.add(checkBox); 
     } 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(scrollPane); 
     frame.getContentPane().add(checkBoxes, BorderLayout.SOUTH); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+1

這是錯誤的,因爲我在這裏錯過了任何跡象WidlCard +1 – mKorbel

1

要注意的是,從mKorbeltrashgod代碼示例不保留列的原始順序。試着按順序隱藏所有列,然後再次以相同的順序顯示它們(名稱 - >大小 - >類型 - >修改日期 - >權限),然後您會看到原始順序丟失。

如果需要再次顯示他們時保留列的原始順序,看看Stephen Kelvin's solution

不幸的是,「查看」和「模式」之間的混亂是在JTable API普遍。即使方法名稱也是誤導性的。對於一些啓示,請參閱相關討論here

+0

_「JTable API_no」中普遍存在「view」和「model」之間的混淆,這不是真的:在JTable級別,_everything_在視圖座標 – kleopatra

+0

@kleopatra ,我的意思是難以區分關於'JTable'和聚合類的模型和視圖,例如:'table.getColumnModel()。getColumnCount(); //「2」與'table.getModel()。getColumnCount(); //「3」',就像[這裏]展示的一樣(http://www.coderanch.com/t/345725/GUI/java/hide-column-JTable-view)。 – msugar

0

我已經將DefaultTableModel的addColumn方法調整爲自定義AbstractTableModel,如下所示。假設列標識符(標題)和模型數據(localCache)都是ArrayLists - 模型數據是ArrayList的ArrayList。

public void addColumn(String columnName, List columnData) { 
    headers.add(columnName); 
    colCount = headers.size(); 
    if (columnData != null) { 
     for (int r = 0; r < localCache.size(); r++) { 
      ((List)localCache.get(r)).add(columnData.get(r)); 
     } 
    } else { 
     System.out.println("Null columnData passed"); 
    } 
    fireTableStructureChanged(); 
} 
相關問題