Tutorial TextField

Tutorial de TextField



¿Cómo usar TextField?


Un campo de texto es un control básico que permite al usuario teclear una pequeña cantidad de texto y dispara un evento acción cuando el usuario indique que la entrada de texto se ha completado (normalmente pulsando Return). Generalmente se usa la clase JTextField para proporcionar campos de texto. Si necesitamos proporcionar un password field -- un campo de texto editable que no muestra los caracteres tecleados por el usuario -- utilizaremos la clase JPasswordField. Esta sección explica estos dos campos de texto.
Si queremos un campo de texto que también proporcione un menú de cadenas desde la que elegir una, podemos considerar la utilización de un combo box editable. Si necesitamos obtener más de una línea de texto desde el usuario deberíamos utilizar una de las glases que implementan text area para propósito general.
El Applet siguiente muestra un campo de texto básico y un área de texto. El campo de texto es editable y el áera de texto no lo es. Cuando el usuario pulse Return en el campo de texto, el campo dispara un action event. El applet reacciona al evento copiando el contenido del campo de texto en el área de texto y seleccionando todo el texto del campo de texto.












Esta es una imagen del GUI del applet. Para ejecutar el applet, pulsa sobre la imagen. El Applet aparecerá en una nueva ventana del navegador.
Puedes encontrar el programa fuente en TextDemo.java. Aquí está el código de TextDemo que crea el campo de texto del applet.
textField = new JTextField(20);
textField.addActionListener(this);
...
contentPane.add(textField);
El argumento entero pasado al constructor de JTextField, 20 en el ejemplo, indica el número de columnas del campo, que es usada junto con la métrica proporcionada por el font actual del campo, para calcular la anchura preferida por el campo. Como varios controladores de disposición ignoran los tamaños preferidos y como los márgenes, los bordes y otros factores afectan al tamaño del componente, toma este número como una aproximación, no un número absoluto.
Las siguientes líneas de código registran el applet como oyente de acción para el campo de texto y añade el campo de texto al panel de contenidos del applet. Aquí está el método actionPerformed que maneja los eventos action del campo de texto.
public void actionPerformed(ActionEvent evt) {
String text = textField.getText();
textArea.append(text + newline);
textField.selectAll();
}
Observa el uso del método getText de jTextField para recuperar el contenido actual del campo de texto. El texto devuelto por este método no incluye un carácter de nueva línea para la tecla Return que disparó el evento acción.
Este ejemplo ilustra usando un campo de texto básico para introducir datos textuales y realizar algunas tareas cuando el campo de teto dispara un evento acción. Otros programas, sin embargo, necesitan un comportamiento más avanzado. Una subclase de JTextComponent, JTextField puede ser configurada y personalizada. Un personalización común es proporcionar un campo de texto cuyos contenidos sean validados. Esta sección cubre los siguientes tópicos de los campos de texto avanzados. Para entender toda la información, necesitas haber comprendido el material presentado en Reglas Generales para el uso de Componentes.


Crear un TextField Validado

Muchos programas requieren que el usuario introduzca un dato textual de un cierto tipo o formato. Por ejemplo, un programa podría proporcionar un campo de texto para entrar una fecha, un número decimal, o un número de teléfono. Los contenidos de dichos campos como campos de texto deben ser validados antes de ser utilizados para cualquier propósito. Un campo de texto puede ser validado cuando se dispare el evento acción o el evento keystroke.
El dato en un campo validado-en-acción se chequea cada vez que el campo dispara un evento acción (cada vez que el usuario pulsa la tecla Return). Un campo validado-en-acción podría, en un momento dado, contener datos no válidos. Sin embargo, el dato será validado antes de ser utilizado. Para crear un campo validado-en-acción, necesitamos proporcionar un oyente acción para nuestro campo e implementa su método actionPerformed de la siguiente forma.
• Usa getText para obtener el contenido del campo de texto.
• Evalúa el valor devuelto por getText.
• Si el valor es válido, realiza cualquier tarea de cálculo que sea requerida. Si el campo es nulo, reporta el error y retorna sin realizar ninguna tarea de cálculo.
El dato en un campo validado-en-pulsación se chequea cada vez que el campo cambia. Un campo validado-en-pulsación nunca puede contener datos no válidos porque cada cambio (pulsación, cortar, copiar, etc.) hace que el dato no válido sea rechazado. Para crear un campo de texto validado-en-pulsación necesitamos proporcionar un documento personalizado para nuestro campo de texto. Si no estás familiarizado con los documentos, puedes ir a Trabajar con el Documento de un Componente de Texto.
Aviso: No use un oyente de documento para validación-por-pulsación. El momento en que un oyente de documento es notificado de un cambio, es demasiado tarde, el cambio ya ha tenido lugar. Puedes los dos últimos párrafos de Escuchar los Cambios en un Documento para más información
La aplicación mostrada en la siguiente figura tiene tres campos validados-por-pulsación. El usuario introduce información en los tres primeros campos de texto. Cada vez que el usuario teclea un carácter, el programa valida la entrada y actualiza el resultado del cuarto campo de texto.












