Cómo escribir un Oyente de List Selection

Los eventos List selection ocurren cuando una selección en una list o una table cambia o acaba de cambiar. Los eventos List selection son disparados por un objeto que implementa el interface ListSelectionModel.

Para detectar un evento list selection debemos registrar un oynete con el objeto selection model apropiado. La clase JList también ofrece la opción de registrar un oyente sobre la propia lista, mejor que directamente al selection model de la lista.

Métodos de Evento List Selection

El interface ListSelectionListener sólo tiene un método y por lo tanto ni tiene la correspondiente clase adaptador. Aquí está el método:
void valueChanged(ListSelectionEvent)
Se le llama cuando cambia la selección del componente escuchado, también se la llama después de que la selección haya cambiado.

Ejemplos de Manejo de Eventos List Selection

La sección Cómo usar Lists proporciona un ejemplo de un oyente que escucha los eventos de una lista single-selection (no del selection model de la lista).

Esta sección proporciona un ejemplo que mustra cómo escuchar este tipo de eventos en un selection model. El selection model es compartido por un lista y una tabla. Dinámicamente podemos cambiar el modo de selección a uno de los tres modos soportados:

  • single selection
  • single interval selection
  • multiple interval selection

Aquí podmeos ver una imágen del ejemplo ejecutándose:


Prueba esto:
  1. Compila y ejecuta la aplicación. El código fuente está en ListSelectionDemo.java.
  2. Selecciona y deselecciona items de la lista y de la tabla. Los comandos requeridos de ratón y de teclado para seleccionar ítems dependen del "aspecto y comportamiento". Para Metal, pulsa el botón izquierdo delr atón para empezar una selección, usa la tecla Shift para extender una selección contigüa, y usa la tecla Control para extender una selección discontigüa. Arrastrar el ratón mueve o extiende la selección dependiendeo del modo de selección.

Aquí está el código de ListSelectionDemo.java que configura el modelo de selección y le añade un oyente:
...//where the member variables are defined
JList list;
JTable table;
    ...//in the init method:
    listSelectionModel = list.getSelectionModel();
    listSelectionModel.addListSelectionListener(
                            new SharedListSelectionHandler());
    ...
    table.setSelectionModel(listSelectionModel);
Y aquí está el código para el oyente, que funciona para todos los modos de selección posibles:
class SharedListSelectionHandler implements ListSelectionListener {
    public void valueChanged(ListSelectionEvent e) {
        ListSelectionModel lsm = (ListSelectionModel)e.getSource();

        int firstIndex = e.getFirstIndex();
        int lastIndex = e.getLastIndex();
        boolean isAdjusting = e.getValueIsAdjusting();
        output.append("Event for indexes "
                      + firstIndex + " - " + lastIndex
                      + "; isAdjusting is " + isAdjusting
                      + "; selected indexes:");

        if (lsm.isSelectionEmpty()) {
            output.append(" <none>");
        } else {
            // Find out which indexes are selected.
            int minIndex = lsm.getMinSelectionIndex();
            int maxIndex = lsm.getMaxSelectionIndex();
            for (int i = minIndex; i <= maxIndex; i++) {
                if (lsm.isSelectedIndex(i)) {
                    output.append(" " + i);
                }
            }
        }
        output.append(newline);
    }
}

El método valueChanged muestra el primer y último índices reportados por el evento, el valor de la bandera isAdjusting del evento, y el indice actualmente seleccionado.

Observa que el primer y útlimo indices reportados por el eventos indican el rango inclusivo de ítems para los que la selección ha cambiado. Si el modo de selección es multiple interval selection algunos ítems dentro del rango podrían no haber cambiado. La bandera isAdjusting es true si el usuario todavía está manipulando la selección, y false si el usuario ha terminado de modificar la selección.

El objeto ListSelectionEvent pasado dentro de valueChanged indica sólo que la selección ha cambiado. El evento no contiene información sobre la selección actual. Por eso, este método le pide al selection model que se imagine la selección actual.


Nota: La salida de este programa depende de la verión Swing que estemos utilizando. Swing 1.0.x contiene varios bugs y la operación de listas y tablas era inconsistente. Las versiones posteriores de Swing corrigieron estos problemas.

La clase ListSelectionEvent

Cada método de evento list selection tiene un sólo parámetro: un objeto ListSelectionEvent. Este objeto le dice al oyente que la selección ha cambiado. Un evento list selecton puede indicar un cambio en la selección de múltiples ítems, discontigüos de la lista.

Para obtener la fuente de un ListSelectionEvent, se usa el método getSource, que ListSelectionEvent hereda de EventObject. Si registramos un oyente de list selection directamente sobre una lista, la fuente de cada evento será la propia lista. De otra forma, sería el selection model.

La clase ListSelectionEvent define los siguientes métodos:

int getFirstIndex()
Devuelve el índice del primer ítem cuyo valor de selección ha cambiado. Observa que para selecciones de intervalo múltiple, el primer y último ítems es seguro que han cambiado, pero los ítems que hay entre medias podrían no haberlo hecho.
int getLastIndex()
Devuelve el índice del último ítem cuyo valor de selección ha cambiado. Observa que para selecciones de intervalo múltiple, el primer y último ítems es seguro que han cambiado, pero los ítems que hay entre medias podrían no haberlo hecho.
int getValueIsAdjusting()
Devuelve true si se está modificando todavía la selección. Muchos oyentes de list selectionsólo están intereados en el estado final de la selección y pueden ignorar eventos cuando este método devuelve true.

Ozito