Swing y JFC (Java Foundation Classes)

Un JScrollPane proporciona una vista desplazable de un componente ligero. Cuando el estado de la pantalla real est� limitado, se utiliza un ScrollPane para mostrar un componente que es grande o cuyo tama�o puede cambiar din�micamente.

El c�digo para crear un panel desplazable puede ser m�nimo. Por ejemplo aqu� tenemos una imagen de un programa que utiliza un panel desplazable para ver una salida de texto.

Y aqu� est� el c�digo que crea el �rea de texto, crea el cliente del panel desplazable, y a�ade el panel desplazable a la ventana.

textArea = new JTextArea(5, 30);
JScrollPane scrollPane = new JScrollPane(textArea);
...
contentPane.setPreferredSize(new Dimension(400, 100));
...
contentPane.add(scrollPane, BorderLayout.CENTER);

El programa proporciona el �rea de texto como argumento al constructor del JScrollPane. Esto establece el �rea de texto como el cliente del panel desplazable. El panel desplazable maneja todo esto: crear las barras de desplazamiento cuando son necesarias, redibujar el cliente cuando el usuario se mueve sobre �l, etc.

Observa que el c�digo de ejemplo selecciona el tama�o preferido del contenedor del panel desplazable. Una alternativa ser�a seleccionar el tama�o preferido del propio panel desplazable. De cualquier modo, se est� limitando el tama�o del panel desplazable. Esto es necesario porque el tama�o preferido de un panel desplazable es ser tan grande como pueda.

Por defecto, un panel desplazable intenta redimensionarse para que su cliente se muestre en su tama�o preferido. Muchos componetes tienen un sencillo tama�o preferido que es lo suficientemente grande como para dibujarse entero. Esto hace que el panel desplazable sea redundante. Otros componentes, como listas, tablas, componentes de texto, y �rboles, reportan un tama�o preferido separado para desplazamiento, que normalmente es m�s peque�o que el tama�o preferido est�ndard. Por ejemplo, por defecto, el tama�o preferido de una lista para despalzarla es lo suficientemente grande para mostrar ocho filas. Si el tama�o preferido reportado por el componente, no es el que queremos, se selecciona el tama�o preferido del panel desplazable o de su contenedor.

Si todo lo que necesitas es proprocionar desplazamiento b�sico para un componente ligero, no leas m�s. Lo que demuestra esta ejemplo es suficiente para la mayor�a de los programas.

Sin embargo, un ScrollPane es un objeo altamente personalizable. Se puede determinar bajo que circunstancias se mostrar�n las barras de desplazamiento. Tambi�n se puede decorar con una fila de cabecera, una columna de cabecera y esquinas. Finalmente se puede crear un cliente de desplazamiento que seguro que avisa al panel desplazable sobre el comportamiento de desplazamiento como los incrementos de unidad y de bloques. Estos t�picos se cubren en las siguientes secciones:

.�C�mo funciona un ScrollPane

Aqu� puedes ver una imagen de una aplicaci�n que utiliza un panel desplazable para ver una foto del padre de Mary cuando era joven.

El panel desplazable de esta aplicaci�n parece totalmente diferente del de la aplicaci�n anterior. En vez de texto, contiene una gran imagen. El ScrollPane tambi�n tiene dos barras de desplazamiento, un fila y una columna de cabecera y tres esquinas personalizadas, una de las cuales contiene un bot�n.

Intenta esto:
  1. Compila y ejecuta la aplicaci�n. El fichero fuente es ScrollDemo.java. Tambi�n necesitar�s ScrollablePicture.java, Rule.java, Corner.java y youngdad.jpeg.
  2. Mueve las barras de desplazamiento. Mira que la imagen se mueve y con ella las reglas vertical y horizontal.
  3. Pulsa el bot�n cm en la esquina superior izquierda. Las unidades de las cabecera de fila y de columna cambian a pulgadas (o vuelve a cent�metros).
  4. Pulsa las flechas de las barras de desplazamiento. Tambi�n, pulsa sobre el camino de las barras de desplazamiento arriba o debajo de la barra vertical, o a la izquierda o derecha de la barra horizontal.
  5. Aumenta el tama�o de la ventana. Observa que las barras desaparecen cuando no son necesarias y como resultado las esquina a�adidas tambi�n desparecen. Disminuye la ventana y las barras de desplazamiento y las esquinas reaparecer�n.

