001: /*
002: * Jacareto Copyright (c) 2002-2005
003: * Applied Computer Science Research Group, Darmstadt University of
004: * Technology, Institute of Mathematics & Computer Science,
005: * Ludwigsburg University of Education, and Computer Based
006: * Learning Research Group, Aachen University. All rights reserved.
007: *
008: * Jacareto is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * Jacareto is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public
019: * License along with Jacareto; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package jacareto.trackimpl;
025:
026: import jacareto.record.Recordable;
027: import jacareto.track.TrackSelectionEvent;
028: import jacareto.track.TrackSelectionListener;
029: import jacareto.track.TrackSelectionModel;
030: import jacareto.track.block.Block;
031: import jacareto.track.block.BlockType;
032: import jacareto.trackimpl.blockimpl.DefaultBlockFactory;
033:
034: import org.apache.commons.lang.Validate;
035: import org.apache.log4j.Logger;
036:
037: import java.util.HashMap;
038: import java.util.Map;
039:
040: import javax.swing.JTree;
041: import javax.swing.event.TreeSelectionEvent;
042: import javax.swing.event.TreeSelectionListener;
043: import javax.swing.tree.TreeNode;
044: import javax.swing.tree.TreePath;
045: import javax.swing.tree.TreeSelectionModel;
046:
047: /**
048: * <p>
049: * Connects the TrackSelectionModel with a TreeSelectionModel.
050: * </p>
051: *
052: * <p>
053: * Prevents a "pingpong" effect when firing a {@link TreeSelectionEvent} or a {@link
054: * TrackSelectionEvent}.
055: * </p>
056: *
057: * @author Oliver Specht
058: * @version $revision$
059: */
060: public class SelectionModelConnector {
061: /** The Logger */
062: private static final Logger LOG = Logger
063: .getLogger(SelectionModelConnector.class);
064:
065: /** The TrackSelectionModel the connector connects to a TreeSelectionModel */
066: TrackSelectionModel trackSelectionModel;
067:
068: /** The TreeSelectionModel the connector connects to a TreeSelectionModel */
069: TreeSelectionModel treeSelectionModel;
070:
071: /** The TreeSelectionListener which is switched on and off */
072: TreeSelectionListener treeSelectionListener;
073:
074: /** The TrackSelectionListener which is switched on and off */
075: TrackSelectionListener trackSelectionListener;
076:
077: /** The TreeModel to get the TreePaths from */
078: JTree tree;
079:
080: /** A Map to store the StructureElements including their TreePaths */
081: Map treePathMap = new HashMap();
082:
083: /**
084: * Creates a new SelectionModelConnector. Connects the {@link TrackSelectionModel} with the
085: * {@link TreeSelectionModel} from the given {@link JTree}.
086: *
087: * @param tree {@link JTree} for which the {@link TreeSelectionModel} is to connect
088: */
089: private SelectionModelConnector(JTree tree) {
090: this .tree = tree;
091: initTreePaths();
092:
093: // init
094: this .treeSelectionListener = new TreeSelectionListenerAdapter();
095: this .trackSelectionListener = new TrackSelectionListenerAdapter();
096:
097: this .trackSelectionModel = new DefaultTrackSelectionModel();
098: this .treeSelectionModel = this .tree.getSelectionModel();
099: this .trackSelectionModel
100: .addTrackSelectionListener(this .trackSelectionListener);
101: this .treeSelectionModel
102: .addTreeSelectionListener(this .treeSelectionListener);
103: }
104:
105: /**
106: * Sets the TrackSelectionListener andTreeSelectionListener to given status.
107: *
108: * @param enable boolean true if Listeners should be enabled
109: */
110: public void setListenersEnabled(boolean enable) {
111: if (enable) {
112: this .trackSelectionModel
113: .addTrackSelectionListener(this .trackSelectionListener);
114: this .treeSelectionModel
115: .addTreeSelectionListener(this .treeSelectionListener);
116: } else {
117: this .trackSelectionModel
118: .removeTrackSelectionListener(this .trackSelectionListener);
119: this .treeSelectionModel
120: .removeTreeSelectionListener(this .treeSelectionListener);
121: }
122: }
123:
124: /**
125: * Returns the TreePath for the given Recordable
126: *
127: * @param recordable
128: *
129: * @return TreePath
130: */
131: public TreePath getTreePath(Recordable recordable) {
132: return (TreePath) this .treePathMap.get(recordable);
133: }
134:
135: public TrackSelectionModel getTrackSelectionModel() {
136: return this .trackSelectionModel;
137: }
138:
139: /**
140: * Returns the object currently selected in the JTree as a {@link Block}
141: *
142: * @return Block
143: */
144: public Block getSelectedTreeBlock() {
145: TreeNode node = (TreeNode) this .treeSelectionModel
146: .getSelectionPath().getLastPathComponent();
147:
148: while (!node.isLeaf()) {
149: if (node.getChildCount() > 0) {
150: node = node.getChildAt(0);
151: }
152: }
153:
154: return DefaultBlockFactory.getInstance().createCustomBlock(
155: (Recordable) node);
156: }
157:
158: /**
159: * Initializes the tree path map which holds all Recordables with their TreePaths.
160: */
161: public void initTreePaths() {
162: Validate.notNull(this .treePathMap);
163:
164: this .treePathMap.clear();
165:
166: for (int i = 1; i < this .tree.getRowCount(); i++) {
167: treePathMap
168: .put(this .tree.getPathForRow(i)
169: .getLastPathComponent(), this .tree
170: .getPathForRow(i));
171: }
172: }
173:
174: /**
175: * Creates a new SelectionModelConnector
176: *
177: * @param tree {@link JTree}
178: *
179: * @return SelectionModelConnector
180: */
181: public static SelectionModelConnector create(JTree tree) {
182: return new SelectionModelConnector(tree);
183: }
184:
185: private class TreeSelectionListenerAdapter implements
186: TreeSelectionListener {
187: //~ Methods --------------------------------------------------------------------------------
188:
189: public void valueChanged(TreeSelectionEvent e) {
190: // get selected/deselected structure element
191: Object selectedComponent = e.getPaths()[0]
192: .getLastPathComponent();
193:
194: if (selectedComponent instanceof Recordable) {
195: Recordable recordable = null;
196: TreeNode node = (TreeNode) selectedComponent;
197:
198: while (!node.isLeaf()) {
199: node = node.getChildAt(0);
200: }
201:
202: recordable = (Recordable) node;
203:
204: // create block to set in selection model
205: Block block = DefaultBlockFactory.getInstance()
206: .createCustomBlock(recordable);
207:
208: /**
209: * Node has been selected
210: */
211: if (e.isAddedPath()) {
212: // remove track model listener
213: trackSelectionModel
214: .removeTrackSelectionListener(trackSelectionListener);
215:
216: // set selection in track model
217: // eigentlich: trackSelectionModel.setSelectionRange (null, null);
218: if (block.getType() != BlockType.EVENT) {
219: trackSelectionModel
220: .removeSelection(BlockType.EVENT);
221: }
222:
223: trackSelectionModel.setSelection(block);
224:
225: // re-add TrackSelectionListener
226: trackSelectionModel
227: .addTrackSelectionListener(trackSelectionListener);
228:
229: /**
230: * Node has been deselected
231: */
232: } else {
233: // remove track model listener
234: trackSelectionModel
235: .removeTrackSelectionListener(trackSelectionListener);
236:
237: // set deselection in track model
238: trackSelectionModel
239: .removeSelection(block.getType());
240:
241: // re-add TrackSelectionListener
242: trackSelectionModel
243: .addTrackSelectionListener(trackSelectionListener);
244: }
245: }
246: }
247: }
248:
249: private class TrackSelectionListenerAdapter implements
250: TrackSelectionListener {
251: //~ Methods --------------------------------------------------------------------------------
252:
253: /**
254: * Gets the selected audio or video block from the {@link TrackSelectionModel}, gets the
255: * {@link Recordable} from it and selectes the {@link TreePath} in the {@link JTree}
256: *
257: * @param event {@link TrackSelectionEvent}
258: */
259: public void blockSelected(TrackSelectionEvent event) {
260: // Not yet implemented!
261: }
262:
263: /**
264: * Not yet implemented!
265: *
266: * @param event
267: */
268: public void rangeSelected(TrackSelectionEvent event) {
269: }
270:
271: /**
272: * Removes the selection
273: *
274: * @param event TrackSelectionEvent
275: */
276: public void selectionRemoved(TrackSelectionEvent event) {
277: treeSelectionModel
278: .removeTreeSelectionListener(treeSelectionListener);
279: tree.removeSelectionPath(treeSelectionModel
280: .getSelectionPath());
281: treeSelectionModel
282: .addTreeSelectionListener(treeSelectionListener);
283: }
284: }
285: }
|