El campo Years es un ejemplar de WholeNumberField.java, que es una subclase de JTextField. Sobrescribiendo el método createDefaultModel,WholeNumberField establece una subclases Document personalizada -- un ejemplar de WholeNumberDocument -- como documento para cada WholeNumberField creado.
protected Document createDefaultModel() {
return new WholeNumberDocument();
}
Aquí está la implementación de WholeNumberDocument.
protected class WholeNumberDocument extends PlainDocument {

public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {

char[] source = str.toCharArray();
char[] result = new char[source.length];
int j = 0;

for (int i = 0; i < result.length; i++) {
if (Character.isDigit(source[i]))
result[j++] = source[i];
else {
toolkit.beep();
System.err.println("insertString: " + source[i]);
}
}
super.insertString(offs, new String(result, 0, j), a);
}
}
Esta clase sobrescribe el método insertString el cual es llamado cada vez que un string o un carácter va a ser insertado en el documento. La implementación de WholeNumberDocument de insertString evalúa cada carácter a ser insertado dentro del campo de texto. Si el carácter es un dígito, el documento permite que sea insertado. De otro modo, el método pita e imprime un mensaje de error. Por lo tanto, WholeNumberDocument permite los números en el rango 0, 1, 2, ...
Un detalle de implementación interesante es que nuestra clase documento personalizada no tiene que sobrescribir el método remove. Este método es llamado cada vez que un carácter o grupos de caracteres es eliminado del campo de texto. Como eliminar un dígito de un entero no puede producir un resultado no válido, esta clase no presta atención a las eliminaciones.
Los otros dos campos de texto del ejemplo, así como el campo no editable Monthly Payment, son ejemplares de DecimalField.java, una subclase personalizada de JTextField. DecimalField usa un documento personalizado,FormattedDocument, que sólo permite que será introducidos los datos en un formato particular.
FormattedDocument no tiene conocimiento del formato real de su contenido. En su lugar FormattedDocument realza en un formato, una ejemplar de una subclase de Format, para aceptar o rechazar el cambio propuesto. El campo de texto que usa el FormattedDocument debe especificar el formato que se debe utilizar.
Los campos Loan Amount y Monthly Payment usan un objeto NumberFormat creado de esta forma
moneyFormat = NumberFormat.getNumberInstance();
El siguiente código crea el formato dle campo de texto APR.
percentFormat = NumberFormat.getNumberInstance();
percentFormat.setMinimumFractionDigits(3);
Como muestra el código, la misma clase (NumberFormat) puede soportar diferentes formatos. Además, Format y sus subclases son sensitivas a la localidad, por eso un campo decimal, puede hacerse para soportar formatos de otros países y regiones. Puedes referirte a Formateando ien la sección de Internacionalización para información más detallada sobre los formatos.
Aquí está la implementación que FormattedDocument hace de insertString.
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {

String currentText = getText(0, getLength());
String beforeOffset = currentText.substring(0, offs);
String afterOffset = currentText.substring(offs, currentText.length());
String proposedResult = beforeOffset + str + afterOffset;

try {
format.parseObject(proposedResult);
super.insertString(offs, str, a);
} catch (ParseException e) {
Toolkit.getDefaultToolkit().beep();
System.err.println("insertString: could not parse: "
+ proposedResult);
}
}
El método usa el formato para analizar el resultado de la inserción propuesta. Si el resultado se formatea adecuadamente, el método llamada al método insert de su superclase para hacer la inserción. Si el resultado no se formatea de la forma adecuada, el ordenador pita.
Además de sobrescribir el método insertString, FormattedDocument también sobrescribe el método remove.
public void remove(int offs, int len) throws BadLocationException {
String currentText = getText(0, getLength());
String beforeOffset = currentText.substring(0, offs);
String afterOffset = currentText.substring(len + offs,
currentText.length());
String proposedResult = beforeOffset + afterOffset;

try {
if (proposedResult.length() != 0)
format.parseObject(proposedResult);
super.remove(offs, len);
} catch (ParseException e) {
Toolkit.getDefaultToolkit().beep();
System.err.println("remove: could not parse: " + proposedResult);
}
}
La implementación que FormattedDocument hace del método remove es similar a su implementación del método insertString. El formato analiza el resultado del cambio propuesto, y realiza la eliminación o no, dependiendo de si el resultado es válido.
Nota: La solución propuesta en este ejemplo no es una solución general para todos los tipos de formatos. Algunos formatos pueden ser validados-por-pulsación simplemente llamando al método parseObject. Aquí tenemos un ejemplo que te puede ayudar a entender por qué. Supongamos que tenemos un campo de texto que contiene la fecha "Mayo 25, 1996" y queremos cambiarlo a "June 25, 1996". Deberías selección "Mayo" y empezar a teclear "June". Tan pronto como teclearas la "J", el campo no analizaría porque "J 25, 1996" no es un dato válido, aunque si es un cambio válido. Hay un número de posibles soluciones para fechas y otros tipos de datos cuando un cambio incompleto puede crear un resultado no válido. Se puede cambiar la validación-por-pulsación para que rechace definitivamente todos los cambios no válido (teclear "X" en un campo de fecha, por ejemplo) pero permitir todos los cambios válidos posibles. O cambiar a un campo validado-en-acción.
Usar un Oyente de Documento en un Campo de Texto
Entonces, si no podemos utilizar un oyente de documento para validación de campos, ¿para qué podemos utilizarlo? Se usa para oír, pero no interferir, con los cambios del contenido del documento. La calculadora de pagos usa el siguiente oyente de documento para actualizar el pago mensual después de cada cambio.
class MyDocumentListener implements DocumentListener {
public void insertUpdate(DocumentEvent e) {
update(e);
}
public void removeUpdate(DocumentEvent e) {
update(e);
}
public void changedUpdate(DocumentEvent e) {
// we won't ever get this with a PlainDocument
}
private void update(DocumentEvent e) {
Document whatsup = e.getDocument();
if (whatsup.getProperty("name").equals("amount"))
amount = amountField.getValue();
else if (whatsup.getProperty("name").equals("rate"))
rate = rateField.getValue();
else if (whatsup.getProperty("name").equals("numPeriods"))
numPeriods = numPeriodsField.getValue();
payment = computePayment(amount, rate, numPeriods);
paymentField.setValue(payment);
}
}
Este es un uso apropiado para el uso de un oyente de documento.
Para información general sobre oyentes de documento, puedes ir a la página Cómo Escribir un Oyente de Documento.

