From 2603c481fe0780cdaacb04c3754cb6e1f9d143ff Mon Sep 17 00:00:00 2001 From: Michael Bien Date: Mon, 24 Feb 2025 13:14:06 +0100 Subject: [PATCH] Implement wait cursor delay for TreeView. TreeView will now wait a little bit before showing the wait cursor. Co-authored-by: Laszlo Kishalmi --- .../org/openide/explorer/view/TreeView.java | 93 ++++++++----------- 1 file changed, 37 insertions(+), 56 deletions(-) diff --git a/platform/openide.explorer/src/org/openide/explorer/view/TreeView.java b/platform/openide.explorer/src/org/openide/explorer/view/TreeView.java index 3554c161d5df..cc36ba97863a 100644 --- a/platform/openide.explorer/src/org/openide/explorer/view/TreeView.java +++ b/platform/openide.explorer/src/org/openide/explorer/view/TreeView.java @@ -84,6 +84,7 @@ import javax.swing.KeyStroke; import javax.swing.ScrollPaneLayout; import javax.swing.SwingUtilities; +import javax.swing.Timer; import javax.swing.ToolTipManager; import javax.swing.TransferHandler; import javax.swing.UIManager; @@ -920,73 +921,53 @@ 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)); - } + DelayedWaitCursor waitCursor = new DelayedWaitCursor(getRootPane()); + ViewUtil.uiProcessor().post(() -> { + try (waitCursor) { + node.getChildren().getNodesCount(true); // blocks until expanded + } 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. + /// construct on EDT, close() may be called from any thread. + private static class DelayedWaitCursor implements AutoCloseable { + + private static final int DELAY = 200; - private static class CursorR implements Runnable { - private Component glassPane; - private boolean show; + private final JRootPane root; + private final Timer timer; - private CursorR(Component cont, boolean show) { - this.glassPane = cont; - this.show = show; + private DelayedWaitCursor(JRootPane root) { + this.root = root; + timer = new Timer(DELAY, e -> { + if (root != null) { + root.getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + root.getGlassPane().setVisible(true); + } + }); + timer.setRepeats(false); + timer.start(); } @Override - public void run() { - doShowWaitCursor(glassPane, show); + public void close() { + SwingUtilities.invokeLater(() -> { + timer.stop(); + if (root != null) { + root.getGlassPane().setVisible(false); + root.getGlassPane().setCursor(null); + } + }); } } - private void prepareWaitCursor(final Node node) { - // check type of node - if (node == null || !autoWaitCursor) { - return; - } - - 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); - } - } - }); - } - - - /** Synchronize the selected nodes from the manager of this Explorer. * The default implementation does nothing. */ @@ -1507,7 +1488,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