Skip to content

Commit bc38cc9

Browse files
committed
feat: add UI.debounce
1 parent 4862bc5 commit bc38cc9

1 file changed

Lines changed: 43 additions & 0 deletions

File tree

  • plugin/src/main/java/de/sebthom/eclipse/commons/ui

plugin/src/main/java/de/sebthom/eclipse/commons/ui/UI.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@
1515
import org.eclipse.jdt.annotation.Nullable;
1616
import org.eclipse.jface.action.IStatusLineManager;
1717
import org.eclipse.jface.viewers.IStructuredSelection;
18+
import org.eclipse.swt.SWT;
1819
import org.eclipse.swt.SWTException;
20+
import org.eclipse.swt.events.ModifyEvent;
21+
import org.eclipse.swt.events.ModifyListener;
1922
import org.eclipse.swt.graphics.Point;
2023
import org.eclipse.swt.graphics.Rectangle;
2124
import org.eclipse.swt.widgets.Display;
25+
import org.eclipse.swt.widgets.Event;
2226
import org.eclipse.swt.widgets.Shell;
2327
import org.eclipse.ui.IEditorReference;
2428
import org.eclipse.ui.IViewPart;
@@ -57,6 +61,45 @@ public static void center(final Shell shell) {
5761
shell.setLocation(new Point(x, y));
5862
}
5963

64+
public static ModifyListener debounce(final int delayMS, final ModifyListener listener) {
65+
final int delay = Math.max(0, delayMS);
66+
return new ModifyListener() {
67+
private static final Runnable NOOP = () -> { /* empty lambda to avoid null checks */ };
68+
private Runnable fireModifyText = NOOP;
69+
70+
@Override
71+
public void modifyText(final ModifyEvent ev) {
72+
final var display = ev.display;
73+
final var widget = ev.widget;
74+
75+
// Cancel the previously scheduled task, if any
76+
if (fireModifyText != NOOP) {
77+
display.timerExec(-1, fireModifyText);
78+
}
79+
80+
fireModifyText = () -> {
81+
if (widget.isDisposed())
82+
return;
83+
try {
84+
// create a fresh event so downstream code doesn't see a stale one
85+
final var newEv = new Event();
86+
newEv.type = SWT.Modify;
87+
newEv.widget = widget;
88+
newEv.display = display;
89+
newEv.time = (int) (System.currentTimeMillis() & 0x7fff_ffff);
90+
listener.modifyText(new ModifyEvent(newEv));
91+
} finally {
92+
// drop references quickly
93+
fireModifyText = NOOP;
94+
}
95+
};
96+
97+
// schedule after debounce delay
98+
display.timerExec(delay, fireModifyText);
99+
}
100+
};
101+
}
102+
60103
@SuppressWarnings("unchecked")
61104
public static @Nullable <T extends IViewPart> T findView(final String viewId) {
62105
try {

0 commit comments

Comments
 (0)