2009-12-30 30 views
1

我有一個具有X個字段的對象。我的JTable中的每一行都對應一個項目。行中的每一列代表該項目的一個字段。我還需要保持對項目的引用(該項目還有一個唯一的ID字段),以便我可以確定所選單元格中的項目。具有多個字段的Java JTable對象

對此的首選方法是將實際的對象放在表格中的每個單元格中,並使用各種渲染器來顯示項目或簡單地將字段值放在每個單元格中並且具有隱藏的列具有項目我需要知道物品ID時可以參考的ID?

感謝, 傑夫

+0

這不是問題。 –

+0

它可能不會被格式化爲一個問題,但實際上它確實需要一個首選方法。 – Carlos

+1

我加了問號。 –

回答

3

我會寫一個自定義的表格模型(而不是試圖鞋拔子設計成默認的表模型實現)。這個模型然後保存你的實際對象,並且在它的方法實現中(例如getValueAt),它會將每個字段視爲列。


簡單實例(未測試,但應很好地示出的想法):

import java.util.List; 
import java.util.ArrayList; 
import javax.swing.table.AbstractTableModel; 

/** 
* Simple table model for displaying properties common to all objects. 
* Note that all methods must run inside the event dispatch thread. 
*/ 
public class ObjectPropertyTableModel extends AbstractTableModel { 
    private final List<Object> objects = new ArrayList<Object>(); 

    public void addObject(Object obj) { 
     addObject(obj, objects.size()); 
    } 

    public void addObject(Object obj, int index) { 
     objects.add(index, obj); 
     fireTableRowsInserted(index, index); 
    } 

    public void removeObject(Object obj) { 
     int index = objects.indexOf(obj); 
     objects.remove(index); 
     fireTableRowsDeleted(index, index); 
    } 

    public Object getObject(int rowIndex) { 
     return objects.get(rowIndex); 
    } 

    @Override 
    public int getRowCount() { 
     return objects.size(); 
    } 

    @Override 
    public int getColumnCount() { 
     return 3; 
    } 

    @Override 
    public String getColumnName(int columnIndex) { 
     switch (columnIndex) { 
     case 0: return "toString"; 
     case 1: return "hashCode"; 
     case 2: return "class"; 
     default: throw new IndexOutOfBoundsException(); 
     } 
    } 

    @Override 
    public Class<?> getColumnClass(int columnIndex) { 
     switch (columnIndex) { 
     case 0: return String.class; 
     case 1: return Integer.class; 
     case 2: return Class.class; 
     default: throw new IndexOutOfBoundsException(); 
     } 
    } 

    @Override 
    public Object getValueAt(int rowIndex, int columnIndex) { 
     Object obj = objects.get(rowIndex); 
     switch (columnIndex) { 
     case 0: return obj.toString(); 
     case 1: return obj.hashCode(); 
     case 2: return obj.getClass(); 
     default: throw new IndexOutOfBoundsException(); 
     } 
    } 
} 
+0

這意味着一行中的每個單元格都會對同一個對象有一個引用,對嗎? –

+0

不完全。在自定義表格模型的情況下,單元格是「虛擬的」。當表想要顯示一個單元格時,它會調用你的'getValueAt'方法。在那一點,訪問你的對象的相關領域。 –

+1

(是的,在模型中工作,保持渲染器簡單。) –

0

我的優選的方法是具有從字段返回一個值針對各列的表模型。爲了能夠獲得對象的引用,我在模型中添加了一個可以稱爲getObjectFromRow的方法,正如其名稱所示,它返回對應於行索引的對象。這樣,您可以在單元格中顯示實際顯示的數據,並且不需要隱藏列來獲取對行對象的引用。當然這需要一個自定義表格模型,但我認爲這很值得遇到麻煩。
使用渲染器從正確的字段顯示數據當然也是可以的,但在我的經驗,這有幾個問題,包括編寫所有的渲染器針對不同的數據類型,從表中複製&粘貼的麻煩,也是事實的確無法正常使用。

1

您可能可以使用Bean Table Model。如果不是,那麼JButtonTableModel示例顯示如何實現getValueAt/setValueAt()方法並利用RowTableModel提供的功能,因此您無需從頭開始創建TableModel。

+0

謝謝。不幸的是,它們不一定是getXXX方法。它們是getProperty(XXX),因爲屬性是在運行時確定的,但這是一個很好的瞭解。 –

+0

這就是爲什麼我建議JButtonTableModel示例可能會更好,因爲通過重寫一些方法可以輕鬆進行自定義,並且您仍然擁有所需的全部功能。它支持檢索行對象的方法,因此即使它在表中不可見,也可以獲得ID。它還支持動態添加/刪除行。 – camickr