Distribuir Parejas Etiqueta/Campo de Texto


Esta sección describe cómo se han alineado las etiquetas y los campos de texto del ejemplo y requiere algún conocimiento de controladores de distribución.
Las líneas de parejas de etiquetas y campos de texto como los encontradas en la calculadora de pagos son bastante comunes en los paneles que implementan formularios. Aquí está el código que distribuye las etiquetas y los campos de texto.
. . .
//distribuye las etiquetas sobre el panel
JPanel labelPane = new JPanel();
labelPane.setLayout(new GridLayout(0, 1));
labelPane.add(amountLabel);
labelPane.add(rateLabel);
labelPane.add(numPeriodsLabel);
labelPane.add(paymentLabel);

//distribuye los campos de texto sobre el panel
JPanel fieldPane = new JPanel();
fieldPane.setLayout(new GridLayout(0, 1));
fieldPane.add(amountField);
fieldPane.add(rateField);
fieldPane.add(numPeriodsField);
fieldPane.add(paymentField);

//Pone los paneles sobre otro panel, las etiquetas a la izquierda,
//los campos de texto a al derecha
JPanel contentPane = new JPanel();
contentPane.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
contentPane.setLayout(new BorderLayout());
contentPane.add(labelPane, BorderLayout.CENTER);
contentPane.add(fieldPane, BorderLayout.EAST);

