view java/src/uk/ac/qmul/eecs/ccmi/diagrammodel/DiagramModelTreeNode.java @ 0:9418ab7b7f3f

Initial import
author Fiore Martin <fiore@eecs.qmul.ac.uk>
date Fri, 16 Dec 2011 17:35:51 +0000
parents
children
line wrap: on
line source
/*  
 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
  
 Copyright (C) 2011  Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)

 This program 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 3 of the License, or
 (at your option) any later version.

 This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package uk.ac.qmul.eecs.ccmi.diagrammodel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;

/**
 * This class represent a general node in a TreeModel
 *
 */
@SuppressWarnings("serial")
public abstract class DiagramModelTreeNode extends DefaultMutableTreeNode {
	public DiagramModelTreeNode() {
		super();
		notes = "";
		userObject = new UserObject();
		setSuperClassUserObject(userObject);
		bookmarkKeys = new ArrayList<String>();
	}

	public DiagramModelTreeNode(Object userObject) {
		this();
		setUserObject(userObject);
	}
	
	/**
	 * Each DiagramModelTreeNode keeps track of the bookmarks it has been assigned. Bookmarks
	 * will affect how this tree node will be represented on a JTree: when a tree node is bookmarked 
	 * an apex appears at the right of its name. 
	 * @param key the bookmark 
	 * @return true if this bookmark inner collection changed as a result of the call
	 */
	boolean addBookmarkKey(String key){
		return bookmarkKeys.add(key);
	}
	
	/**
	 * Removes a bookmark key from the inner collection
	 * @param key the key to remove 
	 * @return true if this bookmark inner collection changed as a result of the call
	 */
	boolean removeBookmarkKey(String key){
		return bookmarkKeys.remove(key);
	}
		
	/**
	 * Returns the the bookmarks currently associated to this tree node 
	 * @return
	 */
	public List<String> getBookmarkKeys(){
		return Collections.unmodifiableList(bookmarkKeys);
	}
	
	public String getNotes(){
		return notes;
	}
	
	/**
	 * Set a note for this tree node. A Note is a text the user wants to attach to a tree node. Notes
	 * will affect how this tree node will be represented on a JTree: when a tree node is assigned a note 
	 * a number sign (#) appears at the right of its name. 
	 * @param note the text of the note 
	 * @return true if this bookmark inner collection changed as a result of the call
	 */
	void setNotes(String note){
		this.notes = note;
	}
	
	/**
	 * @see DefaultMutableTreeNode#getParent()
	 */
	@Override
	public DiagramModelTreeNode getParent(){
		return (DiagramModelTreeNode)super.getParent();
	}
	
	/**
	 * @see DefaultMutableTreeNode#getChildAt(int)
	 */
	@Override
	public DiagramModelTreeNode getChildAt(int i){
		return (DiagramModelTreeNode)super.getChildAt(i);
	}
	
	/**
	 * @see DefaultMutableTreeNode#getRoot()
	 */
	@Override
	public DiagramModelTreeNode getRoot(){
		return (DiagramModelTreeNode)super.getRoot();
	}
	
	/**
	 * @see DefaultMutableTreeNode#setUserObject(Object)
	 */
	@Override
	public void	setUserObject(Object userObject){
		((UserObject)this.userObject).setObject(userObject);
	}
	
	/**
	 * @see DefaultMutableTreeNode#getUserObject()
	 */
	@Override
	public Object getUserObject(){
		return userObject;
	}
	
	/**
	 * Return a String representing this object for this tree node in a way more suitable 
	 * for a text to speech synthesizer to read, than toString(). 
	 * @return a String suitable for text to speech synthesis
	 */
	public String spokenText(){
		return ((UserObject)userObject).spokenText();
	}
	
	/**
	 * Returns a more detailed description of the tree node than {@link #spokenText()}.
	 * 
	 *  @return a description of the tree node
	 */
	public String detailedSpokenText(){
		return spokenText();
	}
	
