2011-08-31 62 views
2

我試圖使用從http://java.sun.com/products/jfc/tsc/articles/treetable2/index.html,其中我已經取代我的模型文件系統模型所採取的例子。JTreeTable更新

我最初創建一個模型,我在JTreeTable顯示它,但現在我想更新我的模型,然後JTreeTable(例如,我想在樹上添加一個節點,修改節點,刪除節點等)。

我不知道我該怎麼做。我看不到讓我做我想做的事情的方法,我只看到一些方法,如treeNodesChanged,treeNodesInserted等,但可能我錯過了此JTreeTable組件的全局邏輯中的某些內容。

除了我不確定我是否正確創建模型,因爲在各種示例中,我已經看到人們通過「模型」對象調用各種方法(model.insertNodeInto,model.reload),儘管我沒有模型對象..In上面的例子中,被簡稱爲抽象類AbstractTreeTableModel它實現TreeTableModel ..

更新

public class TableModel extends AbstractTreeTableModel 
         implements TreeTableModel { 
static protected String[] cNames = {"TrackNumber", "MWRTN", "LSRTN", "RFTN","TrackStatus","Prova","Prova2"}; 
    // Types of the columns. 
static protected Class[] cTypes = {TreeTableModel.class,Integer.class, Integer.class, Integer.class, Integer.class,String.class,String.class}; 

private ArrayList<Object> data=new ArrayList<Object>(); 
    public void insertNode(Object node) 
    { this.data.add(node); super.setRoot(data.get(0));} 

在我的主類我以這種方式將對象添加到我的模型:

... 
model =new TableModel(); 
model.insertNode(threatList.get(i)); //inserting the root node 
model.addChild(threatList.get(i),threatList.get(j)); // inserting the child 
... 

然後我的模型傳遞給我的JTreeTable,並把它添加到我的框架:

treeTable = new JTreeTable(model); 
JScrollPane scroll=new JScrollPane(treeTable); 
scroll.setAutoscrolls(false); 
scroll.setPreferredSize(new Dimension(1000,80)); 
frame.add(scroll); 

這是JTreeTable類:

public class JTreeTable extends JTable { 
protected TreeTableCellRenderer tree; 

public JTreeTable(TreeTableModel treeTableModel) { 
super(); 

// Create the tree. It will be used as a renderer and editor. 
tree = new TreeTableCellRenderer(treeTableModel); 

// Install a tableModel representing the visible rows in the tree. 
super.setModel(new TreeTableModelAdapter(treeTableModel, tree)); 

// Force the JTable and JTree to share their row selection models. 
tree.setSelectionModel(new DefaultTreeSelectionModel() { 
    // Extend the implementation of the constructor, as if: 
/* public this() */ { 
    setSelectionModel(listSelectionModel); 
    } 
}); 
// Make the tree and table row heights the same. 
tree.setRowHeight(getRowHeight()); 

// Install the tree editor renderer and editor. 
setDefaultRenderer(TreeTableModel.class, tree); 
setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor()); 

setShowGrid(false); 
setIntercellSpacing(new Dimension(0, 0)); 
setPreferredSize(new Dimension(60,60)); 
} 

/* Workaround for BasicTableUI anomaly. Make sure the UI never tries to 
* paint the editor. The UI currently uses different techniques to 
* paint the renderers and editors and overriding setBounds() below 
* is not the right thing to do for an editor. Returning -1 for the 
* editing row in this case, ensures the editor is never painted. 
*/ 
public int getEditingRow() { 
    return (getColumnClass(editingColumn) == TreeTableModel.class) ? -1 : editingRow; 
} 

// 
// The renderer used to display the tree nodes, a JTree. 
// 

public class TreeTableCellRenderer extends JTree implements TableCellRenderer { 

protected int visibleRow; 

public TreeTableCellRenderer(TreeModel model) { 
    super(model); 
} 

public void setBounds(int x, int y, int w, int h) { 
    super.setBounds(x, 0, w, JTreeTable.this.getHeight()); 
} 

public void paint(Graphics g) { 
    g.translate(0, -visibleRow * getRowHeight()); 
    super.paint(g); 
} 

public Component getTableCellRendererComponent(JTable table, 
          Object value, 
          boolean isSelected, 
          boolean hasFocus, 
          int row, int column) { 
    if(isSelected) 
      setBackground(table.getSelectionBackground()); 
    else 
      setBackground(table.getBackground()); 

    visibleRow = row; 
    return this; 
    } 
} 

// 
// The editor used to interact with tree nodes, a JTree. 
// 

public class TreeTableCellEditor extends AbstractCellEditor implements TableCellEditor { 
    public Component getTableCellEditorComponent(JTable table, Object value, 
          boolean isSelected, int r, int c) { 
     return tree; 
    } 

    @Override 
    public Object getCellEditorValue() { 
     // TODO Auto-generated method stub 
     return null; 
    } 
} 

我會是觸發一個事件在添加(或修改,或刪除)一個孩子之後。

回答

2

該模型是持有您的數據的類。每次數據更改時都必須告訴其視圖,以便視圖自行刷新並顯示模型的新數據。這是方法fireXxx()的目標。

像與其他Swing組件,當您更改由組件顯示的數據,你應該通過這樣的模式轉變中的數據做了,並調用相應的fireXxx方法。最好的辦法是將其封裝在模型類中,方法是在AbstractTreeTableModel的子類中添加特定的方法,它們執行數據修改,並使用一次或多次調用fireXxx來觸發適當的事件。

我建議你閱讀關於tables和或trees的Swing教程,然後將你在這裏學到的東西應用到你的樹形表中。這個想法是一樣的。

+0

完美...我開始理解機制!謝謝! – marco

+0

方法fireTreeNodesInserted採用四個參數: 源 - 其中被插入的新元素節點 路徑 - 路徑到根節點 childIndices - 新元素 兒童的指數 - 新要素 以我情況下,我我已經將一個名爲A1的孩子添加到名爲A的父親,所以在我添加了這個模型之後,我必須調用fireTreeNodesInserted()...我想象的第一個和最後一個參數分別是A和A1 ......但我不知道第二個和第三個怎麼填滿...... – marco

+0

第三個應該是包含單個元素的數組:A1的列表中的A1的索引(從0開始)。如果它是A的第一個孩子,那麼它應該包含0.第二個參數是從A到根的路徑。因此它應該包含A作爲其第一個元素,然後包含A的父元素等,直到最後一個索引處的根節點。在DefaultTreeModel(getPathToRoot)中有一個實用方法可以爲你做到這一點。 –