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 = (QedeqTreeNode) getRoot();
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 = (QedeqTreeNode) root.getChildAt(i);
081 final QedeqBo p = (QedeqBo) n.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 = (TreePath) address2Path.get(prop.getModuleAddress());
109 if (path == null) {
110 throw new IllegalArgumentException("unknown property: "
111 + prop.getModuleAddress());
112 }
113 final QedeqTreeNode node = (QedeqTreeNode) path.getLastPathComponent();
114 QedeqBo sameProp = (QedeqBo) node.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 = (TreePath) address2Path.get(prop.getModuleAddress());
140 if (path == null) {
141 throw new IllegalArgumentException("unknown property: "
142 + prop.getModuleAddress());
143 }
144 final QedeqTreeNode node = (QedeqTreeNode) path.getLastPathComponent();
145 QedeqBo sameProp = (QedeqBo) node.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 }
|