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();
}
}