2011-08-31 3 views
2

J'essaie d'utiliser l'exemple tiré du http://java.sun.com/products/jfc/tsc/articles/treetable2/index.html, dans lequel j'ai substitué le modèle de système de fichiers à mon modèle.JTreeTable mise à jour

Je crée d'abord un modèle, je l'affiche dans le JTreeTable, mais maintenant je voudrais mettre à jour mon modèle puis le JTreeTable (par exemple je veux ajouter un nœud à l'arbre, modifier un nœud, supprimer un nœud, etc.).

Je ne sais pas comment je peux le faire. Je ne peux pas voir la méthode qui me permet de faire ce que je veux, je vois seulement une méthode comme treeNodesChanged, treeNodesInserted, etc., mais probablement quelque chose me manque dans la logique globale de ce composant JTreeTable. En outre, je ne suis pas sûr de créer correctement le modèle, parce que dans divers exemples, j'ai vu des gens appeler diverses méthodes sur un objet "modèle" (model.insertNodeInto, model.reload), malgré que je n'ai pas d'objet modèle ..dans l'exemple ci-dessus, est simplement appelé la classe abstraite AbstractTreeTableModel qui implémente TreeTableModel ..

Mise à jour

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

dans ma classe principale ajouter des objets à mon modèle de cette façon:

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

Ensuite, je passe le modèle à mon JTreeTable et l'ajouter à mon image:

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

Et c'est la classe 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; 
    } 
} 

Ce que j'est de déclencher un événement après avoir ajouté (ou modifié ou supprimé) un enfant.

Répondre

2

Le modèle est la classe contenant vos données. Il doit indiquer sa vue chaque fois que les données changent, afin que la vue se rafraîchisse et affiche les nouvelles données du modèle. C'est l'objectif des méthodes fireXxx().

Comme pour les autres composants Swing, lorsque vous modifiez les données affichées par le composant, vous devez le faire en changeant les données du modèle et en appelant les méthodes fireXxx appropriées. La meilleure chose à faire est de l'encapsuler dans la classe model, en ajoutant des méthodes spécifiques dans votre sous-classe de AbstractTreeTableModel qui effectuent la modification des données et déclenchent l'événement approprié en utilisant un ou plusieurs appels à fireXxx.

Je vous suggère de lire le tutoriel de Swing sur tables ou trees et ensuite appliquer ce que vous avez appris ici à votre arbre. L'idée est la même.

+0

Parfait ... Je commence à comprendre le mécanisme! Merci! – marco

+0

La méthode fireTreeNodesInserted prend quatre paramètres: source - le nœud où de nouveaux éléments sont insérés chemin - le chemin vers le nœud racine childIndices - les indices des éléments nouveaux enfants - les nouveaux éléments Dans mon cas, je Pour ajouter un enfant appelé A1 à un père appelé A, donc après avoir ajouté ceci dans mon modèle, je dois appeler le fireTreeNodesInserted() ... le premier et le dernier paramètres que j'imagine qui sont respectivement A et A1 ... mais je ne sais pas comment remplir le deuxième et le troisième ... – marco

+0

le troisième devrait être un tableau contenant un seul élément: l'index (commençant à 0) de A1 dans la liste des enfants de A. Si c'est le premier enfant de A, il doit donc contenir 0. Le second argument est le chemin de A à la racine. Il devrait donc contenir A comme premier élément, puis parent de A, etc. jusqu'au nœud racine, au dernier index. Il existe une méthode d'utilitaire dans DefaultTreeModel (getPathToRoot) pour le faire pour vous. –