JScrollPane

From ChuWiki
Jump to navigation Jump to search


Poner un componenete en el JScrollPane[edit]

Para ponerle barras de scroll a un componente grande, usamos el JScrollPane. El componente puede meterse o bien en el contructor, o bien con el método setViewportView(). Es incorrecto añadirlo con el add(), ya que no funciona.

JTextArea textArea = new JTextArea (25,80);
JScrollPane scroll = new JScrollPane(textArea);

o bien

JTextArea textArea = new JTextArea (25,80);
JScrollPane scroll = new JScrollPane();
scroll.setViewportView(textArea);

A continuación tienes un ejemplo completo de una ventana con un JTextArea dentro de un JScrollPane

package com.chuidiang.ejemplos.scroll_pane_text_area;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

/**
 * Ejemplo de JTextArea metido en un JScrollPane.
 * 
 * @author Chuidiang
 * 
 */
public class EjemploScrollPaneTextArea {

    private static final int NUMERO_COLUMNAS = 80;
    private static final int NUMERO_FILAS = 25;

    public static void main(String[] args) {
        new EjemploScrollPaneTextArea();
    }

    private final JFrame ventana;
    private final JTextArea textArea;
    private final JScrollPane scrollPane;

    /** Crea y visualiza la ventana de ejemplo */
    public EjemploScrollPaneTextArea() {
        ventana = new JFrame("Ejemplo de JTextArea en JScrollPane");
        textArea = new JTextArea(NUMERO_FILAS, NUMERO_COLUMNAS);
        scrollPane = new JScrollPane(textArea);

        ventana.getContentPane().add(scrollPane);
        ventana.pack();
        ventana.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        ventana.setVisible(true);
    }
}


Hacer que la barra del JScrollPane se desplace automáticamente[edit]

Según vamos desde código añadiendo texto al JTextArea, la barra de scroll se queda arriba y siempre nos muestra las primeras líneas. Si queremos que se vaya desplazando automáticamente, no he encontrado ningún método sencillo y maravilloso que lo haga. Sin embargo, si podemos hacerlo con unas cuentas y varios métodos.

Del JScrollPane podemos obtener el JViewport. Este sí tiene un método setViewPosition() en el que decimos qué punto queremos que esté visible.

¿Qué punto queremos visible?. Una opción es darle directamente el punto de más abajo del JTextArea, así

Dimension tamanhoTextArea = textArea.getSize();
Point p = new Point(
   0,
   tamanhoTextArea.height);
scroll.getViewport().setViewPosition(p);

Para que esto funciona es importante que el JScrollPane ya esté visible, realmente visible. No vale un setVisible(true). Hay que hacer el setVisible(true) y esperar a que a java le de tiempo a pintar realmente la ventana en la pantalla. Si hacemos estas operaciones mientras no es visible, a mi no me ha funcionado.

Para hacer esta espera, podemos meter todo esto en un SwingUtilites.invokeLater(), que garantiza que el código se ejecuta en el hilo de repintado de ventanas y, por tanto, queda encolado detrás de la llamada al setVisible(true).

SwingUtilities.invokeLater(new Runnable() {
   public void run() {
      for (int i=0;i<100;i++)
      {
         textArea.append("texto "+i+"\n");
         Dimension tamanhoTextArea = textArea.getSize();
         Point p = new Point(
            0,
            tamanhoTextArea.height
         );
         scroll.getViewport().setViewPosition(p);
      }
   }
});

Aquí he puesto ya un bucle que va añadiendo líneas y en cada línea se hace que se mueva el scroll con el mecanismo explicado. De todas formas, es sólo un ejemplo. Si se van a añadir cien líneas como en el ejemplo todas seguidas, no tiene mucho sentido desplazar la barra de scroll en cada línea. Lo suyo sería hacerlo al final, cuando ya hemos añadido todo.