setContentPane(contentPane);
. . .
Podrías haberte sorprendido de encontrar que las etiquetas fueran distribuidas sin referencia a los campos de texto, y de hecho, están en un panel diferente, sólo alineados correctamente con ellos. Esto es un efecto colateral de los controladores de distribución usados por el programa.














Como muestra el diagrama, el programa usa dos controladores GridLayout, uno para la columna de etiquetas y otro para la columna de campos de texto. GridLayout garantiza que todos sus componentes sean del mismo tamaño, por eso todos los campos de texto tienen la mista altura y todas las etiquetas tienen la misma altura.
Para conseguir que las etiquetas y los campos de texto estén alineados, el programa usa un tercer controlador, un BorderLayout. con sólo dos componentes, en la izquierda y en el centro, BorderLayout garantiza que las columnas son de la misma altura. Y así se alinean las etiquetas y los campos de texto.
Otra forma de conseguir alinear las etiquetas y los campos de texto es utilizar el más complejo de los controladores de distribución del AWT, el GridBagLayout.


Proporcionar un Campo de Password

Swing proporciona la clase JPasswordField, una subclase de JTextField, que se usa en lugar de un campo de texto cuando el texto introducido por el usuario es una password. Por razones de seguridad, un campo de password no muestra los caracteres que teclea el usuario. En su lugar el campo muestra otro carácter, como un asterisco "*".
El ejemplo PasswordDemo descrito en Usar la Clase SwingWorker usa un JPasswordField. El programa trae una pequeña ventana para pedirle al usuario que teclee una password.















Aquí está el código de PasswordDemo que crea y configura el campo password.
JPasswordField password = new JPasswordField(10);
password.setEchoChar('#');

password.addActionListener(showSwingWorkerDialog);
Como con los campos de texto, el argumento pasado al constructor JPasswordField indica que el campo deberá tener 10 columnas de ancho. Por defecto, un campo password muestra asteriscos "*" por cada carácter tecleado. La llamada a setEchoChar lo cambia por el signo de almohadilla "#". finalmente, el código añade una oyente de acción al campo password. El método actionPerformed del oyente de actual obtiene la password tecleada por el usuario y la verifica con este código.
public void actionPerformed(ActionEvent e) {
JPasswordField input = (JPasswordField)e.getSource();
char[] password = input.getPassword();
if (isPasswordCorrect(password))
JOptionPane.showMessageDialog(f, worker.get());
else
JOptionPane.showMessageDialog(f,
new JLabel("Invalid password."));
}
Este método utiliza el método getPassword para obtener el contenido del campo. Esto es por lo que getPassword devuelve un array de caracteres. La información de passwords no debería ser almacenada no pasada en strings, porque no son seguras.
Un programa que usa un campo de password tipicamente valida la password antes de completar cualquier acción que requiera la password. Este programa llama a un método personalizado, isPasswordCorrect, que compara el valor devuelto por getPassword con el valor almacenado en un array de caracteres.




El API de Text Field

Las siguientes tablas listan los constructores y métodos más comúnmente utilizados de JTextField. Otros métodos a los que se podría llamar están definidos en las clases JComponent y Component. Estos incluyen los métodos setForeground, setBackground, y setFont.
Además, podrías querer llamar a algunos de los métodos definidos en la clase padre de JTextField, JTextComponent.
El API para usar campos de texto se divide en tres categorías.
Seleccionar u Obtener el Contenido de un Campo de Texto
Método o Constructor Propósito
JTextField()
JTextField(String)
JTextField(String, int)
JTextField(int)
JTextField(Document, String, int) Crea un ejemplar de JTextField, inicializando su contenido al texto especificado. El argumento int seleccionar el número de columnas. Esto se utiliza para calibrar la anchura preferida del componente y podría no ser el número de columnas realmente mostradas.
void setText(String)
String getText() Selección u obtiene el texto mostrado por el campo de texto.












