QedeqTreeModel.java
001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002  *
003  * Copyright 2000-2013,  Michael Meyling <mime@qedeq.org>.
004  *
005  * "Hilbert II" is free software; you can redistribute
006  * it and/or modify it under the terms of the GNU General Public
007  * License as published by the Free Software Foundation; either
008  * version 2 of the License, or (at your option) any later version.
009  *
010  * This program is distributed in the hope that it will be useful,
011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013  * GNU General Public License for more details.
014  */
015 
016 package org.qedeq.gui.se.tree;
017 
018 
019 import java.util.HashMap;
020 import java.util.Map;
021 
022 import javax.swing.SwingUtilities;
023 import javax.swing.event.TreeModelListener;
024 import javax.swing.tree.DefaultTreeModel;
025 import javax.swing.tree.TreeNode;
026 import javax.swing.tree.TreePath;
027 
028 import org.qedeq.base.trace.Trace;
029 import org.qedeq.kernel.bo.common.QedeqBo;
030 import org.qedeq.kernel.bo.log.ModuleEventListener;
031 
032 
033 /**
034  * Model for a JTree.
035  *
036  * A Model, which represents the underlying, logical structure of data in a
037  * software application and the high-level class associated with it. The
038  * object model does not contain any information about the user interface.
039  *
040  @author  Michael Meyling
041  */
042 public final class QedeqTreeModel extends DefaultTreeModel implements ModuleEventListener {
043 
044     /** This class. */
045     private static final Class CLASS = QedeqTreeModel.class;
046 
047     /**
048      * Maps {@link org.qedeq.kernel.bo.module.ModuleAddress}es to {@link TreeNode}s..
049      */
050     private final Map address2Path = new HashMap();
051 
052     private QedeqTreeModel(final TreeNode root) {
053         super(root);
054     }
055 
056     /**
057      * Creates tree model.
058      */
059     public QedeqTreeModel() {
060         this(new QedeqTreeNode(new ModuleElement()true));
061     }
062 
063     /*  (non-Javadoc)
064      * @see javax.swing.tree.TreeModel#addTreeModelListener(javax.swing.event.TreeModelListener)
065      */
066     public void addTreeModelListener(final TreeModelListener listener) {
067         Trace.trace(CLASS, this, "addTreeModelListener", listener);
068         super.addTreeModelListener(listener);
069     }
070 
071     public void addModule(final QedeqBo prop) {
072         Runnable addModule = new Runnable() {
073             public void run() {
074                 synchronized (QedeqTreeModel.class) {
075                     final QedeqTreeNode root = (QedeqTreeNodegetRoot();
076                     final QedeqTreeNode node = new QedeqTreeNode(prop, false);
077                     Trace.trace(CLASS, this, "addModule""calls insertNodeInto=" + node);
078                     address2Path.put(prop.getModuleAddress()new TreePath(node.getPath()));
079                     for (int i = 0; i < root.getChildCount(); i++) {
080                         final QedeqTreeNode n = (QedeqTreeNoderoot.getChildAt(i);
081                         final QedeqBo p = (QedeqBon.getUserObject();
082                         if (p.getModuleAddress().getFileName().compareTo(prop.getModuleAddress()
083                                 .getFileName()) 0) {
084                             Trace.param(CLASS, this, "addModule""adding at", i);
085                             insertNodeInto(node, root, i);
086                             return;
087                         }
088                     }
089                     Trace.param(CLASS, this, "addModule""adding at end", root.getChildCount());
090                     insertNodeInto(node, root, root.getChildCount());
091                 }
092             }
093         };
094         SwingUtilities.invokeLater(addModule);
095     }
096 
097     public void stateChanged(final QedeqBo prop) {
098         Runnable stateChanged = new Runnable() {
099             public void run() {
100 // LATER mime 20080502: take the following code and make it workable. Currently problems if deleting
101 //                synchronized (QedeqTreeModel.class){
102 //                    final QedeqTreeNode root = (QedeqTreeNode) getRoot();
103 //                    final QedeqTreeNode node = new QedeqTreeNode(prop, false);
104 //                    node.setParent(root);
105 //                    nodeChanged(node);
106 //                }
107                 synchronized (QedeqTreeModel.class) {
108                     final TreePath path = (TreePathaddress2Path.get(prop.getModuleAddress());
109                     if (path == null) {
110                         throw new IllegalArgumentException("unknown property: "
111                             + prop.getModuleAddress());
112                     }
113                     final QedeqTreeNode node = (QedeqTreeNodepath.getLastPathComponent();
114                     QedeqBo sameProp = (QedeqBonode.getUserObject();
115                     if (!prop.equals(sameProp)) {
116                         throw new IllegalStateException("should not happen");
117                     }
118                     Trace.param(CLASS, this, "stateChanged""nodeChanged", node);
119                     Trace.param(CLASS, this, "stateChanged""state", prop.getStateDescription());
120                     nodeChanged(node);
121                 }
122             }
123 
124         };
125 
126         SwingUtilities.invokeLater(stateChanged);
127     }
128 
129     public void removeModule(final QedeqBo prop) {
130         Runnable removeModule = new Runnable() {
131             public void run() {
132 // LATER mime 20080502: take the following code and make it workable. Currently problems if deleting
133 //                final QedeqTreeNode root = (QedeqTreeNode) getRoot();
134 //                final QedeqTreeNode node = new QedeqTreeNode(prop, false);
135 //                node.setParent(root);
136 //                removeNodeFromParent(node);
137 
138                 synchronized (QedeqTreeModel.class) {
139                     final TreePath path = (TreePathaddress2Path.get(prop.getModuleAddress());
140                     if (path == null) {
141                         throw new IllegalArgumentException("unknown property: "
142                             + prop.getModuleAddress());
143                     }
144                     final QedeqTreeNode node = (QedeqTreeNodepath.getLastPathComponent();
145                     QedeqBo sameProp = (QedeqBonode.getUserObject();
146                     if (!prop.equals(sameProp)) {
147                         throw new IllegalStateException("should not happen");
148                     }
149                     address2Path.remove(prop.getModuleAddress());
150                     Trace.trace(CLASS, this, "removeModule""nodeRemoved=" + node);
151                     removeNodeFromParent(node);
152                 }
153             }
154         };
155         SwingUtilities.invokeLater(removeModule);
156     }
157 
158 }