tags:

views:

226

answers:

3

I've got an SWT shell that's resizable. Every time it is resized, I have to do something computationally intensive. I can register a ControlListener on my shell, but this generates events continuously throughout the resize operation, and I have no idea when a resize drag type mouse operation ends. I'd like to be able to detect when the user is finished resizing the shell and then initiate my computationally intensive operation. Any ideas how to go about that?

+3  A: 

How about using a timer and start your operation after a delay of say one sec since last received resize event? A rough draft:

long lastEvent;

ActionListener taskPerformer = new ActionListener() {
            public void doCalc(ActionEvent evt) {
                if ( (lastEvent + 1000) > System.currentTimeMillis() )
                   hardcoreCalculationTask();
                else
                  // this can be timed better
                  new Timer(1000, taskPerformer).start();

            }
        };
}

In your resize event:

 lastEvent = System.currentTimeMillis();
 new Timer(1000, taskPerformer).start();
stacker
This, or something like it, is probably the best solution. Guarantees that no resizing has been done for at least a second. Adds a delay to the processing time, but there's probably nothing to be done about that.The other responses made use of AsyncExec, which will still fire resize events in the middle of a continuous resize drag, but not as often. Could be useful to somebody. I should have specified that by "computationally intensive" I meant that it could take upwards of a minute and doesn't like to be interrupted, so starting it over as few times as possible is preferable.
jsn
A: 

Here's an alternative suggestion for the same problem: [platform-swt-dev] Mouse resize listener:

You could try setting a flag and defering the resize work using Display.asyncExec(). When you get a resize, if the flag is set, just return. This should cause the resize work only when the UI is idle.

My instant idea was to listen to mouse up events but obviously (I just tried it), mouse events are not fired for mouse actions on the shell's border. Could be so damn easy...

Andreas_D
A: 

If the problem is blocking the UI Thread during resizing, you should consider the method asyncExec of the class Display

/**
 * Causes the <code>run()</code> method of the runnable to
 * be invoked by the user-interface thread at the next 
 * reasonable opportunity. The caller of this method continues 
 * to run in parallel, and is not notified when the
 * runnable has completed.  Specifying <code>null</code> as the
 * runnable simply wakes the user-interface thread when run.
 * <p>
 * Note that at the time the runnable is invoked, widgets 
 * that have the receiver as their display may have been
 * disposed. Therefore, it is necessary to check for this
 * case inside the runnable before accessing the widget.
 * </p>
 *
 * @param runnable code to run on the user-interface thread or <code>null</code>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @see #syncExec
 */
public void asyncExec (Runnable runnable) {
    synchronized (Device.class) {
        if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
        synchronizer.asyncExec (runnable);
    }
}
Arnaud