/*
* funCKit - functional Circuit Kit
* Copyright (C) 2013 Lukas Elsner <open@mindrunner.de>
* Copyright (C) 2013 Peter Dahlberg <catdog2@tuxzone.org>
* Copyright (C) 2013 Julian Stier <mail@julian-stier.de>
* Copyright (C) 2013 Sebastian Vetter <mail@b4sti.eu>
* Copyright (C) 2013 Thomas Poxrucker <poxrucker_t@web.de>
* Copyright (C) 2013 Alexander Treml <alex.treml@directbox.com>
*
* 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 de.sep2011.funckit.view.projecttreemodel;
import de.sep2011.funckit.model.sessionmodel.SessionModel;
import javax.swing.JTree;
import javax.swing.event.EventListenerList;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
/**
* This class implements the {@link TreeModel} interface used by the the
* {@link JTree} representing the Project tree.
*/
public class ProjectTreeModel implements TreeModel {
private final ProjectTreeNode<?> root;
private final EventListenerList treeModelListeners;
/**
* Creates a new {@link ProjectTreeModel}. It builds a tree with
* {@link ProjectTreeRootNode} as its root node.
*
* @param sm
* The {@link SessionModel} the root node will be initialized
* with.
*/
public ProjectTreeModel(SessionModel sm) {
this.root = new ProjectTreeRootNode(this, sm);
this.treeModelListeners = new EventListenerList();
this.root.generateChildren();
}
/**
* Notifies all listeners that have registered interest for notification on
* this event type. The event instance is lazily created using the
* parameters passed into the fire method.
*
* @param path
* the path to the root node
* @param childIndices
* the indices of the changed elements
* @param children
* the changed elements
* @see EventListenerList
*/
void fireTreeNodesChanged(Object[] path, int[] childIndices,
Object[] children) {
// Guaranteed to return a non-null array
Object[] listeners = treeModelListeners.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == TreeModelListener.class) {
// Lazily create the event:
TreeModelEvent ev = new TreeModelEvent(this, path,
childIndices, children);
((TreeModelListener) listeners[i + 1]).treeNodesChanged(ev);
}
}
}
/**
* Notifies all listeners that have registered interest for notification on
* this event type. The event instance is lazily created using the
* parameters passed into the fire method.
*
* @param path
* the path to the root node
* @param childIndices
* the indices of the new elements
* @param children
* the new elements
* @see EventListenerList
*/
void fireTreeNodesInserted(Object[] path, int[] childIndices,
Object[] children) {
// Guaranteed to return a non-null array
Object[] listeners = treeModelListeners.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == TreeModelListener.class) {
// Lazily create the event:
TreeModelEvent ev = new TreeModelEvent(this, path,
childIndices, children);
((TreeModelListener) listeners[i + 1]).treeNodesInserted(ev);
}
}
}
/**
* Notifies all listeners that have registered interest for notification on
* this event type. The event instance is lazily created using the
* parameters passed into the fire method.
*
* @param path
* the path to the root node
* @param childIndices
* the indices of the removed elements
* @param children
* the removed elements
* @see EventListenerList
*/
void fireTreeNodesRemoved(Object[] path, int[] childIndices,
Object[] children) {
// Guaranteed to return a non-null array
Object[] listeners = treeModelListeners.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == TreeModelListener.class) {
// Lazily create the event:
TreeModelEvent ev = new TreeModelEvent(this, path,
childIndices, children);
((TreeModelListener) listeners[i + 1]).treeNodesRemoved(ev);
}
}
}
/**
* Notifies all listeners that have registered interest for notification on
* this event type. The event instance is lazily created using the
* parameters passed into the fire method.
*
* @param path
* the path to the root node
* @see EventListenerList
*/
void fireTreeStructureChanged(Object[] path) {
// Guaranteed to return a non-null array
Object[] listeners = treeModelListeners.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == TreeModelListener.class) {
// Lazily create the event:
TreeModelEvent ev = new TreeModelEvent(this, path);
((TreeModelListener) listeners[i + 1]).treeStructureChanged(ev);
}
}
}
@Override
public ProjectTreeNode<?> getRoot() {
return root;
}
@Override
public ProjectTreeNode<?> getChild(Object parent, int index) {
return ((ProjectTreeNode<?>) parent).getChild(index);
}
@Override
public int getChildCount(Object parent) {
return ((ProjectTreeNode<?>) parent).getChildCount();
}
@Override
public boolean isLeaf(Object node) {
return ((ProjectTreeNode<?>) node).isLeaf();
}
@Override
public void valueForPathChanged(TreePath path, Object newValue) {
throw new UnsupportedOperationException("Unimplemented!");
}
@Override
public int getIndexOfChild(Object parent, Object child) {
if (!(parent instanceof ProjectTreeNode<?>)
|| !(child instanceof ProjectTreeNode<?>)) {
return -1;
}
return ((ProjectTreeNode<?>) parent)
.getIndexOfChild((ProjectTreeNode<?>) child);
}
@Override
public void addTreeModelListener(TreeModelListener l) {
treeModelListeners.add(TreeModelListener.class, l);
}
@Override
public void removeTreeModelListener(TreeModelListener l) {
treeModelListeners.remove(TreeModelListener.class, l);
}
/**
* Do everything necessary to expand the tree. Meant to be called from a
* {@link TreeWillExpandListener}.
*
* @param node
* The node to expand.
* @return true if the expansion was successful, false otherwise
*/
public static boolean expandNode(Object node) {
return ((ProjectTreeNode<?>) node).generateChildren();
}
/**
* Do everything necessary to collapse the tree. Meant to be called from a
* {@link TreeWillExpandListener}.
*
* @param node
* The node to collapse.
* @return true if the collapse was successful, false otherwise
*/
public static boolean collapseNode(Object node) {
((ProjectTreeNode<?>) node).disposeChildren();
return true;
}
}