X-Git-Url: https://git.argeo.org/?p=gpl%2Fargeo-suite.git;a=blobdiff_plain;f=org.argeo.suite.ui%2Fsrc%2Forg%2Fargeo%2Fsuite%2Fui%2Fwidgets%2FDelayedText.java;fp=org.argeo.suite.ui%2Fsrc%2Forg%2Fargeo%2Fsuite%2Fui%2Fwidgets%2FDelayedText.java;h=a03c2501f50d66742976c7380acf63195e442006;hp=0000000000000000000000000000000000000000;hb=3440f51df3e4c015972c7b6a0efb3ce16188b89b;hpb=752a7b2614895002a3d184be166ef4162caf0d05 diff --git a/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/DelayedText.java b/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/DelayedText.java new file mode 100644 index 0000000..a03c250 --- /dev/null +++ b/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/DelayedText.java @@ -0,0 +1,127 @@ +package org.argeo.suite.ui.widgets; + +import java.util.Timer; +import java.util.TimerTask; + +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.Event; +import org.eclipse.swt.widgets.Text; + +/** + * Text that introduce a timer in the attached ModifyListener. + * + * Note that corresponding ModifyEvent will *NOT* be sent in the UI thread. + * Calling ModifierInstance must be implemented in consequence. Note also that + * this delayed text only manages one listener at a time. + * + */ +public class DelayedText { + final int delay; + private Object lock = new Object(); + private MyTimer timer = new MyTimer(DelayedText.this.toString()); + private ModifyListener delayedModifyListener; + private ServerPushSession pushSession; + + private Text text; + + private ModifyListener modifyListener = new ModifyListener() { + private static final long serialVersionUID = 1117506414462641980L; + + public void modifyText(ModifyEvent e) { + ModifyEvent delayedEvent = null; + synchronized (lock) { + if (delayedModifyListener != null) { + Event tmpEvent = new Event(); + tmpEvent.widget = text; + tmpEvent.display = e.display; + tmpEvent.data = e.data; + tmpEvent.time = e.time; + delayedEvent = new ModifyEvent(tmpEvent); + } + } + final ModifyEvent timerModifyEvent = delayedEvent; + + synchronized (timer) { + if (timer.timerTask != null) { + timer.timerTask.cancel(); + timer.timerTask = null; + } + + if (delayedEvent != null) { + timer.timerTask = new TimerTask() { + public void run() { + synchronized (lock) { + delayedModifyListener.modifyText(timerModifyEvent); + // Bad approach: it is not a good idea to put a + // display.asyncExec in a lock... + // DelayedText.this.getDisplay().asyncExec(new + // Runnable() { + // @Override + // public void run() { + // delayedModifyListener.modifyText(timerModifyEvent); + // } + // } + // ); + } + synchronized (timer) { + timer.timerTask = null; + } + } + }; + timer.schedule(timer.timerTask, delay); + if (pushSession != null) + pushSession.start(); + } + } + }; + }; + + public DelayedText(Composite parent, int style, int delayInMs) { + // super(parent, style); + text = new Text(parent, style); + this.delay = delayInMs; + text.addModifyListener(modifyListener); + } + + /** + * Adds a modify text listener that will be delayed. If another Modify event + * happens during the waiting delay, the older event will be canceled an a new + * one will be scheduled after another new delay. + */ + public void addDelayedModifyListener(ServerPushSession pushSession, ModifyListener listener) { + synchronized (lock) { + delayedModifyListener = listener; + this.pushSession = pushSession; + } + } + + public void removeDelayedModifyListener(ModifyListener listener) { + synchronized (lock) { + delayedModifyListener = null; + pushSession = null; + } + } + + private class MyTimer extends Timer { + private TimerTask timerTask = null; + + public MyTimer(String name) { + super(name); + } + } + + public Text getText() { + return text; + } + + public void close() { + if (pushSession != null) + pushSession.stop(); + if (timer != null) + timer.cancel(); + }; + +}