2015-02-26 3 views
0

Я изучаю, как реализовать TreeTable в SwingX. Для начала у меня есть модель таблицы:Добавление и удаление элементов в Jtreetable в swingX

import java.util.ArrayList; 
import java.util.List; 

import org.jdesktop.swingx.treetable.AbstractTreeTableModel; 
import org.jdesktop.swingx.treetable.DefaultTreeTableModel; 

public class MyTreeTableModel extends AbstractTreeTableModel 
{ 
    private MyTreeNode myroot; 
    //here we add new children 
    public MyTreeTableModel() 
    { 
     myroot = new MyTreeNode("root", "Root of the tree"); 


     myroot.getChildren().add(new MyTreeNode("Empty Child 1", "This is an empty child")); 

     MyTreeNode subtree = new MyTreeNode("Sub Tree", "This is a subtree (it has children)"); 
     subtree.getChildren().add(new MyTreeNode("EmptyChild 1, 1", "This is an empty child of a subtree")); 
     subtree.getChildren().add(new MyTreeNode("EmptyChild 1, 2", "This is an empty child of a subtree")); 
     myroot.getChildren().add(subtree); 

     myroot.getChildren().add(new MyTreeNode("Empty Child 2", "This is an empty child"));  

    } 

    public void addChildren(){ 
     myroot.getChildren().add(new MyTreeNode("Empty Child 1", "This is an empty child")); 
    } 

    //get colunmcount 
    public int getColumnCount() 
    { 
     return 4; 
    } 

    @Override 
    public String getColumnName(int column) 
    { 
     switch(column) 
     { 
     case 0: return "Description"; 
     case 1: return "Amount"; 
     case 2: return "Date"; 
     case 3: return "Paid"; 

     default: return "Unknown"; 
     } 
    } 

    public Object getValueAt(Object node, int column) 
    { 
     System.out.println("getValueAt: " + node + ", " + column); 
     MyTreeNode treenode = (MyTreeNode)node; 
     switch(column) 
     { 
     case 0: return treenode.getName(); 
     case 1: return treenode.getDescription(); 
     case 2: return treenode.getChildren().size(); 
     default: return "Unknown"; 
     } 
    } 

    public Object getChild(Object node, int index) 
    { 
     MyTreeNode treenode = (MyTreeNode)node; 
     return treenode.getChildren().get(index); 
    } 

    public int getChildCount(Object parent) 
    { 
     MyTreeNode treenode = (MyTreeNode)parent; 
     return treenode.getChildren().size(); 
    } 

    public int getIndexOfChild(Object parent, Object child) 
    { 
     MyTreeNode treenode = (MyTreeNode)parent; 
     for(int i=0; i>treenode.getChildren().size(); i++) 
     { 
      if(treenode.getChildren().get(i) == child) 
      { 
       return i; 
      } 
     } 

     // TODO Auto-generated method stub 
     return 0; 
    } 

    public boolean isLeaf(Object node) 
    { 
     MyTreeNode treenode = (MyTreeNode)node; 
     if(treenode.getChildren().size() > 0) 
     { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public Object getRoot() 
    { 
     return myroot; 
    } 
    } 

class MyTreeNode 
{ 
    private String name; 
    private String description; 
    private List<MyTreeNode> children = new ArrayList<MyTreeNode>(); 

    public MyTreeNode() 
    { 
    } 

    public MyTreeNode(String name, String description) 
    { 
     this.name = name; 
     this.description = description; 
    } 

    public String getName() 
    { 
     return name; 
    } 

    public void setName(String name) 
    { 
     this.name = name; 
    } 

    public String getDescription() 
    { 
     return description; 
    } 

    public void setDescription(String description) 
    { 
     this.description = description; 
    } 

    public List<MyTreeNode> getChildren() 
    { 
     return children; 
    } 

    public String toString() 
    { 
     return "MyTreeNode: " + name + ", " + description; 
    } 

И вот я пытаюсь запустить его:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.Toolkit; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTabbedPane; 
import javax.swing.JTable; 
import javax.swing.SwingUtilities; 

import models.ExpenseModel; 

import org.jdesktop.swingx.JXTreeTable; 


public class SwingXExample extends JFrame 
{ 
    private JTabbedPane tabs = new JTabbedPane(); 

    private MyTreeTableModel treeTableModel = new MyTreeTableModel(); 
    private JXTreeTable treeTable = new JXTreeTable(treeTableModel); 

    public SwingXExample() 
    { 
     super("SwingX Examples"); 

     // Build the tree table panel 
     JPanel treeTablePanel = new JPanel(new BorderLayout()); 
     treeTablePanel.add(new JScrollPane(treeTable)); 
     tabs.addTab("JXTreeTable", treeTablePanel); 


     JButton add_button = new JButton("+"); 
     JPanel buttonsPanel = new JPanel(); 
     buttonsPanel.setBounds(10, 260, 300, 30); 
     getContentPane().add(buttonsPanel); 
     buttonsPanel.setLayout(new GridLayout(0, 3, 0, 0)); 
     buttonsPanel.add(add_button); 
     add_button.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       // Get active table 
       treeTableModel.addChildren(); 
      } 
     }); 

     // Add the tabs to the JFrame 

     add(tabs); 

     setSize(1024, 768); 
     Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); 
     setLocation(d.width/2 - 512, d.height/2 - 384); 
     setVisible(true); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 


