/*
* Jacareto Copyright (c) 2002-2005
* Applied Computer Science Research Group, Darmstadt University of
* Technology, Institute of Mathematics & Computer Science,
* Ludwigsburg University of Education, and Computer Based
* Learning Research Group, Aachen University. All rights reserved.
*
* Jacareto is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* Jacareto is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with Jacareto; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
package jacareto.trackimpl;
import jacareto.record.Recordable;
import jacareto.track.TrackSelectionEvent;
import jacareto.track.TrackSelectionListener;
import jacareto.track.TrackSelectionModel;
import jacareto.track.block.Block;
import jacareto.track.block.BlockType;
import jacareto.trackimpl.blockimpl.DefaultBlockFactory;
import org.apache.commons.lang.Validate;
import org.apache.log4j.Logger;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
/**
* <p>
* Connects the TrackSelectionModel with a TreeSelectionModel.
* </p>
*
* <p>
* Prevents a "pingpong" effect when firing a {@link TreeSelectionEvent} or a {@link
* TrackSelectionEvent}.
* </p>
*
* @author Oliver Specht
* @version $revision$
*/
public class SelectionModelConnector {
/** The Logger */
private static final Logger LOG = Logger.getLogger (SelectionModelConnector.class);
/** The TrackSelectionModel the connector connects to a TreeSelectionModel */
TrackSelectionModel trackSelectionModel;
/** The TreeSelectionModel the connector connects to a TreeSelectionModel */
TreeSelectionModel treeSelectionModel;
/** The TreeSelectionListener which is switched on and off */
TreeSelectionListener treeSelectionListener;
/** The TrackSelectionListener which is switched on and off */
TrackSelectionListener trackSelectionListener;
/** The TreeModel to get the TreePaths from */
JTree tree;
/** A Map to store the StructureElements including their TreePaths */
Map treePathMap = new HashMap();
/**
* Creates a new SelectionModelConnector. Connects the {@link TrackSelectionModel} with the
* {@link TreeSelectionModel} from the given {@link JTree}.
*
* @param tree {@link JTree} for which the {@link TreeSelectionModel} is to connect
*/
private SelectionModelConnector (JTree tree) {
this.tree = tree;
initTreePaths ();
// init
this.treeSelectionListener = new TreeSelectionListenerAdapter();
this.trackSelectionListener = new TrackSelectionListenerAdapter();
this.trackSelectionModel = new DefaultTrackSelectionModel();
this.treeSelectionModel = this.tree.getSelectionModel ();
this.trackSelectionModel.addTrackSelectionListener (this.trackSelectionListener);
this.treeSelectionModel.addTreeSelectionListener (this.treeSelectionListener);
}
/**
* Sets the TrackSelectionListener andTreeSelectionListener to given status.
*
* @param enable boolean true if Listeners should be enabled
*/
public void setListenersEnabled (boolean enable) {
if (enable) {
this.trackSelectionModel.addTrackSelectionListener (this.trackSelectionListener);
this.treeSelectionModel.addTreeSelectionListener (this.treeSelectionListener);
} else {
this.trackSelectionModel.removeTrackSelectionListener (this.trackSelectionListener);
this.treeSelectionModel.removeTreeSelectionListener (this.treeSelectionListener);
}
}
/**
* Returns the TreePath for the given Recordable
*
* @param recordable
*
* @return TreePath
*/
public TreePath getTreePath (Recordable recordable) {
return (TreePath) this.treePathMap.get (recordable);
}
public TrackSelectionModel getTrackSelectionModel () {
return this.trackSelectionModel;
}
/**
* Returns the object currently selected in the JTree as a {@link Block}
*
* @return Block
*/
public Block getSelectedTreeBlock () {
TreeNode node = (TreeNode) this.treeSelectionModel.getSelectionPath ().getLastPathComponent ();
while (! node.isLeaf ()) {
if (node.getChildCount () > 0) {
node = node.getChildAt (0);
}
}
return DefaultBlockFactory.getInstance ().createCustomBlock ((Recordable) node);
}
/**
* Initializes the tree path map which holds all Recordables with their TreePaths.
*/
public void initTreePaths () {
Validate.notNull (this.treePathMap);
this.treePathMap.clear ();
for (int i = 1; i < this.tree.getRowCount (); i++) {
treePathMap.put (this.tree.getPathForRow (i).getLastPathComponent (),
this.tree.getPathForRow (i));
}
}
/**
* Creates a new SelectionModelConnector
*
* @param tree {@link JTree}
*
* @return SelectionModelConnector
*/
public static SelectionModelConnector create (JTree tree) {
return new SelectionModelConnector(tree);
}
private class TreeSelectionListenerAdapter implements TreeSelectionListener {
//~ Methods --------------------------------------------------------------------------------
public void valueChanged (TreeSelectionEvent e) {
// get selected/deselected structure element
Object selectedComponent = e.getPaths ()[0].getLastPathComponent ();
if (selectedComponent instanceof Recordable) {
Recordable recordable = null;
TreeNode node = (TreeNode) selectedComponent;
while (! node.isLeaf ()) {
node = node.getChildAt (0);
}
recordable = (Recordable) node;
// create block to set in selection model
Block block = DefaultBlockFactory.getInstance ().createCustomBlock (recordable);
/**
* Node has been selected
*/
if (e.isAddedPath ()) {
// remove track model listener
trackSelectionModel.removeTrackSelectionListener (trackSelectionListener);
// set selection in track model
// eigentlich: trackSelectionModel.setSelectionRange (null, null);
if (block.getType () != BlockType.EVENT) {
trackSelectionModel.removeSelection (BlockType.EVENT);
}
trackSelectionModel.setSelection (block);
// re-add TrackSelectionListener
trackSelectionModel.addTrackSelectionListener (trackSelectionListener);
/**
* Node has been deselected
*/
} else {
// remove track model listener
trackSelectionModel.removeTrackSelectionListener (trackSelectionListener);
// set deselection in track model
trackSelectionModel.removeSelection (block.getType ());
// re-add TrackSelectionListener
trackSelectionModel.addTrackSelectionListener (trackSelectionListener);
}
}
}
}
private class TrackSelectionListenerAdapter implements TrackSelectionListener {
//~ Methods --------------------------------------------------------------------------------
/**
* Gets the selected audio or video block from the {@link TrackSelectionModel}, gets the
* {@link Recordable} from it and selectes the {@link TreePath} in the {@link JTree}
*
* @param event {@link TrackSelectionEvent}
*/
public void blockSelected (TrackSelectionEvent event) {
// Not yet implemented!
}
/**
* Not yet implemented!
*
* @param event
*/
public void rangeSelected (TrackSelectionEvent event) {
}
/**
* Removes the selection
*
* @param event TrackSelectionEvent
*/
public void selectionRemoved (TrackSelectionEvent event) {
treeSelectionModel.removeTreeSelectionListener (treeSelectionListener);
tree.removeSelectionPath (treeSelectionModel.getSelectionPath ());
treeSelectionModel.addTreeSelectionListener (treeSelectionListener);
}
}
}
|