2009-04-13 19 views
15

Tengo un cuadro desplegable en mi GUI que muestra los contenidos de una ArrayList en otra clase. Se pueden agregar objetos nuevos a ArrayList en otra parte de la GUI, así que necesito saber cuándo se actualizan para que pueda actualizar el menú desplegable. Por lo que puedo deducir, mis dos opciones son extender la clase ArrayList para permitirme agregar mi propio changeListener, o hacer que la clase que contiene el ArrayList en cuestión se extienda observable.¿Debo usar un Listener u Observer?

¿Cuál sería una solución más adecuada?

+1

¿se refiere a un JComboBox? Si es así, analizaría ComboBoxModel y sus implementaciones. – Avrom

Respuesta

10

Las dos soluciones son esencialmente las implementaciones del mismo patrón de diseño de la raíz (el patrón de "observador" como se define por la Gang of Four.) En el primer caso, usted está haciendo que ArrayList sea "observable", en este último hace que el objeto de dominio que utiliza la lista de arreglos sea "observable".

Mi tendencia sería hacer lo último: hacer que el objeto de dominio sea observable. Esto se debe principalmente a que posiblemente tenga otras cosas que podrían cambiar sobre el objeto de dominio (para lo cual se debe actualizar la GUI). Si ya es observable, ya está configurado.

Tenga en cuenta que no tiene que extender estrictamente java.util.Observable - puede implementar el patrón de diseño sin hacer eso.

+0

Esto parece ser la manera más fácil, gracias por todas las demás respuestas. – Simonw

9

La implementación de Observable en Java se utiliza raramente, y no interfunciona bien con Swing. Use un EventListener en su lugar.

En particular, ¿hay alguna razón para no ampliar AbstractListModel o incluso usar DefaultListModel directamente al gestionar los contenidos de la lista "en otro lugar de la GUI"? Entonces su cuadro combinado podría usar un ComboBoxModel que delega a la misma instancia ListModel, agregando su propia implementación para rastrear el estado de selección.

que tengo en mente algo como esto (pero no he probarlo):

final class MyComboBoxModel 
    extends AbstractListModel 
    implements ComboBoxModel 
{ 

    private final ListModel data; 

    private volatile Object selection; 

    MyComboBoxModel(ListModel data) { 
    /* 
    * Construct this object with a reference to your list, 
    * which contents are managed somewhere else in the UI. 
    */ 
    this.data = data; 
    data.addListDataListener(new ListDataListener() { 
     public void contentsChanged(ListDataEvent evt) { 
     fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
     } 
     public void intervalAdded(ListDataEvent evt) { 
     fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
     } 
     public void intervalRemoved(ListDataEvent evt) { 
     fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
     } 
    }); 
    } 

    public void setSelectedItem(Object selection) { 
    this.selection = selection; 
    fireContentsChanged(this, 0, data.getSize() - 1); 
    } 

    public Object getSelectedItem() { return selection; } 

    public int getSize() { return data.getSize(); } 

    public Object getElementAt(int idx) { return data.getElementAt(idx); } 

} 
1

Siempre prefiero la composición sobre la extensión (mi referencia es Java efectiva y mi experiencia personal). extender ArrayList es simplemente una promesa de que no violarás ninguna de las clases invariantes. También lo vincula a la implementación de la lista específica que está extendiendo.

0

Puede cambiar a usar GUI design pattern. O construir una implementación limitada.

crear una interfaz Formulario interfaz gráfica de usuario que tiene un DrawXArrayList método (siendo X un nombre meaningfull Tiene un parámetro de ArrayList tipo

Crear una nueva clase llamada GUIView Tiene al menos dos métodos:.. UpdateXArrayList, y RegisterForm

al inicializar su aplicación tienen la forma GUI registrarse con la clase que implementa GUIView. Hacer la clase que implementa GUIView visible para el formulario.

Cuando nada en su formulario de interfaz gráfica de usuario actualiza el ArrayList tiene que llamar UpdateXArrayList como lo último que hace. Th El método UpdateXArrayList en la clase que implementa GUIView luego llamará a DrawXArrayList pasando la lista de arrays actualizada. DrawXArrayList en la clase de formulario que implementa GUIFormInterface tomará los pasos necesarios para actualizar el control que muestra ArrayList.

Si bien esto parece un montón de pasos en comparación con una configuración de observador y oyente.Usted tiene más control sobre cómo las diversas acciones del usuario afectan a la UI y luego al patrón observador-oyente. Además, documentó, en código, la interacción entre la acción del usuario y las actualizaciones de la interfaz de usuario.

2

¿Por qué no utilizar enlaces?

http://wiki.eclipse.org/index.php/JFace_Data_Binding

Enlazar el widget de interfaz gráfica de usuario a su lista. Los cambios se propagarán entre los dos objetos de forma transparente. Asegúrese de ajustar su modelo con un observable apropiado, como WritableList (si usa ArrayList directamente).

0

Si usted puede agregar un nuevo frasco para la aplicación, echa un vistazo a glazed Lists