Ajuste Fino de la Apariencia de un Campo de Texto


Método o Constructor Propósito
void setEditable(boolean)
boolean isEditable() Selecciona u obtiene si el usuario puede editar el texto del campo del texto.
void setForeground(Color)
Color getForeground() Selecciona u obtiene el color del texto en el campo de texto.
void setBackground(Color);
Color getBackground() Selecciona u obtiene el color del fondo del campo de texto
void setFont(Font);
Font getFont() Selecciona u obtiene la fuente utilizada por el campo de texto.
void setColumns(int);
int getColumns() Selecciona u obtiene el número de columnas mostradas por el campo de texto.
int getColumnWidth() Obtiene la anchura de las columnas del campo de texto. Este valor es establecido implícitamente por la fuente usada.
void setHorizontalAlignment(int);
int getHorizontalAlignment() Selecciona u obtiene cómo se alinea el texto horizontalmente dentro de su área. Se puede utilizar JTextField.LEFT, JTextField.CENTER, y JTextField.LEFT como argumentos.
Implementar la Funcionalidad del Campo de Texto
Método o Constructor Propósito
void addActionListener(ActionListener)
void removeActionListener(ActionListener) Añade o elimina un oyente de action.
Document createDefaultModel() Sobrescribe este método para proporcionar un documento personalizado.

Tutorial ScrollPane

Tutorial ScrollPane

¿Cómo Usar ScrollPane?
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 objeto 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.
Bueno para dejar en claro lo que es ScrollPane aquí tienes un código para que veas su estructuración:
1.
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.
• listas
• tablas
• componentes de texto
• árboles



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) Selecciona 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


Esto es un ejemplo d usar el JscrollPane. Para ello vamos a meter una imagen (puede ser un fichero.gif,jpg o .png en versiones modernas de java ) dentro de un Jlabel y esta a su vez dentro de un JscrollPane. Todo ello dentro de un Jframe para visualizarlo.
Tal cual esta hecho el código , el Jframe saldrá con el tamaño necesario para ver la imagen completa (la línea que pone ventana.pack() hace eso). Para que aparezcan las barras de scroll hay que redimensionar la ventana, haciéndola mas pequeña que la imagen. También, en el código , se podría usar el método setVerticalScrollBarPolicy(JscrollPane.VERTICAL_SCROLLBAR_ALWAYS ) de JscrollPane para obligar a que salga siempre la barra vertical. Hay un método similar para la horizontal.
El “truco” del JscrollPane consiste en llamar al método setViewPortview (Component), en vez de al método add().
Aquí tienes un ejemplo que se puede compilar es sumamente sencillo:
/*
* PruebaJScrollPane.java
*
* Created on 15 de abril de 2005, 17:26
*/

package chuidiang.ejemplos.JScrollPane;

import javax.swing.*;
/**
* @author Chuidiang
*
* Ejemplo de uso del JScrollPane. Se mete dentro un JLabel con una imagen.
*/
public class PruebaJScrollPane {

/** Creates a new instance of PruebaJScrollPane */
public PruebaJScrollPane() {

// La ventana
JFrame ventana = new JFrame("Imagen");

// El panel de scroll
JScrollPane scroll = new JScrollPane();

// La etiqueta.
JLabel etiqueta = new JLabel();

// Se carga la imagen, con path absoluto para evitar problemas y debe
// ser un gif.
Icon imagen = new ImageIcon (
"d:/users/javier/paginas_web/chuidiang/iconos/pizarra.gif");

// Se mete la imagen en el label
etiqueta.setIcon (imagen);

// Se mete el scroll en la ventana
ventana.getContentPane().add(scroll);

// Se mete el label en el scroll
scroll.setViewportView(etiqueta);

// Y se visualiza todo.
ventana.pack();
ventana.setVisible(true);
}

/**
* Programa principal. Instancia un PruebaJScrollPane
* @param args the command line arguments
*/
public static void main(String[] args) {
new PruebaJScrollPane();
}

}

JRadioButton y JMenu TUTORIAL

























Tutorial de JScrollPane

Tutorial ScrollPane