Este programa establece el cliente cuando crea el panel desplazable.

// where the member variables are declared
private ScrollablePicture picture;
...
	// where the GUI is created
        picture = new ScrollablePicture( ... );
        JScrollPane pictureScrollPane = new JScrollPane(picture);

Se puede cambiar din�micamente el cliente del panel desplazable llamado al m�todo setViewportView.

Cuando se manipulan las barras de desplazamiento de un ScrollPane, se cambia el �rea del cliente que es visible. Es imagen muestra esta relaci�n e indica las clases que ayudan al ScrollPane.

Cuando se mueve la barra de desplazamiento arriba y abajo, el �rea visible del cliente se mueve arriba y abajo. De forma similar trabaja la barra de desplazamiento horizontal.

Un ScrollPane utiliza un ejemplar de JViewport para manejar el �rea visible de un cliente. Este objeto calcula los l�mites del �rea visible actual, bas�ndose en las posiciones de las barras de desplazamiento, y la muestra. Un ScrollPane utiliza dos ejemplares separados de JScrollBar para las barras de desplazamiento. Las barras proporcionan el interface para que el usuario manipule el �rea visible.

Normalmente los programas no ejemplarizan directamente, ni llaman a los m�todos de JViewPort o JScrollBar. En su lugar, los programas alcanzan su comportamiento desplazable utilizando el API de JScrollPane o el API descrito en Implementar un Cliente de Desplazamiento Seguro. Algunos componentes de desplazamiento seguro como JTable y JTree tambi�n proporcionan alg�n API para ayudar a efectuar su desplazamiento.

.�Seleccionar el Vigilante de ScrollBar

Cuando arranca, la aplicaci�n ScrollDemo contiene dos barras de desplazamiento. Si agrandamos la ventana, las barras de desplazamiento desparecen porque ya no son necesarias. Este comportamiento esta controlado por el Vigilante de SCrollBar. Realmente hay dos vigilantes, uno para cada una de las barras de desplazamiento.

De los constructores proporcionados por JScrollPane, dos nos permite seleccionar vigilantes de barras de desplazamiento cuando creamos nuestro ScrollPane.

JScrollPane(Component, int, int)
JScrollPane(int, int)

El primer int especifica el vigilante para la barra vertical, y el segundo para la horizontal. Tambi�n se pueden seleccionar los vigilantes con los m�todos setHorizontalScrollBarPolicy y setVerticalScrollBarPolicy. En ambos casos se utilizan los siguientes enteros definidos en el interface ScrollPaneConstants que es implementado por JScrollPane.

Vigilante Descripci�n
VERTICAL_SCROLLBAR_AS_NEEDED

HORIZONTAL_SCROLLBAR_AS_NEEDED

Valor por defecto. Las barras de desplazamiento aparecen cuando el JViewPort es m�s peque�o que el cliente y desaparecen cuando es m�s grande.
VERTICAL_SCROLLBAR_ALWAYS

HORIZONTAL_SCROLLBAR_ALWAYS

Siempre muestra las barras.
VERTICAL_SCROLLBAR_NEVER

HORIZONTAL_SCROLLBAR_NEVER

Nunca muestra las barras de desplazamiento. Se utiliza esta opci�n si no queremos darle al usuario el control sobre la parte del cliente a visualizar. Quiz�s tengamos alguna aplicaci�n que requiera que el desplazamiento ocurra program�ticamente.

.�Proprorcionar Decoraci�n Personalizada

