Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 206773

Summary: Text widget should provide API for batching ModifyEvents
Product: [Eclipse Project] Platform Reporter: Eric Rizzo <eclipse-bugs>
Component: SWTAssignee: Platform-SWT-Inbox <platform-swt-inbox>
Status: RESOLVED WONTFIX QA Contact:
Severity: enhancement    
Priority: P3 CC: bokowski, bradleyjames, Ed.Merks, qualidafial, snorthov
Version: 3.3   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:

Description Eric Rizzo CLA 2007-10-18 11:22:32 EDT
There is a common theme in applications that want to monitor changes to Text widgets and update a model, mark the editor dirty, etc. Currently, there are only two built-in options for getting notified: ModifyListener and FocusListener. The drawback of FocusListener is that notification of changes don't propagate until the focus leaves the Text, confusing some users and requiring extra clicks or tabs. The drawback of ModifyListener is the sheer number and frequency of events that are received.
Bug 180746 talks about fixing this problem at the Data Binding layer by batching ModifyEvents and I've seen similar discussions on the newsgroups and with other application/plugin developers. However, I think it should be an (optional) API on Text itself, so that each client (framework, application, or plugin) does not have to design and implement its own solution.
I suggest a configurable delay which represents the smallest unit of time during which ModifyEvents can be fired. Thus, listeners can easily control how frequently they receive ModifyEvents from the Text.
Comment 1 Eric Rizzo CLA 2007-10-18 11:30:48 EDT
A couple of thoughts on implementation:

a) the simple approach (which would be fine with me) is to make the setting apply to the whole Text, all listeners. The benefit is that it is far easier to implement and test; the drawback is that setting it will affect other ModifyListeners.

b) a more sophisticated approach would be to all individual listeners to specify their own "batch delay" value in an overloaded method:
addModifyListener(ModifyListener listener, long batchDelay)
The benefit is that setting the delay for one does not affect other listeners; the drawback is that (I think) this would be much more work to implement and test, and thus have more potential for bugs.

c) to come at it from a different angle, a special implementation of ModifyListener could be provided that encapsulates the batching instead of relying on the Text to do it. The benefits of this are similar to both a) and b) above. The drawback is that existing listeners would have to be re-written in order to take advantage.
Comment 2 Ed Merks CLA 2007-10-18 11:36:51 EDT
It's not entirely clear this should be done at the SWT level, I know Steve is a firm believer in minimalism in the core.  But certainly as we move up in the food chain into the forms and data binding space, having everyone solve this problem in various clever ways instead of having something reusable is problematic.
Comment 3 Boris Bokowski CLA 2007-10-18 12:07:31 EDT
Why is the number of events a problem?

Here are some use cases that come to mind:
 1. You want to do expensive validation (e.g. involving disk access)
 2. You are updating other parts of the UI based on the current value of the
text,
    and updating for every keystroke is too costly or makes the UI too noisy.
    Example: the filtered tree that appears in Eclipse's preference dialog and
    in a couple of other places
 3. You are making changes in your back-end store directly (think database) and
    would like to avoid too many changes.

A snippet for one of these cases would be good, because it seems to be a common
problem.  Not sure if it belongs in SWT though.
Comment 4 Eric Rizzo CLA 2007-10-18 13:09:45 EDT
(In reply to comment #3)
> Why is the number of events a problem?
> 
> Here are some use cases that come to mind:
>  1. You want to do expensive validation (e.g. involving disk access)

My current project runs EMF validation on every model change, and the performance when using ModifyEvent on a field is noticeably poor even with a small model and project. I don't know if that is doing disk access or not.

Another use were it causes a problem is when using some kind of command framework to modify the model or back-end. For example, our editors use EMF.Edit to issue commands to modify the model objects. If we try to trigger off every ModifyEvent, the CommandStack gets very deep very fast and undo/redo end up operating at the keystroke level which is usually not practical for users.

> A snippet for one of these cases would be good, because it seems to be a common
> problem.  Not sure if it belongs in SWT though.

Part of the reasoning behind this request is to avoid multiple layers, plugins, or applications having to reinvent the wheel. If its not in SWT, where should it go so that everyone can take advantage? 

Comment 5 Steve Northover CLA 2007-10-18 14:15:38 EDT
When the text widget changes, the operating system sends notification.  I think waiting a time period to deliver the event is wrong.  Possibly, an API that froze then thawed events could collapse them, but this requires the application to call freeze() and thaw() and if the application can to this, then it may as well write the code to ignore modify events.

One way to do this is to set an ignore flag, post an asyncExec() for the event loop, clear the flag in the Runnable, and send then do the work.