    public static void main(String[] args) 
    { 
     AppStarter starter = new AppStarter(args); 
     SwingUtilities.invokeLater(starter); 
    } 
} 

class AppStarter extends Thread 
{ 
    private String[] args; 

    public AppStarter(String[] args) 
    { 
     this.args = args; 
    } 

    public void run() 
    { 
     SwingXExample example = new SwingXExample(); 
    } 

} 

Проблема в том, что мой метод, addChildren не работает вообще, таблица является не обновляясь, когда я нажимаю кнопку. Кроме того, мне интересно, как я могу удалить что-то из таблицы. Если кто-то знает, что я делаю неправильно здесь, пожалуйста, помогите мне.

+1

Задайте себе этот вопрос, «Как известно представление, когда модель изменилась»? – MadProgrammer

+0

хорошая точка, но я не могу найти какую-либо функцию, которая может обновить представление. – Ophelia

ответ

0

После некоторого рыть вокруг JavaDocs, я был разочарован в не найти метод fireXxx ...

Так что я начал копаться в исходном коде DefaultTreeTableModel, потому что он имеет метод insertNodeInto ...

public void insertNodeInto(MutableTreeTableNode newChild, 
     MutableTreeTableNode parent, int index) { 
    parent.insert(newChild, index); 

    modelSupport.fireChildAdded(new TreePath(getPathToRoot(parent)), index, 
      newChild); 
} 

Итак, есть еще один класс, который использовался для поддержки уведомления о событиях, удивительный ... теперь, как мы получаем доступ к нему?

После выполнения кода назад, я нашел ...

public abstract class AbstractTreeTableModel implements TreeTableModel { 

    /** 
    * Provides support for event dispatching. 
    */ 
    protected TreeModelSupport modelSupport; 

Итак, modelSupport определяется в AbstractTreeTableModel в protected! Не так, как я хотел бы это сделать, но это так.

Таким образом, в методе addChildren, вам нужно стрелять событие, говоря мнение о том, что новый узел был вставлен ...

public void addChildren(){ 
    MyTreeNode newChild = new MyTreeNode("Empty Child 1", "This is an empty child"); 
    myroot.getChildren().add(newChild); 
    modelSupport.fireChildAdded(
     new TreePath(getPathToRoot(myroot)), 
     myroot.getChildren().size() - 1, 
     newChild); 
} 

или некоторые такие ...

+0

hmmm, он говорит, что метод fireChildAdded (TreePath, int, Object) в типе TreeModelSupport не применим для аргументов (TreePath, int, MyTreeNode) И по какой-то причине путь дерева не может быть разрешен как type0_o – Ophelia

+0

Ну, [' javax.swing.tree.TreePath'] (http://docs.oracle.com/javase/7/docs/api/javax/swing/tree/TreePath.html) является частью Swing API ... (и я не тестировал код, я просто ковылял его вместе) – MadProgrammer

+0

ok, с импортом treepath эта проблема была решена, но теперь она, похоже, не знает метода getPathtoRoot – Ophelia