El �rea dibujada por un ScrollPane est� dividida, al menos, en nueve partes: el centro, cuadro laterales y cuatro esquinas. El centro es el �nico componente que siempre est� presente en un ScrollPane. Cada uno de los cuatro lados son opcionales. El lado superior puede contener una columna de cabecera, el lado izquierdo puede contener una fila de cabecera, el lado inferior puede contener una barra de desplazamiento horizontal, y el lado derecho puede tener una barra de desplazamiento vertical. La presencia de las cuatro esquinas depende completamente de la presencia de los dos laterales que interseccionan en ellas.

Como se ve en la figura, el ScrollPane de ScrollDemo.java tiene cabeceras de fila y columna personalizadas. Adem�s, como los cuatro laterales est�n llenos, las cuatro esquinas est�n presentes. Tres de las esquinas tambi�n est�n personalizadas.

Las cabeceras de fila y columna del ScrollPane est�n proporcionadas por una subclase personalizada de JComponent, Rule.java, que dibuja una regla en cent�metros o pulgadas. Aqu� est� el c�digo que crea y selecciona las cabecetas de fila y columna del ScrollPane.

...where the member variables are defined...
private Rule columnView;
private Rule rowView;
    ...
    // Create the row and column headers
    columnView = new Rule(Rule.HORIZONTAL, false);
    columnView.setPreferredWidth(david.getIconWidth());
    rowView = new Rule(Rule.VERTICAL, false);
    rowView.setPreferredHeight(david.getIconHeight());
    ...
    pictureScrollPane.setColumnHeaderView(columnView);
    pictureScrollPane.setRowHeaderView(rowView);
    ...

Se pueden utilizar componentes de peso ligero para cabeceras de fila y columna de un ScrollPane. El ScrollPane pone las cabeceras de fila y columna en su propio JViewPort. As�, cuando se desplaza horizontalmente, la cabecera de columnas la sigue, y cuando se desplaza verticalmente, la cabecera de filas tambi�n lo hace.

Como subclase de JComponent, Rule se dibuja a s� misma sobreescriendo el m�todo paintComponent. Un escurtinio cuidadoso del c�digo revela que se ha tomado un esfuerzo especial para dibujar s�lo dentro de los l�mites actuales. Nuestras cabeceras de fila y columna deben hacer los mismo para asegurarnos un desplazamiento r�pido.

Tambi�n podemos utilizar cualquier componente de peso ligero para las esquinas de un ScrollPanel. ScrollDemo.java ilustra esto poniendo un bot�n en la esquina superior izquierda, y objetos Corner personalizados en las esquinas superior derecha e inferior izquiedda. Aqu� est� el c�digo que crea los objetos Corner y llama a setCorner para situarlos.

// Create the corners
JPanel buttonCorner = new JPanel();
isMetric = new JToggleButton("cm", true);
isMetric.setFont(new Font("SansSerif", Font.PLAIN, 11));
isMetric.setMargin(new Insets(2,2,2,2));
isMetric.addItemListener(new UnitsListener());
buttonCorner.add(isMetric); //Use the default FlowLayout

./ Set the corners:
pictureScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, 
				buttonCorner);
pictureScrollPane.setCorner(JScrollPane.LOWER_LEFT_CORNER,
				new Corner());
pictureScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER,
				new Corner());

Recuerda que el tama�o de cada esquina est� determinado completamente por el tama�o de los lados que intersecciona all�. Debemos tener cuidado de que el objeto quepa en la esquina. La clase Corner lo hace dibujando dentro de sus l�mites, que son configurados por el ScrollPane. El bot�n fue configurado espec�ficamente para caber en la esquina establecida por las cabeceras.

Como podemos ver desde el c�digo, las constantes indican la posici�n de las esquinas. Esta figura muestra las constantes para cada posici�n.

Las constantes est�n definidas en el interface ScrollPaneConstants, que es implementado por JScrollPane.

