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