I am using my own custom model for JXTree which extends from AbstractTreeTableModel
. So the option of reload / removeNodeFromParent
is not there.
I have tried using TreeModelListener
and treeModelListener.treeNodesRemoved(event)
call with every input option possible. Never is my tree's GUI getting updated. Unless i call tree.updateUI()
the changed structure is not getting reflected.(But that call is updating the entire tree and i just want the deleted node to be refreshed). I am using my custom tree editor and tree renderer. I have not written any custom tree listener.
So the question i ask is : Does listener.treeNodesRemoved()
implicitly call some code that would have the same result as tree.updateUI()
. Or do i need to write some code myself to refresh that particular parent node from which the child was deleted. Is the listener call not working because i am using custom tree editor and renderer.
EDIT :
I am posting an SSCCE. In this case i am not using any tree editor or rendrer but the issue can be seen using this code also.
public class TestListener extends JFrame{
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestListener();
}
});
}
public TestListener(){
Departement dept1 = new Departement("1ST DEPARTMENT");
Departement dept2 = new Departement("2ND DEPARTMENT");
Employee emp1 = new Employee("1ST Employee");
Employee emp2 = new Employee("2ND Employee");
Employee emp3 = new Employee("3rd Employee");
final Employee emp4 = new Employee("4th Employee");
ArrayList<Employee> empList1 = new ArrayList<Employee>();
empList1.add(emp1);
empList1.add(emp2);
final ArrayList<Employee> empList2 = new ArrayList<Employee>();
empList2.add(emp3);
empList2.add(emp4);
dept1.setEmpList(empList1);
dept2.setEmpList(empList2);
ArrayList<Departement> deptList = new ArrayList<Departement>();
deptList.add(dept1);
deptList.add(dept2);
TestModel model = new TestModel(deptList);
final JXTree rootTree = new JXTree(model);
rootTree.setShowsRootHandles(true); // to show collapse and expand icons
rootTree.setEditable(true);
rootTree.setRootVisible(false); //not to show the top root
rootTree.setVisible(true);
JButton button = new JButton("Delete Node");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
JXTree rootNew = rootTree;
empList2.remove(emp4);
TestModel model = (TestModel) rootNew.getModel();
TreeModelEvent event = new TreeModelEvent(this,
new Object[] {rootNew.getPathForRow(3)}, // harcoding because i know i am deleting from dept2
new int[]{1}, //hardcoding as i am removing emp4
new Object[] {emp4});
TreeModelListener[] listeners = model.getTreeModelListeners();
for (TreeModelListener listener : listeners) {
listener.treeNodesRemoved(event);
}
}
});
this.setLayout(new GridLayout(0, 1));
this.getContentPane().add(new JScrollPane(rootTree));
this.getContentPane().add(button);
this.setSize(new java.awt.Dimension(400, 400));
this.setLocation(280, 50);
this.setVisible(true);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
}
}
TestModel Class
public class TestModel extends AbstractTreeTableModel {
private final static String[] COLUMN_NAMES = { "LABEL" };
public TestModel(ArrayList<Departement> depList) {
super(depList);
this.depList = depList;
}
private ArrayList<Departement> depList;
/* (non-Javadoc)
* @see org.jdesktop.swingx.treetable.TreeTableModel#getColumnCount()
*/
@Override
public int getColumnCount() {
return COLUMN_NAMES.length;
}
/* (non-Javadoc)
* @see org.jdesktop.swingx.treetable.TreeTableModel#getValueAt(java.lang.Object, int)
*/
@Override
public Object getValueAt(Object arg0, int arg1) {
if (arg0 instanceof Employee) {
Employee emp = (Employee) arg0;
JLabel newLabel = new JLabel();
newLabel.setText(emp.getName());
return (JLabel)newLabel;
} else if (arg0 instanceof Departement) {
Departement dept = (Departement) arg0;
JLabel newLabel = new JLabel();
newLabel.setText(dept.getName());
return (JLabel)newLabel;
}
return null;
}
/* (non-Javadoc)
* @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)
*/
@Override
public Object getChild(Object arg0, int arg1) {
if (arg0 instanceof Departement) {
Departement dept = (Departement) arg0;
return dept.getEmpList().get(arg1);
}
return depList.get(arg1);
}
/* (non-Javadoc)
* @see javax.swing.tree.TreeModel#getChildCount(java.lang.Object)
*/
@Override
public int getChildCount(Object arg0) {
if (arg0 instanceof Departement) {
Departement dept = (Departement) arg0;
return dept.getEmpList().size();
}
if (arg0 instanceof Employee) {
return 0;
}
return this.depList.size();
}
/* (non-Javadoc)
* @see javax.swing.tree.TreeModel#getIndexOfChild(java.lang.Object, java.lang.Object)
*/
@Override
public int getIndexOfChild(Object arg0, Object arg1) {
Departement dept = (Departement) arg0;
Employee emp = (Employee) arg1;
return dept.getEmpList().indexOf(emp);
}
}
The Department and Employee class is fairly simple with a constructor and some getter/setters .
So when i click on the delete node button no action is happening on the tree. The UI is not getting updated at all. I am using swingx 1.6.4 version.
Department
public class Departement {
private String name;
public String getName() {
return name;
}
private ArrayList<Employee> empList;
public ArrayList<Employee> getEmpList() {
return empList;
}
public void setEmpList(ArrayList<Employee> empList) {
this.empList = empList;
}
public Departement(String name){
this.name = name;
}
}
Employee
public class Employee {
private String name;
public String getName() {
return name;
}
public Employee(String name){
this.name =name;
}
}