/**
* $Id: $
* $Date: $
*
*/
package org.xmlsh.marklogic.ui;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
@SuppressWarnings("serial")
public abstract class LazyTreeModel extends DefaultTreeModel implements TreeWillExpandListener {
abstract void loadNodes( LazyTreeNode node );
public LazyTreeModel(TreeNode root, JTree tree) {
super(root);
setAsksAllowsChildren(true);
tree.addTreeWillExpandListener(this);
tree.setModel(this);
}
public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
LazyTreeNode node = (LazyTreeNode) event.getPath().getLastPathComponent();
if (node.isLoaded()) {
return;
}
setLoading(node, false);
loadNodes(node);
}
public void reloadNode(String id) {
LazyTreeNode node = findNode(id);
if (node != null) {
node.setLoaded(false);
setLoading(node, true);
loadNodes(node);
}
}
public void reloadParentNode(String id) {
LazyTreeNode node = findParent(id);
if (node != null) {
node.setLoaded(false);
setLoading(node, true);
loadNodes(node);
}
}
public LazyTreeNode findParent(String id) {
LazyTreeNode node = findNode(id);
if (node != null && node.getParent() != null) {
return (LazyTreeNode) node.getParent();
}
return null;
}
public void loadFirstLevel() {
setLoading((LazyTreeNode) getRoot(), false);
loadNodes((LazyTreeNode) getRoot());
}
public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
}
protected void setChildren(LazyTreeNode parentNode, LazyTreeNode... nodes) {
if (nodes == null) {
return;
}
int childCount = parentNode.getChildCount();
if (childCount > 0) {
for (int i = 0; i < childCount; i++) {
removeNodeFromParent((MutableTreeNode) parentNode.getChildAt(0));
}
}
for (int i = 0; i < nodes.length; i++) {
insertNodeInto(nodes[i], parentNode, i);
}
}
private void setLoading2(final LazyTreeNode parentNode, final boolean reload) {
if (reload) {
setChildren(parentNode, createReloadingNode());
} else {
setChildren(parentNode, createLoadingNode());
}
}
private void setLoading(final LazyTreeNode parentNode, final boolean reload) {
if (SwingUtilities.isEventDispatchThread()) {
setLoading2(parentNode, reload);
} else {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
setLoading2(parentNode, reload);
}
});
} catch (Exception e) {
// LOG.error("Cannot create loading node", e);
}
}
}
private LazyTreeNode findNode(String id) {
return findNode(id, (LazyTreeNode) getRoot());
}
private LazyTreeNode findNode(String url, LazyTreeNode parent) {
int count = parent.getChildCount();
for (int i = 0; i < count; i++) {
LazyTreeNode node = (LazyTreeNode) parent.getChildAt(i);
if (url.equals(node.getUrl())) {
return node;
}
if (node.isLoaded()) {
node = findNode(url, node);
if (node != null) {
return node;
}
}
}
return null;
}
protected LazyTreeNode createLoadingNode() {
return new LazyTreeNode(null, "Loading ..." );
}
protected LazyTreeNode createReloadingNode() {
return new LazyTreeNode(null, "Refreshing...");
}
void postSetChildren( final LazyTreeNode parentNode , final LazyTreeNode[] treeNodes ){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
parentNode.setLoaded(true);
setChildren(parentNode, treeNodes);
nodeChanged( parentNode );
}
});
}
void postReload( final LazyTreeNode node ){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if( node == null )
loadFirstLevel() ;
else {
node.setLength(-1, -1);
node.setLoaded(false);
setLoading(node, true);
loadNodes(node);
nodeChanged( node );
}
}
});
}
void postReset( final LazyTreeNode node ){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
node.setLength(-1, -1);
node.setLoaded(false);
setLoading(node, true);
setChildren(node, new LazyTreeNode[]{ } );
nodeChanged( node );
}
});
}
void postNext( final LazyTreeNode node , final int n ){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
node.setLength( node.getEnd() + 1 , node.getEnd() + n );
node.setLoaded(false);
setLoading(node, true);
loadNodes(node);
nodeChanged( node );
}
});
}
void postPrev( final LazyTreeNode node , final int n ){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
int start = node.getStart() - n ;
if( start <1 )
start = 1;
node.setLength( start , start + n - 1 );
node.setLoaded(false);
setLoading(node, true);
loadNodes(node);
nodeChanged( node );
}
});
}
}
/*
* Copyright (C) 2008-2014 David A. Lee.
*
* The contents of this file are subject to the "Simplified BSD License" (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy of the
* License at http://www.opensource.org/licenses/bsd-license.php
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights and limitations under the License.
*
* The Original Code is: all this file.
*
* The Initial Developer of the Original Code is David A. Lee
*
* Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
*
* Contributor(s): David A. Lee
*
*/