2010-04-30 9 views

Respuesta

15

Parece que desea envolver un booleano en una clase en la que pueda escuchar los cambios.

class ObservableBoolean { 

    // "CopyOnWrite" to avoid concurrent modification exceptions in loop below. 
    private final List<ChangeListener> listeners = 
      new CopyOnWriteArrayList<ChangeListener>(); 

    private boolean value; 

    public boolean getValue() { 
     return value; 
    } 

    public synchronized void setValue(boolean b) { 
     value = b; 
     for (ChangeListener cl : listeners) 
      cl.stateChanged(new ChangeEvent(this)); 
    } 

    public synchronized void addChangeListener(ChangeListener cl) { 
     listeners.add(cl); 
    } 

    public synchronized void removeChangeListener(ChangeListener cl) { 
     listeners.remove(cl); 
    } 
} 

Después, simplemente hacer:

ObservableBoolean b = new ObservableBoolean(); 

//... 

// Start the "period of time": 
b.addChangeListener(iWantToBeNotifiedOfChanges); 

// ... 

// End the "period of time": 
b.removeChangeListener(iWantToBeNotifiedOfChanges); 

Esto es en realidad un simple caso del patrón MVC (y el patrón de observador). El modelo en este caso es el ObservableBoolean y la vista sería la "vista" que quiere que se le notifiquen los cambios.

También puede escribir su propia interfaz ChangeListener si se quiere evitar un aspecto extraño javax.swing... importación

+0

+1 para patrón de observador. Me pregunto si desea monitorear el booleano en sí, o si en su lugar debería tener la Clase que está cambiando el estado de la lista de oyentes, y disparar los eventos de cambio cuando realiza el mod en el booleano. – akf

+0

@aioobe -> ver mi edición ahora – Xorty

+1

+1 ... pero algunos puntos: la lista de oyentes debería ser probablemente final, getValue() no está sincronizado, si un oyente intenta eliminarse a sí mismo como un oyente cuando se le notifica esto conducirá a una ConcurrentModificationException. Puede resolver este problema final utilizando CopyOnWriteArrayList en lugar de ArrayList. – Adamski

1

uso Timer o escribir su propia clase que se extiende Thread.

googlear esas cosas debe darle buen comienzo

edición: De la pregunta no es del todo claro qué son su intención. Tal vez quiera invocar algún método en un período de tiempo exacto, no inmediatamente después del evento. Para este patrón, aún me apegaría al temporizador o escribiría mi propio Tema. Escribir el hilo propio sigue siendo la mejor forma de interpretar los requisitos específicos del usuario. Por otro lado, si esto es realmente caso de escuchar eventos, mi patrón de temporizador sería completamente incorrecto.

ejemplo: Quiero actualizar la base de datos (imagine el juego del navegador web) cada 5 minutos, si los usuarios lo requieren (reques = true). Con una solicitud falsa, no necesito actualizar la base de datos. La base de datos de actualización inmediata (por ejemplo, estadísticas en el juego Tribal Wars con miles de jugadores) es totalmente exagerada.

+1

Un cambio rápido de true -> false -> true pasaría desapercibido a menos que ajuste el booleano en alguna clase "check-if-changed-since-last-pall". – aioobe

+0

cierto, pero la pregunta no era para verificar de inmediato sino en cierta cantidad de tiempo (período de tiempo). Depende del diseño del modelo. La clase Thread Extender es básicamente la implementación de Listeners (no literalmente, pero casi igual) – Xorty

+0

"si se realiza un cambio durante ese período de tiempo, realice un método". Estoy diciendo que si se realizan * dos * cambios en ese momento, * necesitas * un booleano extra 'stateHasChanged' que realiza un seguimiento de esto (de lo contrario, es muy posible que el cambio pase desapercibido). – aioobe

-2

Parece que debe buscar implementar algún tipo de Model View Controller Pattern. Eche un vistazo here

La idea básica es que debe desencadenar un evento cuando se modifique el booleano, y luego se desencadene ese evento, su oyente debería manejarlo.

+0

Ehm, ¿por qué votar? –

6

La forma más sencilla de hacerlo es con una clase contenedora ...

public class Bool 
{ 
    public Bool(){ _val = false; } 
    public Bool(boolean val) { _val = val; } 

    public boolean getValue(){ return _val; } 
    public void setValue(boolean val){ 
     _changesupport.firePropertyChange("value",_val,_val=val); 
    } 

    public void addPropertyChangeListener(PropertyChangeListener listener){ 
     _changesupport.addPropertyChangeListener(listener); 
    } 

    public void removePropertyChangeListener(PropertyChangeListener listener){ 
     _changesupport.removePropertyChangeListener(listener); 
    } 

    private boolean _val = false; 
    private final PropertyChangeSupport _changesupport = new PropertyChangeSupport(this); 
} 

Este es un patrón común en Swing, y se puede utilizar PropertyChangeSupport para simplificar la creación de objetos sobre los que se puede observar y escucha los cambios de propiedad. Con tales clases, puede registrar un PropertyChangeListener para manejar el resultante PropertyChangeEvent s resultante.

+0

Agradable con el 'PropertyChangeSupport'. ¿Por qué no está ubicado en un paquete más "genérico"? – aioobe

+0

+1 para PropertyChangeSupport. Aunque solo lo haría final y público y omitiría los métodos de agregar y eliminar en la clase Bool. –

Cuestiones relacionadas