	/**
	 * returns the tree node name "as it is", without any decoration such as notes, bookmarks or cardinality.
	 * Unlike the String returned by toString
	 * @return the tree node name
	 */
	public String getName(){
		return ((UserObject)userObject).getName();
	}
	
	/**
	 * @see DefaultMutableTreeNode#isRoot()
	 */
	@Override
	public boolean isRoot(){
		return false; // root node overwrites this method
	}

	/**
	 * @see DefaultMutableTreeNode#getLastLeaf()
	 */
	@Override
	public DiagramModelTreeNode getLastLeaf() {
		return (DiagramModelTreeNode)super.getLastLeaf();
	}

	/**
	 * @see DefaultMutableTreeNode#getNextLeaf()
	 */
	@Override
	public DiagramModelTreeNode getNextLeaf() {
		return (DiagramModelTreeNode)super.getNextLeaf();
	}

	/**
	 * @see DefaultMutableTreeNode#getNextNode()
	 */
	@Override
	public DiagramModelTreeNode getNextNode() {
		return (DiagramModelTreeNode)super.getNextNode();
	}

	/**
	 * @see DefaultMutableTreeNode#getNextSibling()
	 */
	@Override
	public DiagramModelTreeNode getNextSibling() {
		return (DiagramModelTreeNode)super.getNextSibling();
	}

	/**
	 * @see DefaultMutableTreeNode#getPreviousLeaf()
	 */
	@Override
	public DiagramModelTreeNode getPreviousLeaf() {
		return (DiagramModelTreeNode)super.getPreviousLeaf();
	}

	/**
	 * @see DefaultMutableTreeNode#getPreviousNode()
	 */
	@Override
	public DiagramModelTreeNode getPreviousNode() {
		return (DiagramModelTreeNode)super.getPreviousNode();
	}

	/**
	 * @see DefaultMutableTreeNode#getPreviousSibling()
	 */
	@Override
	public DiagramModelTreeNode getPreviousSibling() {
		return (DiagramModelTreeNode)super.getPreviousSibling();
	}
	
	private void setSuperClassUserObject(Object u){
		super.setUserObject(u);
	}
	
	private UserObject getUserObjectInstance(){
		return new UserObject();
	}
	
	protected List<String> bookmarkKeys;
	protected String notes;
	/* hides the DefaultMutableTreeNode protected field */
	private Object userObject;
	protected static final char NOTES_CHAR = '#';
	protected static final char BOOKMARK_CHAR = '\'';
	protected static final String BOOKMARK_SPEAK = ", bookmarked";
	protected static final String NOTES_SPEAK = ", has notes";
	
	@Override
	public Object clone(){
		DiagramModelTreeNode clone = (DiagramModelTreeNode )super.clone();
		clone.notes = "";
		clone.bookmarkKeys = new ArrayList<String>();
		clone.userObject = clone.getUserObjectInstance();	
		clone.setSuperClassUserObject(clone.userObject);
		return clone;
	}
	
	/* this works as a wrapper for the real user object in order to provide */
	/* decoration on the treeNode label to signal and/or bookmarks          */
	private class UserObject {
		private Object object;

		public UserObject(){
			object = "";
		}
		public void setObject(Object o){
			this.object = o;
		}

		@Override
		public boolean equals(Object o){
			return this.object.equals(o);
		}
		
		@Override
		public String toString(){
			StringBuilder builder = new StringBuilder(object.toString());
			if(!"".equals(notes)){
				builder.append(NOTES_CHAR);
			}
			if(!bookmarkKeys.isEmpty())
				builder.append(BOOKMARK_CHAR);
			return builder.toString();
		}
		
		public String spokenText(){
			StringBuilder builder = new StringBuilder(object.toString());
			if(!"".equals(notes)){
				builder.append(NOTES_SPEAK);
			}
			if(!bookmarkKeys.isEmpty())
				builder.append(BOOKMARK_SPEAK);
			return builder.toString();
		}
		
		public String getName(){
			return object.toString();
		}
	}
}