|
84 | 84 | import javax.swing.KeyStroke; |
85 | 85 | import javax.swing.ScrollPaneLayout; |
86 | 86 | import javax.swing.SwingUtilities; |
| 87 | +import javax.swing.Timer; |
87 | 88 | import javax.swing.ToolTipManager; |
88 | 89 | import javax.swing.TransferHandler; |
89 | 90 | import javax.swing.UIManager; |
@@ -920,73 +921,53 @@ public void setAutoWaitCursor(boolean enable) { |
920 | 921 | autoWaitCursor = enable; |
921 | 922 | } |
922 | 923 |
|
923 | | - // |
924 | | - // showing and removing the wait cursor |
925 | | - // |
926 | | - private void showWaitCursor (boolean show) { |
927 | | - JRootPane rPane = getRootPane(); |
928 | | - if (rPane == null) { |
| 924 | + private void maybeShowWaitCursor(Node node) { |
| 925 | + if (node == null || !autoWaitCursor) { |
929 | 926 | return; |
930 | 927 | } |
931 | | - |
932 | | - if (SwingUtilities.isEventDispatchThread()) { |
933 | | - doShowWaitCursor(rPane.getGlassPane(), show); |
934 | | - } else { |
935 | | - SwingUtilities.invokeLater(new CursorR(rPane.getGlassPane(), show)); |
936 | | - } |
| 928 | + DelayedWaitCursor waitCursor = new DelayedWaitCursor(getRootPane()); |
| 929 | + ViewUtil.uiProcessor().post(() -> { |
| 930 | + try (waitCursor) { |
| 931 | + node.getChildren().getNodesCount(true); // blocks until expanded |
| 932 | + } catch (Exception e) { |
| 933 | + LOG.log(Level.WARNING, "can't determine node count", e); |
| 934 | + } |
| 935 | + }); |
937 | 936 | } |
938 | 937 |
|
939 | | - private static void doShowWaitCursor (Component glassPane, boolean show) { |
940 | | - if (show) { |
941 | | - glassPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); |
942 | | - glassPane.setVisible(true); |
943 | | - } else { |
944 | | - glassPane.setVisible(false); |
945 | | - glassPane.setCursor(null); |
946 | | - } |
947 | | - } |
| 938 | + /// Shows the wait cursor after an initial delay. |
| 939 | + /// construct on EDT, close() may be called from any thread. |
| 940 | + private static class DelayedWaitCursor implements AutoCloseable { |
| 941 | + |
| 942 | + private static final int DELAY = 200; |
948 | 943 |
|
949 | | - private static class CursorR implements Runnable { |
950 | | - private Component glassPane; |
951 | | - private boolean show; |
| 944 | + private final JRootPane root; |
| 945 | + private final Timer timer; |
952 | 946 |
|
953 | | - private CursorR(Component cont, boolean show) { |
954 | | - this.glassPane = cont; |
955 | | - this.show = show; |
| 947 | + private DelayedWaitCursor(JRootPane root) { |
| 948 | + this.root = root; |
| 949 | + timer = new Timer(DELAY, e -> { |
| 950 | + if (root != null) { |
| 951 | + root.getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); |
| 952 | + root.getGlassPane().setVisible(true); |
| 953 | + } |
| 954 | + }); |
| 955 | + timer.setRepeats(false); |
| 956 | + timer.start(); |
956 | 957 | } |
957 | 958 |
|
958 | 959 | @Override |
959 | | - public void run() { |
960 | | - doShowWaitCursor(glassPane, show); |
| 960 | + public void close() { |
| 961 | + SwingUtilities.invokeLater(() -> { |
| 962 | + timer.stop(); |
| 963 | + if (root != null) { |
| 964 | + root.getGlassPane().setVisible(false); |
| 965 | + root.getGlassPane().setCursor(null); |
| 966 | + } |
| 967 | + }); |
961 | 968 | } |
962 | 969 | } |
963 | 970 |
|
964 | | - private void prepareWaitCursor(final Node node) { |
965 | | - // check type of node |
966 | | - if (node == null || !autoWaitCursor) { |
967 | | - return; |
968 | | - } |
969 | | - |
970 | | - showWaitCursor(true); |
971 | | - // not sure whenter throughput 1 is OK... |
972 | | - ViewUtil.uiProcessor().post(new Runnable() { |
973 | | - @Override |
974 | | - public void run() { |
975 | | - try { |
976 | | - node.getChildren().getNodesCount(true); |
977 | | - } catch (Exception e) { |
978 | | - // log a exception |
979 | | - LOG.log(Level.WARNING, null, e); |
980 | | - } finally { |
981 | | - // show normal cursor above all |
982 | | - showWaitCursor(false); |
983 | | - } |
984 | | - } |
985 | | - }); |
986 | | - } |
987 | | - |
988 | | - |
989 | | - |
990 | 971 | /** Synchronize the selected nodes from the manager of this Explorer. |
991 | 972 | * The default implementation does nothing. |
992 | 973 | */ |
@@ -1507,7 +1488,7 @@ public void treeWillExpand(TreeExpansionEvent event) |
1507 | 1488 | throws ExpandVetoException { |
1508 | 1489 | // prepare wait cursor and optionally show it |
1509 | 1490 | TreePath path = event.getPath(); |
1510 | | - prepareWaitCursor(DragDropUtilities.secureFindNode(path.getLastPathComponent())); |
| 1491 | + maybeShowWaitCursor(DragDropUtilities.secureFindNode(path.getLastPathComponent())); |
1511 | 1492 | } |
1512 | 1493 | } |
1513 | 1494 | // end of TreePropertyListener |
|
0 commit comments