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  @version $Revision: 1.7 $
041  @author  Michael Meyling
042  */
043 public final class QedeqTreeModel extends DefaultTreeModel implements ModuleEventListener {
044 
045     /** This class. */
046     private static final Class CLASS = QedeqTreeModel.class;
047 
048     /**
049      * Maps {@link org.qedeq.kernel.bo.module.ModuleAddress}es to {@link TreeNode}s..
050      */
051     private final Map address2Path = new HashMap();
052 
053     private QedeqTreeModel(final TreeNode root) {
054         super(root);
055     }
056 
057     /**
058      * Creates tree model.
059      */
060     public QedeqTreeModel() {
061         this(new QedeqTreeNode(new ModuleElement()true));
062     }
063 
064     /*  (non-Javadoc)
065      * @see javax.swing.tree.TreeModel#addTreeModelListener(javax.swing.event.TreeModelListener)
066      */
067     public void addTreeModelListener(final TreeModelListener listener) {
068         Trace.trace(CLASS, this, "addTreeModelListener", listener);
069         super.addTreeModelListener(listener);
070     }
071 
072     public void addModule(final QedeqBo prop) {
073         Runnable addModule = new Runnable() {
074             public void run() {
075                 synchronized (QedeqTreeModel.class) {
076                     final QedeqTreeNode root = (QedeqTreeNodegetRoot();
077                     final QedeqTreeNode node = new QedeqTreeNode(prop, false);
078                     Trace.trace(CLASS, this, "addModule""calls insertNodeInto=" + node);
079                     address2Path.put(prop.getModuleAddress()new TreePath(node.getPath()));
080                     for (int i = 0; i < root.getChildCount(); i++) {
081                         final QedeqTreeNode n = (QedeqTreeNoderoot.getChildAt(i);
082                         final QedeqBo p = (QedeqBon.getUserObject();
083                         if (p.getModuleAddress().getFileName().compareTo(prop.getModuleAddress()
084                                 .getFileName()) 0) {
085                             Trace.param(CLASS, this, "addModule""adding at", i);
086                             insertNodeInto(node, root, i);
087                             return;
088                         }
089                     }
090                     Trace.param(CLASS, this, "addModule""adding at end", root.getChildCount());
091                     insertNodeInto(node, root, root.getChildCount());
092                 }
093             }
094         };
095         SwingUtilities.invokeLater(addModule);
096     }
097 
098     public void stateChanged(final QedeqBo prop) {
099         Runnable stateChanged = new Runnable() {
100             public void run() {
101 // LATER mime 20080502: take the following code and make it workable. Currently problems if deleting
102 //                synchronized (QedeqTreeModel.class){
103 //                    final QedeqTreeNode root = (QedeqTreeNode) getRoot();
104 //                    final QedeqTreeNode node = new QedeqTreeNode(prop, false);
105 //                    node.setParent(root);
106 //                    nodeChanged(node);
107 //                }
108                 synchronized (QedeqTreeModel.class) {
109                     final TreePath path = (TreePathaddress2Path.get(prop.getModuleAddress());
110                     if (path == null) {
111                         throw new IllegalArgumentException("unknown property: "
112                             + prop.getModuleAddress());
113                     }
114                     final QedeqTreeNode node = (QedeqTreeNodepath.getLastPathComponent();
115                     QedeqBo sameProp = (QedeqBonode.getUserObject();
116                     if (!prop.equals(sameProp)) {
117                         throw new IllegalStateException("should not happen");
118                     }
119                     Trace.param(CLASS, this, "stateChanged""nodeChanged", node);
120                     Trace.param(CLASS, this, "stateChanged""state", prop.getStateDescription());
121                     nodeChanged(node);
122                 }
123             }
124 
125         };
126 
127         SwingUtilities.invokeLater(stateChanged);
128     }
129 
130     public void removeModule(final QedeqBo prop) {
131         Runnable removeModule = new Runnable() {
132             public void run() {
133 // LATER mime 20080502: take the following code and make it workable. Currently problems if deleting
134 //                final QedeqTreeNode root = (QedeqTreeNode) getRoot();
135 //                final QedeqTreeNode node = new QedeqTreeNode(prop, false);
136 //                node.setParent(root);
137 //                removeNodeFromParent(node);
138 
139                 synchronized (QedeqTreeModel.class) {
140                     final TreePath path = (TreePathaddress2Path.get(prop.getModuleAddress());
141                     if (path == null) {
142                         throw new IllegalArgumentException("unknown property: "
143                             + prop.getModuleAddress());
144                     }
145                     final QedeqTreeNode node = (QedeqTreeNodepath.getLastPathComponent();
146                     QedeqBo sameProp = (QedeqBonode.getUserObject();
147                     if (!prop.equals(sameProp)) {
148                         throw new IllegalStateException("should not happen");
149                     }
150                     address2Path.remove(prop.getModuleAddress());
151                     Trace.trace(CLASS, this, "removeModule""nodeRemoved=" + node);
152                     removeNodeFromParent(node);
153                 }
154             }
155         };
156         SwingUtilities.invokeLater(removeModule);
157     }
158 
159 }