.�Implementar un Cliente de Desplazamiento Seguro

Para personalizar la forma en la que el componente cliente interact�a con su ScrollPane, podemos hacer que el componente implemente el interface Scrollable. Implementando este interface, un cliente puede especificar tanto al tama�o del cuadro de visi�n que el ScrollPane utilizar� para verlo como la cantidad de desplazamiento para los diferentes controles de las barras de desplazamiento.

La siguiente figura muestra las tres �reas de un barra de desplazamiento: la barra, los botones y la pista.

Habr�s podido observar cuando manipulabas las barras de desplazamiento de ScrollDemo que pulsando los botones la imagen se desplaza un poco. Tambi�n podr�as haber observado que al pulsar sobre la pista el desplazamiento es mayor. M�s generalmente, el bot�n desplaza el �rea visible una unidad de incremento y la pista desplaza el �rea visible un bloque de incremento. El comportamiento que has visto en el ejemplo no es el comportamiento por defecto de un ScroolPane, pero si es especificado por el cliente en su implementaci�n del interface Scrollable.

El cliente del programa ScrollDemo es ScrollablePicture.java. ScrollablePicture es una subclase de JLabel que proporciona implementaciones para los cinco m�todos de Scrollable.

  • getScrollableBlockIncrement
  • getScrollableUnitIncrement
  • getPreferredViewportSize
  • getScrollableTracksViewportHeight
  • getScrollableTracksViewportWidth

ScrollablePicture implementa el interface Scrollable principalmente para afectar a los incrementos de unidad y de bloque. Sin embargo, debe proporcionar implementaciones para los cinco m�todos. Las implementaciones para los tres �ltimos son razonables por defecto.

El ScrollPane llama al m�todo getScrollableUnitIncrement del cliente siempre que el usuario pulse uno de los botones de las barras de desplazamiento. Este m�todo devuelve el n�mero de pixels a desplazar. Una implementaci�n obvia de este m�todo devuelve el n�mero de pixels entre marcas de las reglas de cabecera. Pero ScrollablePicture hace algo diferente: devuelve el valor requerido para posiconar la imagen en el l�mite de una marca. Aqu� est� la implementaci�n.

public int getScrollableUnitIncrement(Rectangle visibleRect,
				      int orientation,
				      int direction) {
    //get the current position
    int currentPosition = 0;
    if (orientation == SwingConstants.HORIZONTAL)
        currentPosition = visibleRect.x;
    else
        currentPosition = visibleRect.y;

    //return the number of pixels between currentPosition
    //and the nearest tick mark in the indicated direction
    if (direction < 0) {
        int newPosition = currentPosition -
			 (currentPosition / maxUnitIncrement) *
			  maxUnitIncrement;
        return (newPosition == 0) ? maxUnitIncrement : newPosition;
    } else {
        return ((currentPosition / maxUnitIncrement) + 1) * 
		 maxUnitIncrement - currentPosition;
    }
}

Si la imagen ya se encuentra en un marca, este m�todo devuelve el n�mero de pixels entre marcas. De otro modo devuelve el n�mero de pixels entre la posici�n actual y la marca m�s cercana.

De igual modo el ScrollPane llama al m�todo getScrollableBlockIncrement del cliente cada vez que el usuario pulsa sobre la pista de la barra de desplazamiento. Aqu� est� la implementaci�n que ScrollablePicture hace de este m�todo.

public int getScrollableBlockIncrement(Rectangle visibleRect,
				       int orientation,
				       int direction) {
    if (orientation == SwingConstants.HORIZONTAL)
        return visibleRect.width - maxUnitIncrement;
    else
        return visibleRect.height - maxUnitIncrement;
}

Este m�todo devuelve la altura del rect�ngulo visible menos una marca. Este comportamiento es t�pico. Un incremento de bloque deber�a permitir que el JViewpor deje un poco del �rea visible anterior por razones de contexto. Por ejemplo, un �rea de texto podr�a dejar una o dos l�neas y una tabla podr�a dejar una fila o una columna (dependiendo de la direcci�n de desplazamiento).

