Skip to content

Commit

Permalink
Implement wait cursor delay for TreeView.
Browse files Browse the repository at this point in the history
 - initial delay for wait cursor change
 - adds max lifespan for reset failures
 - cancellable

Co-authored-by: Laszlo Kishalmi <[email protected]>
  • Loading branch information
mbien and lkishalmi committed Feb 24, 2025
1 parent 4de8ce2 commit e05c956
Showing 1 changed file with 65 additions and 54 deletions.
119 changes: 65 additions & 54 deletions platform/openide.explorer/src/org/openide/explorer/view/TreeView.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.accessibility.AccessibleContext;
Expand Down Expand Up @@ -915,73 +917,82 @@ public void setAutoWaitCursor(boolean enable) {
autoWaitCursor = enable;
}

//
// showing and removing the wait cursor
//
private void showWaitCursor (boolean show) {
JRootPane rPane = getRootPane();
if (rPane == null) {
private void maybeShowWaitCursor(Node node) {
if (node == null || !autoWaitCursor) {
return;
}

if (SwingUtilities.isEventDispatchThread()) {
doShowWaitCursor(rPane.getGlassPane(), show);
} else {
SwingUtilities.invokeLater(new CursorR(rPane.getGlassPane(), show));
JRootPane rootPane = getRootPane();
if (rootPane == null) {
return;
}
// not sure whenter throughput 1 is OK...
ViewUtil.uiProcessor().post(() -> {
try (DelayedWaitCursor cursor = new DelayedWaitCursor(rootPane)) {
cursor.enable();
node.getChildren().getNodesCount(true);
} catch (Exception e) {
LOG.log(Level.WARNING, "can't determine node count", e);
}
});
}

private static void doShowWaitCursor (Component glassPane, boolean show) {
if (show) {
glassPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
glassPane.setVisible(true);
} else {
glassPane.setVisible(false);
glassPane.setCursor(null);
}
}
/// Shows the wait cursor after an initial delay.
/// Can be used in ARM-blocks.
private static class DelayedWaitCursor implements AutoCloseable {

private static class CursorR implements Runnable {
private Component glassPane;
private boolean show;
private static final RequestProcessor RP = new RequestProcessor(DelayedWaitCursor.class.getName());

private CursorR(Component cont, boolean show) {
this.glassPane = cont;
this.show = show;
}
private static final int SPAWN_DELAY = 200;
private static final int MAX_LIFE_SPAN = 60_000;

@Override
public void run() {
doShowWaitCursor(glassPane, show);
}
}
private final JRootPane root;
private ScheduledFuture<?> scheduled;

private void prepareWaitCursor(final Node node) {
// check type of node
if (node == null || !autoWaitCursor) {
return;
private DelayedWaitCursor(JRootPane root) {
this.root = root;
}

showWaitCursor(true);
// not sure whenter throughput 1 is OK...
ViewUtil.uiProcessor().post(new Runnable() {
@Override
public void run() {
try {
node.getChildren().getNodesCount(true);
} catch (Exception e) {
// log a exception
LOG.log(Level.WARNING, null, e);
} finally {
// show normal cursor above all
showWaitCursor(false);
private void enable() {
if (scheduled != null) {
return;
}
scheduled = RP.schedule(() -> {
if (!scheduled.isCancelled()) {
// switch to wait
SwingUtilities.invokeLater(() -> {
if (!scheduled.isCancelled()) {
root.getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
root.getGlassPane().setVisible(true);
}
});
// block to limit lifespan
try {
Thread.sleep(MAX_LIFE_SPAN);
} catch (InterruptedException cancelled) {
Thread.interrupted();
}
}
// reset
SwingUtilities.invokeLater(() -> {
root.getGlassPane().setVisible(false);
root.getGlassPane().setCursor(null);
});
}, SPAWN_DELAY, TimeUnit.MILLISECONDS);
}

private void disable() {
if (scheduled != null) {
scheduled.cancel(true);
scheduled = null;
}
});
}

@Override
public void close() {
disable();
}
}




/** Synchronize the selected nodes from the manager of this Explorer.
* The default implementation does nothing.
*/
Expand Down Expand Up @@ -1499,7 +1510,7 @@ public void treeWillExpand(TreeExpansionEvent event)
throws ExpandVetoException {
// prepare wait cursor and optionally show it
TreePath path = event.getPath();
prepareWaitCursor(DragDropUtilities.secureFindNode(path.getLastPathComponent()));
maybeShowWaitCursor(DragDropUtilities.secureFindNode(path.getLastPathComponent()));
}
}
// end of TreePropertyListener
Expand Down

0 comments on commit e05c956

Please sign in to comment.