Den 17.06.2011 16:29, skrev Greg Brown:
Ahh, I hadn't considered the mouse blocking side of things, which is certainly 
desirable in some scenarios.  In this particular case, I think it would be 
unwanted as the ActivityIndicator would be shown to the user while a TreeBranch 
is being populated via a potentially long running Task.  Leaving the mouse 
enabled means that the user is free to do other things.
That's true. But I still think a custom node renderer would be the easiest way 
to accomplish what Edvin is trying to do.  :-)
You are oh so right :) It was super easy, I just did a quick test, and it works perfectly, even with multiple busy nodes simultaneously.Before I load data in a background task I do:

nodeRenderer.setBusyNode(node)

And remove the busy node after the loading task has completed (removeBusyNode(node)). Attached is my rudimentary implementation, will refactor it now that I see it is working :)

-- Edvin


package vortex.ui;

import org.apache.pivot.wtk.ActivityIndicator;
import org.apache.pivot.wtk.ApplicationContext;
import org.apache.pivot.wtk.TreeView;
import org.apache.pivot.wtk.content.TreeViewNodeRenderer;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class BusyCapableNodeRenderer extends TreeViewNodeRenderer {
	private ActivityIndicator indicator;
	private List<Object> busyNodes = new ArrayList<Object>();
	private Timer repaintTimer;
	private TreeView treeView;

	public BusyCapableNodeRenderer(TreeView treeView) {
		this.treeView = treeView;
	}

	public void render(Object node, Tree.Path path, int rowIndex, TreeView treeView, boolean expanded, boolean selected, TreeView.NodeCheckState checkState, boolean highlighted, boolean disabled) {
		if (isBusy(node))
			showIndicator();
		else
			hideIndicator();

		super.render(node, path, rowIndex, treeView, expanded, selected, checkState, highlighted, disabled);
	}

	private void hideIndicator() {
		if (indicator != null) {
			indicator.setVisible(false);
			imageView.setVisible(true);
		}
	}

	private void showIndicator() {
		if (indicator == null) {
			indicator = new ActivityIndicator();
			indicator.setPreferredSize(16, 16);
			insert(indicator, 0);
		}

		imageView.setVisible(false);
		indicator.setVisible(true);
	}

	private boolean isBusy(Object node) {
		for (Object busyNode : busyNodes)
			if (busyNode == node)
				return true;
		return false;
	}

	public void setBusyNode(final Object node) {
		busyNodes.add(node);
		indicator.setActive(true);
		if (repaintTimer == null) {
			TimerTask repaintTask = new TimerTask() {
				public void run() {
					ApplicationContext.queueCallback(new Runnable() {
						public void run() {
							treeView.getParent().repaint();
						}
					});
				}
			};
			repaintTimer = new Timer("BusyCapableNodeRendererRepaintTimer", true);
			repaintTimer.schedule(repaintTask, 0, 100);
		}
	}

	public void removeBusyNode(Object node) {
		busyNodes.remove(node);
		if (busyNodes.isEmpty() && repaintTimer != null) {
			indicator.setActive(false);
			repaintTimer.cancel();
			repaintTimer = null;
		}
		treeView.getParent().repaint();
	}
}

Reply via email to