¿Cómo Usar ScrollPane?
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 objeto 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.
Bueno para dejar en claro lo que es ScrollPane aquí tienes un código para que veas su estructuración:
1.
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.
• listas
• tablas
• componentes de texto
• árboles



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) Selecciona 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


Esto es un ejemplo d usar el JscrollPane. Para ello vamos a meter una imagen (puede ser un fichero.gif,jpg o .png en versiones modernas de java ) dentro de un Jlabel y esta a su vez dentro de un JscrollPane. Todo ello dentro de un Jframe para visualizarlo.
Tal cual esta hecho el código , el Jframe saldrá con el tamaño necesario para ver la imagen completa (la línea que pone ventana.pack() hace eso). Para que aparezcan las barras de scroll hay que redimensionar la ventana, haciéndola mas pequeña que la imagen. También, en el código , se podría usar el método setVerticalScrollBarPolicy(JscrollPane.VERTICAL_SCROLLBAR_ALWAYS ) de JscrollPane para obligar a que salga siempre la barra vertical. Hay un método similar para la horizontal.
El “truco” del JscrollPane consiste en llamar al método setViewPortview (Component), en vez de al método add().
Aquí tienes un ejemplo que se puede compilar es sumamente sencillo:
/*
* PruebaJScrollPane.java
*
* Created on 15 de abril de 2005, 17:26
*/

package chuidiang.ejemplos.JScrollPane;

import javax.swing.*;
/**
* @author Chuidiang
*
* Ejemplo de uso del JScrollPane. Se mete dentro un JLabel con una imagen.
*/
public class PruebaJScrollPane {

/** Creates a new instance of PruebaJScrollPane */
public PruebaJScrollPane() {

// La ventana
JFrame ventana = new JFrame("Imagen");

// El panel de scroll
JScrollPane scroll = new JScrollPane();

// La etiqueta.
JLabel etiqueta = new JLabel();

// Se carga la imagen, con path absoluto para evitar problemas y debe
// ser un gif.
Icon imagen = new ImageIcon (
"d:/users/javier/paginas_web/chuidiang/iconos/pizarra.gif");

// Se mete la imagen en el label
etiqueta.setIcon (imagen);

// Se mete el scroll en la ventana
ventana.getContentPane().add(scroll);

// Se mete el label en el scroll
scroll.setViewportView(etiqueta);

// Y se visualiza todo.
ventana.pack();
ventana.setVisible(true);
}

/**
* Programa principal. Instancia un PruebaJScrollPane
* @param args the command line arguments
*/
public static void main(String[] args) {
new PruebaJScrollPane();
}

}

Como utiliza JToolBar en Java

Nivel de dificultad: Básico intermedio
Conocimiento requerido: Solo saber como hacer un ventana básica (JFrame) y/o botones (JButton).


¿Para que sirve JToolBar?


Esta clase implemente una barra de herramientas, formada normalmente por botones o controles que incluyen iconos y que aparecen organizados como una fila o una columna dependiendo de la zona de la pantalla donde se coloque.





import java.lang.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class EjemploJToolbar {

public static void main(String[] args){
// area de definicion de propiedades de el objeto
JFrame ventana = new JFrame();
ventana.setTitle("Ejemplo de JToolBar");
ventana.setDefaultCloseOperation(ventana.EXIT_ON_CLOSE);
ventana.setBounds(200,250,200,70);

// llamada JToolBar
JToolBar barra = new JToolBar("barra");

//creación de botones
JButton copiar = new JButton("Copiar");
JButton cortar = new JButton("Cortar");
JButton pegar = new JButton("Pegar");

//cargando toolbar panel con sus componentes

barra.add(copiar);
barra.add(cortar);
barra.add(pegar);

// cargando la ventana con el toolbar

ventana.getContentPane().add(barra);
ventana.setVisible(true);
ventana.setResizable(false);

}
}

También se puede considerar utilizar las siguientes opciones para JToolbar:


barra.addSeparator(); //añade un separador

barra.setFloatable(false); //impide que se pueda mover de su sitio

barra.setOrientation(JToolBar.VERTICAL); //pone la orientación vertical



Ejercicio de JList junto a JToolBar propuesto: descargar aquí

Tutorial JList


TUTORIAL JAVA: JPasswordField y JInternalFRame