Puedes ver la tabla Implementar el Interface Scrollable para obtener m�s detalles sobre los m�todos definidos en Scrollable.

El paquete Swing proporciona estas clases de desplazamiento seguro.

.�El API de ScrollPane

Las siguiente tablas listan los m�todos y constructores m�s utilizados de JScrollPane. Otros m�todos �tiles son definidos por las clases JComponent y Component.

El API para utilizar ScroolPane se divide en estas categor�as:

.�Configurar el ScrollPane

M�todo Prop�sito
JScrollPane()

JScrollPane(Component)

JScrollPane(int, int)

JScrollPane(Component, int, int)

Crea un ScrollPanel El par�metro Component, cuando existe, selecciona el cliente. Los dos par�metros int, cuando existen, seleccionan los vigilantes de seguridad de las barras de desplazamiento vertical y horizontal (respectivamente).
void setViewportView(Component) Selecciona el cliente del ScrollPane.
void setVerticalScrollBarPolicy(int)

int getVerticalScrollBarPolicy()

Selecciona u obtiene el vigilante de desplazamiento vertical. ScrollPaneConstants define tres valores para especificar estos vigilantes: VERTICAL_SCROLL_BAR_AS_NEEDED (por defecto), VERTICAL_SCROLL_BAR_ALWAYS, y VERTICAL_SCROLL_BAR_NEVER.
void setHorizontalScrollBarPolicy(int)

int getHorizontalScrollBarPolicy()

Selecciona u obtiene el vigilante de desplazamiento horizontal. ScrollPaneConstants define tres valores para especificar estos vigilantes: HORIZONTAL_SCROLL_BAR_AS_NEEDED (por defecto), HORIZONTAL_SCROLL_BAR_ALWAYS, y HORIZONTAL_SCROLL_BAR_NEVER.
void setViewportBorder(Border)

Border getViewportBorder()

Selecciona u obtiene el borde alrededor del JViewport.

.�Decorar el ScrollPane

M�todo Prop�sito
void setColumnHeaderView(Component)

void setRowHeaderView(Component)

Selecciona la cabecera de fila o de columna para el ScrollPane.
void setCorner(Component, int)

Component getCorner(int)

Seleciona u obtiene la esquina especificada. El par�metro int indica qu� columna y debe ser una de las siguientes constantes definidas en ScrollPaneConstants: UPPER_LEFT_CORNER, UPPER_LEFT_CORNER, LOWER_LEFT_CORNER, y LOWER_LEFT_CORNER.

.�Implementar el Interface Scrollable

M�todo Prop�sito
int getScrollableUnitIncrement(Rectangle, int, int)

void getScrollableBlockIncrement(Rectangle, int, int)

Obtiene el incremento de unidad o de bloque en pixels. El par�metro Rectangle son los l�mites del �rea visible actualmente. El primer par�metro int es SwingConstants.HORIZONTAL o SwingConstants.VERTICAL dependiendo de la barra que haya pulsado el usuario. El segundo par�metro int indica la direcci�n del desplazamiento. Un valor menor que 0 indica arriba o izquierda. Una valor mayor que 0 indica abajo o derecha.
Dimension getPreferredScrollableViewportSize() Obtiene el tama�o preferido del JViewport. Esto permite al cliente influenciar en el tama�o del componente en el que va ser mostrado. Si este tama�o no es importante devuelve getPreferredSize.
boolean getScrollableTracksViewportWidth()

boolean getScrollableTracksViewportHeight()

Obtiene su el ScrollPane deber�a forzar al cliente a tener la misma anchura o altura que el JViewport. Devolver true por alguno de esto m�todos efectivamente desactiva el desplazamiento horizontal o vertival (respectivamente).

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR