## SwingGUI – Java-based GUI classes

last mod: 13-jan-08 sciss

# UpdateListener

This class is somewhat similar to Updater from the Crucial-library, but with a few extras. It implements the `update` method needed to register dependants with objects, so it acts as an observer in the observer software-design pattern, and can also be used in model-view-controller (mvc) design.

When the observed object is issued a `changed` message (after its state has been changed in some way) all of its dependants – including the `UpdateListener` – are sent the `update` message. The `UpdateListener` forwards this call to the Function that was passed in its constructor:

        UpdateListener.new( <(Function) update>, [ <(Symbol) what> ])

where `update` is a Function that will get invoked with the first argument being the `UpdateListener` itself, followed by all arguments of the `update` call. The optional `what` argument is a filter to limit `update` forwarding to a specific type of update-message (see below).

When you use this plain constructor, the listener needs to be added as dependant to some object / model, using the `addTo( <(Object) object> )` method. As a shorthand, the contructor method

        UpdateListener.newFor( <(Object) object>, <(Function) update>, [ <(Symbol) what> ])

can be used. Examples:

    s.boot;

    x = Synth( \default, [ \amp, 0.2 ]);
    x.register;     // now a NodeWatcher will call 'changed' on x
    // create and add a new UpdateListener that tracks changes of x by printing them
    // to the post-window:
    u = UpdateListener.newFor( x, { arg upd, obj ... info; ([ obj ] ++ info).postln });
    // isListening reports whether the UpdateListener is still a dependant
    u.isListening;  // --> true
    x.run( false ); // --> [ Synth("default" : 1000), n_off ]
    x.run( true );  // --> [ Synth("default" : 1000), n_on ]
    x.release;      // --> [ Synth("default" : 1000), n_end ]
    u.remove;       // removes the dependant from all observed objects
    u.isListening;  // --> false

    x = Synth( \default, [ \freq, 441, \pan, -1, \amp, 0.2 ]).register;
    y = Synth( \default, [ \freq, 662, \pan,  1, \amp, 0.2 ]).register;
    z = Synth( \default, [ \freq, 332, \pan,  0, \amp, 0.2 ]).register;
    u = UpdateListener({ "update!".postln });
    // it is allowed to add the listener to several objects
    u.addTo( x );
    u.addTo( y );
    u.addTo( z );
    x.free;
    u.removeFrom( y );      // remove dependant only from y
    u.isListeningTo( y );   // --> false
    u.isListeningTo( z );   // --> true
    y.free;                 // ... so this will not notify u anymore
    u.verbose = true;       // prints out invocations the post-window (independent of the update function)
    z.free;
    u.removeFromAll;        // synonym with 'remove'

## Using the 'what' filter-argument

    x = Synth.basicNew( \default ).register;
    // now a listener that only registers changes of type \n_go:
    u = UpdateListener.newFor( x, { arg ... args; args.postln }, \n_go );
    x.server.listSendMsg( x.newMsg( args: [ \amp, 0.2 ]));
    x.run( false );
    x.run( true );
    x.free;
    u.remove;