X-Git-Url: https://git.argeo.org/?p=gpl%2Fargeo-suite.git;a=blobdiff_plain;f=org.argeo.app.ui%2Fsrc%2Forg%2Fargeo%2Fapp%2Fui%2Fwidgets%2FDelayedText.java;fp=org.argeo.app.ui%2Fsrc%2Forg%2Fargeo%2Fapp%2Fui%2Fwidgets%2FDelayedText.java;h=ecf66396868364ba893c187a5dbf0014babe04bd;hp=0000000000000000000000000000000000000000;hb=6e56ffa34cb02ab04d028423aea342e3dfed4358;hpb=c285180bece610b2c2921d44fe14b6dde2123efa diff --git a/org.argeo.app.ui/src/org/argeo/app/ui/widgets/DelayedText.java b/org.argeo.app.ui/src/org/argeo/app/ui/widgets/DelayedText.java new file mode 100644 index 0000000..ecf6639 --- /dev/null +++ b/org.argeo.app.ui/src/org/argeo/app/ui/widgets/DelayedText.java @@ -0,0 +1,91 @@ +package org.argeo.app.ui.widgets; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +import org.eclipse.rap.rwt.service.ServerPushSession; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; + +/** + * A text input which notifies changes after a delay, typically in order to + * apply a filter. + */ +public class DelayedText { + private final static ScheduledExecutorService scheduler; + static { + // create only one scheduler, in order not to exhaust threads + scheduler = Executors.newScheduledThreadPool(0, (r) -> { + Thread thread = new Thread(r, "Delayed text scheduler"); + // we mark threads as deamons so that the shutdown hook is triggered + thread.setDaemon(true); + return thread; + }); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + scheduler.shutdown(); + }, "Shutdown delayed text scheduler")); + } + private final static int DEFAULT_DELAY = 800; + + private final long delay; + private final InternalModifyListener modifyListener; + private final Text text; + protected List> toDos = new ArrayList<>(); + private ServerPushSession pushSession; + + private ScheduledFuture lastTask; + + public DelayedText(Composite parent, int style) { + this(parent, style, DEFAULT_DELAY); + } + + public DelayedText(Composite parent, int style, long delayInMs) { + this.delay = delayInMs; + this.modifyListener = new InternalModifyListener(); + pushSession = new ServerPushSession(); + pushSession.start(); + text = new Text(parent, style); + text.addModifyListener(modifyListener); + } + + protected void notifyText(String txt) { + // text.getDisplay().syncExec(()-> pushSession.start()); + for (Consumer toDo : toDos) { + text.getDisplay().syncExec(() -> toDo.accept(txt)); + } + // text.getDisplay().syncExec(()->pushSession.stop()); + } + + public Text getText() { + return text; + } + + public void addListener(Consumer toDo) { + toDos.add(toDo); + } + + private class InternalModifyListener implements ModifyListener { + private static final long serialVersionUID = -6178431173400385005L; + + public void modifyText(ModifyEvent e) { + String txt = text.getText(); + ScheduledFuture task = scheduler.schedule(() -> { + notifyText(txt); + return txt; + }, delay, TimeUnit.MILLISECONDS); + // cancel previous task + if (lastTask != null && !lastTask.isDone()) { + lastTask.cancel(false); + } + lastTask = task; + } + }; + +}