d .

-&y;?%-,
t..

Indice

. Introduccion

. ............................................................................................. 23
............................................................................................ 29

Contenido del libro ......................................................................................... 24 Requerimientos ............................................................................................. 25 Otros recursos ................................................................................................ 26

1 Java básico

.

Todo sobre Java ........................................................................................... 30 Orígenes del lenguaje Java ....................................................................... 32 Todo sobre bytecodes ............................................................................... 32 La seguridad del lenguaje Java .................................................................33 Programas Java .......................................................................................34 ¿Es Java 2 o Java 1.2? .............................................................................. 37 Adquirir e instalar Java .................................................................................. 37 ¿Qué ocurre con CLASSPATH? ................................................................ 38 ¿Cuáles son las novedades de Java 1.1? ......................................................... 39 ¿Qué está censurado en Java 1.1 ? ................................................................... 41 ¿Cuáles son las novedades de Java 2? ............................................................. 41 ¿Qué se censuró en Java 2? ........................................................................... 44 Escribir código: creación de archivos de código ............................................. 44

Escribir código: conocer las palabras reservadas de Java................................ 45 Escribir código: crear una aplicación .............................................................. 48 public class app ...................................................................................... 49 public static void main[String[] args) ........................................................ 50 System.out.println("iHola desde Java!"); ................................................... 51 Compilación ................................................................................................... 51 Compilación: utilizando opciones en la línea de comandos ............................ 52 Opciones de compilación cruzada .............................................................. 55 Compilación: revisión de los métodos censurados ..........................................55 Ejecución del código ...................................................................................... 56 Ejecución de código: utilizar las opciones de la línea de comandos ...............59 Conocimientos básicos: comentar el código ................................................... 61 Conocimientos básicos: importando paquetes y clases Java ........................... 64 Conocimientos básicos: buscar clases Java con CLASSPATH ...................... 66 Crear applets ................................................................................................... 69 Ejecutarapplets ...............................................................................................71 Crear aplicaciones ventana.............................................................................. 72 Ejecutar aplicaciones ventana ......................................................................... 73 Diseño de programas Java ..............................................................................74 Rendimiento .............................................................................................. 75 Mantenimiento ........................................................................................... 75 Extensibilidad .......................................................................................... 76 Disponibilidad ........................................................................................... 76 Distribución del programa Java ...................................................................... 77

2 Variables. arrays y cadenas

.

..................................................................79

Variables ....................................................................................................79 Tipos de datos .................................................................................................81 Arrays ............................................................................................................. 82 Cadenas........................................................................................................... 85 ¿De qué tipo de datos disponemos? ................................................................ 87 Creación de literales enteros ...........................................................................88 Creación de literales en coma flotante ...........................................................89 . Creacion de literales booleanos.......................................................................91 Creación de literales carácter .......................................................................... 91 Creación de literales tipo cadena ....................................................................93 Declaración de variables de tipo entero ....................................................... 93

.

Declaración de variables de tipo coma flotante ............................................... 94 Declaración de variables de tipo carácter ....................................................... 95 Declaración de variables de tipo booleano...................................................... 96 Inicialización de variables............................................................................... 98 . Inicializaclondinámica ................................................................................... 99 Conversión de tipos de datos ........................................................................ 100 Conversionesautomáticas........................................................................100 Casting a nuevos tipos de datos ...............................................................101 Declaración de arrays unidimensionales ....................................................... 103 Creación de arrays unidimensionales............................................................ 104 Inicialización de arrays unidimensionales .....................................................105 Declaración de arrays multidimensionales.................................................... 105 Creación de arrays multidimensionales.........................................................106 Inicialización de arrays multidimensionales .................................................108 Creación de arrays multidimensionales......................................................... 109 Longitud de un array .....................................................................................110 La clase String ...........................................................................................110 Creacion de cadenas...................................................................................... 117 Obtención de la longitud de la cadena .........................................................119 Concatenación de cadenas ............................................................................ 120 Obtención de caracteres y substring ..............................................................121 Búsqueda y reemplazamientos en cadenas .................................................... 122 Cambio de mayúsculas a minúsculas (o viceversa) en cadenas .................... 123 Formateo de números en cadenas ............................................................... 124 La clase StringBufferr................................................................................... 124 .. de StringBuffers............................................................................. 125 Creacion Obtención y establecimiento de longitudes y capacidades de StringBuffer .. 129 Establecer caracteres en StringBuffers..........................................................130 Añadir e insertar utilizando StringBuffers ....................................................130 Borrar texto en StringBuffers........................................................................ 131 Reemplazar texto en StringBuffers ............................................................... 132

.

..

3 Operadores. condicionales y bucles

.

...................................................135

Operadores ................................................................................................135 Condicionales ........................................................................................... 137 Bucles ....................................................................................................... 139 Precedencia de operadores ............................................................................ 140

Incremento y decremento: ++ y................................................................... 141 NOT unario:.y ! ......................................................................................... 143 Multiplicación y división: * y / ..................................................................... 144 Módulo: % .................................................................................................... 145 Suma y resta: + y ......................................................................................... 145 Operadores de desplazamiento: » >>> y <c.............................................. 146 , Operadores de relación: >. >=. <. <=. == y != .............................................. 147 Operadores lógicos a nivel de bit AND. Xor y OR: &. A y I ......................... 148 && y II lógicos .............................................................................................. 151 El operador If-Then-Else: ?: .......................................................................... 153 Operadores de asignación: = y [operador]= .................................................. 154 Utilización de la clase Math ..........................................................................156 Comparación de cadenas............................................................................... 158 La sentencia if ............................................................................................... 159 La sentencia else ........................................................................................... 160 If anidados ............................................................................................... 161 Escalas if-else .......................................................................................... 161 La sentencia switch ....................................................................................... 162 Bucle while .................. ................................................................................ 164 Bucle do-while.............................................................................................. 167 Bucle for ...................................................................................................... 168 Bucles anidados ............................................................................................ 171 Sentenciabreak ............................................................................................. 172 Sentenciacontinue ....................................................................................... 174

4 Programación orientada a objetos

.

.................................................... 177

Clases ......................................................................................................... 179 Objetos .........................................................................................................179 Miembros de datos........................................................................................ 180 Métodos .......................................................................................................181 Herencia........................................................................................................ 182 . Declaración y creacion de objetos................................................................. 182 Declarar y definir clases ................................................................................186 Crear variables de instancia ..........................................................................188 Acceso a variables ........................................................................................ 190 Crear variables de clase ................................................................................ 191 Crear métodos ............................................................................................... 193

.

Establecer el acceso a los métodos................................................................ 195 Pasar parámetros a los métodos .................................................................... 196 Argumentos de la línea de comandos pasados a main .................................. 198 Devolver valores desde los métodos ............................................................. 199 Crear métodos de clase ................................................................................. 201 Crear métodos de acceso a datos ...................................................................202 Crear constructores ....................................................................................... 204 Pasar parámetros a constructores ............................................................... 205 Un ejemplo completo de clase ..................................................................... 205 Comprender el alcance de las variables ....................................................... 207 209 Recursividad ............................................................................................ Colección garbage y gestión de memoria ..................................................... 210 212 Evitar las referencias circulares ................................................................ Colección garbage y el método finalize ....................................................... 213 Sobrecarga de métodos ............................................................................... 214 Sobrecarga de constructores ......................................................................... 215 Pasar objetos a métodos ............................................................................... 217 Pasar arrays a métodos ..................................................................................219 220 Usar la palabra clave this ............................................................................ Devolver objetos desde métodos ................................................................221 Devolver arrays desde métodos .................................................................. 222

5 Herencia. clases internas e interfaces

.

................................................225

¿Por qué la herencia? .................................................................................... 226 ¿Por qué las interfaces? ................................................................................. 227 ¿Por qué las clases internas? ......................................................................... 228 229 Crear una subclase ...................................................................................... Especificadores de acceso y herencia ............................................................ 231 Llamar a los constructores de la superclase .................................................. 234 Crear multiniveles de herencia .................................................................... 237 Gestionar multiniveles de constructores ....................................................... 239 Sobrescritura de métodos .............................................................................. 241 Acceso a los miembros sobrescritos ............................................................. 242 Usar variables de superclase con objetos de subclases .................................. 244 Dispatching dinámico de métodos (Polimorfismo en tiempo de ejecución) . 246 Crear clases abstractas ................................................................................ 249

Abandonar la sobrescritura con final............................................................. 251 Abandonar la herencia con final .................................................................... 252 Crear constantes con final ............................................................................. 253 Relación es-a frente a tiene-a ........................................................................ 253 La clase Object de Java ................................................................................. 255 Usar interfaces para herencia múltiple .......................................................... 258 Crear clases internas .....................................................................................261 Crear clases internas anónimas ..................................................................... 262

6 AWT: Applets. aplicaciones y gestión de eventos

.

.............................. 265

Abstract Windowing Toolkit ..................................................................... 266 Applets.......................................................................................................... 267 Aplicaciones ............................................................................................... 269 Usar Abstract Windowing Toolkit ................................................................ 270 Crear Applets ................................................................................................ 284 Usar la etiqueta HTML <APPLET> .............................................................287 Gestionar browsers no Java ......................................................................... 290 Introducir etiquetas <APPLET> en el código ............................................... 290 Usar los métodos init. start. stop. destroy. paint y update ............................. 291 Dibujar gráficos en applets ......................................................................... 293 Usar el plug-in de Java del browser .............................................................. 294 Leer parámetros en applets ........................................................................... 295 Usar las consolas de Java en los browsers ................................................... 297 Añadir controles a las applets: Campos de texto ........................................... 297 Añadir controles a las applets: botones .........................................................300 Gestión de eventos ........................................................................................ 300 Gestión de eventos estándar ...................................................................302 Uso de clases delegadas ..........................................................................304 Uso de los comandos de acción ............................................................... 306 La forma antigua de gestionar eventos ....................................................307 Extender componentes .............................................................................. 307 Usar las clases adaptador .............................................................................. 309 Usar clases adaptador internas anónimas ...................................................... 311 . Crear ventanas de aplicacion......................................................................... 312 Salir de una aplicación al cerrar su ventana ................................................. 316 Aplicaciones que se pueden ejecutar como applets ....................................... 317

.

7 AWT: Cuadros de texto. botones. casillas de activación y plantillas

.

........................................................................................... 321

Cuadros de texto ........................................................................................... 321 Botones ....................................................................................................... 322 Casillas de activación.................................................................................... 322 Botones de opción ........................................................................................322 323 Plantillas .................................~................................................................... .................................................................................... 324 Usar cuadros de texto Usar etiquetas ................................................................................................ 327 329 Usar botones ................................................................................................. ............................................................................334 Usar casillas de activación Usar botones de opción .................................................................................339 Esquemas de flujo (flow layout) ................................................................... 341 Grid layouts ..................................................................................................345 Usar paneles ..................................................................................................349 351 Border Layout ............................................................................................ Card Layouts................................................................................................. 355 Grid bag layouts............................................................................................ 358 Usar intercalados y rellenos ........................................................................365 Crear el propio gestor de esquemas .............................................................367

8 AWT: Listas. cuadros de lista. áreas de texto. barras y cuadros de desplazamiento

.

............................................................. 371

Listas ........................................................................................................ 371 Cuadros de lista desplegables ....................................................................... 372 Areas de texto ............................................................................................ 372 Barras de desplazamiento .............................................................................. 373 Paneles de desplazamiento............................................................................373 Usar las áreas de texto .................................................................................. 374 377 Reemplazar texto en áreas de texto ............................................................... Buscar y seleccionar texto en áreas de texto .................................................379 Usar listas .................................................................................................... 381 Usar listas de selección múltiple................................................................... 388 Usar cuadros de lista desplegables ................................................................ 391 Usar barras de desplazamiento......................................................................396

Barras de desplazamiento y border layouts ................................................... 404 Usar cuadros de desplazamiento .................................................................. 407

9. AWT: Gráficos. imágenes. texto y fuentes ........................................ 415
Gráficos .....................................................................................................415 Imágenes ....................................................................................................... 415 416 Texto y fuentes ............................................................................................. Teclado y ratón ............................................................................................ 416 416 Usar el ratón ................................................................................................ 420 Usar el teclado ............................................................................................ 425 Usar fuentes .................................................................................................. Usar imágenes ............................................................................................. 434 Redimensionar imágenes .............................................................................. 437 Dibujar gráficos ........................................................................................ 439 Dibujar rectas ........................................................................................ 447 Dibujar óvalos.......................................................................................... 447 Dibujar rectángulos .................................................................................. 447 Dibujar rectángulos redondeados ............................................................ 448 Dibujo libre.............................................................................................. 449 Dibujar arcos .......................................................................................... 450 Dibujar polígonos ................................................................................. 450 Establecer los modos de dibujo .............................................................. 450 Seleccionar colores ..................................................................................... 450 Usarcanvases ...............................................................................................454 Usar la interfaz ImageObserver ..................................................................... 456 Usar la clase MediaTracker........................................................................... 458 Trabajar pixel por pixel: Las clases PixelGrabber y MemoryImageSource .. 462 Dar brillo a las imágenes ............................................................................. 466 Convertir imágenes a escala de grises ........................................................... 467 Realzar imágenes .......................................................................................... 469

10. AWT: Ventanas. menús y cuadros de diálogo 473 Ventanas ..................................................................................................... 473 Menús ........................................................................................................ 474 Cuadros de diálogo ....................................................................................... 475 Crear ventanas Frame ................................................................................... 475
Mostrar y ocultar ventanas ............................................................................ 477

.................................

.

Gestionar eventos de ventana ........................................................................ 480 Ocultar ventanas automáticamente al cerrarlas ............................................ 4 8 3 Usar la clase Window ................................................................................ 484 Crear rnenús.................................................................................................. 489 Crear un objeto MenuBar ............................................................................. 491 Crear objetos Menu ....................................................................................... 493 Crear objetos MenuItem ............................................................................... 495 Gestionar los eventos de menú' ..................................................................... 498 Más opciones de menú .................................................................................. 500 Añadir separadores de menú ..................................................................... 503 Deshabilitar elementos de menú ................................................................. 503 Añadir marcas de activación a menús .........................................................505 Crear submenús ..........................................................................................508 Menús emergentes ...................................................................................510 Cuadros de diálogo ................................................................................... 512 Cuadros de diálogo de archivos ................................................................... 518

11 Swing: Applets. aplicaciones y cambios de apariencia

.

...................523

Clases Foundation de Java .......................................................................... 523 Swing ....................................................................................................... 524 Componentes peso pesado contra peso ligero ............................................... 527 CaracterísticasSwing .................................................................................... 528 Utilizar paneles en la programación de gráficos ........................................... 529 ArquitecturaModelo-Vista-Controlador....................................................... 530 Trabajar con Swing .......................................................................................531 Preparar para crear un applet Swing .............................................................536 Comprender los root panes .........................................................................539 542 Comprender layered panes ........................................................................... Comprender los content panes .....................................................................545 Crear un applet Swing ................................................................................. 545 Pintar en Swing frente a AWT ................................................................545 Visualizar controles en Swing frente a AWT .........................................546 Usar la clase JPanel ....................................................................................546 Crear una aplicación Swing .........................................................................549 Cerrar ventanas JFrame ................................................................................. 553 Seleccionar los bordes del componente .......................................................555

Usar Insets ............................................................................................... 555 Establecer la apariencia................................................................................. 560 Establecer los componentes para la apariencia.............................................. 565

12 Swing: Cuadros de texto. botones y casillas de activación

.

............571

Etiquetas y cuadros de texto ......................................................................... 571 Botones ......................................................................................................572 Botones toggle ............................................................................................572 572 Casillas de activación y botones de opción ................................................... 573 Usar etiquetas ............................................................................................... 577 Usar iconos imagen ....................................................................................... Usar imágenes en etiquetas ...........................................................................579 Usar cuadros de texto .................................................................................... 580 Abstract Button: base de los botones Swing ................................................ 583 Usar botones .............................................................................................. 589 .................................................................... Visualizar imágenes en botones 592 594 Usar imágenes rollover y deshabilitadas ....................................................... Botones por defecto y mnemónicos ............................................................595 Usar botones toggle ...................................................................................... 597 Crear grupos de botones toggle ..................................................................... 600 Usar casillas de activación ............................................................................ 601 Usar botones de opción ................................................................................. 604 Usar imágenes en casillas de activación y botones de opción ....................... 607 Obtener y fijar el estado de las casillas de activación y de los botones de opción ................................................................................................. 608

13 Swing: viewports. desplazamiento. deslizadores y listas

.

................613

Viewports...................................................................................................... 613 ........................................... 614 Paneles de desplazamiento.............................. : Deslizadores.................................................................................................. 614 Barras de desplazamiento.............................................................................. 614 Listas ............................................................................................................614 Manejo de viewports..................................................................................... 615 Creación de paneles de desplazamiento ........................................................ 621 Creación de paneles de desplazamiento con cabeceras y bordes ...................627 Desplazamiento de imágenes ........................................................................ 629 .. Creacion de deslizadores............................................................................... 630

Relleno de un deslizador ............................................................................... 636 Pintar las marcas de un deslizador ................................................................ 637 Pintar etiquetas en un deslizador................................................................... 638 Ajuste de la extensión del deslizador ............................................................ 639 Creación de barras de desplazamiento .........................................................640 ., Creacion de listas .......................................................................................... 646 Gestión de selecciones múltiples ................................................................653 Modos de selección de lista ...................................................................653 Visualización de imágenes en listas .............................................................655 Creación de un modelo de lista personalizado ..............................................657 Creación de un renderizador personalizado para celdas de lista .................... 657 Procesamiento de doble clic en listas ............................................................658

14 Swing: barras. herramientas. cuadros. separadores y selectores

.

.........................................................................................663

Cuadros combinados..................................................................................... 663 Barras de progreso ........................................................................................ 664 664 Selectores ................................................................................................... Herramientas de ayuda ............................................................................... 665 Separadores ................................................................................................665 . Creacion de cuadros combinados.................................................................. 665 Manejo de los eventos de selección del cuadro combinado .......................... 672 Creación de cuadros combinados editables .................................................. 674 Adici6n de imágenes a cuadros combinados ................................................. 676 Creación de un modelo de cuadro combinado .............................................678 Creación de un renderizador personalizado para el cuadro combinado ............................................................................................ 678 679 Creación de barras de progreso ..................................................................... Actualización de barras de progreso ............................................................ 684 Manejo de los eventos de barras de progreso ................................................ 686 Creación de ayudas de herramientas .............................................................687 Creación de separadores................................................................................ 690 Cambio de tamaño automático de separadores ............................................. 693 Creación de un selector de color .................................................................695 Creación de selectores de archivos ...............................................................699 709 Creación de filtros para selectores de archivo ...............................................

.

15 Swing: paneles de capas. de lengüetas. separadores y distribuciones

.

................................................................................. 715

Paneles de capas ........................................................................................... 716 Paneles de lengüetas ..................................................................................... 716 Paneles de separación ................................................................................... 716 Distribución .................................................................................................. 717 Comprensión de los componentes de la Swing y el orden Z ......................... 717 Transparencia en los componentes de la Swing ...........................................719 Uso de paneles de capas ................................................................................ 722 Creación de paneles de lengüetas.................................................................. 725 Especificación de la posición de las lengüetas en los paneles de lengüetas ........................................................................................732 Uso de paneles de separación ........................................................................ 734 Paneles de separación expandibles con un clic ............................................. 740 Configuración de la orientación del panel de separación .............................. 742 Configuración del tamaño del divisor de un panel de separación ................. 744 Uso del gestor de distribución de cuadro ...................................................... 745 Uso de la clase Box ...................................................................................... 748 Uso del gestor de distribución de superposición ...........................................752

16 Swing: menús y barras de herramientas

.

........................................ 757

Menús ........................................................................................................... 757 Barras de herramientas.................................................................................. 758 Crear una barra de menús ............................................................................. 758 Crear un menú ..............................................................................................761 Crear un elemento de menú ......................................................................... 765 Crear un sistema de menús básico ................................................................ 768 Adición de imágenes a menús....................................................................... 772 Crear elementos de menú de casillas de verificación ....................................774 Crear menús de botones de activación ..........................................................777 Crear subrnenús ............................................................................................780 Crear aceleradores y mnemónicos de menú .................................................. 782 Habilitarlinhabilitar elementos de menú y cambiar títulos en tiempo de ejecución ...........................................................................................:785 Añadir y eliminar elementos de menú en tiempo de ejecución ..................... 788 Añadir botones y otros controles a menús .................................................... 790

Crear menús emergentes ............................................................................... 79 1 Crear barras de herramientas ......................................................................... 797 Añadir cuadros combinados y otros controles a barras de herramientas ........................................................................................ 801

17 Swing: ventanas. paneles. marcos internos y cuadros . de dialogo 805 Ventanas ....................................................................................................... 805 Cuadros de diálogo ....................................................................................... 806
Crear una ventana ......................................................................................... 806 Crear una ventana de marco .......................................................................... 810 Crear un panel de escritorio .......................................................................... 812 Crear marcos internos ................................................................................... 814 Uso de JOptionPane para crear cuadros de diálogo ...................................... 825 Crear cuadros de diálogo con panel de opciones de confirmación ................ 834 Crear cuadros de diálogo con panel de opciones de mensaje ........................ 835 Crear cuadros de diálogo con panel de opciones de campo de texto de entrada ............................................................................................... 837 Crear cuadros de diálogo con panel de opciones para entrada de cuadros combinados ............................................................................ 839 Crear cuadros de diálogo con panel de opciones de marcos internos ............ 841 Crear cuadros de diálogo con JDialog ........................................................... 843 Obtener entrada de los cuadros de diálogo creados con JDialog ................... 848

.

. ...........................................................................................

18 Swing: tablas y árboles

.

.....................................................................851
851 852 852 871

Tablas ....................................................................................................... Árboles ...................................................................................................... Crear tablas ............................................................................................... Crear árboles ...............................................................................................

19 Swing: Componentes de texto

.

..........................................................

885

Crear componentes de texto en Swing: la clase JTextComponent ................ 885 Crear campos de texto ................................................................................... 885 Ajustar la alineación del campo de texto .................................................... 886 Desplazar campos de texto .......................................................................... 889 Crear campos de palabra clave ..................................................................... 890

20 Stream U 0 y archivos

.

.......................................................................895

Usar la clase File ........................................................................................... 895 Trabajar con InputStream..............................................................................897 Trabajar con OutputStream ........................................................................... 897 Trabajar con FileInputStream ...................................................................... 897 Trabajar con FileOutputStream ..................................................................... 899 Trabajar con ByteArrayInputStream .............................................................900 Trabajar con ByteArrayOutputStream .......................................................... 901

21 Programación multihilo y animación

.

........................................ 905

Usar hilos en Java ....................................................................................... 905 Obtener el hilo principal ............................................................................. 907 Dar nombre a un hilo .................................................................................... 907 Detener un hilo ............................................................................................908 909 Crear un hilo con la interfaz Runnable ........................................................ Crear un hilo con la clase Thread .................................................................. 911 Crear hilos múltiples ..................................................................................... 916 .. Espera (para union) de hilos .......................................................................... 917 Comprobar que un hilo está vivo .................................................................. 919 Asignar la prioridad y detención de hilos ...................................................... 920 ¿Por qué utilizar la sincronización? .............................................................. 923 Sincronizar bloques de código ...................................................................... 924 Métodos sincronizados ................................................................................. 926 Comunicación entre hilos ............................................................................. 927 Suspender y reanudar hilos ...........................................................................929 Crear gráficos animados con hilos ................................................................931 Eliminar el parpadeo en animaciones gráficas .............................................. 934 Suspender y reanudar animaciones gráficas ..................................................935 Doble buffer..................................................................................................937

22 Creación de paquetes. inteffaces. archivos JAR y Java Beans

.

......941

Crear un paquete ........................................................................................... 941 Crear paquetes que contienen paquetes ........................................................943 944 Crear una interfaz .......................................................................................... Implementación parcial de una interfaz ........................................................ 945

Crear un archivo JAR ................................................................................ 946 Obtener los contenidos del archivo JAR ................................................... 948 Extraer archivos desde un archivo JAR ........................................................ 948

.......................................................951 .. Índice alfabetico...................................................................................... 953
Apéndice Contenido del CD-ROM

.

Introducción

Bienvenido a la biblia de Java 2. Este libro se ha diseñado para que sea todo lo comprensible y accesible que es posible teniendo en cuenta que es un libro de Java. En él va a encontrar tanto Java como quepa en sus páginas. Java no es un lenguaje de programación ordinario: inspira devoción, pasión, exaltación y excentricidad (no se menciona exasperación ni frustración). Esperemos que lo que Java tiene que ofrecer le resulte irresistible al igual que ha ocurrido con otros muchos programadores (de hecho, la programación en Java es uno de los conocimientos más lucrativos que se pueden tener hoy en día). Al lenguaje de programación Java se le ha llamado "C++ para Internet", y aunque hay algo de verdad en eso, Internet no es el único lugar en el que actualmente se encuentra Java. Cada vez hay más empresas que utilizan el lenguaje de programación Java para construir aplicaciones que no tienen relación con Internet, pero que tienen que ser independientes de la plataforma. He visto que muchas de las grandes corporaciones han cambiado gradualmente su programación interna de C++ a Java. La influencia del lenguaje de programación Java se está extendiendo y no hay visos de pararlo, y con cada versión se tiene más poder y más profundidad para trabajar con este lenguaje.

se sentirá atraído por la programación en Java. imágenes. conexión de bases de datos y multithread. cuadros de diálogo y ventanas barras de progreso. Contenido del libro Este libro está diseñado para mostrarle toda la historia del lenguaje de programación Java que un libro puede contener. En este libro se tratan cientos de temas. sino también el lenguaje Java en el mundo real. separadores y cuadros de desplazamiento tratamiento y ajuste de imágenes Java Swing cambios de apariencia con Swing todos los componentes Swing componentes de texto Swing colecciones Java . uso del visualizador de Java. texto y fuentes menús.Si está de acuerdo conmigo. creación de conexiones clientelservidor sobre Internet. Se cubrirán temas como permisos de acceso a applets. Está dividido en temas separados y fácilmente accesibles y en cada uno de ellos se trata un caso de programación diferente. barras de desplazamiento. y cada uno de ellos viene con un ejemplo que muestra cómo funciona. ya que lo que puede hacer con este lenguaje es asombroso. listas y cuadros de lista desplegables gráficos. Algunos de estos temas son los que se muestran a continuación: toda la sintaxis de Java 2 programación orientada a objetos herencia y clases internas abstract windowing toolkit (AWT) botones. Verá lo que quiero decir en cada una de las páginas de este libro. creación de Java Beans. Veremos no sólo toda la sintaxis de Java. desde la declaración de variables hasta temas de orientación a objetos avanzada. casillas de activación y botones de opción selectores.

JDK tiene . Por ello.com/products/jdk/ 1.sun.sun. Existe una norma que se usará en este libro y que deberá conocer: para resaltar una línea concreta de código. interfaces y ficheros JAR seguridad manejo de excepciones manejo del teclado y del ratón Esta lista no es completa. vea el capítulo l . lo puede obtener en el sitio Web de Sun Java. es Java Swing.com. Todo lo que necesita para usar este libro. además del editor de programas.2 (o la última versión).multithreads flujos de E/S manejo d e ficheros redes y sockets árboles y tablas Java Beans paquetes. se sombreará de la siguiente forma: public class app { public static void main(String [ 1 args) { (new p r i n t e r ( ) ) . http://java. Estos programas son ficheros planos de texto con instrucciones y declaraciones Java. p r i n t ( ). También necesitará tener una forma de crear programas Java. deberá tener un editor que permita guardar ficheros en formato texto. Para más detalles. versión 1. utilizará Java 2. la nueva y revolucionaria interfaz para la programación de clases Java. puede que al ejecutar el código aparezcan algunos errores. Si no usa esta versión como mínimo. Uno al que prestaremos especial atención y que no se trata en la mayoría de los libros.2. Requerimientos En este libro. Para crear un programa Java.2. obtenga Java Development Kit (JDK) en http://java. Más adelante trataremos muchos temas más.

sun.com guía didáctica de Sun Java en http://java. sin mencionar un gran número de utilidades. Otros recursos Hay otros recursos Java que pueden servir de ayuda con el lenguaje de programación Java.comlproducts/jdW 1.todo lo que necesita para crear applets y aplicaciones estándares de Java e incluso posee un visualizador de applets para verlos mientras está trabajando.com/docs/books/tutorial soporte técnico en línea de Sun en http:l/java.html para obtener el lenguaje de programación Java.sun.sun. necesitará crear en su máquina una fuente de datos ODBC. necesitará tener un navegador Web. Esa documentación está almacenada en páginas HTML enlazadas y para trabajar con ellas y visualizarlas. Hay además muchas. Java le ofrece gran cantidad de documentación. y Java Servlet Development Kit (JSDK).2 Entre otros temas. muchas páginas Web referentes al lenguaje Java (haciendo una búsqueda aleatoria en la Web se encuentran unas 10.268.200 páginas que mencionan Java.sun. usaré Beans Development Kit (BDK).com/ products/jdWl. que también se pueden obtener en el sitio Web de Java.614 páginas). buscando "Java tutorial" se encuentran unas 11.sun. de hecho. hay decenas de miles de páginas de documentación que vienen con el mismo lenguaje Java. ir a http://java.com/dosc/books/ tutorial: colecciones internacionalización servlets . Como se mencionó anteriormente. junto con el código. imágenes y otros ficheros utilizados en el libro. cientos de libros de calidad. A continuación se citan algunos de estos recursos útiles: página principal de Java en http://java.2/docs/index. Finalmente. En el CD encontrará la base de datos que trabaja con esta fuente de datos. puede encontrar guías didácticas sobre los conceptos siguientes en la página de tutorías de Sun http://java. Además de JDK. Si quiere continuar con la programación de base de datos incluida en el libro.

gráficos 2D seguridad en JDK 1. Este libro está diseñado para proporcionarle todo lo que necesite (y espero que así sea. comenzando por el capítulo 1.2 sonido ficheros Java Archive (JAR) Java Beans conectividad de bases dedatos Java (JDBC) interfaz nativa de Java llamada remota a métodos (RMI) reflexión Además hay un número de grupos Usenet para programadores de Java. pero espero que no tenga que acudir a ella. que incluyen: Para Java existe mucha ayuda. Ahora es el momento de empezar a trabajar con Java. .

En este libro. verá la ejecución de código Java. En este capítulo. es el tema de este capítulo. la creación y ejecución de programas Java. trararemos con detenimiento y detalle toda aquella programación Java que puede estar contenida en un libro. preparándole para usarlo.m Java básico Bienvenido a nuestro gran libro de programación Java. desde asegurarse de que el programa es capaz de encontrar lo que necesita hasta visualizar una simple salida. vamos a trabajar con la mecánica de crear programas Java. Como el propósito de este libro es poner a su disposición todo el lenguaje de programación Java. y en los siguientes podrá poner en práctica dicha información para ensayar la sintaxis Java que desarrollaremos. desde la instalación hasta la escritura de código. Estos se centran en todas las interioridades de la escritura de . pero ninguno es útil si no puede ejecutar y crear programas Java. y espero que elija Java como plataforma de programación. no dejaremos de lado los temas difíciles. Este primer capítulo cubre los conocimientos fundamentales de Java que habrá que recordar para el resto de los capítulos. Habrá algunos paquetes de programación con los que disfrutará más que con otros. En los siguientes capítulos. Ese conjunto básico de conocimientos. Estos conocimientos son los que podrá usar en los siguientes capítulos.

activaría un interruptor que arrancara el compresor e hiciera funcionar las válvulas para que el frío circulara. trabaje con el contenido de este capítulo. Por consiguiente. Java satisfizo una necesidad específica de su tiempo. Esto quiere decir que el código de la primera línea de un programa largo podría interferir con el código de la última línea. muy poca gente sabe lo que la línea de comandos del compilador Java puede hacer). Sin embargo. y el programador tendría que recordar todo el código mientras programaba. puede pasar rápidamente por las páginas siguientes y continuar con el capítulo 2. Ya debería conocer mucho sobre el contenido de este capítulo. Por ejemplo. pues proporciona la base para varios de los capítulos siguientes. lo que realmente hace que Java funcione. Esa es una forma de hacerlo. donde empezaremos a profundizar en la sintaxis de Java. al igual que los lenguajes de programación anteriores. La programación orientada a objetos se hizo popular por ser capaz de dividir programas largos en unidades semi-autónomas. Todo sobre Java ¿De dónde procede el lenguaje de programación Java y por qué es tan popular? Como otros lenguajes de programación.código Java. ya está familiarizado con la mayor parte de lo que verá en este capítulo. combinando los mejores elementos de los lenguajes de bajo y alto nivel en un lenguaje de programación que se ajustaba a la arquitectura del ordenador y que gustaba a los programadores. Si ya tiene una instalación de Java que funciona y puede escribir y ejecutar un programa básico en Java. De lo contrario. otra consiste en coordinar todas esas operaciones de forma que sean automáticas. el lenguaje C tenía limitaciones. supongamos que para mantener fresca la comida utilizara un sistema complejo. y cuando la temperatura fuera lo suficientemente alta. C era un lenguaje extremadamente popular entre los programadores y parecía que era el lenguaje de programación perfecto. Cuando los programas crecían. Debería comprobar la temperatura de la comida usando un termómetro. este capítulo trata el resto del proceso que hace que el código funcione. por ejemplo. cubriendo todo con una unidad senci- . Sin embargo. los programas C se hacían inmanejables porque no había una forma fácil de acortarlo. En otras palabras. El lema de la programación orientada a objetos es "divide y vencerás". un programa se puede dividir en partes fácilmente identificables. Antes de que Java apareciera. en cualquier caso se revisará con detenimiento (alguno de ellos está limitado por ser nuevo y a pesar de todo. luego arrancaría un ventilador que moviera el aire.

reduciendo todas las interdependencias que aparecen en un programa C e inicializando una interfaz bien definida y controlable que mantiene la conexión entre el objeto y el resto del código. Así usted -puede pensar en el objeto como algo fácil. Cuando se añadió al lenguaje C la programación orientada a objetos. nació C++. al igual que una variable puede ser de tipo entero. por lo que para crear una ventana sólo era necesaria una línea de código. Por ejemplo. Se puede pensar en una clase como un tipo de objeto. Para crear un objeto. Así funcionan los objetos: ocultan los detalles de la programación al resto del programa. Como C++ soporta clases. Por ejemplo. simplemente había que crear un objeto del tipo de ventana que se quisiera usar: con o sin borde. los proveedores de software pueden proporcionarle enormes librerías de clases. se necesitaban aproximadamente cinco páginas de código para visualizar una ventana vacía. un objeto al que le llame pantalla. a partir de las cuales se puede empezar a crear objetos. para manipular aquello en lo que pretende actuar (en este caso. utiliza una clase que actúa como una plantilla o creador de patrones para ese objeto. y los programadores tuvieron un nuevo aliciente. Cuando se escribía un programa Windows en C. por ejemplo. etc. sabe que la pantalla es gestionada por ese objeto y puede tenerlo en mente. la pantalla). Sin embargo. pero en ninguna otra parte del código tendrá que gestionar el manejo de la pantalla. como un cuadro de diálogo. Después de crear ese objeto. y el código orientado a objetos ayudó a resolver también muchos de los otros problemas. Ahora las interioridades no se ven y lo único que hay que hacer es introducir o sacar comida del frigorífico. Puede utilizarlo de distintas formas. el hecho de soportar objetos lo hacía más fácil para los fabricantes que suministraban software con mucho código reutilizable. y en ella los programadores encontraron una mejora tremenda respecto a los tiempos pasados. la línea en la que se creaba el nuevo objeto ventana de la clase que se había seleccionado. añadiendo la funcionalidad que se quisiera por medio de la herencia de la programación orientada a objetos.lla. supongamos que quiere que su ventana tenga una barra de . C++ permite a los programadores tratar grandes programas. podrá usar en su lugar el objeto pantalla que ha creado. que verá a lo largo de este libro. preparado para su uso. El objeto ya tenía toda la funcionalidad del tipo de ventana que quería crear. Por ejemplo. utilizando una clase de la librería MFC. Más impresionante todavía era el hecho de que se podía usar una clase MFC como clase base para las clases propias. una de las librerías de clases de C++ más populares es la librería Microsoft Foundation Class (MFC) que viene con Visual C++ de Microsoft. un refrigerador. puede tener un objeto que gestiona toda la interacción con la pantalla.

La primera versión de Java empezó en 1991 y fue escrita en 18 meses en Sun Microsystems. En otras palabras. pero el entorno corporativo podía incluir toda clase de plataformas de programación. Parecía que el lenguaje de programación perfecto había llegado. normalmente un programa MFC puro no baja de 5MB sin incluir las librerías de enlace dinámico (DLLs) que la plataforma Windows necesita para ejecutar los programas Visual C++. De hecho. en ese momento. Todo c'obre bytecodes Un programa Visual C++ de Microsoft es grande. ni siquiera se llamó Java.menús. lo que justifica que tengan un gran tamaño. Y eso es lo que hizo que Java fuera tan popular. . Java no fue creado para la red Internet. muchos programadores se limitaban a la programación del IBM PC. (En este libro verá en detalle cómo funciona la programación orientada a objetos). Todo esto parecía fabuloso a los programadores. Por entonces. ¿Qué podía haber mejor? Sin embargo. desde el PC hasta los grandes sistemas. cada vez más corporaciones están adoptándolo para uso interno en lugar de C++. De esta forma. cuando se lanzó para el uso público y supuso un éxito casi inmediato. precisamente por esa razón). En ese momento. los programas C++ son completamente ejecutables en el ordenador en el que residen. el modelo bytecode. Sun quería crear un lenguaje que se pudiera usar en electrónica. Imaginemos que intentamos descargar todo eso como parte de una página Web para permitir que esa página haga algo interactivo en su ordenador. el mismo entorno de programación iba a verse sometido a un gran cambio con la popularización de lo que equivale a un nuevo e inmenso entorno de programación: la red Internet. y C++ llegó muy lejos. Orígenes del lenguaje Java Originalmente. Lo que había detrás de Oak era crear algo que se pudiera usar en todos los ordenadores ( y ahora que Java se ha hecho popular gracias a la red Internet. se llamó Oak y se utilizó en Sun para uso interno. Java había adoptado un modelo que lo hizo perfecto para la red Internet. Oak pasó a llamarse Java en 1995. puede construir su propia clase. añadiendo unas cuantas líneas de código a las de los programadores de Microsoft. entonces puede derivar su propia clase de una ventana simple de MFC. La idea original para Oak era crear un lenguaje orientado a objetos independiente de la plataforma. añadiendo a esa clase una barra de menús para crear la clase nueva. El lanzamiento original de Oak no fue especialmente fascinante.

no necesitan ser autosuficientes. Utilizar bytecodes significa que los programas Java son muy compactos. esto quiere decir que su programa Java se ejecutará más rápido con el nuevo compilador JIT. JVM puede ver todo lo que un programa hace. Java 2 incorpora la compilación al instante Just in Time (JIT) en JVM. es decir. éste puede ejecutar programas Java. La seguridad del lenguaje Java Cuando se ejecuta un programa. Cuando JVM se instala en un ordenador. y si hay algo dudoso. como puede ser tratar de escribir en un archivo. se ejecutará en cualquier ordenador en el que JVM esté instalado. la seguridad ha llegado a ser un asunto extremadamente importante en la red Internet. por lo que el programa puede ejecutarse más rápido ( todo el programa Java no se compila de una vez. es la seguridad. Los programas Java. Para distribuir Java entre una gran variedad de ordenadores. Cuando descarga una applet Java de la red Internet. los programas Java son compilados creando bytecodes compactos y son estos bytecodes lo que JVM lee e interpreta para ejecutar el programa. por lo tanto. mayor que la descarga de programas. Dado que su programa está almacenado en un archivo de bytecode. que no tiene tales restricciones. En cambio. por el contrario. Por esta razón. para la red Internet.Los programas Java. lo que les hace ideales para descargarlos en la red Internet. ya que todo el código máquina necesario para ejecutarlo está ya en el ordenador de destino y no tiene que descargarse. Fuera de toda duda. Aunque en un principio se suponía que los programas Java eran interpretados por JVM. Java sea más atractivo que C++. y Java se ha lanzado a esa tarea. De esta forma. El propio lenguaje Java está implementado como la máquina virtual de Java (JVM). El compilador JIT realmente lee los bytecodes por secciones y los compila de forma interactiva en lenguaje máquina. puede prevenir esa operación. Eso sólo hace que. . ya que Java va realizando comprobaciones en tiempo de ejecución en varias secciones del código). ejecutados bytecode por bytecode. su programa Java puede ser muy pequeño. lo que realmente está descargando es un archivo de bytecodes. y no tienen por qué incluir todo el código máquina que se ejecuta en el ordenador. lo cual es importante para las aplicaciones de la red Internet. Desde su punto de vista. JVM puede monitorizar estrictamente lo que va ocurriendo. se construyen de forma diferente. Sun sólo tuvo que rescribir JVM para que funcionara en esos ordenadores. que es la aplicación que actualmente ejecuta un programa Java. Y otra ventaja a la hora de ejecutar tales programas con JVM. la interpretación podía ser un proceso lento.

El resultado final es que se puede escribir un programa Java una vez y puede descargarse fácilmente y ejecutarse en todo tipo de máquinas. con frecuencia son son sencillos de escribir comparados con C++. Los programas Java son robustos (lo que significa que son fiables y pueden gestionar bien los errores). de hecho. Java no tiene como único objetivo a la red Internet. lo cual es útil cuando se quiere continuar haciendo otras cosas mientras se espera a que un archivo de datos se descargue. Por ejemplo. mostrando la misma applet que la figura 1 . uno para el uso de la red Internet y otro para el uso en máquina local. en el directorio bin de Java junto con otras utilidades Java que usaremos en este y algunos de los siguientes capítulos. por ejemplo) y ofrecen un alto rendimiento. aquellos privilegios que quiera dar para descargar código. Puede ver el visualizador de applets funcionando en la figura 1. usaré el visualizador de applets de Sun que viene con Java. independientes de la plataforma. orientados a objetos. hay dos tipos de programas Java. Programas Java Los programas Java son de dos tipos principales: aplicaciones y applets. la receta perfecta para la red Internet.1. Además presentan otras características que gustan a los programadores. donde la applet se está ejecutando en Microsoft Internet Explorer y visualiza un saludo. l.Además se puede configurar la seguridad de Java de la forma que se desee. La mayor parte de los navegadores Web han sido algunas veces lentos a la hora de implementar las versiones más recientes de Java.exe en Windows). Como puede observar. ofreciendo una solución muy flexible. y son las que han hecho que Java sea tan popular. puede ver una applet en funcionamiento en la figura 1. como verá en este libro. Encontrará esta utilidad. llamada appletviewer (con una extensión según sea requerida por el sistema.2. (En este libro utilizaré el término programa para referirme a applets y aplicaciones). y potentes. seguros. Echaremos un vistazo a todo esto y más a lo largo de este libro. ahora puede especificar. por lo que en este libro. Además. . multihilo (pueden ejecutar un número de tareas al mismo tiempo. como appletviewer. Por ejemplo. tomando como base programa por programa. Las applets son programas Java que pueden descargarse y ejecutarse como parte de una página Web. Java tiene una baza ganada en la red Internet: los programas Java son pequeños. ahora puede firmar su código Java de forma que muestre de dónde procede para evitar modificaciones malévolas. Esta es la razón por la que Java ha llegado tan alto.

Figura 1. IHOla desde Javal Figura 1.1. Una applet en funcionamiento con el visualizador de applets de Java.2. . Una applet en funcionamiento.

Una aplicación ventana en ejecución. la aplicación visualizará este mensaje en la pantalla. En la figura 1. En este caso. Ejecute la aplicación arrancando la máquina virtual de Java con el comando Java.Además de applets descargables. la aplicación es responsable de arrancar su propia ventana (el visualizador de applets lo hará).3 puede ver una aplicación ventana de Java.3. donde '%' es el command prompt: % java app ¡Hola desde Java! En Windows. En Unix. Al estar instaladas localmente en vez de ser descargadas con una página Web. En este capítulo comprobará cómo tales aplicaciones funcionan. podrá decir que tiene una aplicación Java llamada app que visualiza el mensaje "¡Hola desde Java!" (acaba de ver cómo lo hace la applet). puede instalarlas y ejecutarlas en el suyo. Las aplicaciones Java funcionan como otras aplicaciones de ordenador. ¡Hola desde Javal Figura 1. y de hecho. . como es la capacidad para leer y escribir archivos. sería así: c:\>java app ¡Hola desde Java! ¿Las aplicaciones Java pueden ser gráficas? Realmente pueden serlo. las aplicaciones tienen más privilegios que las applets. pasándole el nombre de la aplicación que quiere ejecutar. la mayoría de ellas lo son. Las aplicaciones que usaremos en los siguientes capítulos serán el tipo más sencillo de aplicaciones Java: aplicaciones consola. y pueden leer y visualizar texto. En este caso. Son aplicaciones basadas en texto que se ejecutan desde la línea de comandos (en Windows esto quiere decir desde una ventana DOS). Java soporta aplicaciones que están diseñadas para ejecutarse localmente. sería así. Por ejemplo.

que está disponible en http://java. JVM y otras utilidades.html.2 en el momento de escribir este manual).21 (1. selecciona Java como lenguaje para realizar esa tarea.com/products/jdk/1. pero esa es una de las mayores trampas en las que un libro de Java puede caer. se encontrará con alguna de estas referencias en la siguiente sección. como es usual. aunque me referiré a la versión actual de Java como Java 2.2/installsolaris. de hecho. es hora de empezar a crear programas Java y de ver cómo avanza.2. El paquete actual de Java.2/install-windows. Por lo tanto.comlproducts/jdW1. ¿Qué va a hacer? Conociendo lo bien que funciona Java en casos como este.com/products/ jdW1. y para Solaris se encuentran en http://java.2.com.sun. Por supuesto. que ahora se llama Java 2 Development Kit. .sun. versión 1.2. que incluye el compilador Java.htm1. Es hora de descargar e instalar Java. Puede que haya oído decir que Sun renombró Java 1. generalmente como un paquete ejecutable autoinstalable. en el último minuto. se ha asegurado de tenerlo antes de poder utilizarlo. se llama oficialmente Java 2 JDK. por ejemplo. Tiene 20 minutos para escribir una nueva página Web que permita a los usuarios tener una visión general de los productos de su compañía. las instrucciones de instalación en Windows están en http://java. Adquirir e instalar Java El gran jefe le llama. Después de descargar JDK. pero esto es sólo verdadero en parte. seguir las instrucciones de instalación en el sitio Web java.2 se refiere a la versión de JDK.¿Es Java 2 o Java 1. que será el que usemos.2 como Java 2. Para una visión general ya es suficiente. lo que significa descargar Java Development Kit (JDK). verá aún referencias a la versión 1. Estaría encantado de proporcionar aquí las instrucciones de instalación. versión 1.2? La última área que hay que revisar antes de empezar es la versión actual de Java.sun.sun. Java Development Kit (JDK).

tanto los que creó como los del sistema que vienen con JDK. el directorio bin es c:\jdkl. ¿Qué ocurre con CLASSPATH? Los veteranos en Java se preguntarán por la variable de entorno llamada CLASSPATH cuando instalen Java2. ya no tiene que preocuparse de poner la variable CLASSPATH. dice a Java donde encontrar los archivos bytecode compilados. Llevo escribiendo sobre Java desde sus orígenes y se ha demostrado que las instrucciones de instalación son muy volátiles. Cuando el directorio bin esté en la ruta de acceso.C:\JDK1. incluyendo el compilador. Por esa razón. como veremos pronto en este capítulo.2. La variable CLASSPATH. si quiere buscar otros archivos bytecode creados al compilar un archivo. debe volver a arrancar su ordenador para que los cambios tengan efecto. debería acudir a las instrucciones de instalación que se encuentran en el sitio Web de Java. en lugar de tener que invocarlas con toda la ruta de acceso cada vez.2\bin para JDK 2.ZZ2\BIN Además. El proceso de instalación se ha ido haciendo cada vez más fácil en las diferentes versiones y ahora sólo consiste en ejecutar el archivo que se ha descargado. tendrá que poner la variable CLASSPATH. podrá utilizar las herramientas de Java directamente desde la línea de comandos. en Windows 95/98. y por consiguiente. Verá cómo hacer esto cuando discutamos la compilación de programas en este capítulo (hay dos formas de indicar al compilador de Java dónde buscar los archivos bytecode . es asegurarse de que su máquina es capaz de localizar las herramientas de Java. Para hacer eso.incluso uno que haya sido diseñado para ser lo más completo posible. CLASSPATH ha sido el foco de grandes confusiones al trabajar con Java y estoy contento de decir que Cun ha facilitado las cosas.2. versión 1. y basta con añadir una línea como esta (asegúrese de que están incluidos en la ruta de acceso todos los directorios que quiere utilizar) en el archivo autoexec. dando lugar a gran cantidad de llamadas y cartas. Cuando instale JDK. verificar que el directorio bin de Java está en la ruta de acceso de su ordenador. las que incorporé en los libros anteriores se quedaron obsoletas al instante. lo mejor que se puede hacer es ver cómo Sun quiere que se instale JDK. Como esas instrucciones cambian. Sin embargo. como indican las instrucciones de instalación de Sun.bat: SET PATH=C:\WINDOWS. Algo que se debería hacer. Por ejemplo.2. porque JDK sabrá dónde buscar sus propias librerías.

todavía podrá usar las técnicas antiguas de gestión de eventos en Java 1. en Java llamadas censuradas. comprimiéndolos para reducir su tamaño y . buscando ayuda.1? El programador novato (PN) comienza. mover el ratón o pulsar una tecla (veremos todo sobre las viejas y nuevas técnicas de gestión de eventos en el capítulo 6). y es importante saber lo que es obsoleto y lo que es nuevo.1 y 2.O. era más rápido que antes (algo que los programadores de Java podían apreciar de forma definitiva). menús emergentes. dirá.1 fue la forma en que los programas Java gestionaban los eventos. Veamos este tema a continuación. un modelo de eventos basado en la delegación. "y estaba pensando en actualizarlo a Java 1. En Java 2 hay muchas novedades. pero el rendimiento de los programas se verá degradado). mejoras en las imágenes y gráficos y más temas. como pulsar un botón.que quiere encontrar: poniendo la variable de entorno CLASSPATH y usand o la opción del compilador -classpath). como es usual. Java 1 . el portapapeles. y es bastante diferente de cómo se hacía en Java 1. de hecho.O. dice el PN.1?" "Bien".1. Además. A continuación se enumeran los más importantes (observar que algunos de estos temas no tienen mucho sentido ahora pero estarán más claros a lo largo del libro): Mejoras en Abstract Windowing Toolkit (AWT). Un evento ocurre cuando el usuario ejecuta alguna acción significativa en la interfaz de usuario.0.0". el proceso s e detendrá. tome una silla y las iremos viendo". "¿Cuáles son las novedades de Java 1.1 para servir de utilidad a los programadores que proceden de Java 1 . más rapidez en los desplazamientos. ¿Cuáles son las novedades de Java 1. La nueva técnica en Java 1.l soportaba la impresión. Tan diferente. (En cambio. Los archivos JAR (archivo Java) permiten empaquetar un número de archivos. De hecho. "He utilizado Java 1. "muchas cosas.1 y 2 utiliza el modelo de eventos delegado.O y 1. "la versión actual es la 2". Probablemente el mayor cambio entre Java 1 . Sin embargo. Hubo muchos cambios en Java 1. Java 2 también tiene algunas cosas obsoletas.1". Archivos JAR. que si intenta ejecutar un programa Java que usa el modelo de evento delegado en un navegador Web que sólo soporta el modelo de evento de Java 1 . El PN ignora eso y pregunta. "Bien". responderá . echaremos un vistazo a lo que era nuevo en Java 1.

así como hacer uso de esos métodos reflejados y constructores. como veremos más tarde. fecha sensible a la localidad. Los valores de tipo byte y short pueden ser gestionados como números "envueltos" cuando se usan las nuevas clases de tipo Byte y Short. Permite almacenar copias de los objetos que se van a serializar. Esto forma parte de las nuevas precauciones de seguridad de la red mundial (World Wide Web). Una clase adaptadora es una clase que implementa una interfaz que es requerida por un API (interfaz de programación de aplicaciones). de forma que se descargue mucho más rápido. Permite que los objetos Java tengan métodos que son llamados desde el código Java que se ejecuta en otras sesiones. En un archivo JAR se pueden poner muchas applets y los datos que necesiten. La escritura y la llamada a código nativo puede mejorar significativamente la velocidad de ejecución. JavaBeans. . hora. Java 1. Hay clases encerradas en otras clases y el uso de las clases internas hace que sea más fácil crear clases adaptadoras.1 incluía un nuevo método nativo de interfaz. Es una nueva característica muy potente. utilizando caracteres UNICODE. Se pueden desarrollar applets locales. soporte de mensajes locales. mecanismo local. Permite al código Java examinar la información sobre los métodos y constructores de clases cargadas. Reflexión. Clases de tipo byte y short. El código nativo es un código que se escribe específicamente para una máquina particular. Utilizando las clases adaptadoras se facilita la gestión de eventos. zona horaria y más. Clases internas. y además es la base de la comunicación entre objetos incluidos en RMI. Applets firmadas y firmas digitales. Una firma digital permite a los usuarios dar marcha atrás en el caso de que algo vaya mal. Método remoto de llamada (RMI). Son componentes Java que pueden conectarse con otros programas Java. Se pueden crear aplicaciones Java con firmas digitalizadas. Interfaz de un nuevo método nativo de Java. Objetos en serie de objetos. Permite almacenar objetos y gestionarlos con flujos binarios de entradalsalida. Internacionalización.permitiendo la descarga de muchos archivos a la vez.

cuando ya me había habituado a Java 1 . "Mejor tomemos un café". . l Wse queja el programador novato.1. Además. "Eso es porque gran parte de la clase Date fue censurada en Java l. etc. muchas más que la lista que aquí mostramos. ¿Cuáles son las novedades de Java 2? "De acuerdo".1 en http://java. dice. Ver el siguiente tema para más información. el compilador Java da un aviso cuando se compila el código que utiliza algo censurado.1 . observe que esta lista no le será muy útil si usa Java 2. dice el programador novato. Ahora. ¿Qué está censurado en Java 1. La mayor parte de las características de Java 1 . como haremos en este libro. Está claro que. La política que especifica qué permisos están disponibles para el código de varios firmantesllugares. ahora estoy teniendo errores cuando utilizo la clase Date de Java". ¿cuáles son las novedades de Java 2?" "Muchas cosas". acceso para conectarse a un host o puerto. debería actualizar a Java 2.11 docs/relnotes/deprecatedlist.La mayoría de los métodos de Java 1. Por ejemplo."dice.Sin embargo. y están marcados como censurados en la documentación de Java 1. puede ser inicializada desde un archivo externo configurable. en cambio vea el tema "¿Qué está censurado en Java 2?". "Justo . que viene a continuación.com/products/jdW l . A continuación verá las novedades de Java 2 (observe que como en la lista mostrada en "¿Cuáles son las novedades de Java 1. cuando el código está cargado.). pero los verá más tarde en este libro): Mejoras en la seguridad. Entonces. se asignan permisos basándose en las políticas de seguridad que actualmente tienen efecto.1. no a Java 1. Cada permiso indica que se tiene un acceso permitido a un recurso particular (como acceso de lectura y escritura a un archivo o directorio concreto.1?".html.1 ahora." dice el programador novato. no tiene que estar familiarizado ahora con los conceptos. y mi código es erróneo.1.1 ? "iEh!.1.O se censuraron en Java 1. "actualizo a Java 1. Puede encontrar una lista de todo lo que se censuró en Java 1. no se puede acceder al recurso que está protegido por ese permiso. "usted gana.sun.0 han quedado obsoletos con Java 1. A menos que un permiso sea garantizado explícitamente.

sistemas de reconocimiento de voz y terminales Braille. . Permite que todos los componentes de los editores de texto reciban textos en japonés. permitiéndoles ser manipulados independientemente de los detalles de su representación. Paquete de identificación de versiones.1 Lightweight U1 Framework. Las extensiones son paquetes de clases Java (y el código nativo asociado) que los desarrolladores de aplicaciones pueden usar para heredar el núcleo de la plataforma Java. texto e imágenes en un modelo sencillo y extenso. Forma parte de las clases Java Foundation (JFC). Mejoras en JavaBeans. Engloba el conjunto de líneas. Java 2D (JFC). El API Java 2D es un conjunto de clases para gráficos 2D e imágenes. Implementa un nuevo conjunto de componentes GUI de tipopluggable. chino o coreano a través de los métodos estándar de entrada. Por medido del API de accesibilidad de Java. JVM y paquete de clases. Swing está implementado en Java puro y está basado en JDK 1. Windows. El mecanismo de herencia permite que la máquina virtual de Java (JVM) utilice las clases heredadas de la misma forma que JVM utiliza las clases del sistema. Colecciones. tales como lectores de pantalla. Accesibilidad (JFC). como el escritorio del sistema operativo o del navegador. Solaris y Macinstosh). Java 2 proporciona a los desarrolladores un método estándar para crear componentes y aplicaciones JavaBeans más sofisticados que ofrecen a sus clientes una integración limpia con el resto del entorno de ejecución. Framework de extensiones Java.Swing (JFC). entre aplicaciones Java y en el interior de una aplicación Java sencilla. Framework para las entradas. El carácter pluggable permite diseñar un conjunto sencillo de componentes GUI que pueden automáticamente tener la apariencia de cualquier plataforma (por ejemplo. El API de colecciones Java es un armazón unificado para representar y manipular colecciones Java (verá más sobre ellas más tarde). Arrastrar el cursor y soltar (JFC). los desarrolladores pueden crear aplicaciones Java que interactúen con tecnologías asistenciales. Las aplicaciones y las applets pueden identificar (en tiempo de ejecución) la versión de un entorno de ejecución Java específico. Permite la transferencia de datos entre Java y aplicaciones nativas.

el cual gestiona la memoria. Estas mejoras incluyen la funcionalidad añadida a la herramienta JAR de la línea de comandos para crear y actualizar archivos JAR firmados. Hay además nuevas APIs estándares para leer y escribir archivos JAR. incluyendo la activación remota de objetos. Las mejoras en el audio incluyen una nueva máquina de sonido y soporte para el audio en aplicaciones y enapplets. proporcionando la interoperabilidad y conectividad basada en estándares. Mejoras en el audio. . así como configurar los tipos de socket. La serialización ahora incluye un API que permite que los datos serializados de un objeto sean especificados independientemente de los campos de la clase. Mejoras en JNI. RMI. por sí misma. La interfaz nativa Java es una interfaz de programación estándar para escribir métodos nativos de Java y embeber la máquina virtual de Java en aplicaciones nativas. Java IDL permite que las aplicaciones Java Web distribuidas invoquen de forma transparente operaciones o servicios de red remotos usando el estándar de la industria OMG IDL (Object Management Group Interface Definition Lunguage) e IIOP (Internet Inter. que introduce el soporte de objetos remotos y la activación automática de objetos. Los objetos referencia permiten a un programa mantener una referencia a un objeto que no impide al objeto ser regenerado por el reciclador. Objetos referencia. Java IDL incorpora la capacidad de CORBA (Common Object Request Broker Architecture) a Java. que permite a un objeto remoto especificar el tipo de socket configurado que RMI usará para llamadas remotas a ese objeto. El primer objetivo es la compatibilidad binaria de librerías de método nativo a través de todas las implementaciones de la máquina virtual Java en una plataforma dada. pueda ser examinada y manipulada como cualquier otro objeto. Mejoras en JAR. -0RB Protocol) definido por el Grupo de Gestión de Objetos. Esto permite que los campos de datos serializados se escriban y se lean desde un flujo de datos usando las técnicas existentes (esto asegura la compatibilidad con los mecanismos de escritura y lectura establecidos por defecto). puede ser soportado usando tipos de socket configurados. El método remoto de llamada (RMI) tiene varias mejoras.Mejoras RMI. Un objeto referencia encapsula una referencia a algún otro objeto para que la referencia. Mejoras en la serializadión. Java IDL. sobre un transporte seguro (como SSL).

"¿Qué programas se han escrito?" pregunta el CED. JDBC además proporciona una base común en la que se pueden construir interfaces y herramientas de alto nivel.htm1. Para una lista completa de lo que se ha Haré mencensurado en Java 2. JVMDI. ¿Qué se censuró en Java 2? "iEh!".2. La conectividad Java de bases de datos (JDBC) es una interfaz estándar de acceso a base de datos que proporciona un acceso uniforme a un amplio abanico de bases de datos relacionales. suspend y stop de la clase Thread de Java. Este software es un producto que permite a los usuarios dirigir applets de Java o componentes JavaBeans para que se ejecuten en el entorno Java (JRE) de Sun." protesta el programador novato. ir a C:\jdk1. Mejoras JDBC.". "iVaya!. verá las nuevas formas en el capítulo que trata multihilos más tarde en el libro. Escribir código: creación de archivos de código El coordinador del equipo de diseño (CED) le llama para felicitarle por la instalación de Java. dice. ción a alguno de los temas censurados más importantes en Java 2 a lo largo del libro. Una nueva interfaz de debugger para la máquina virtual de Java proporciona ahora servicios de bajo nivel para el debug. dice el programador novato. piensa. La interfaz para estos servicios es la interfaz Debugger de la máquina virtual de Java (JVMDI).Java 2 extiende el JNI incorporando nuevas características en la plataforma Java. Uno de los cambios más importantes de Java 2 es que no se trabaja con hilos como se hacía en Java 1 . Usted acepta los agradecimientos. "Se han censurado". "¿Programas?" . En Java 2 también e s nuevo el Javaplug-in. l . "Eso es porque no puedes utilizar los métodos resume. "Hmm". Esto se tratará en el capítulo 6. Java 2 incluye JDBC y el enlace JDBC-ODBC. "ya he actualizado a Java 2 y mi código sigue siendo defectuoso. en lugar del entorno de ejecución del navegador Web que viene por defecto con Java. no consigo que la parte de mi código en la que utilizo multihilos funcione del todo".2\docs\api\deprecated-list.

Guardar texto en formato de texto plano es una ejecución sencilla quela mayor parte de los procesadores de texto soportan. debería guardar el programa Java en un archivo llamado app. A continuación se muestran (trataré estas palabras clave a lo largo del libro): abstract: Especifica la clase o método que se va a implementar más tarde en una subclase. Por ejemplo. le dice. es que el compilador de Java. debería tener un editor o procesador de texto que permita guardar archivos en formato de texto plano. como verá en las siguientes páginas. Además. pueda leer e interpretar dicho programa. "Java se está comportando de forma graciosa. boolean: Tipo de dato que sólo puede tomar los valores verdadero o falso. ¿qué pasa con la escritura del código? Escribir código: conocer las palabras reservadas de Java El programador novato aparece y dice. "Eso es porque public es una de las palabras que Java reserva como parte del lenguaje Java". Pase este archivo al compilador de Java para crear el archivo de bytecode. Podría tener problemas con procesadores de texto como Microsoft Word. La prueba real. dice el programador novato. La regla general es que si al editar un archivo desde la línea de comando no se ve ningún carácter que no sea alfanumérico suelto. quiero llamar a una variable "public" y me está dando muchos problemas". "ivaya!". de cualquier modo. Ahora. por supuesto. . por ejemplo. No hay muchas. debería saber que Java reserva ciertas palabras clave como parte del lenguaje. los programas deben estar almacenados en archivos que tengan extensión "java". y empezaremos a investigarlos en el siguiente apartado. Para crear un programa Java. se trata de un archivo de texto plano. que traduce su programa en un archivo de bytecode.Los programas Java son archivos de texto planos formados por instrucciones y declaraciones Java.java. Cuando esté escribiendo código Java. si está escribiendo una aplicación llamada app. Ya tenemos la selección del editor o procesador de textos.Wordejecutando el comando Guardar como del menú Archivo. aunque puede guardar archivos de texto con .

double: Tipo de dato que soporta números en coma flotante. goto: Reservada para uso futuro. byvalue: Reservada para uso futuro.break: Sentencia de control para salirse de los bucles. class: Declara una clase nueva. const: Reservada para uso futuro. flota: Tipo de dato que soporta un número en coma flotante en 32 bits. generic: Reservada para uso futuro. 64 bits. case: Se utiliza en las sentencias switch para indicar bloques de texto. for: Utilizado para iniciar un bucle for. continue: Devuelve el control a la salida de un bucle. cast: Reservada para uso futuro. byte: Tipo de dato que soporta valores en 8 bits. if: Evalúa si una expresión es verdadera o falsa y la dirige adecuadamente. . final: Indica que una variable soporta un valor constante o que un método no se sobrescribirá. implements: Especifica que una clase implementa una interfaz. import: Referencia a otras clases. char: Tipo de dato que puede soportar caracteres Unicode sin signo en 16 bits. extends: Indica que una clase es derivada de otra o de una interfaz. default: Indica el bloque de código por defecto en una sentencia switch. else: Indica la opción alternativa en una sentencia if. future: Reservada para uso futuro. finally: Indica un bloque de código en una estructura try .catch que siempre se ejecutará. do: Inicia un bucle do-while. catch: Captura las excepciones generadas por las sentencias try.

instanceof: Indica si un objeto es una instancia de una clase específica o implementa una interfaz específica. public: Especificador de acceso utilizado para clases. rest: Reservada para uso futuro. static: Indica que una variable o método es un método de una clase (más que estar limitado a un objeto particular). . interfaces. protected: Especificador de acceso que indica que un método o variable sólo puede ser accesible desde la clase en la que está declarado (o una subclase de la clase en la que está declarada u otras clases del mismo paquete). native: Especifica que un método está implementado con código nativo (específico de la plataforma). return: Envía control y posiblemente devuelve un valor desde el método que fue invocado. long: Tipo de dato que soporta un entero de 64 bits. outer: Reservado para uso futuro. package: Declara un paquete Java. operator: Reservado para uso futuro. switch: Sentencia que ejecuta código basándose en un valor. . super: Se refiere a una clase base de la clase (utilizado en un método o constructor de clase). null: Indica que una referencia no se refiere a nada. int: Tipo de dato que puede soportar un entero con signo de 32 bits. métodos y variables que indican que un tema es accesible desde la aplicación (o desde donde la clase defina que es accesible). interface: Declara una interfaz. short: Tipo de dato que puede soportar un entero de 16 bits. private: Especificador de acceso que indica que un método o variable sólo puede ser accesible desde la clase en la que está declarado.inner: Reservada para uso futuro. new: Crea objetos nuevos.

pero sí es bueno para empezar. transient: Especifica que una variable no es parte del estado persistente de un objeto. así como los estados de compilación y ejecución. throws: Indica qué excepciones puede proporcionar un método. 1 Si es nuevo en Java. while: Inicia un bucle while. volatile: Indica que una variable puede cambiar de forma asíncrona. Escriba este código en un archivo llamado app'java: public class app ( public static void main(String [ ] args) ( S y s t e m . var: Reservado para uso futuro. . void: Especifica que un método no devuelve ningún valor. o u t . ¿Qué va a escribir? A continuación hay un ejemplo de aplicación Java que se desarrollará en las siguientes secciones del libro. this: Se refiere al objeto actual en un método o constructor throw: Crea una excepción. ¿no? iHágame una demostración!" Usted se va hacia la terminal e inmediatamente su mente se queda en blanco. p r i n t l n ( ~ o l adesde Java! " ) . Por ejemplo. así sería en una ventana DOS desde Windows: C:\>java app ¡Hola desde Java! No se trata de uno de los programas más significativos. esto puede que le resulte extraño.synchronized: Especifica secciones o métodos críticos de código multihilo. try: Inicia un bloque de código que es comprobado para las excepciones. "Ya puede escribir Java. Veamos este programa línea por línea. Escribir código: crear una aplicación El gran jefe llega y dice. La idea es que esta aplicación visualice el texto "¡Hola desde Java!" cuando se compile y se ejecute.

java (observe que Java es bastante particular en esto. Java le obliga a dar un nombre al archivo. Observe la palabra clave public en el código anterior. .class". El especificador de acceso public indica que esta clase está disponible en cualquier parte del programa que la utilice. estará entre llaves: public class app í Java siempre encierra bloques de código entre llaves. sólo se puede tener una en cada archivo. sólo puede tener una clase pública en un archivo con extensión ".public class app Esta es la primera línea de app-java: public class a99 { Esta línea indica que estamos creando una clase de Java nueva llamada app. sabrá cómo mirar en el archivo app. el código para la clase app debe estar en un archivo llamado app. y el uso de mayúsculas hay que tenerlo en cuenta). y si JVM necesita la clase app. La implementación de la clase que estamos definiendo ahora. sobre la que aprenderá más en los capítulos 4 y 5. Después de que esta clase la transformemos en bytecodes.javaW. Observe además que si construye una clase pública.class. Esta palabra es un especificador de acceso. Como verá en el capítulo 4. este código es sólo para empezar con la programación Java. Por esa razón. razón de esto es que el compilador de Java traduce La el archivo de extensión ". A partir de ahora. lo que significa que app'java se convertirá en app.class. continuaremos construyendo nuestra aplicación siguiendo con la siguiente línea de código. ' { ' y '}'. la máquina virtual de Java podrá crear objetos de esta clase y ejecutarlos. es decir. el código de un bloque tiene su propio alcance (su visibilidad para el resto del programa). Dado que JVM utiliza el nombre del archivo para determinar las clases públicas que hay en él.javan en un archivo bytecode con la extensión ". Aprenderá todo sobre las clases en el capítulo 4. Es decir.

Cuando encuentra el método rnain. no usaremos args en el código del método main. cuando llama a un método. . que es el método que la máquina virtual de Java busca cuando inicia una aplicación (las applets no tienen método main). También debe declararse como static. un bloque de código al que se le puede pasar el control y que puede devolver un valor. Cuando se termine de ejecutar. Estos elementos son valores que se pasan desde la línea de comandos cuando se inicia la aplicación. Los métodos permiten manejar fácilmente el código en una unidad funcional sencilla. Todos los detalles se mostrarán en el capítulo 4. pero aquí la idea es que estamos creando un método llamado main. por lo cual usamos la palabra void en este código (en otras palabras. Un método en la programación orientada a objetos es como una función o subrutina en la programación estándar.public static void main[String[] args) Esta es la siguiente línea de código de nuestra aplicación: public class app { public static void main(String[l arga) { Aquí estamos creando un método de la clase app. y nos situamos en la parte del código que queremos ejecutar de este bloque de código del método. no debe devolver ningún valor. por ejemplo. que main es un método de una clase. Antes de continuar hay varias cosas que observar. no un método de un objeto. que significa. Los métodos serán tratados formalmente en el capítulo 4. lo que quiere decir que puede ser llamado desde fuera de su clase. Dado que no usaremos ningún argumento desde la línea de comandos en esta aplicación. entonces "Hola" y "ahí" serían las dos cadenas del array args. Finalmente. como veremos en el capítulo 4. la máquina virtual de Java ejecuta el código de ese método. estamos indicando que a main se le pasa un array cuyos elementos son cadenas de caracteres. JVM le pasa control. llamado args. En este caso. observe el argumento entre paréntesis que sigue a la palabra main: String[] args. El método main debe declararse con el especificador de acceso public. Aparece una lista de argumentos entre paréntesis en la declaración de un método para indicar que los valores se le pasan al método y que el código del método puede usarlo. si escribe 'Ijava app Hola ahí". un valor de retorno de tipo void significa que actualmente no devuelve valor).

En este caso. y este campo. Todo el trabajo de este método es visualizar el texto "¡Hola desde Java! ".out.java. ya que el compilador de Java rechaza la traducción a bytecodes hasta que el punto y coma esté en su sitio. lo que quiere decir que no hay que hacer nada especial para utilizarlo. inicia el método main. que hace que se visualice el texto. En particular la clase System del paquete java. lo que se realizará en la siguiente línea de código. Para imprimir el texto "¡Hola desde Java!". lo conseguirá rápidamente. Observe además que esta línea de código termina con un punto y coma ('. usamos la terminología Systern.lang incluye un campo (es decir. a diferencia de otros paquetes Java.out. a su vez. La clase System del paquete java.Esta línea de código.println cerrándolo entre comillas. > 1 Esta es la línea de código que hace todo el trabajo.out. usamos la terminología System.'). Compilación El gran jefe. tiene un método llamado println. Java ha heredado muchas cosas de C y C++). El método main tiene una línea de código: public class app I public static void main(String[] args) ( System. se lo pasamos a System. Si no está acostumbrado a ello.out.println. hemos creado una nueva aplicación y la hemos almacenado en un archivo llamado app.println("iHola desde Java!"). Echemos un vistazo al siguiente tema. En Java. ¿Cuál es el siguiente paso? Ejecutarlo. las librerías de clases se llaman paquetes y el paquete java.println("iHola desde Java! "). mascando un cigarro. Para referirse al campo out de la clase System. y casi todas las sentencias de Java se terminan con punto y coma. System. Esto es algo que Java ha heredado de C y C++ (de hecho. Para utilizar el método println del campo out.out. "Hmm". estamos usando el código que los programadores de Sun ya han creado para visualizar el texto "¡Hola desde Java!". permanece de pie detrás de usted mientras guarda la nueva aplicación Java en un archivo. Por lo tanto. un miembro de datos de la clase) llamado out.lang. entonces. dice el gran .lang está en todo programa Java.

printline("iHo1a desde Java!"). "De acuerdo. "tenemos que compilar el programa y ya podremos ejecutarlo". archivos fuente: Uno o más archivos que se van a compilar (como app-java). como en este caso en el que hemos olvidado el métodoprintln e intentamos usar uno llamado printline: C:\javac app. @archivos: Uno o más archivos de la lista de archivos fuente. que está en el directorio bin de Java). toma el archivo app.String) not java. este programa se llamará javac. nada impresionado.java app.out. jcómo lo ejecutamos en JVM? Veamos el siguiente punto.class.class. dice el programador novato.class" en el mismo directorio. Me gusta guardar todos mis archivos con extensión ". en las máquinas Windows. java El compilador de Java. Ahora. que se llama javac (por ejemplo.io .exe. A continuación se indica cómo usará javac en general: javac [opciones] [archivos fuente] [@archivos] Argumentos de javac: opciones: Opciones desde la línea de comandos. "Sorpréndame". app. el nuevo archivo. usaremos este comando: C: \ javac app. Compilación: utilizando opcíones en la línea de comandos "Hmm". System.jefe. "¿Y ahora?" "Ahora".1ang. "tengo un problema.java:5: Method printline(java.Print Strearn. pero .class. Para compilar app. Si hubiera errores. Ya hemos creado app." dice el gran jefe. el compilador de Java nos avisará de que hay errores incluyendo qué Iínea de código está mal. 1 error found in class Cuando app. traduciéndolo y creando un nuevo archivo Ilamado app. dice.java y (suponiendo que no haya errores) lo compila. Para traducir un programa Java a un archivo bytecode que la máquina virtual de Java pueda utilizar. javac.java. contiene todo 10 que la máquina virtual de Java necesitará para crear objetos de la clase app. usará el compilador de Java.java está compilado sin errores.

el archivo de clases se llama c:\clases\com\package l\Classl . Usando esa opción. Muestra una descripción de cada uso o sobrescritura de un miembro o clase censurado. -d directorio." dice el programador. Class1. Genera todo la información de debugging.. sobrescribiéndola en la variable de entorno CLASSPATH. que ya~existe que. Observe que las opciones que empiezan con -X (llamadas opciones no estándar) están marcadas de esa forma por Sun ya que pueden cambiar en el futuro: -classpath ruta de acceso. sólo tengo que acordarme de utilizar esa opción . Fija el nombre codificado del archivo fuente. . puede situar los archivos creados por el compilador en el directorio de destino que quiera". creando los directorios necesarios. sólo se genera el número de línea e información del archivo fuente..class. -encoding. javac pone el archivo de clases en el mismo directorio que el archivo fuente. (Sin -deprecation. Por ejemplo. java A continuación se muestra la lista de opciones de javac. "Hay una opción del compilador que es perfecta para eso: la opción -d.package1. Para los lectores que sepan qué son los paquetes Java. Por ejemplo. javac pone el archivo de clase en un subdirectorio que refleja el nombre del paquete. -deprecation. indicaremos cómo usar la opción -d para situar el archivo app. en este caso. Observe que el directorio indicado por -d no se añade automáticamente a su ruta de acceso de clases. si especifica -d c:\clases y la clase se llama com.class en el directorio temp. -g. Observe que si no se usa la opción -sourcepath. "Entonces. se usará el convertidor por defecto de la plataforma. Establece la ruta de acceso del usuario. Si no se especifica -encoding.algunas veces se me olvida copiar las nuevas versiones de esos archivos en ese directorio". incluyendo variables locales. Hay un buen número de opciones que se pueden usar con javac. Si no se especifica CLASSPATH ni -classpath... la ruta de acceso se busca tanto para los archivos fuentes como para los archivos de clase. Si no se especifica la opción -d. la ruta de acceso es el directorio actual. Por defecto. app. Fija el directorio de destino de los archivos de clase. si una clase forma parte de un paquete. javac sólo muestra los nombres de los archivos fuente que usan o sobrescriben miembros o clases censurados). es un subdirectorio y del directorio actual: javac -d T e m p .

Deshabilita todos los mensajes de aviso. Optimiza el código para la ejecución en términos de hacer más rápido el tiempo de ejecución. Observe que antes de tener JDK 1. -Xdepend.2. Crea la salida "verbose". que verá más tarde. -O. el nombre local de la ruta de acceso dentro del directorio o del archivo debe reflejar el nombre del paquete. las. Por defecto. Al igual que con la ruta de acceso de clases.2. -X. Esta opción descubrirá clases que necesitan ser'recompiladas. Observe que utilizar la opción -O puede ralentizar la compilación. Si usa paquetes. Envía mensajes del compilador a System.-g:none. Hace que el compilador no genere ningún tipo de información de debugging.jarW) o archivos zip. los mensajes del compilador van a System. como verá más tarde. Especifica la ruta de acceso de las fuentes para las definiciones de clases o de interfaces. Con JDK 1. -verbose. -Xverbosepath. lines (información de debugging del número de línea) y vars (información de debugging de Ias variables locales). producir archivos de clase más grandes y hacer que el programa sea difícil de poner a punto. -nowarn. puede combinar -g y -O. .entradas se separan por punto y coma ('. como pérdida de variables o de código. las opciones -g y -O no podían usarse juntas.') y pueden ser directorios. Busca todas las clases que pueden ser utilizadas por los archivos fuente más recientes para recompilar. archivos Java (con extensión ". -sourcepath ruta de acceso de fuentes. Incluye información sobre cada clase cargada y de cada archivo fuente compilado. Sólo genera algunos tipos de información de debugging. Observe que las clases buscadas en la ruta de acceso de clase serán recompiladas automáticamente si sus archivos de código fuente no se encuentran. Visualiza información sobre las opciones no estándares.err. Describe las rutas de acceso y las extensiones estándar que fueron localizadas para buscar archivos fuente y de clases. Las palabras válidas son source (información de debugging del archivo fuente). -Xstdout.out. pero puede ralentizar enormemente el proceso de compilación. -g:(lista de palabras reservadas). especificados por la lista de palabras reservadas separadas por coma. pero puede obtener resultados inesperados.

1 y 1. Por defecto se generan archivos de clase que son compatibles con JVM 1.1 (asegura que los archivos de clase generados serán compatibles con JVM 1. "Eso es fácil".I).jarW los directorios indicados es localide zado automáticamente por los archivos de clase. Opciones de compilación cruzada Las opciones de compilación cruzada se consideran un tema avanzado de Java. estas entradas están separadas por punto y coma ('. Realiza la compilación cruzada contra el conjunto de clases de arranque indicadas. no sé lo que es obsoleto y lo que no". Usa esta opción para pasar una opción al lanzador de Java llamado por javac. -bootclasspath ruta de acceso de arranque.2. Por ejemplo.') y pueden ser directorios.2 (genera archivos de clase que se ejecutarán en JVM 1.'). javac soporta la compilación cruzada. Al igual que con la ruta de acceso de clases.2 pero no en JVM 1 . los directorios están separados por punto y coma ('. "El compilador de Java. responde. Cada archivo con extensión ". Realiza la compilación cruzada contra los directorios indicados.2 son 1. . javac. -J-Xms64m fija la memoria de inicio a 64 MB. archivos con extensiónW. Aunque esta opción no empieza con -X. le dirá si está usando un método que ya ha sido abandonado. no es una opción estándar de javac. A continuación se indican las opciones de compilación cruzada: -target versión.-Joption. en la que las clases se compilan mediante un proceso autosuficiente (por defecto) y la implementación de extensión de clases. " jcómo puedo cambiar todos los métodos censurados para que sean correctos? Ahora que ya estoy en Java 2. Se debe utilizar -bootclasspath y -extdirs cuando se esté hablando de compilación cruzada. -extdirs directorios.2. esto es por defecto) y 1.1 y 1. dice el programador. Las versiones soportadas por javac en JDK 1. Compilación: revisión de los métodos censurados "Bueno".jar"o archivos zip. Es una convención para pasar opciones a las aplicaciones escritas en Java que se están ejecutando en JVM. Genera los archivos de clase que trabajará en JVM con la versión indicada.

exe del directorio bin de Java). Ejecución del código El gran jefe se está poniendo impaciente. llamado utilidad java. y es la opción estándar que utilizo para asegurarme de que estoy evitando los métodos obsoletos. 1 warning Please consult Como puede ver. getSize. A Note: app.1 Estos son los parámetros de las líneas anteriores: opciones.java utiliza el método size en la línea 109 y ese método es obsoleto.stringWidth(text) ) / 2 . Recompile with " deprecation" for details. A continuación puede ver cómo usar la utilidad java: java [opciones] clase [parámetro . y que cuando lo intenta compilar.jar [parámetro . . Opciones de la línea de comandos. . 1 warning Esto no es de mucha ayuda. se resuelve el problema. puede conocer el problema exacto: C: \>javac app. por ejemplo. puede usar la opción -deprecation para asegurarse de tener todos los detalles". .width . El programa java. pero realmente no ha ocurrido nada que el gran jefe pueda ver. es el archivo java. 1 java [opciones] -jar archivo.java uses or overrides a deprecated API. que se verán en otro apartado. Supongamos que tiene un programa de 200 líneas.Component has been deprecated.java:109: Note: The method java. La opción -deprecation es buena.Mejor aún.java -deprecation app. es lo que realmente ejecuta JVM.awt. . Las aplicaciones Java se ejecutan con el programa llamado java (en Windows. java Note: app. Es hora de ejecutar la nueva aplicación.awt. the documentation for a better alternative. el problema es que app. javac le devuelve este resultado: C : \ javac app . Ha escrito usted una nueva aplicación y la ha compilado sin errores a la primera (de lo que puede sentirse orgulloso).Dimension s i z e 0 in class java.java uses or overrides a deprecated API. x = ( s i z e 0 . Si se reemplaza por el método de la nueva versión. . utilizando la opción -deprecation. Sin embargo.fontmetrics.

Parámetro. que está en el archivo app. ¡Felicidades! Figura 1. verá cómo crear aplicaciones ventana.class. Ya ha escrito. Los archivos JAR se tratan en el capítulo 23. y cuando ejecute una de estas aplicaciones con la utilidad java. obtendrá los resultados que aparecen en la figura 1.5. Hay algo que hacer notar sobre la figura 1. inténtelo con la tecla Esc. la ventana consola (aquí una ventana DOS) está por debajo y espera que la aplicación termine antes de . en este libro. para ejecutar la aplicación llamada app. podría ejecutar el siguiente comando en la línea de comandos (observe que se omite la extensión".5. Nombre del archivo de archivo Java (JAR) al que se llama. Nombre de la clase a la que se llama. Un parámetro de la línea de comando que se pasa al método main.clase.jar. Si no funciona.4. Además. compilado y ejecutado su primera aplicación. archivo.4 puede ver cómo funciona en una ventana DOS bajo Windows. Por ejemplo.class" de app. Ejecución de una aplicación en una ventana DOS. Eso es todo. puede pulsar Control-C. Observe que si su aplicación no responde o si quiere pararla por alguna razón.class): java app El resultado aparecerá inmediatamente: java app ¡Hola desde Java! En la figura 1. Se usa sólo con -jar.

5. el lanzador oldjava. si la está ejecutando en DOS. hay otro lanzador en Java 2. . Este lanzador no soporta el framework de extensiones Java (ver el punto "¿Cuáles son las novedades de . Ejecución de una aplicación ventana. que trataremos próximamente. la aplicación aparece y el prompt DOS reaparece en la ventana DOS. Parámetro. Cuando usted lanza una aplicación ventana de Java como esta. clase.jar. Se usa sólo con -jar. Nombre de la clase a la que se llama. antes de que elprompt de DOS aparezca en este caso). como se indica: j avaw app Figura 1. 1 . Esto da un sentido más profesional a estas aplicaciones.continuar (es decir. puede utilizar la utilidad javaw. Si no quiere que una ventana consola esté asociada con su aplicación ventana. 1 Estos son los parámetros utilizados con javaw: opciones. Un parámetro de la línea de comandos pasado al método main. Archivo. Opciones de la línea de comandos. . . javaw [opciones] -jar archivo. Los archivos JAR se tratan en el capítulo 23. A continuación se indica cómo se utiliza javaw en general.jar [parámetro . De hecho. la ventana consola no espera a que la aplicación termine. que Sun incluyó para la compatibilidad hacia atrás. igual que la utilidad java: javaw [opciones] clase [parámetro . Nombre del archivo de archivo Java (JAR) al que se llama.

"Otro problema fácil de resolver. También . javaw u oldjava. "Puede usar la opción -classpath de la utilidad java o establecer la variable de entorno CLASSPATH para que el compilador de Java busque las clases correctamente". por lo que no se usará mucho el oldjava.2 (o quizás las clases que se están cargando han sido generadas o cambiadas de alguna forma que es incompatible con la estructura de clases de 1.Java 2?")." le dice. En este libro estoy siguiendo Java 2. Cuando lance una aplicación java2." dice el programador. Proporciona compatibilidad hacia atrás cuando tiene una aplicación que utiliza el estilo de seguridad de Javal. He almacenado todos mis archivos con extensión ".2). "tengo otro problema. Así es como puede ejecutar una aplicación. usando cualquier utilidad de Java: java. hay una utilidad oldjavaw. pero si está migrando a Java 2 y necesita usar el mecanismo de carga de clases antiguo. hay otro detalle que deberíamos tratar: las opciones de la línea de comando que se pueden usar con los comandos javac y java. que es incompatible con las técnicas de carga de clases de 1. el compilador Just In Time (JIT) compila los bytecodes y ejecuta la aplicación. es bueno saber que está ahí. pero no quiero estar cambiando a ese directorio para ejecutarlos". 1. .class" en un directorio. Mientras estemos en'el tema de compilar y ejecutar el código. Ejecución de código: utilizar las opciones de la línea de comandos "Bien. Les echaremos un vistazo en los dos apartados siguientes.

la ruta de acceso a las clases de usuario está limitada al directorio actual.jar [parámetro . Las herramientas oldjava y oldjavaw no soportan la opción -jar." ya tratado en este capítulo): java [opciones] clase [parámetro .con las utilidades java. Visualiza información sobre cada clase que está cargada. que quiere decir que en un futuro puede que no estén soportadas. especifican la ruta de acceso para las clases de usuario y las de arranque.'). Si no se especifican ni -classpath ni -cp y CLASSPATH no está. Se separan las entradas con punto y coma ('.jar [parámetro . 1 oldjavaw [opciones] -jar archivo.Echaremos un vistazo al uso de las opciones de la línea de comandos en este punto. -jar. empiezan con una X): -classpath ruta de acceso o -cp ruta de acceso. Usadas con oldjava u oldjavaw." más adelante en este capítulo para más información. Informa sobre cada evento de la colección garbage. . . . Ver el apartado "Conocimientos básicos: búsqueda de clases Java con CLASSPATH. . El primer parámetro es el nombre de un archivo JAR en vez de un nombre de clase de inicio. Especifica una lista de directorios. -classpath o -cp sólo especifican la ruta de acceso para las clases de usuario. javaw y oldjava. de la siguiente forma (para ver información sobre estas utilidades. 1 oldjava [opciones] clase [parámetro . Utilizadas con java o javaw. 1 javaw [opciones] -jar archivo. Cuando usa esta opción.'). que está referenciado con un punto ('. . 1 java [opciones] -jar archivo. Ejecuta un programa encapsulado en un archivo JAR. . -verbose:gc... archivos con extensión". . ver la sección "Ejecución del código. el archivo JAR es la fuente de todas las clases de usuario y el resto de las rutas de acceso a otras clases de usuario se ignoran. -verbose o -verbose:clase. 1 javaw [opciones] clase [parámetro . . Utilizará estas opciones. . Observe que al especificar cualquiera de estas dos opciones se está borrando lo que indique la variable de entorno CLASSPATH. .zip" para localizar archivos de clase. . -Dproperty=valor. Esta colección realiza la gestión de memoria en Java. 1 A continuación se citan las opciones de la línea de comandos que puede utilizar con estas herramientas (observe que las opciones no estándar. Fija un valor de propiedad del sistema.jar [parámetro .jar" o archivos con extensión".

-Xdebug. Especifica una lista de directorios separados por punto y coma ('. Visualiza información de ayuda y se cierra. añadir la letra 'k'. -Xfutrue. Inicia con el debugger habilitado. "Su código". . -Xnoclassgc. -Xrs. añadir la letra 'k'. Observe que estos serán utilizados en lugar de los archivos de las clases de arranque que Java incorpora. Deshabilita la colección de clases garbage. Habilita el seguimiento de la CPU. Para multiplicar el valor por un millón. Ejecuta un seguimiento estricto del formato de archivo de clases. -Xbootclasspath:ruta de acceso de arranque. dice. -Xmsn. Visualiza información sobre la versión y se cierra. Esta opción va seguida normalmente por una lista de pares separados por coma ('. "No puedo imaginar lo .-verbose:jni. Reduce el uso de las señales del sistema operativo. añadir la letra 'm'. archivos con extensión ".zipVpara localizar los archivos de la clase de arranque. -Xmxn. específicos de la plataforma) y otras actividades de la interfaz nativa de Java. Da información sobre el uso de métodos nativos (es decir. Xcheck:jni. -? o -help.. Indica el tamaño de memoria inicial que se quiere utilizar (este valor debe ser mayor que 1000).. Conocimientos básicos: comentar el código La persona encargada de la corrección del programa entra y le mira con reproche. El valor por defecto es 64m. Especifica el tamaño máximo de memoria (este valor debe ser mayor que 1000). Xrunhprof[:help] [: csubopción>=cvalor>. Para multiplicar el valor por 1000. Para multiplicar el valor por 1000. la pila o del monitor. Para multiplicar el valor por un millón.l. -version.') de la forma <subopción>=<valor>. -X. pregunta.'). añadir la letra 'm'. El valor por defecto es lm. "¿Qué ocurre?. Ejecuta tratamientos adicionales para las funciones de la interfaz nativa de Java.jar" o archivos con extensión ". Visualiza información sobre las opciones no estándares.

se espera que se use una cabecera de comentario estándar.out. Whiz. Java le permite comentar su código para explicar a todo el mundo que lo lea cómo funciona el programa y lo que hace.println("iHola desde Java!"). creado con "/*" y "*/" para todo código nuevo.out. dice él. olvidé comentarlo".out. "Arréglelo".que ahí está escrito". "Le pido que lo haga". 1 1 El compilador de Java ignorará todo el texto que esté entre "/*" y "*/". dice. Por ello. Como ejemplo. . 1/1/00 */ public static void main(String[] args) ( System.Holadesde Java!" * Autor: G. 1 1 Java admite tres tipos de comentarios. "Lo siento. el código puede ser muy críptico y difícil de descifrar. De hecho. dos de los cuales son de C++. añadamos comentarios a la aplicación que ya hemos desarrollado en los puntos anteriores: public class app public static void mainíString[l args) ( System.Whiz . Puede dividir los comentarios que ponga entre estos indicadores en varias líneas: / * Esta aplicación visualiza "iHola desde JavalR Creado por: public class app { 0.println("iHola desde Java! " ) .Hola desde Java!" * / public class app I public static void main(String[] args) { System. en muchos entoinos corporativos. Sería algo así como: * Esta aplicación visualiza ".println("iHola desde Java!"). A veces. Puede poner cualquier comentario de cualquier longitud con los caracteres y "*/u: "/*M / * Esta aplicación visualiza ".

* ~mportaciones: Ninguna * Parámetros: Argumentos de la línea de comandos * Retorno: Ninguno * Supuestos: Ninguno * Fecha de creación: 1/1/00 * Última actualización: 1/1/01 public class app { * * * e * * ****************************** public static void rnain(String[] args) { System.println("iH01a desde Java!"). Además es muy cómodo si otra persona va a retomar el proyecto en el que ha estado trabajando usted.Hola desde Javanl * / public class app { public static void main(String[] args) ( System.out. A continuación hay un ejemplo para el uso de "/**" y "*/": / * * Esta aplicación visualiza ".out. .out. Java también soporta un comentario que se inicia con "/**" y que termina con "*/". "11".println("iHola desde Java! " ) . El compilador de Java ignorará toda la línea después de la doble barra. punto de entrada a la aplicación. que permite crear documentación casi automáticamente. public static void main(String[l args) { / / Visualizar el mensaje con System. por lo que puede crear líneas enteras de comentarios o añadir un comentario a una sola línea: / * Esta aplicación visualiza "¡Hola desde Java!" * / public class app ( //Crear la clase app //Crear main( ). 1 1 Java también soporta una línea de comentario utilizando la doble barra. 1 1 Comentar el código es de gran importancia en entornos de grupo donde se comparten los códigos de los archivos fuente. Este comentario está diseñado para usarse con la herramienta javadoc. 1 1 Finalmente. Echaremos un vistazo a esto en el capítulo 21.println('iH01a desde Java! " 1 .

de la que aprenderemos más en el capítulo 4): import java. Las clases que Sun ha creado están almacenadas en librerías de clases llamadas "paquetes". Además puede importar clases individuales que no son parte de un paquete. por ejemplo.util. A continuación se indica cómo importar esa clase en un programa: import java..paquete2. Puede referirse a la clase Date en java.uti1 como java.Date. Observe que se pone un punto ('. pero para usar el resto de las clases que vienen con Java tendrá que hacer la importación con la instrucción import.util. Los paquetes Java estándares están almacenados en un gran paquete llamado java. Por defecto. El coordinador del equipo de diseño me dijo que usara la clase Date para visualizar la fecha actual en mi aplicación. ]. dice el programador novato.lang. lo que quiere decir que el compilador localizará ese paquete para esas clases. Para que una clase de un paquete esté disponible en su código. public class app I . tiene que importar el paquete. como se indica a continuación (observe que estamos creando un objeto de la clase Date usado el operador Java new. "tengo un problema. por lo que el paquete de utilidades se llama realmente java. el paquete swing está almacenado en el paquete java). éstas deberían estar en la parte de arriba del código. public class app ( 7 Observe que si va a usar las sentencias import para importar clases en un programa.lang.uti1 (hay otros grandes paquetes disponibles. "Eso se debe a que la clase Date forma parte del paquete de utilidades de Java y tiene que importar ese paquete antes de que pueda utilizarlo". "iImportarlo?".') entre el paquete y los nombres de clase para separarlos.Date. Así. podemos utilizar la clase Date.. las del paquete java.Conocimientos básicos: importando paquetes y clases Java "Hmm".Date. sólo las sentencias básicas de Java están disponibles en una aplicación. me da un error cada vez que intento usarlo".]-(nombrede clase[*). pero Java parece no entender la clase Date. pregunta el programador. El compilador automáticamente importa el paquete java. Aquí se muestra cómo utilizar esa sentencia: import [paquetel[.util.

println("Hoy = " + new Date()). o u t . donde estamos creando un nuevo objeto de la clase printer usando el operador new y usando el método printer de ese objeto en una aplicación llamada app: . se puede usar un asterisco ('*') para utilizar todas las clases de un paquete específico. llamado print: public class printer I public void print( ) C System. ya que Java sabe donde buscar las clases con las que fue instalado. 1 1 Esto está bien si se quiere importar las clases proporcionadas por Sun. 1 > Podría querer utilizar el método print en otras clases.java.~ut. Supongamos que tiene una clase llamada printer en un archivo llamado printer.println(~~Hola desde Javaln). Pero ¿qué pasa si quiere importar sus propias clases u otras proporcionadas por un tercero? He aquí hay un ejemplo. A continuación se indica cómo se podría hacer si quisiera importar todas las clases del paquete java.public static void main(String[] args) > ~ ~ s t ~ . como en este caso.uti1 de una vez: public class app { public static void main(String[] args) { System. hay también una técnica taquigráfica que carga todas las clases de un paquete. verá la fecha del día: c:\>java app HOY = Lunes 2 Agosto 12:15:13 EDT 2000 Como puede ver estudiando la forma general de la sentencia previa import.out. p r i n t l n ( ~ H o y + nrr Date( ))j = m 1 Cuando ejecute esta aplicación. y esa clase tiene un método.

¿Cómo encontrará el compilador printer. Java podrá encontrar sus clases de arranque (con las que viene).class está en el mismo directorio en el que se está compilando esta aplicación. "Ese es el problema". "Me dio un archivo de clases nuevo. Por defecto.class allí? Para contestar a esa pregunta. "llamado jorobadojohnson". extensiones de clases (esas que usan el framework de extensiones Java. supongamos que quiere almacenar todas sus clases en un directorio llamado c:\clases. ver en este mismo capítulo) y clases en el directorio actual (es decir. puede importar la clase printer de esta forma (observe que puede además poner el código de la clase prínter en el mismo archivo que la clase app. dice el PN. en cuyo caso no tendría que importar la clase printer): import printer: public class app public static void main (String[ 1 args) { (new printer ( ) ) . y se suponía que resolvería mis problemas con esa hoja de cálculo. le pregunta. veamos el siguiente punto CLASSPATH.class. le dice. Las clases pueden almacenarse en . 1 1 Esto funciona como debería. dice el programador novato. "En un directorio especial que creé .print ( ). Sin embargo.ara ello". 1 1 Para ello. "¿Dónde tiene ese archivo?". Pero Java dice que no puede encontrar johnson. donde está compilando su programa).class". Felicidades. public static void main(String[l args) ( (new p r i n t e r ( ) ) . "Tiene que incluir el directorio jorobadojohnson en su ruta de acceso a clases". para trabajar con él.public class app i. acaba de importar una clase en su programa. johnson. Conocimientos básicos: buscar clases Java con CLASSPATH "Ese jorobado Johnson".print ( ) . Esta técnica es buena si prínter. ya que el compilador Java buscará el directorio actual por defecto.

class está en el mismo directorio en el que se está compilando esta aplicación. llamado print: public class printer I public void print { ( ) System. Pero supongamos que quiera almacenar todas sus clases en un directorio llamado c:\clases. ¿Cómo buscará el compilador Java printer. ya que Java usa esta variable para determinar dónde quiera buscar las clases. como se indica a continuación para Windows (observe que es importante no dejar espacios entre los signos de igual): . public class app { public static void main(String[] args) { (new printer ( )) . porque el compilador de Java buscará el directorio actual por defecto.class ahí? Para que el compilador Java busque en c:\clases. pero puede añadir a CLASSPATH una lista con separaciones por punto y coma ('.archivos con extensión ". ". Veamos un ejemplo que introduje en el punto anterior. Digamos que tiene una clase llamada printer en un archivo llamado printer. como en este caso. y Java puede localizar todo este tipo de archivos. puede fijar la variable de entorno CLASSPATH para que incluya ese directorio. como en el punto anterior. Pero ¿qué ocurre si quiere hacer una búsqueda de clases en otro directorio suministradas por un tercero? Puede o en un archivo con extensión ". donde creamos un nuevo objeto de la clase printer usando el operador new y usando el método print de ese objeto en una aplicación llamada app: import printer. Por defecto.java. y esa clase tiene un método. 1 1 Esto funciona si printer.classW. > 1 Ahora supongamos.jarW hacerse con la variable de entorno CLASSPATH.jarW ".print ( ).println(~iHoladesde Java! " ) . que quiere usar el método print de otras clases.~ut. no hay ninguna ruta de acceso ni directorios en CLASSPATH.zipW.').

haciendo que se vea el valor actual de CLASSPATH al final del cuadro de diálogo. Añadir la ruta de acceso que quiera a CLASSPATH y hacer clic sobre OK para cerrar el cuadro de diálogo de Propiedades del Sistema.En Windows NT. public class app I public static void main(String[] args) I ( n e w printerO). 4.class está en c:\clases. También puede saber el valor actual de CLASSPATH usando el comando SET: Ahora el compilador de Java (y otras herramientas Java como la utilidad java) tendrá suficiente información para buscar en c:\clases y c:\newclasses automáticamente. Hacer doble clic sobre Panel de Control para abrirlo.zipU para las clases: . ya que ese directorio está en CLASSPATH: import printer . 2. Hacer clic sobre la variable CLASSPATH. Abrir el menú Inicio y abrir el Panel de Control de la opción Configuración.jarUy ". puede seguir estos pasos para fijar la variable de entorno CLASSPATH: 1. 3. Esto significa que este código funcionará si printer. hacer clic sobre la pestaña Entorno. como sigue: Observe que también puede buscar archivos con extensión ". En el cuadro de diálogo Propiedades del Sistema.printO. 1 1 Puede añadir una nueva ruta de acceso en CLASSPATH a la que ya existe.

applet. Sin embargo. es importante saber cómo se fija CLASSPATH. Lo que es más.En los orígenes. Las applets no tienen un método main como las aplicaciones. considere esto como un aperitivo. Sin embargo. sería intolerable si no iniciáramos un libro de un lenguaje tan visual como Java con al menos una applet. El saber crear una applet básica le ayudará a probar. Las applets se introducirán formalmente en el capítulo 6. En este punto. que está en el paquete java. Crear applets El gran jefe se está impacientando. "De acuerdo". lo que significaba que había que fijar y entender CLASSPATH antes de que se pudiera usar Java. La clase java.applet. En los capítulos que siguen.Applet es la clase que forma la base para las applets estándar. que sería un duro camino si lo primero que se quisiera hacer fuera escribir applets en primer lugar.java: import java. le dice. comenzaremos importando esa clase en un nuevo archivo de código fuente Java. Esto se ha arreglado con el concepto de clases de arranque. y puede derivar sus propias clases de applets de esta clase usando la palabra clave extends: import java. "deme un minuto".Applet. esa es la diferencia principal . Las applets estándar están construidas en la clase Applet. que llamaremos applet. que son clases que vienen con Java (y son localizadas automáticamente).applet. si quiere usar paquetes no estándares y almacenar sus propias clases en otros directorios. la sintaxis de los siguientes capítulos. echaremos un vistazo a la sintaxis de Java. cubriré el proceso de crear una applet Java. public class applet extends Applet { Es hora de añadir código a esta nueva applet.applet. visualmente. de hecho. "¿Qué es todo esto de las aplicaciones que visualizan "¡Hola desde Java!" en la ventana consola? Queremos usar Java para crear applets que se puedan utilizar en los navegadores Web". CLASSPATH produjo dolor de cabeza a los programadores de Java ya que ninguna clase era considerada clase de arranque. por lo tanto.Applet.

*. dibujaremos el texto "¡Hola desde Java! " en las coordenadas (60. public class applet extends Applet ( public void paint(Graphics g) ( g.*.class. que la máquina virtual de Java llama cuando es hora de visualizar laapplet.applet. public class applet extends Applet public void paint(Graphics g) ( Este método paint es realmente una parte de Java Abstract Windows Toolkit (AWT). Veremos esto a continuación. En este caso.awt.Applet.100) en la applet. por lo que hemos importado las clases AWT con la instrucción import. que verá con gran detalle en este libro. Hay un paso más: crear una página Web para visualizar en ella la applet.applet. La clase java. por lo que esta posición está a 60 pixels del borde izquierdo de la applet y a 100 pixels del el superior. Applet tiene su propio método paint. las coordenadas se miden en pixels desde la parte superior izquierda de la applet. como sigue (ver capítulos 4 y 5 para más detalles de la sobrescritura): import java.awt.awt.drawString("iHola desde Javaln. ahora puede compilar applet-java para obtener applet. Este es el código: import java. 60.java.applet. 100). Verá cómo el siguiente método paint se pasa a un objeto Java de la clase Graphics (este objeto se llama g en el código). . Por lo tanto.entre applets y aplicaciones. import java. import java. 1 1 Eso es todo.App1et. pero podemos sobrescribir el método definiendo su propio métodopaint. ¿cómo se puede visualizar texto directamente en una applet? El trazado actual de una applet está contenido en su método paint. . Puede usar el método drawstring de este objeto para dibujar el texto.

htm1.6. se puede almacenar el HTML necesario en un archivo de código fuente de applets. dice el gran jefe.. Una applet funcionando con lnternet Explorer. Por ahora. Para visualizar una applet. aquí hay una página Web. applet. De hecho.Ejecutar applets "De acuerdo".. I I . Figura 1. donde la applet se ha abierto con Microsoft Internet Explorer. que visualizará la applet desarrollada en el punto anterior: Puede abrir esta applet en una página Web con un navegador Web. como se ve en la figura 1.6. puede usar una página Web con la etiqueta <APPLET>de HTML (Hypertext Markup Language). además lo aprenderá todo sobre la etiqueta <APPLET>en ese capítulo. "ha creado una applet. como podrá ver en el capítulo' 6. "Creo. ¿Por qué no lo veo en una página Web?" "Veámoslo."." dice.

Crear una aplicación ventana es parecido a la creación de una applet.Además puede usar el visualizador de applets de Sun. a w t . "Vayamos a ello". c l a s s AppFrame e x t e n d s Frame ( public void paintiGraphics g) { g. "¿Puede también hacer que una aplicación visualice ventanas?" "Por supuesto".htm1. 1 1 . Crear aplicaciones ventana El gran jefe está impresionado con su nueva applet y pregunta. * . Figura 1.drawString("iHola desde Javal".7 muestra la applet con el visualizador de applets de Sun. 60. que viene con Java. para abrir applet. con la excepción de que tiene que tener un método main. 100). y que usted es el responsable de crear la ventana. Una applet funcionando en el visualizador de applets de Sun. Con el fin crear la ventana para la aplicación. pero tomaremos un primer contacto aquí. le dice. Lo aprenderá todo sobre la creación de aplicaciones ventana en el capítulo 6. derivaremos una nueva clase de la clase AWT Frame y añadiremos el mismo código del método paint que se utilizó en la applet del apartado anterior: import j ava . de la siguiente forma: La figura 1.7.

Esta es la clase que tendrá un método rnain. Ejecutar aplicaciones ventana Como con las aplicaciones consola. y en ese método. ¿cómo se ejecuta? Echemos un vistazo al siguiente punto.drawString("iHola desde Java!".event. 60.awt. puede usar las utilidades java o javaw: j ava app j avaw app .awt. class AppFrame extends Frame { public void paint(Graphics g) ( g.Ahora crearemos la clase aplicación. Ahora que la nueva aplicación ventana está preparada. para ejecutar una aplicación ventana. import java. que llamaremos app. 1 1 public class app { public static void main(String [ I args) { AppPrame f = new AppFrame( ). 100).*. usaremos el operador new para crear un nuevo objeto de la clase AppFrame al que se le dará un tamaño en pixels y se mostrará en la pantalla: import java.*.

El diseño de los programas en Java no es tarea fácil. Esto es todo. Una aplicación ventana.8. Pero cuando se sienta usted allí. Muchos libros se dedican al diseño de programas. Capacidad de la aplicación para ser extendida de formas bien definidas. ahora ejecutaremos aplicaciones ventana Java. mientras que la utilidad javaw lanza la aplicación y no espera a que la aplicación sea desechada.8. Extensibilidad. Un buen diseño de programación involucra muchos aspectos. Mantenimiento.La utilidad java lanza la aplicación y hace que la ventana consola espere hasta que la aplicación sea desechada. se pregunta si es capaz de conservar su nueva posición. De hecho. uno de los aspectos más importantes de la creación de una nueva aplicación es diseñarla. . mirando fijamente la esquina de la ventana y golpeando su nueva mesa. La ejecución de la aplicación aparece en la figura 1. y echaremos un vistazo a algunos de ellos en este capítulo. Responsabilidad y optimización global de la velocidad y USO de recursos. Si no se selecciona bien puede que sea necesario hacer muchas revisiones del producto. Diseño de programas Java El diseño de la cabecera del programa ya está hecho. que debería saber algo de ello. Microsoft. Capacidad de la aplicación para ser mantenida fácilmente. divide el proceso en cuatro áreas: Rendimiento. y su nueva oficina funciona. antes de empezar a excavar en la sintaxis de Java. Figura 1.

Mantenimiento El mantenimiento es la medida de lo fácilmente que puede adaptarse su aplicación a necesidades futuras. Si los usuarios no consiguen lo que quieren con su aplicación. Este asunto se deriva de buenas prácticas de programación. Veamos rápidamente estas cuatro áreas. simplemente tener en mente las necesidades de codificación futura al escribir el código. Para algunas personas. He aquí algunos aspectos generales de rendimiento que debería considerar cuando escriba programas Java: eficiencia del algoritmo velocidad de CPU diseño y normalización eficiente de base de datos limitación de accesos externos velocidad de la red temas de seguridad de recursos velocidad de acceso a la Web USO A lo largo del libro trataremos más temas específicos de rendimiento. Evitar el paso de variables globales a procedimientos . Robustez de la implementación de la aplicación y disponibilidad para su uso. de las que hablaré a lo largo del libro. Algunos puntos de la "programación óptima" son los siguientes: Evitar el uso de bucles y condicionales anidados. la robustez o el uso eficiente de los recursos es lo que están buscando. el rendimiento depende de las necesidades de los usuarios.Disponibilidad. esto se convierte claramente un problema. Globalmente. el rendimiento de una aplicación es una indicación de lo bien que responde a las necesidades de los usuarios. Rendimiento El rendimiento es un tema de diseño que es duro de argumentar. para otros. Buena parte de esto es de sentido común. En general. la velocidad es esencial.

dar al usuario el estado de la operación). en comparación con el tiempo que los usuarios quieren utilizarla. usando elframework de extensiones Java. puede resultar sorprendente saber que algunos de ellos consideran que el diseño es. involucra a toda una interfaz especialmente diseñada para la extensión de módulos. Java. desde que no se quede congelada cuando se ejecuta una tarea larga (al menos. . en sí mismo.Ser modular cuando se escribe el código. Uso de procedimientos para el acceso a datos sensibles. Extensibilidad La extensibilidad es la capacidad de la aplicación para extenderse de una forma bien definida y relativamente fácil. Disponibilidad La disponibilidad es medir del tiempo que la aplicación puede utilizarse. el quince por ciento del proyecto total cuando se prueba un campo y se añaden planificación. Programar de forma defensiva. Uso de comentarios. Dar a cada procedimiento un único propósito. De hecho. Documentar los cambios de programa. todo el ciclo de desarrollo es tema de muchos estudios. al menos. con frecuencia. De hecho. Uso de constantes en lugar de números "mágicos". cuando el acceso al recurso deseado esté bloqueado. está diseñado para ser extendido. Uso de nombres de variables consistentes. Dividir el código en paquetes. Planificar la reutilización de código. Globalmente el proceso de diseño es de los que más tiempo requiere. Esto lo incluye todo. Asegurarse de que la aplicación puede extenderse sin problemas a más tareas y mayor número de usuarios. supone una preocupación en las aplicaciones grandes y. hacer backups de datos críticos y planificar el uso alternativo de'recursos. Generalmente. diseño y pruebas de interfaz de usuario. si es posible. hasta trabajar con técnicas y métodos que no se cuelguen.

no tiene que dar instrucciones a los usuarios para que establezcan las rutas de acceso en sus sistemas). lo que viene a decir que la licencia de JRE le permite empaquetarlo con su software. Aquí es donde la distribución de JRE en lugar de JDK ocupa un lugar destacado: El entorno de ejecución de Java es redistribuible. Dado que el JRE es pequeño. y estoy preparado para venderlo".com/products/jdk/l. Sin embargo. pero no incluye las herramientas de desarrollo y las aplicaciones que forman parte del JDK. el instalador JRE instala automáticamente java y javaw en la ruta de acceso del sistema operativo. El JDK de Java 2 contiene un entorno de ejecución. observe que la mayoría de los usuarios no tendrán todo el JDK Java 2 instalado. pero los programadores no deberían cambiar los pasos críticos del diseño en proyectos serios. El JRE contiene todo lo que los usuarios necesitan para ejecutar su software. necesitarán tener un entorno de ejecución Java en sus sistemas. es más fácil empaquetarlo con su software en vez de que los usuarios lo descarguen del sitio Web de software Java.sun. En Windows. dice el programador novato. Distribución del programa Java Bien". "Ah. "Revisaremos primero los temas de licencia". lo que significa que no tiene que preocuparse de encontrar los lanzadores para iniciar la aplicación (es decir. Puede encontrar más información sobre el entorno de ejecución de Java 2 en http://java.html. Mediante la distribución de JRE de su aplicación. jsí?" pregunta. y el JDK de Java 2 no. por lo que los usuarios podrían usar su programa si lo tuvieran instalado. El JRE es más pequeño que el JDK.No entraremos en más detalle sobre el ciclo de desarrollo de software. puede asegurarse de que sus usuarios tendrán la versión correcta del entorno de ejecución de su software. por lo que la mejor selección para los usuarios será el entorno de ejecución de Java 2 (JRE). Para que los usuarios ejecuten sus programas. ya que pueden dar más problemas en una ejecución larga que el tiempo que ahorran en una ejecución corta.2/runtime. . "he terminado mi programa Java.

Aunque ya programe en Java. enteros. porque hay mucho que ver. coma flotante y caracteres. arrays y cadenas Este capítulo inicia nuestra discusión sobre la sintaxis de Java. Esto hace que un dato de tipo int pueda tomar un rango de valores que va desde -2. vamos a tratar sobre cómo se almacenan y recuperan. Por ejemplo. Los diferentes tipos tienen que ver con el formato de los datos que se almacenan en ellas.147. Variables Las variables pueden ser de diferentes tipos y actúan como gestores de memoria de los datos. así como con la memoria que es necesaria para gestionar ese dato.483. . por ejemplo.147. El trabajo con datos es parte fundamental de cualquier programa. es de 4 bytes (o 32 bits) y se utiliza para almacenar valores enteros. la variable de tipo entero. hay bastantes tipos de variables.647.483. En Java. int. arrays y cadenas. y la información contenida en este capítulo es esencial para cualquier programador de Java. en Java. Aquí. que veremos en este capítulo.648 hasta 2.m Variables. y se verá gran parte de ella. los datos de variables. eche un vistazo al material de este capítulo.

A lo largo de este capítulo. . days = 365. especificando su tipo. Para comprobar que days contiene el valor 365. es decir que contiene un entero (la variable se llama days): public class app ( public static void main(String[] args) { int days. utilizando el operador de asignación de Java (=): public class app ( public static void main(String[] args) { int days. se indica cómo se almacena un valor numérico de 365 en days.Antes de usar una variable en Java. Ahora. nombre [ = valor] . . . days = 365. ]. veremos los tipos de constantes que Java permite. lo visualizamos por pantalla: public class app I public static void mainíString[] args) { int days. es decir. de forma que el compilador entiende la variable days y en el código puede haber referencias a ese nombre. A continuación se indica cómo se declaran las variables en Java: tipo nombre [ = valor] [ . En este caso. debe declararla. un valor constante que se sitúa directamente en el código. Este código aloca 32 bits de memoria y etiqueta esa ubicación. podemos ver cómo se declara una variable de tipo int. A continuación. el valor 365 es una constante entera.

Veremos todos estos tipos con más detalle más adelante. que guardan el signo y el valor. . Hay un convenio que permite inicializar una variable en el momento de declararla. Es posible almacenar un dato en una variable de cualquier tipo y ese dato debe estar dentro del rango permitido para ese tipo. ~ystem. se puede ver como days se declara e inicializa con el valor 365 en un único pasoi public class app ( public static void main(String[l args) { int days = 365. que guarda las representaciones de los caracteres. hemos creado una variable en la que se han almacenado datos y se ha obtenido ese dato para visualizarlo en pantalla. no uno compuesto (en oposición a un array. incluyendo el rango de valores que puede tomar cada uno. Así funciona. que almacenan números en coma flotante con signo. Números en coma flotante: Estos tipos sonfloat y double.out. Es un lenguaje que insiste en que las variables sencillas que se declaran y se utilizan deben corresponderse con la lista establecida.println("Número de días = " + days). Booleano: Este tipo está diseñado para guardar sólo dos valores: verdadero (true) o falso (false).Este es el resultado del código: C:\>java aPP Número de días = 365 Como puede ver. Estas son todas las posibilidades: Enteros: Estos tipos son byte. Cada uno de estos tipos representa un valor de datos sencillos. tanto letras como números. Todos ellos forman lo que en Java se conoce como tipos de datos sencillos. int y long. short. A continuación. 1 1 El tipo int es una de las clases de variables que se pueden usar. que también se tratará en este capítulo). Caracteres: Este es el tipo char. Tipos de datos Java pone mucho énfasis en sus tipos de datos.

entre tipos de enteros. en C++. simplemente incrementando el índice del array para así. Eso es importante. empezaré con 100 nuevas cuentas en el Banco de Programación de Java y cada una tendrá su propia entrada en . que quiere crear un nuevo banco. Sin embargo. que son proporcionados por los arrays. podrá agrupar tipos de datos sencillos en estructuras más complejas y hacer referencia a esa nueva estructura por su nombre. Además. se puede trabajar muy rápido con un conjunto de datos. Java es muy particular para mantener la integridad de esos tipos. y necesita obtener la cantidad de dinero de cada cuenta. En este caso. puede haber conversión entre ciertos tipos de datos. toda expresión. Java es más insistente en cuanto al tipo d e datos que un lenguaje como C++. por lo tanto si se puede hacer referencia a los datos con un índice numérico. por ejemplo. hemos revisado lo que Java hace con los tipos de datos sencillos y variables. podrá hacer referencia a los datos individuales almacenados en el array. Lo que es más importante: mediante un índice numérico. en Java. En este caso. los datos son más complejos. Utilizando un array. Arrays Los tipos sencillos son buenos para almacenar datos simples. el Banco de Programación Java. Hasta aquí. por ejemplo. es mejor trabajar con datos compuestos. Aquí tenemos un ejemplo. acceder a todos sus elementos. pero eso no se puede hacer en Java. utilizando como índice el número de cuenta. ya es hora de echar un vistazo al almacenamiento de datos. por ejemplo. como veremos en este capítulo. especialmente si intenta asignar un valor de un tipo a una variable de otro tipo. pero con frecuencia. porque los ordenadores se destacan por ejecutar millones de operaciones muy rápidamente. también tiene un tipo).Todas las variables sencillas deben tener un tipo (y de hecho. toda combinación de términos que Java puede evaluar para obtener un resultado. lo que se denomina arrays. se puede asignar un número en coma flotante a un entero y C++ gestionará la conversión de tipos. Supongamos.

account S = new double [1001 . A continuación se puede ver cómo he creado el array accounts[]. ahora puede referirse a los elementos del array utilizando un índice numérico. que los organiza fácilmente. por lo que la sentencia accounts = new double[100] crea un arraycuyo primer elemento es accounts[O] y el último es accounts[99]. . que es el que Java utiliza para ubicar memoria: public class app I public static void main(String[l args) I double accounts [ 1.95 en la cuenta 3 y visualizando esa cantidad): public class app { public static void main(String[l args) I double accounts [ 1 . En Java. haciendo que cada elemento sea de tipo doble para obtener mucha precisión.out.95 Como puede ver. Se pueden combinar los pasos de declaración y creación en uno solo: public class app I public static void main(String[l args) I double accountsl 1 = new double[1001.un array llamado accounts[]. y entre ellos se sitúa el índice del elemento del array al que se quiere acceder. Primero. como se indica a continuación (observe que estoy almacenando $43. declaro el array y luego lo creo con el operador new. System.println("La cuenta 3 tiene $ " = + accounts[31): 1 1 Este es el resultado del programa: C:\>java app La cuenta 3 tiene $43. el elemento más bajo declarado de esta forma es el 0. puedo hacer referencia a ellos numéricamente. Los corchetes indican que es un array. accounts = new double[1001. Ahora que he creado un array con 100 elementos.

es una lista de números que pueden ser indexados por otro número.95. lo que significa que se pueden tener muchos índices. además de una cuenta corriente quieren una cuenta de ahorro. System. System. accounts[] []. este código crea cuatro cuentas y guarda el valor 43.~ut. también llamado vector. y el segundo índice será el número de la cuenta como antes. para gestionar la cuenta de ahorro y la cuenta corriente. encerrando entre llaves la lista de valores.accounts [ 31 = 43.out.println("La cuenta 3 tiene S " + accounts[31). por supuesto. System. Así sería el código: public class app public static void main(String[] args) { double accounts [ 1 [ 1 = new double [2][lo01 .95.out. 0. 1 1 Además se puede inicializar un array con valores cuando se declara. los arrays pueden tener muchas dimensiones.printin(~La cuenta corriente 3 tiene $ " + accounts[ll 131.95). la referencia a cada elemento se hace utilizando dos índices. extenderé accounts[] a un array de dos dimensiones. ¿Cómo gestionaremos esto y mantendremos todo indexado por número de cuenta? El array accounts[] es un array unidimensional. El primer índice de accounts[][] será O para la cuenta de ahorro y 1 para la cuenta corriente.06. el saldo de la . 0.95. accounts [l]131 = 2385489382. en Java. 1 1 Esto hará que algunos clientes del Banco de Programación de Java no estén contentos.95 en accounts[3]: public class app ( public static void main(String[] args) ( double accounts[ 1 = {O.println(~~a cuenta de ahorro 3 tiene $ " + account[0] 131. accounts[01[31 = 43.println("La cuenta 3 tiene S " + accounts[31). Por ejemplo. 43.~ut. es decir. Sin embargo. System. accounts[3] = 43. En el siguiente ejemplo. 1 1 Ahora que accounts[][] es un array de dos dimensiones. por ejemplo.

out.println("Lacuentade ahorro 3 tiene 5" + accounts[01 131. he usado el operador + para crear el texto que se va a visualizar: public class app { public static void main(String[l args) L double accounts [ 1 [ 1 = new double [ 2 1 [ l o 0 1 .cuenta de ahorro 3 es accounts[0][3] y el saldo de la cuenta corriente es accounts[l][3]. a continuación se puede ver cómo se crea una cadena llamada greeting que guarda el texto "¡Hola desde Java!": public class app ( public static void main(String[l args) .06 (ilusión) y que Java ha visualizado 2. soportan las cadenas de texto y se puede considerar la clase String como la definición de un nuevo tipo de datos. Systam.out.println("La cuentacorriente 3tine $ " + accounts[ll[31.385. Por ejemplo. Cadenas Quizás se haya dado cuenta de que. System.38548938206 x lo9. 1 } Esto se debe a que las propias clases de Java (la clase String).95 La cuenta corriente 3 tiene $2.489.382.3854893820639 Observe que he dado a la cuenta corriente 3 un saldo de $2. en los ejemplos anteriores. Estos son los resultados al ejecutar la aplicación: C:\>java app La cuenta de ahorro 3 tiene $43.

Una de las cosas sobre C++ que hacía felices a los programadores era que la mayoría de las implementaciones incluían una clase String. ya que la mayoría de los programadores los tratan como cualquier otro tipo de datos. De hecho. Revisaremos también el uso de operadores en las cadenas. se puede tratar esta cadena de igual forma que los otros tipos de variables. arrays y cadenas. Se utiliza la clase String para crear cadenas de texto que no se pueden modificar. muchos programadores argumentarían que las cadenas deberían ser un tipo de datos sencillos en Java. como lo son en otros lenguajes. tienen un espacio en este capítulo. H o l a desde J a v a ! " . lo que es bastante embarazoso. Echaremos un vistazo al uso de cadenas en este capítulo y en el siguiente (uso de operadores + y -). Por ahora. Ahora. implementando las cadenas como una clase. se gestionan las cadenas como arrays unidimensionales de caracteres. Java continúa con este uso. . La razón es que no tienen nada que ver con la línea de Java. Hay dos clases string en Java: String y StringBuffer. que tiene sentido revisar las cadenas en este capítulo. Como puede ver en el código anterior. que se podía usar igual que cualquier otro tipo de datos. no como un tipo de dato intrínseco. Comenzaremos a crear y a usar variables. en C.I String greeting = " . C no tiene un tipo sencillo de cadenas. Este es el resultado de la aplicación: C:\>java app ¡Hola desde Java! Aunque las cadenas no son uno de los tipos sencillos d e Java. pero la gestión de cadenas es tan fundamental para la programación. incluyendo su visualización: public class app ( public static void main(String [ ] args) ( String greeting = "¡Hola desde Java!". puede utilizar cadenas como si fuera un tipo sencillo de Java. que extiende el lenguaje C. es suficiente.

Tipos de variables.7976931 3486232E308 para valores positivos -3. como se hizo al principio de este capítulo: Enteros: estos tipos son byte. int y long. " ¿cómo escribiría un programa Java para gestionar la deuda de la empresa?" "¿Estamos en deuda?" pregunta. "Hmm".768 a 32.848.902. "Aproximadamente $2. dice GJ. responde GJ.402823E38 para valores positivos float 1 int 1 short 4 -2. 1 boolean 2 Verdadero. "¿Cuánto?" l e pregunta. short. dice el gran jefe (GJ). dice. .147.401298E-45 a 3.7976931 3486232E308 a -94065645841 247E-324 para y valores negativos 4. ¿Qué tipo de datos sencillos puede usar para crear variables en Java? Los encontrará en la tabla 2. "Creo que hay que usar números en coma flotante".1. Los tipos de datos sencillos pueden clasificarse por categorías. que guardan el signo y el valor.483.493.401 298E-45 para valores negativos y 1.238.647 2 -32.1.402823E38 a -1.94065645841 247E-324 a 1. que almacenan números en coma flotante con signo. "Sólo un poco".77".483.¿De qué tipo de datos disponemos? "Veamos".648 a2.147. . Falso I I 1 char double 2 8 N/A -1. Tabla 2.767 I Números en coma flotante: estos tipos sonfloat y double.

value = 1234567890123456789L. una visión general de los tipos de datos sencillos que están disponibles. estoy asignando un literal entero con un valor de 365 a la variable days. 1 } Aquí.Caracteres: este es el tipo char. tanto letras como números.out. y hay una serie de reglas para controlarlo. los valores long pueden tener más dígitos que los int. Sin embargo. Por otro lado. Creación de literales enteros El programador novato aparece y dice. Booleano: este tipo está diseñado para guardar sólo dos valores: verdadero (true) o falso (false). Java convierte el tipo de literal automáticamente. le responde. Veamos los siguientes puntos para ver cómo funciona cada uno de ellos. los literales enteros son del tipo int. System. Este es el ejemplo: 7 public class app I public static void rnain(String[l args) { long value. que son los que uilizan la mayoría de los programadores.println("Número de días = " + daysl . que guarda las representaciones de los caracteres.println("E1 valor = " + value). "¿cómo asigno un valor hexadecimal. En este capítulo. como short. por lo que Java proporciona una forma explícita de crear constantes long: se añade una 'L al final del literal. ya he usado literales enteros. base 16. si se les asigna a otros tipos de enteros. System. Un literal es un valor constante que se puede usar directamente en el código Java. Hasta aquí. a una variable en Java?" "Tiene que usar un literal hexadecimal. . Este es el ejemplo anterior: public class app { public static void main(String[] args) { int days = 365. Por defecto. que empieza con los caracteres Ox o OX".out .

1 1 Esto es lo que el programa visualiza: C:\>java app 16 decimal = 16 20 octal = 16 en decimal.contesta el PN. out. no de tipofloat. 1. System. println("10 hexadecimal = " + value + " en decimal". "iAh!".println("20 octal = " + value + " en decimal".println( "16 decimal = " + value).Este es el resultado del código: c:\>java app ~l valor = 1234567890123456789 Además puede crear literales en formato octal empezando con un cero y en formato hexadecimal empezando con O o OX. Quiero poner un número en coma flotante. "Tengo un problema. value = 0 2 0 . le dice. value = 0x10. en una variable de coma flotante.out. System. Se fo pueden cambiar añadiendo una ' ' 'F' al final del literal para convertirlo en float o una 'd' o 'D' para pasarlo a double". Se necesita conversión específica para double". System. ).). 10 hexadecimal = 16 en decimal. Creación de literales en coma flotante El programador novato aparece y dice. ¿Qué ocurre?" "Por defecto". pero Java insiste en decir "Tipo incompatible para =.5. "los números en coma flotante que se utilizan como literales son de tipo double. Estos son algunos ejemplos: x public class app I public static void main(String[] args) { int value. value = 16. .out.

System. como por ejemplo. el código se ejecuta como esperamos: C:\>java app ~l valor = 1. Explicit cast needed to convert double to float. vemos un ejemplo en el que se trata de asignar un literal en coma flotante a una variable tipofiroat: public class app I public static void main(String[l args) I float value. 1 1 Desafortunadamente. java:7: Incompatible type for = . 1 1 Ahora. los literales en coma flotante son de tipo double por defecto.1415926535.println("E1 valor = " + value).5f.out.345 x 101° ó -9. value = 1.En el código.out. por lo que Java devuelve el siguiente error: C: \>javac app. 3.5f. 1.5. A 1 error Esto se puede arreglar explícitamente convirtiendo el literal afiroat. System. A continuación.println("E1 valor = ' + value).5 .5 y 0. value = 1.999E-23. que es lo mismo que -9. es double.999 x 1o-23. Además se puede indicar en potencia de 10 con 'e o 'E : 7 7 Esto es lo mismo que 1.java -deprecation app.111 111 1. el tipo por defecto de los literales en coma flotante. value = 1. como se indica a continuación: public class app { public static void main(String[] args) { float value. La notación estándar para los literales en coma flotante es un número seguido por una parte fraccionaria.

unicode.Creación de literales booleanos En Java. La forma básica de un literal de tipo carácter en Java es un valor que corresponde a un carácter del conjunto de caracteres Unicode (para más detalles sobre Unicode. Por ejemplo. esto forma parte de la insistencia de Java en los tipos de datos).org). los valores booleanos sólo pueden ser verdaderos o falsos (no O ó 1 u otros valores numéricos como ocurre en otros lenguajes. cada uno de los cuales representa un carácter". dice el programador novato. "¿cómo asigno una letra a una variable en Java? Estoy evaluando todos los productos de la empresa y quiero asignarles letras". no caracteres actuales.println("E1 valor = " + value). . "Puede usar literales de tipo carácter. le responde. ver www. Esto quiere decir que los únicos dos literales booleanos que se pueden usar son verdadero y falso.out. dice el PN. Sin embargo. la siguiente aplicación visualiza una 'C': public class app ( public static void main(String[l args) i char char3. value = true. System. ¿el gran jefe sabe esto?" "Todavía no". "Por cierto. el código Unicode para la letra 'C' es 67. A continuación vemos un ejemplo que utiliza verdadero (true) como literal booleano: public class app { public static void main(String[l args) ( boolean value. 1 1 Este es el resultado del programa: C:\>java app El valor = true Creación de literales carácter "Hey". Los literales de tipo carácter son números que actúan como índices dentro del conjunto de caracteres Unicode.

1 1 Además de encerrar los caracteres entre comillas simples. \n.println("La tercera letra del alfabeto = " + char3).Rolal\"m). . puede referirse al código Unicode para la letra C con un literal de tipo carácter encerrado entre comillas simples: public class app 1 public static void main(String[] args) 1 char char3. puede utilizar la secuencia de escape \": public class app 1 public static void main(String[] args) I ~yet~. también puede encerrar secuencias de escape entre este tipo de comillas para obtener literales de tipo carácter que no pueden conseguirse tecleando un simple carácter. Estas son las secuencias de escape: \' (comilla simple) \" (comillas dobles) \\ (barra invertida) \b (espacio en blanco) \ddd (carácter octal) \f (avance) \n (nueva línea) \r (retorno de carro) \t (tabulador) \uxxxx (carácter Unicode en hexadecimal) Por ejemplo.out. si quiere que se visualice una doble comilla que aparece en el texto. 1 También.System.out.out.printiní~É1 dijo.printlní"La tercera letra del alfabeto = " + char3). System.

Declaración de variables de tipo entero "Realmente. ¿Cómo puedo hacerlo?" "Con una variable entera". int (cuatro . no en tipos de datos sencillos inherentes (lo que quiere decir que el código como "HolaW. "utilice el literal de tipo carácter \n para añadir una pregunta PN.). le dice. Java utiliza cuatro tipos de enteros. "Tome una silla y veámoslo". "y necesito almacenar algunos datos enteros. se pueden poner cadenas entre comillas dobles (al igual que los literales de tipo carácter se encierran entre comillas simples). " ~ C Ó ~ O ? . dice el programador novato.Este es el resultado del código: c:\>java aPP $1 dijo. ahora es cuando estoy programando".o~t. cada uno con su propio número de bytes alocados en memoria: byte (un byte). Además se pueden utilizar secuencias de escape introducidas en la sección anterior. En este caso. dice. visualizaré varias líneas de texto utilizando el literal \n para comenzar una nueva línea: public class app { public static void main(String[] args) { System.println(~Esto es \nun texto\nde varias líneasm. nueva línea". "De acuerdo". Esto es un ejemplo de lo que PN quiere hacer. short (dos bytes).length() es perfectamente legal y devuelve la longitud de la cadena "Hola"). "este es el problema: quiero usar una sentencia println para sacar varias líneas. Observe que el compilador convierte los literales de tipo cadena en objetos String. ¿puedo hacerlo?" "Claro". 1 1 Esta es la salida de la aplicación: C:\>java app Esto es un texto de varias líneas Como con la mayoría de los lenguajes de programación. "iHola!" Creación de literales tipo cadena El programador novato regresa con un café. le dice.

Para conocer el posible rango de valores que cada uno puede tomar.println("1ongl = " + longl). asigna a cada tipo un dato y luego visualiza ese dato: public class app public static void main(String[l args) { byte bytel. "Puede usarfloats y doubles". El .out . ver el punto "¿De qué tipos de datos disponemos?". System. así como de otras consideraciones.out. pero el gran jefe me dijo que todos los decimales cuentan.bytes) y long (ocho bytes). Usar uno u otro depende del rango de datos que se quiera. le dice. 1 1 Este es el resultado de la aplicación: bytel = 1 shortl = 100 intl = 10000 longl = 100000000 Declaración de variables de tipo coma flotante "Lo siento". System. cada uno con su propio número de bytes para alocar en memoria:float (cuatro bytes) y double (ocho bytes). long longl.out. Java incluye dos tipos de variables en coma flotante. "pero los enteros no se truncan. longl = 100000000. shortl = 100. System.println ( "intl = ' + intl). intl = 10000. ¿Hay algún otro tipo de datos que pueda utilizar?" "Claro". bytel = 1. en este capítulo. declara un entero de cada tipo. Estoy tratando de diseñar un conversor de moneda y creía que se podía ignorar la parte decimal de cada valor. System. short shortl. ver la sección "¿De qué tipo de datos disponemos?". en este capítulo.println("byte1 = " + bytel). como cuánta memoria hay disponible (en caso de que se quieran tener muchos enteros). dice el programador novato. int intl.println("shortl = " + shortl). Para ver el rango posible de valores que cada tipo puede gestionar.out. Esto es un ejemplo que utiliza todos los tipos enteros.

ver también en este capítulo. floatl = 1.out. charl = 65. Para los posibles valores que se pueden almacenar en una variable char.lllllllllllllE9 Declaración de variables de tipo carácter Se pueden declarar variables de tipo carácter con la palabra clave char.println("char1 = " + charl).1111111111111E+9D. doublel = 1. el compilador traduce los literales de tipo carácter en códigos Unicode): public class app { public static void main(String[l args) { char charl.11111111111F.usar uno u otro depende del rango de los datos que se quiera. System. double doublel. por lo que no habrá ningún problema con las conversiones de tipo): public class app { public static void rnain(String[] args) { float floatl. float y double (observe que explícitamente hago que los literales seanfloat o double.out. Este ejemplo prueba que se puede asignar a un char un código Unicode o un literal de tipo carácter (de hecho.out. char2.println("f10atl = " + floatl). System.println("doub1el = " + doublel). Esto es un ejemplo en el que se declaran dos variables de tipo char: charl y char2. así como de otras consideraciones. como cuánta memoria hay disponible (en el caso de que se quiera tener muchos valores en coma flotante). por lo que el valor se ha redondeado): C:\zjava app floatl = 1. . 1 1 Esta es la salida del código (observe que he sobrepasado la precisión permitida para un float. System. char2 = '' B. A continuación tiene un ejemplo que declara y usa ambos tipos.1111112 doublel = l.

cambiando de 'B' a 'C': public class app I public static void main(String[l args) I char charl.Este e s el resultado del código: C:\=-java app charl = A char2 = B A continuación veremos un punto clave que se tratará en un tema futuro: añadir parte de un texto al final del charl. System. Esta es la salida de la nueva versión del programa: charl = A char2 = B charl + 1 = Al ++char2 = C Declaración de variables de tipo booleano Las variables de tipo booleano se declaran con la palabra clave boolean. e incrementar el valor de char2. charl = 65. Aquí tenemos un ejemplo en el que se declara y se usan dos variables de tipo booleano: public class app t public static void main(String [ ] args) . las variables de tipo booleano sólo pueden tener dos valores: verdadero y falso (no valores numéricos como O y 1.println("char1 = " + charl).println("char2 = " + char2).println(~char1 1 = + + charl + 1). Sy~tcrm.out. como ocurre en otros lenguajes de programación). char2 = 'B': System.out. char2. En Java. convirtiéndolo a una cadena.out.

estoy usando dos tipos de variables con la sentenciaifde Java. boolean2 = false. 1 else { System. . en caso contrario: public class app { public static void main (String[1 args) { boolean booleanl.). durante las pruebas.o~t.out.println("boolean2 = " + booleanl). Este es el resultado del código: C:\>java app booleanl = true boolean2 = false Generalmente. se usan valores booleanos para determinar el flujo de un programa.. boolean2.{ boolean booleanl. si es verdadero (true) y "booleanl es falso". es 1 1 1 El nuevo resultado es: C: \>java app booleanl = true boolean2 = false booleanl es verdadero.println(~boo1eanl " + booleanl). booleanl = trUe. no diré más sobre ello y le daremos un repaso en el siguiente capítulo. If(booleanl) { System.println(~boolean1es verdadero". De momento.).println(~boolean1 falsom. haciendo que el código visualice el mensaje "booleanl es verdadero".out.o~t. En este caso. = System. boolean2 = false: System.o~t.println("b001eanl = " + booleanl). Compruebo el valor de booleanl con la sentencia if. booleanl = true. boolean2. System.

Inicialización de variables "De acuerdo". int3 = 3 . declaro una variable y después le asigno un valor". "puede hacer las dos cosas en un solo paso". El PN contesta. dice el programador novato. int2 = 2. Primero. System. vamos a declarar variables y a asignarles valores de la siguiente forma: public class app I public static void main(String[l args) { int intl. 1 1 Sin embargo. System.out.println("int1 = " + intl + " . i n t 2 3 2. int2 = " + int2 + " . le dice.println("int1 = " + intl). "Realmente".out.println("int1 = " + intl). int3 = " + int3). 1 1 A continuación se indica cómo se declaran e inicializan varias variables: public class app ( public static void main(String[] args) { i n t i n t l = 1. "Ya lo tengo todo claro. i n t 3 = 3. 1 1 Este es el resultado del programa: C:\>java app intl = 1. "idígame cómo! " Pues bien.out. System. i n t l = 1. puedo combinar estos dos pasos en uno solo inicializando una variable cuando la declaro: public class app ( public static void main(String[] args) { i n t i n t l = 1.

int2 = 3.println("int1 = " + intl + " . acabamos de asignar valores constantes a variables.out. i n t int3 = i n t l * int2. Por ejemplo. int3 = 6 Observe que el compilador de Java no tiene ni idea de lo que valdrá intl veces int2 cuando crea los bytecodes para esta aplicación. System. i n t 2 = 3. int3 = " + int3). i n t int3 = i n t l int2.out. como se indica a continuación: public class app I public static void main(String[] args) I i n t i n t l = 2. . en Java se puede introducir declaración de variables en el código.println("int1 = " + intl + " . y es por lo que este proceso se llama inicialización dinámica. int2 = " + int2 + " .Inicialización dinámica Llegados a este punto. int2 = " + int2). siempre que la expresión sea válida en ese momento. System. Esto es lo que nos devuelve el código cuando lo ejecutamos: C:\>java app intl = 2. Esto significa que el valor actual con el que int3 está inicializado será determinado en tiempo de ejecución. Al igual que en C++. usando el operador multiplicación de Java (*): public class app I public static void main(String[] args) { int intl = 2. int2 = 3. pero se puede asignar cualquier expresión (una expresión es cualquier combinación de términos Java que da un valor) a una variable cuando es declarada. aquí se está asignando el valor 2 a intl y 3 a int2 y el valor de intl veces int2 a int3.

con frecuencia nos enfrentamos a la situación de asignar una variable de un tipo a una variable de otro. ya que byte e int son tipos compatibles y las variables int tienen un rango mayor que los valores byte.Este es el resultado del código: C:\>java app intl = 2. System. Por ejemplo. int2 = 3 int3 = 6 Conversión de tipos de datos "Uf". no se perderá ningún dato en la conversión de tipos. Veámoslas. dice PN. Java convertirá el dato al nuevo tipo de variable de forma automática si las dos condiciones siguientes son verdaderas: Los tipos del dato y de la variable son compatibles. Esto es un ejemplo: public class app { 7 public static void main(String[l args) ( byte bytel = 1. ¿Qué es lo que está mal?" "Es un problema de conversión de tipos". Hay dos formas de hacerlo: contando con una conversión automática y haciendo explícitamente un cast de tipos.out. pero Java me devuelve un error "Tipo incompatible para =". Por lo tanto. "Me he atascado. y como consecuencia de ello. le explica. "y tiene que usar explícitamente un cast de tipos". "Hmm". dice el programador novato. Tengo una variable de tipo int y quiero asignarla a una variable de tipo byte. Conversiones automáticas "1 Cuando asigna un tipo de dato a una variable de otro tipo.println("int1 = " + intl). "¿cómo se hace eso?" Java es un lenguaje muy insistente con los tipos. se puede asignar un valor de tipo byte a una variable int. El tipo de destino tiene un rango mayor que el de origen. . int intl. i n t l = bytel.

El compilador de Java no las ejecuta automáticamente. Este es el resultado del programa: c:\>java app intl = 1 Este tipo de conversiones. los tipos numéricos. Casting a nuevos tipos de datos Si se está asignando un valor que es de un tipo con un rango mayor que la variable a la que se le está asignando. la parte fracciona1 del número se trunca- . Si se quiere hacer un estrechamiento de conversiones. en este código. se debe usar explícitamente un cast.out. el compilador devolverá error. System. son compatibles entre sí. cuando se pone un número en coma flotante en un long. se está convirtiendo un tipo entero a un tipo byte: public class app I public static void main(String[l args) { byte bytel.println("byte1 = " + bytel). ya que Java decide que se conoce la posibilidad de perder algunos datos cuando se introduce un valor probablemente mayor en un tipo más pequeño. en las que se convierte a un tipo de datos que tiene mayor rango. Por otro lado. En ellas. pero con el cast de tipos.El compilador de Java no tiene ningún problema con este código y hace la conversión de tipos automáticamente. ya que se perdería la posibilidad de precisión. no hay problema. 1 1 Si no se hace explícitamente el cast. que tiene el siguiente formato: (tipo de dato de destino) valor Por ejemplo. byte1 = (byte) intl. se está ejecutando lo que se denomina estrechamiento de conversiones. los tipos char y boolean no son compatibles entre sí y tampoco con los tipos numéricos. como entero o coma flotante. Por ejemplo. int intl = 1. se llaman extensión de conversiones.

en el que parece que sólo hay bytes involucrados: public class app I public static void main(String[] args) { byte bytel = 100. Por lo tanto. byte3 = bytel * byte2 /100. Esta es la salida del código: C:\>java app bytel = 1 Algo a tener en cuenta es que el compilador de Java convierte a un tipo de mayor precisión. si es necesario. Este código se compila y se ejecuta como esperábamos. como Java sabe que de la multiplicación de tipos puede resultar valores del tamaño de un entero. lo que quiere decir que realmente hay que usar explícitamente un cast para mantener el tipo byte: public class app public static void rnain(String[] args) ( 7 byte bytel = 100. byte byte2 = 100. byte byte3. vamos a considerar el siguiente código. byte byte3. automáticamente convierte el resultado de bytel * byte2 en un entero. al evaluar expresiones. y puede que se pierdan más datos si el valor en coma flotante está fuera del rango que un long puede gestionar.rá. byte3 = (byte) (bytel * byte2 / 100). byte byte2 = 100. Por ejemplo. pero no sería así sin el cast (byte): C:\>java app byte3 = 100 .

dice el GJ. . y ambos los veremos aquí. se debe declarar el array. le dice. así e s como se declara un array de valores double. "Ah". "Creo que tendré que crear un array para almacenar las cuentas".:laraciónde arrays unidimensionales El gran jefe aparece y dice. A continuación se indica cómo se declara. "De acuerdo". en general. le contesta. Java soporta arrays unidimensionales y multidimensionales. los arrays proporcionan una forma fácil de gestionar un conjunto de datos por medio de un índice. Para tener un array preparado es necesario ejecutar dos pasos. Primero. "¿puedo ver las cuentas?" "Realmente. Como ya vimos antes en este capítulo. lo que es fácil para los ordenadores. nunca guardamos las cuentas". que se llama accounts[]: public class app { public static void main(String[] args) I double accounts [ 1 . Por ejemplo. "Es hora de atacar a los clientes que nos deben facturas". ya que se puede manipular el índice en el código. un array unidimensional: tipo nombre[].

El límite inferior de todo array de Java es 0. .Al igual que al declarar variables sencillas. Java devolverá un error fatal. por lo que el primer elemento del array es accounts[O] y el superior es accounts[99].out. System. Este es el resultado del programa: C:\zjava app La cuenta 3 debe $1335. Creación de arrays unidimensionales Después de que se ha declarado un array unidimiensional. Si el índice del array está fuera del rango del O al 99.println("La cuenta 3 debe S " + accounts[31). Esto quiere decir que es necesario otro paso en este proceso: la creación del . y el programa se parará. Como se verá en el capítulo o usar el nuevo array de la siguiente forma: public class app I public static void main(String[l args) I double accounts [ 1 .println("La cuenta 3 debe S " + accountsi31). que Java inicializa a O. ) 1 Aquí se ha creado un array de exactamente 100 valores double. system. se puede combinar el proceso de declaración y creación de arrays en un paso: public class app ' I public static void main(String[] args) { double accounte[ ] = new double [1001. accounts = new double[100]. Veamos el siguiente punto para más detalles. el siguiente paso es crear ese array alocando memoria para él. array. ya que Java no sabe exactamente qué tamaño va a tener.out. la declaración de un array no reserva memoria.67 De hecho.

. "Utilice un array multidimensional". 0. empezando con el primer valor del array. le dice.. únicamente hay que poner los valores entre llaves. 1335. en este capítulo. tipo nombre[] i l [l. Para inicializar los arrays unidimensionales. dice. dice pensativo el programador novato. "pero ¿puedo hacer lo mismo con los arrays?" "Sin problema".45. "Sé que puedo inicializar variables sencillas cuando las declaro". sólo con incluir un par de corchetes para cada dimensión del array.67).out. "creo que necesito más que un array unidimensional. el número". Se pueden declarar arrays multidimensionales de la misma forma que se declaran los unidimensionales.33. Ya vimos anteriormente. y el array supongo que almacenará el número de artículos del inventario. 1 Declaración de arrays multidimensionales "Hmm". separados por comas. "Manténgalo"..Inicialización de arrays unidimensionales El programador novato regresa con una pregunta. le dice. Este es un ejemplo que inicializa los primeros cuatro elementos del array accounts[ ] con datos: public class app I public static void main(String[l args) { double accounts[l = C238. System. su coste.println("La cuenta 3 debe S " + accounts[31). las ventas. un valor detrás de otro... Estoy pensando en mantener los productos indexados por número de producto. 999. cómo declarar un array de dos dimensiones con dos filas y 100 columnas: public class app { public static void main(String[l args) .

¿cómo lo creo?" "Veámoslo". aquí tiene cómo declarar un array de cuatro dimensiones: public class app I public static void main(String[] args) I double accounts[l [l [ 1 [l = new double[Z] [31 [41 [ 5 1 . la columna. Ahora. Así funcionan los arrays de dos dimensiones: el índice izquierdo especifica la fila y el derecho. ¿cómo se crea un array después de haberlo declarado? Ver el siguiente punto para más detalles. es tan fácil declarar arrays multidimensionales como declararlos unidimensionales. Con el operador new se crea Un nuevo array multidimensional reservándole memoria y dándole las dimensiones que se quiera.{ double accounts[l [l = new double[ZI [lo01. Creación de arrays multidimensionales El programador novato pregunta. Veámoslo con un ejemplo: public class app t public static void main(String[] args) I . le dice. Por supuesto. no tiene por qué limitarse a las dos dimensiones. "Ahora que he declarado un nuevo array multidimensional. Como puede observar.

System. System. accounts = new double[2][100].out. 1 1 En este ejemplo se crea y utiliza un array de cuatro dimensiones: public class app { public static void main(String[l args) { double accounts[l 11 [l [l = new doublet21 131 [41 [SI. la declaración y reserva de memoria se pueden hacer en un solo paso: public class app { public static void main(String[] args) { double accounts = new double[2] [1001. accounts[01 [l][21 [31 = 43.out.double accounts [ 1 [ 1 .95 . System. System.println("Lacuentade ahorro 3 tiene $ " + accounts[01[31). System.3854893820639 Además.println("Lacuenta [O][l][21 [31 tiene $ " + accounts[Ol [ll [21 [31).95.out. 1 1 Este es el resultado del programa: C:\>java app La cuenta [O][11 [21 131 tiene $43.95 La cuenta corriente 3 tiene $2.println("Lacuentade ahorro 3 tiene $ " + accounts[OI [31). 1 1 Este es el resultado del código: C:\>java app La cuenta de ahorro 3 tiene $43.out .println( "La cuenta corriente 3 tiene $ " + accounts[ll [31) .println( "La cuenta corriente 3 tiene $ " + accounts[ll [31).out.

1 1 Este es el resultado del código: C:>\java app Valor medio del array = 2 Hasta ahora. basta con incluir un par de corchetes para cada dimensión y poner los valores con los . todos los arrays que hemos utilizado tenían el mismo número de elementos en cada dimensión. de la misma forma que se inicializan los unidimensionales. al que se puede acceder con array[O].Los arrays multidimensionales son realmente arrays de arrays. outer-index++) 1 for(int inner-index = 0. pero no es necesario que sea así. array[2] y así sucesivamente. 3 1 ) . Primero.println("Valormedio del array = " + (sum / total) ) . 2. lo que significa que si se tiene un array de dos dimensiones (array[][]). Para aprender más. inner-index < array[outer-index1. se puede echar un vistazo a la sección que viene después de la siguiente. 11.length. veamos cómo se inicializan los arrays multidimensionales. 3 ) . total = 0. 2 .out . = for(int outer-index = 0. inner-inc¶ex++) C sum += array[outer-index] [inner-indexl. Hay una manera sencilla de hacer esto utilizando un bucle for (del que veremos más en el siguiente capítulo) y el método length (que veremos en las siguientes secciones) para averiguar la longitud de un array: public class app 1 public static void main(String[] args) ( double array[l [ l 1 { 1 . array[l]. 2 . int sum = O . total++: System. { 3 . Inicialización de arrays multidimensionales Los arrays multidimensionales se pueden inicializar cuando se los declara. outer-index < array. 11. se puede tratar como unarray de arrays unidimensionales.length.

out. double[4001.out.951.56. 4343.95 La cuenta corriente 3 tiene $2. double[3001.que se quiere inicializar el array dentro de los mismos.println("Lacuenta [3](31 tiene S " + array[31 [31). disculpe?" Como en otros muchos lenguajes de programación. "Ah.06)).11.23. ¿sí?". {11.91. 19.62. "¿Sabe cómo poner diferente número de elementos en cada fila de un array?" El PN dice. System. Systern. 43. en Java. double[5001. . 2385489382. los arrays multidimensionales son arrays de arrays. como en el ejemplo.out. 1 1 La ejecución del código produce: C:\>java app La cuenta de ahorro 3 tiene $43. le dice. aquí vemos cómo se inicializa un array de dos dimensiones: public class aPP { public static void main(String[] args) { double accounts[ ][ ] = {{10. Esto quiere decir que se pueden construir arrays como se quiera.println("La cuenta corriente 3 tiene S " + accounts[ll 131). dice orgulloso el progamador novato.3854893820639 Creación de arrays multidimensionales "De acuerdo". "ya soy un experto en arrays". double [lo01 .23. Por ejemplo. 543. en el que cada fila de un array de dos dimensiones tiene un diferente número de elementos: public class app { public static void main(String[l args) I double array [ 1 array[O] array[l] array[21 array[3] array 141 = new = new = new 3 new = new [ 1 = new double [51 [ 1 . double 12001. 54.println("La cuenta de ahorro 3 tiene S " + accounts[Ol [31) . System.

64). Este es un ejemplo del capítulo siguiente. es útil conocer la longitud de un array. loop-index++) { sum += grades[loop-index]. 1 1 Este es el resultado: C:\>java app Grado medio = 77. double sum.83333333333333 La clase String "He estado revisando la lista de tipos de datos sencillos de Java". ¿No deberían n.length. especialmente si se está iterando sobre todos los elementos del array dentro del código. que utiliza el bucle for para calcular el grado medio de un estudiante entre un grupo de seis grados (en este caso. 99. Para saber el número de elementos de un array llamado array 1. ii .67 Longitud de un array Con frecuencia. grades. dice el programador novato.length devuelve el valor 6): public class app { public static void mainíString[] args) { double grades[l = I88. se puede usar el término arrayl. 73. Este es el resultado del código: C:\>java app La cuenta [31[31 tiene $1335. average.length. 1 average = sum / grades.Lo que ocurre aquí es que se está tratando cada fila de un array de dos dimensiones como un array unidimensional y creando cada uno de esos arrays unidimensionales de forma separada.out. 56.println("Grado medio = " + average). loop-index < grades. for (int loop-index = 0. 87. System. "y no encuentro las cadenas de texto.length. sum = 0.

estar ahí?" "Algunas personas dicen que sí. " le responde. Este es un ejemplo en el que se crea una cadena y se visualiza (observe cómo este código hace la clase String como si fuera otro tipo de dato sencillo): public class app { public static void main(String[] args) { String sl = "¡Hola desde Java!": Este es el resultado: C:\>java app ¡Hola desde Java! La clase String es muy poderosa. en este capítulo). además. de hecho. Veamos primero la clase String. no un tipo de dato intrínseco.3 y los métodos de la clase String aparecen en la tabla 2. Aquí verá una rápida presentación de los constructores de la clase String. si se quiere cambiar el texto actual de la cadena. las cadenas de texto son tipos de datos fundamentales inherentes al lenguaje. Los constructores de la clase String que se pueden usar para crear objetos String (ver la sección "Creación de cadenas". aparecen en la tabla 2. crear substrings. lo que significa que se crean objetos de esa clase con constructores. las cadenas se gestionan como si fueran objetos. comparar cadenas y mucho más. "pero.2. pero en Java. La clase String tiene. se debería usar la clase StringBuffer. La clase String es una clase. Este miembro de datos se muestra en la tabla 2. buscar cadenas. En muchos lenguajes. en Java. de los que aprenderá todo lo necesario en el capítulo 4. Los objetos de tipo string gestionan las cadenas de texto que no se pueden cambiar. salvo cuando se usa para crear un objeto de esa clase.4. cambiar la cadena de mayúsculas a minúsculas o viceversa. pues con los métodos que proporciona permite convertir la cadena en un a r r a y de caracteres. . Un constructor es como un método normal de una clase. obtener la longitud de la cadena. convertir números en cadenas. las cadenas son gestionadas con las clases String y StringBufSer. un miembro de datos que se usa cuando se comparan cadenas (lo veremos en el siguiente capítulo). Una de las ventajas de esto es que un objeto de tipo string tiene gran variedad de métodos que se pueden usar".

String enc) String(char[ ] value) . en comparación con Tolgnorecase. en las que crearemos y usaremos objetos de String. Inicializa un nuevo objeto String para gestionar un secuencia de caracteres vacía. int hibyte) String(byte[ ] bytes.2. int hibyte. Tabla 2.Estas tablas se usarán en las siguientes secciones. Obsoleto. Construye un nuevo objeto String convirtiendo el array de bytes mediante la codificación de caracteres que se especifica. Este método noconvierte bien bytes en caracteres. Obsoleto. String(byte[ ] ascii. int offset.3. Aloca un nuevo objeto String para representar la secuencia de carac- String (byte[ ] bytes. Resumen de los constructores de la clase String. int offset. int count) String (byte[ ] bytes. enc) Construye un nuevo objeto String convirtiendo el entero length y el subarray de caracteres utilizando la codificación de caracteres especificada. String(byte[ ] bytes) Construye un nuevo objeto String convirtiendo el array de bytes mediante la codificación de caracteres que tiene la plataforma por defecto. Construye un nuevo objeto String convirtiendo el subarray de bytes usando la codificación de caracteres por defecto. Este método no convierte bien los bytes en caracteres. int length) String(byte[ ] ascii. Tabla 2. int offset. Resumen de los campos de la clase String. Static Comparator CASE-INSENSITIVE-ORDER Permite la ordenación de objetos String.

Aloca un nuevo objeto String que contiene la secuencia de caracteres del argumento buffer. Compara lexicográficamente dos cadenas.-- teres contenida en el argumento array de caracteres. String(char[] value. Static String copyValueOf(char[ ] it offset. Concatena la cadena dada al final de esta cadena. Verdadero si esta cadena termina con el sufijo dado. Métodos de la clase String. usando offsets. .4. Compara este objeto String con otro. int offset. String(String value) Inicializa un nuevo objeto String para que represente la misma secuencia de caracteres que el argumento. String(StringBuffer buffer) Tabla 2. int count) Aloca un nuevo objeto String que contiene caracteresde un subarray del array de caracteres del argumento. Compara lexicográficamente dos cadenas ignorando mayúsculas o minúsculas. char charAt(int index) int compareTo(0bject o) int compareTo(String anotherstring) int compareTolgnoreCase(String str) Proporciona el carácter del índice especificado. int count) boolean endsWith(String sufijo) Produce un objeto de tipo String con datos equivalentes al array de caracteres dado. String concat(String str) Static String copyValueOf(char[ ] data) Produce un objeto de tipo String que es equivalente al array de caracteres dado.

Obsoleto. Convierte este objetostringen bytes. dentro de la cadena. int srcEnd. Proporciona el índice. void getBytes(int srcBegin. de la primeravez que aparece el substring dado. empezando por el índice especificado. Produce una representación para el objeto String. char[ ] dst.boolean equals(0bject un objeto) boolean equalslgnoreCase(String otra cadena) Compara esta cadena con un objeto. byte[ ] dst. de acuerdo con la codificación de caracteres por defecto y almacenando el resultado en un nuevo array de bytes. Proporciona el índice. int srcEnd. int fromlndex) String intern( ) . int indexOf(int ch. int fromlndex) int indexOf(Sting str) int indexOf(String str. Produce el índice. Compara este objeto String con otro objeto. dentro de la cadena de la primera vez que aparece elsubstringespecificado. Copia caracteres de esta cadena en el array de destino. int dstBegin) int hashCode() int indexOf(int ch) Produce un hashcode para esta cadena. int dstBegin) byte[ ] getBytes(String enc) Convierte este objetostringen bytes de acuerdo con la codificación de caracteres dada. dentro de la cadena. almacenando el resultado en un nuevo array de bytes. void getBytes(int srcBegin. de la primera vez que aparece el carácter dado. dentro de la cadena. de la primeravez que aparece el carácter dado empezando por el índice especificado. Este método no convierte bien caracteres a bytes. Produce el índice. ignorando las mayúsculas.

dentro de la cadena. int lastlndexOf(int ch. de la última ocurrencia del carácter especificado. que es devuelto por Locale. char newchar) boolean startsWith(String prefix) boolean startswith (String prefix. Devuelve el índice.int lastlndexOf(int ch) Devuelve el índice. dentro de la cadena de la última ocurrencia del carácter dado. int toffset. int len) String replace (char oldChar. dentro de la cadena. int frornlndex) Produce el índice dentro de esta cadena de la última ocurrencia del substring dado. int length() boolean regionMatches String other. buscando hacia atrás desde el índice especificado. usando las reglas del defecto local. de la ocurrencia más a la derecha del substring dado. int toffset) String substring(int beginlndex) Devuelve la longitud de la cadena Compruebasi dos regiones de cadenas son iguales. Produce una nueva cadena situando todas las ocurrencias de oldChar en esta cadena con newchar. permitiendo ignorar las mayúsculas. (boolean ignorecase. Produce el índice. int ooffset. String other. Chequea si esta cadena empieza con el prefijo dado empezando con el índice dado.getDefault. Chequea si esta cadena empieza con el prefijo dado. Convierte estacadena en un nuevo array de caracteres. Produce una nueva cadena que es una subcadena de esta. int len) boolean regionMatches(int toffset. int ooffset. String toLowerCase( ) Convierte a minúsculas todos los caracteres de este objeto String. . Chequea si dos regiones de cadenas son iguales. int fromlndex) int lastlndexOf(String str) int lastlndexOf(String str.

Static String valueOf(0bject obj) .String toLowerCase(Locale locale) Convierte a minúsculas todos los caracteres de este objeto String. Elimina el espacio en blanco desde ambos finales de esta cadena. Produce la representación string de un float. usando las reglas del locale dado. Produce la representación string de un int. Produce la representación de la cadena de un subarray específico del argumentochararraydeenteros. Produce la representación string de un object. usando las regalas del argumento locale especificado. Produce la representación string de un long. Produce la representación de la cadena del argumento char. offset. String toString( ) String toUpperCase( ) String toUpperCase (Locale locale) String trim( ) Static String valueOf(boolean b) Static String valueOf(char c) Static String valueOf(char[ ] data) Static String valueOf(char[ ] data. Convierte a mayúsculas todos los caracteres de este objeto String. utilizando las reglas del locale por defecto. Produce la representación de la cadena del argumento booleano.getDefault. Produce la representación de la cadena del array de caracteres que se pasa como argumento. Se devuelve este objeto (que ya es una cadena). Convierte a mayusculas todos los caracteres de este objeto String. que es devuelto por Locale. Produce la representación string de un double. int count) Static String valueOf(double d) Static String valueOf(float f) Static String valueOf(int i) Static String valueOf(long 1 ) .

cuando en el código se usa un literal de cadena como "iH01a desde Java!". y".. le dice. . se crea una cadena vacía y luego se le asignan datos: public class app { public static void main(String[] args) { String sl = "¡Hola desde Java! " . "No quiero saber nada más sobre eso". se puede declarar una cadena primero y luego asignarle un valor: public class app { public static void main(String[l args) { String s1 = "¡Hola desde Java!". por tanto. "Eso es fabuloso. Esta es una forma que ya hemos visto: public class app { public static void main(String[] args) I String S1 = hola desde Java!".. "Mantengámoslo". Echemos un vistazo a algunas de las muchas formas de crear objetos String. Este es un caso en el que usamos uno de los constructores de la clase String. De hecho. mire. s2 = "iHola desde Java!". lo que realmente está ocurriendo es que se está asignando un objeto String a otro. Java lo trata como un objeto String.. Java incluye una clase String para gestionar las cadenas de texto". Por supuesto. porque estoy escribiendo esta novela. En este caso. String 8 2 . String s2. ~2 = " i ~ o l a desde Java!".Creación de cadenas "Entonces. dice el programador novato. String 83 = new String( ).

. nhn. * í s > . String s4 = new String("iHo1a desde Java!"). lar. String s6 = new String(c1. String s3 = new StringO. \1'.Hola desde Java!". \ o r .83 = hola desde JavaIm. Char cl[ ] = {\H.~alueOf(doublel). s2 = "¡Hola desde Java! " . * 8 . String s2. String s2. . s2 = "¡Hola desde Java! " . String s4 = new String("iHo1a desde Javai*). -a*. String s7 = String. 0. Hay otros constructores de la clase String que pueden tomar arrays de caracteres o subconjuntos de arrays de caracteres (la clase String sabe qué constructor se está usando por el número y tipo de argumentos que se le pasan). s3 = "[Hola desde Java! " . en cadena. de valores numéricos: public class app I public static void mainíString[l args) I String sl = ". s3 = "¡Hola desde Java!". Incluso se puede usar el método valueOf de la clase String para obtener una representación. String 85 = new String(c1). directamente. double doublel = 1. como sigue: public class app I public static void main(String[l args) ( String sl = "¡Hola desde Java!". String s3 = new StringO. Además al constructor de la clase String se le puede pasar. 4). una cadena de texto para crear una nueva cadena.23456789.

).). "y necesito averiguar cuánto me queda. visualizamos todas las cadenas que se han creado. System.length()+ ' caracteres".23456789 Obtención de la longitud de la cadena El programador novato está sin aliento.out.println(''\"" + "Hola" + " \ " " + " tiene " + "Holan. ¿Cómo puedo hacerlo?" "Use el método length de la clase String". } 1 . + " characters long". "He escrito la mitad de mi novela". le dice. Esto es lo que aparecería al ejecutar el programa: C:\>java app ¡Hola desde Java! ¡Hola desde Java! ¡Hola desde Java! ¡Hola desde Java! Hola ahí Hola 1.Al final de este código. Este es un ejemplo en el que se muestra cómo se usa el método length de la clase String (observe que además se puede ver que Java trata los literales cadena como objetos String usando length en un literal de cadena): public class app I public static void main(String[l args) { String sl = "¡Hola desde Java!". dice.

String s3 = 82 + m Java!l. se puede usar el método concat de la clase String para unir dos cadenas y crear una nueva. Concatenación de cadenas La concatenación de cadenas significa ponerlas juntas. System. String s4 = sl. System.concat(" desdem). cuando se concatena un valor numérico con una cadena. Sin embargo. String s5 = s4.out. ¿Cómo se programa eso? Este es un ejemplo en el que se usa tanto el operador + como el método concat para crear la misma cadena: public class app { public static void main(String[l args) ( String sl = "¡Holav. a la hora de visualizar números. el valor numérico se concatena como una cadena.Esta es la salida del programa: C:\>java app " ¡Hola desde Java! " tiene 17 caracteres "Hola" tiene 4 caracteres. hay otra forma de concatenar cadenas.out.println(c3). y ya hemos usado el operador + en este libro para hacer esto. } } Este es el resultado del código anterior: C:\zjava app ¡Hola desde Java! .Hola desde Java! Como ya ha visto.println(s5). 3) visual - . String s2 = sl + " desde".concat(" Javaln).

char charsl[ 1 = sl. se puede usar el método charAt para obtener el carácter que ocupa una posición determinada: public class aPP { public static void main(String[] args) { String sl = "¡Hola desde Java!".out. System. Se puede usar el método toCharArray para convertir un objeto String en un array de caracteres. sl.charAt(0). Además. Por ejemplo. char cl = sl.println("Los primeros cinco caracteres de \ " " + sl + " \ " son " + new String(chars2)). system.println("E1 primer carácter de \ " " + sl + " \ " es " + cl). char chars2[ 1 = new charl51. char cl = sl.Obtención de caracteres y substring La clase String proporciona un número de métodos que descompone las cadenas en sus componentes.out. System.println("E1 segundo carácter de \ " " + sl + es + charsl[ll.charAt(0). 5. System. como sigue: public class app { . puede usar el método substring para crear una cadena nueva que es un substring de la antigua.toCharArray( ) .out. y se puede usar el método getChars para obtener un número de caracteres: public class app ( public static void main(String[] args) I String s1 = "¡Hola desde Java!". 0). chars2.out. caracteres y substring.getChara(0.println("E1 primer carácter de \ " " + s1 + " \ " es " + cl).

public static void main(String[l args) 1 String s1 = ". System.println("~a última vez que aparece \"dibu\" es " + . System.charAt(0). t char chars2[1 = new char[5].getChars(0.println("Los primeros cinco caracteres de \ " " + sl + "\" son + s2). " + System. tomando como base el cero. Este es el resultado del programa: C:\>java app El primer carácter de "¡Hola desde Java!" es i El segundo carácter de "¡Hola desde Java!" is H Los primeros cinco caracteres de ".out.toCharArray(). String s2 = sl. Esto es un ejemplo que prueba como se usa indexOf y lastlndexOf: public class app I public static void main(String[] args) ( String sl = "He dibujado un bonito dibujon. 5). de la primera ocurrencia del carácter o substring en una cadena y 1astIndexOf devuelve la localización de la última ocurrencia de un carácter o substring. 5.Hola desde Java!" son ¡Hola Los primeros cinco caracteres de "¡Hola desde Java!" son ¡Hola Búsqueda y reemplazamientos en cadenas Se pueden buscar caracteres y substrings utilizando los métodos indexOf y 1astIndexOf.println(E1 segundo carácter de \ " " + sl + " \ " es " + charsl[l]).println("La primera vez que aparece \"dibu\" es "en la posición + sl.out.println("E1 primer carácter de \ " " + s1 " \ " es " + cl). char charsl[l = sl. El método indexOf devuelve el lugar.out. System.out. chars2. 0). System.println("Loc primeros cinco caracteres de \ " " + s1 + " \ " son " + new String(chars2)) . System.Hola desde Java! " . sl.indexOf("dibun)). char cl = sl.out.substring(0..out.

"en la posición " + sl. que permite reemplazar todas las ocurrencias de un carácter simple por otro carácter.out. String s2 = "Ecina.println("La última vez que aparece \"dibu\"es " + "en la posición " + sl.println(s2.out.lastIndexOf("dibu") ) . 'f')). este método crea un nuevo objeto String.println("La primera vez que aparece \ "dibu\" es " + ''en la posición " + sl. sin embargo. La clase String tiene también el método replace. Este es el resultado del código: C:\>java app La primera vez que aparece "dibu" es en la posición 3 La última vez que aparece "dibu" es en la posición 22 Edna. Esto es un ejemplo que muestra cómo funciona (observe que se están cambiando todas las ocurrencias de la letra h por la letra f en una cadena de texto): public class app I public static void main(String[l args) { String sl = "He dibujado un bonito dibujo".out. ¿Tiene alguna sugerencia?" "Intente le usar el método UpperCaseW. Así sería el código: . ) System. "El gran jefe me dijo que la salida de mi programa no tenía énfasis suficiente. Se puede usar el método toLowerCase para convertir a minúsculas una cadena..rep1ace(\hr. you\'re hired!". System.lastIndexOf("dibu")). Quizás piense que esto va en contra de la idea de no poder cambiar el texto en un objeto String.indexOf("dibu") . dice. y el toUpperCase para convertirla en mayúsculas. you're fired! Cambio de mayúsculas a minúsculas (o viceversa) en cadenas El programador novato dice. System.

en el que se usa el método set-Maximum-Fraction-Digits. Esta clase soporta los métodos formar. redondeando un valor double al formatearlo: import java.println(~yEIola desde Javalm.public class app ( public static void main(String[l args) ( Syst~. 1 } Este es el resultado del programa: C:\>java app ihola desde java! . public class app ( public static void main(String[] args) I double value = 1. ) 1. ¿Qué problema hay?" "N O . setMinimum-Integer-Digits.set-Minimum-Fraction-Digits.toUpperCase( )).o~t.HOLA DESDE JAVA! Formateo de números en cadenas Se pueden formatear números en cadenas utilizando la clase NumberFormat del paquete java.23456789.text.println(". Esto es un ejemplo. String S = nf.text. set-Maximum-integerDigits y set-Maximum-Fraction-Digits.*.getNumberInstance0. NumberFormat nf = NumberFormat.toLmrCase( System. dice el programador novato.Aola desde Javaln.format(value). "He almacenado toda mi novela en un objeto String y ahora no puedo cambiarlo.out. Este es el resultado: La clase StringBufferr "Hmm".

sl. Por ejemplo. contesta el NP. Este es un ejemplo en el que se usa el método replace de la clase StringBuffer para cambiar el contenido de un objeto StringBuffer de "¡Hola desde Java!" a "¡Hola a Java!": public class app ( public static void main(Stringt1 args) í StringBuffer sl = new StringBuffer("iHo1a desde Java! " ) . . dice. cuénteme".replace(6. "Tiene que usar un objeto le StringBuffer en su lugar". aquí tenemos cómo se crea un objeto StringBuffer vacío (que se inicializa con 16 espacios en blanco. Constructores d e la clase StringBuffer.puede cambiar el texto en el objetoStringU. La clase StringBuffer le da tanto y más como lo que ofrece la clase String: la posibilidad de modificar la cadena actual. 1 StringBuffer( ) Construye un bufferde ti postring. por defecto) y luego introducimos algo de texto: public class app I public static void main(String[l args) ( StringBuffer sl = new StrinBufferi 1.Hola a Java! Creación de StringBuHers Se pueden crear objetos StringBuffers usando los constructores de la clase StringBuffer. "Entonces. Este es el resultado del código: C:\>java app .insert(0. mlHola desde Javaln).5. "a"). Tabla 2. sin caracteres y con una capacidad de 16 caracteres. 11. sl.

Añade al buffer la representación string del argumento int. sin caracteres y con la capacidad marcada por el argumento length. StringBuffer(String str) Tabla 2. Añade al buffer la representación string del argumento float. Devuelve el carácter que ocupa la posicición marcada por el argumento indexen la secuencia representada por el buffer. Añade la representación string del argumento subarray del array de caracteres al buffer string. StringBuffer append(char[ ] str. int len) StringBuffer append(doub1e d) StringBuffer append(float f) StringBuffer append(int i) StringBuffer append(long 1 ) StringBuffer append(0bject obj) StringBuffer append(String str) Char charAt(int index) . Añade al buffer la representación string del arrayde caracteres pasado como argumento. Construye un bufferde tipostringque representa la misma secuencia de caracteres que el argumento. int offset.6. Añade al buffer la cadena pasada como argumento. Añade al buffer la representación string del argumento long. StringBuffer append(boolean b) StringBuffer append(char c) StringBuffer append(char[ ] str) Añade al buffer la representación string del argumento booleano.StringBuffer(int length) Construye unbufferde tipostring. Métodos de la clase StringBuffer. Añade al buffer la representación string del argumento Object. Añade al buffer la representación string del argumento char. Añade al buffer la representación string del argumento double.

char c) lnserta la representación string del argumento char en el buffer. lnserta la cadena en el buffer string. boolean b) Asegura que la capacidad del buffer sea al menos igual al mínimo dado Los caracteres se copian de este bufferstringen elarrayde caracteres de destino. int i) ) StringBuffer insert(int offset. acortando el buffer en un carácter. float f) StringBuffer insert(int offset. String str) int length( ) lnserta en elbufferla representación string del argumento float. StringBuffer insert(int offset. lnserta la representación del argumento Object en el buffer string. void ensureCapacity(int minimum Capacity) void getChars(int srcBegin. lnserta la representación string del argumento booleano en el buffer string. intsrcEnd. StringBuffer insert(int offset. long 1 StringBuffer insert(int offset. StringBuffer insert(int offset. int dstBegin) StringBuffer insert(int offset. . StringBuffer insert(index. double d) lnserta la representación string del argumento doubleen elbufferstring. Devuelve la longitud (en caracteres) del buffer. char[ ] str) lnserta la representación stringdel array de caracteres del argumento en el buffer string. StringBuffer deleteCharAt(int index) Borra el caracter delbuffeque ocupa la posicion dada por el argumento. int end) Borra los caracteres en un substring de este buffer. int len) array del array str del argumento en el buffer string. char[ ] dst. Inserta en elbufferla representación string del segundo argumento. lnserta en elbufferla representación del argumento long.StringBuffer delete(int start. lnserta la representación de un subint offset. Object obj) StringBuffer insert(int offset. char[ ] str. StringBuffer insert(int offset.

println(s2). sl.insert(0. veamos cómo se inicializa un nuevo objeto StringBuffer con una cadena: public class app { public static void main(String[l args) I StringBuffer sl = new StringBufferO. Establece la longitud del string.println(s1). Produce una nueva cadena que contiene una subsecuencia de caracteres actualmente contenida en el buffer. Además se puede crear un objeto StringBuffer con una longitud específica. Produce una nueva cadena que contiene una secuencia de caracteres contenida en el buffer. int end) String toString( ) Ahora. System. "¡Hola desde Java!"). El carácter del buffer que ocupa la posición dada por el índice se cambia por el marcado en el segundo argumento. El substring empieza en el índice dado. String~uffers2 = new ~tringBuffer(~iH0ia desde Java!"). Convierte los datos del buffer a un string. System.out.StringBuffer replace(start. String str) StringBuffer reverse( ) void setCharAt(int index. La secuencia de caracteres delbuffer es reemplazado por su inversa. int end. char ch) Reemplaza los caracteres del substring del bufferstring con los caracteres del string dado. void setLenght (int newlength) String substring(int start) String substring(int start. como sigue: public class app I .out.

out. cómo determinar su capacidad (Java normalmente hace que la capacidad sea 16 caracteres mayor que la longitud. .out. StringBuffer S2 = new StringBuffer("i~01a desde Java!"). Esto es un ejemplo que muestra cómo determinar la longitud de una cadena. StringBuffer s3 = new StringBufferílO).length( longitud reservada es " + )). caracteres cuyos códigos Unicode son 0).public static void main(String[] args) { stringBuffer si = new StringBufferO.capacity( longitud es m + sl. y se puede usar el método capacity para localizar la cantidad de espacio de memoria alocado para ese texto. y cómo cambiar la longitud de la cadena: public class app { public static void main(String[] args) { StringBuffer sl = new StringBuffer("iHo1adesde Java!").out. Además.println("La Syst-.insert(O. 1 1 Este es el resultado del programa: C:\>java app ¡Hola desde Java! ¡Hola desde Java! .println(s2) . "¡Hola desde Java!"). que permite truncar cadenas o extenderlas con caracteres nulos (es decir.println("La sl. s3. "¡Hola desde Java!"). system.println(s3). system. sl.out.out. System. System. para ahorrar tiempo para futuras alocaciones de memoria). se puede fijar la longitud del texto en un objeto StringBuffer con el método setlength.Hola desde Java! Obtención y establecimiento de longitudes y capacidades de StringBuffer Se puede usar el método length de la clase StringBuffer para buscar las longitudes de los objetos en StringBuffer.println(s1).insert(0. )).

le Para leer caracteres de un objetoStringBuffer. dice el programador novato. le dice. también se pueden introducir caracteres individuales usando el método setCharAt. "De acuerdo". Sin embargo. por "She had a mild look in her eyes".length( )). "use los métodos append e insert". . al igual que con los objetos String.println("La nueva longitud es " + sl. " jnecesito cambiar algo de texto en mi novela!" "Puede intentarlo con el método setCharAtU. usando setCharAt: public class app ( public static void main(String [ ] args) I StringBuffer sl = new StringBuffer("Shehad a wild look in her eyes". "Necesito alguna forma de editar el texto de los objetos StringBuffer como una cadena. 1 1 Esto es lo que el programa muestra al ejecutarlo: C:\>java app La longitud es 17 La longitud alocada es 33 La nueva longitud es 2000 Establecer caracteres en StringBuffers "jSocorro!" grita el programador novato.). Esto es un ejemplo en el que se cambia el texto "She had a wild look in her eyes". Este es el resultado: C:\>java app She had a mild look in her eyes Añadir e insertar utilizando StringBuffers "El método setCharAt no lo hace". se pueden usar los métodos charAt y getChars. dice. en los objetos StringBuffer.System.out. no como caracteres individuales".

println(SI) . System. Esto es lo que produce el código: C:\>java app ¡Hola Java! . se le añade "Java!".insert ( 6 . out .Hola desde Java! Borrar texto en StringBuffers Se puede borrar texto en un objeto StringBuffer usando los métodos delete y deleteCharAt. "desde '' ). aquí podemos ver cómo se cambia el texto "No tengo un buen momento" por "Tengo un buen momento" con delete (al usar este método.Se puede usar el método append para añadir cadenas al texto en un objeto StringBuffer.delete(0. se especifica el rango de caracteres que se quieren borrar): public class app ( public static void main(String[l args) ( StringBuffer sl = new StringBuffer("No tengo un buen momento"). y el método insert para insertar texto en un lugar en particular. 1 1 . s. 2). usando append e insert: public class app ( public static void main(String[] args) { StringBuffer si = new StringBuffer("¡Hola"). Este es un ejemplo que empieza con "¡Hola". Por ejemplo. S1 . y luego se le inserta "desde" en el medio del texto.

Hola desde Java!"). De hecho. "pero hay una cosa que no entiendo. sólo hay que especificar un rango de caracteres y el nuevo texto que debería sustituir al rango marcado. ¿cómo puedo reemplazar un texto por otro? ¿Tengo que borrarlo y luego insertar el nuevo?" "No". como sigue: public class app ( public static void main(String[] args) ( StringBuffer s1 = new StringBuffer(" . "Es fácil.Este es el resultado: C:\>java app tengo un buen momento. ya se ha visto cómo se usa replace. Este es el resultado del código anterior: C:\>java app . dice el programador novato. Reemplazar texto en StringBuffers "Estoy escribiendo un editor de texto usando la clase StringBuffer".Hola a Java! . le contesta. basta con usar el método replace".

se puede iterar sobre todos los datos de un grupo. Por ejemplo. vimos cómo Java gestiona los datos desde un punto de vista básico. supongamos que se ha almacenado un valor de 46 en una variable. Operadores La forma más básica de trabajar con los datos en un programa es hacerlo con los operadores de Java. condicionales y bucles En el capítulo anterior. En este capítulo. se pueden manipular los datos.m Operadores. restar. multiplicar. y el valor 4. Almacenar muchos datos en el programa es bueno. como se indica en este código: . empezaremos a trabajar con esos datos. condicionales y bucles en Java. siempre y cuando se haga algo con ellos. sumar. como examinar los operadores. dividir y mucho más. Utilizando operadores. Se pueden multiplicar esos dos valores con el operador de multiplicación (*). como un array. Con los bucles. en otra. trabajando con ellos sucesivamente de forma fácil. Con los condicionales. se puede alterar el flujo de un programa evaluando los valores de los datos. Estos tres casos son el siguiente paso en la potencia de la programación y los discutiremos en este capítulo.

out. 9. + " * " + operand2 t 1 1 Este es el resultado del código: C:\>java app 46 * 4 = 1 8 4 ¿Qué operadores hay en Java? Esta es la lista: -. operand2 = 4.public class app public static void main(String[] args) i int operandl = 46." + product) . product: product = operandl * operanda.(decremento) -(resta) ! (No lógico) != (distinto) % (módulo) %= (asignación del módulo) & (AND a nivel de bit) && (AND en cortocircuito) &= (asignación de AND) * (multiplicación) *= (asignación del producto) 1(división) /= (asignación de la división) ?: (if-then-else) • (Xor a nivel de bit) A= (asignación de Xor) A 1 (OR a nivel de bit) II (OR en cortocircuito) . System.printlnioperand1 .

logaritnlos. se llaman binarios. Además. s Condicionales Después de los operadores. Aquellos que tienen sólo un operando se llaman operadores unarios. el siguiente paso es usar las sentencias condicionales. Se utilizan para . Los que tienen dos operandos. que tiene tres operandos: el operador ternario. funi trigonlométrica1 y muc ho más. ?:. por ejemplo..(NOT unario a nivel de bit) + (suma) ++ (incremento) += (asignación de la suma) (menor que) I= (asignación de OR) c< (desplazamiento de bits hacia la izquierda) <c= (asignación del desplazamiento de bits a la izquierda) c= (menor o igual que) = (asignación) -= (asignación de la resta) == (igual a) > (mayor que) >= (mayor o igual que) >> (desplazamiento a la derecha) >>= (asignación del desplazamiento a la derecha) >>> (desplazamiento a la derecha con relleno de ceros) >>>= (asignación del desplazamiento a la derecha con relleno de ceros) Se verán todos estos operadores a lo largo de este capítulo. hay un operador. progra Java rio tiene un opeirador de potenc iación). la suma (a + b). también llamadas instrucciones de control de flujo.

Porque.println(~i~ace mucho calor!"). Las sentencias ifpueden ser más complejas si se añaden las cláusulas else. if (temerature < 80) { System. visualizar el mensaje "No hace demasiado calor. la condición de la sentencia ifes verdadera. Un ejemplo: public class app public static void main(String[l args) ( int temperature = 73. 1 1 1 Como veremos en este capítulo. lo que significa que se va a ejecutar el bloque de código de la sentencia if.~ut. si el valor es menor que 80. } else I System. . Esto se puede hacer comprobando la temperatura actual con una sentencia if de Java que compara el valor de la variable temperature con 80 y que. El operador relaciona1 < (menor que) se usa para ver si el valor de la variable temperature es menor que 80. Este es el resultado: C:\>java app NO hace demasiado calor.").out. 1 1 } La sentencia if comprueba si su condición (la parte que aparece entre paréntesis) es verdadera.tomar decisiones basadas en el valor de los datos y dirigir el flujo del programa de acuerdo a esos valores. hay otras sentencias condicionales."). Dado que esta variable se ha inicializado a 73. Deben seguir a la sentencia ify se ejecutan cuando su condición es falsa. que en este caso es temperature < 80.o~t. if (temperature c 80) ( System.println("No hace demasiado calor. supongamos que queremos informar sobre el tiempo y si está por debajo de 80 grados Fahrenheit.println(~Nohace demasiado calor. visualiza el mensaje: public class app I public static void main(String[l args) { int temperature = 7 3 .".

ya que Java lo permite. se está declarando e inicializando el índice del bucle a O en la expresión de inicialización del bucle for. loop-index < grades. puede que quiera gestionar los elementos de un grupo de datos trabajand o con cada uno de ellos en serie. 1 average = sum / grades. A continuación se muestra el formato general del buclefor (observe que la sentencia que forma parte del cuerpo del bucle for puede ser compuesta. condición-final. Cada vez que se pasa por el bucle. Para aclarar todo esto. sum = 0. se pueden usar varios índices en un bucle for). El bucle básico involucra a la sentencia for.expresión-de-iteración) I sentencia 1 Se puede inicializar un índice en expresión-de-inicialización (de hecho. usaremos el bucle for para acumular los grados de seis estudiantes de un array y calcular el grado medio. el índice tendrá un valor diferente y se puede usar para hacer referencia a cada elemento del conjunto de datos. 87. lo que significa que pueden presentarse varias sentencias sencillas encerradas entre paréntesis): for (expresión-de-inicialización. .length. for (int loop-index = 0. En este caso.length. proporcionar una condición para finalizar el bucle en condición-final y añadir alguna forma de cambiar (normalmente incrementando) el índice en expresión-de-iteración.Los bucles son fundamentales en la programación y permiten gestionar distintas tareas repitiendo la ejecución de cierto código específico. El índice del bucle se usa como si fuera un índice de un array. 56. average. 7 3 . loop-index++) C sum += grades[loop-index]. Así aparece el código (observe que. 641. 99. pongamos un ejemplo. al igual que C++): public class app { public static void main(String[] args) { double grades[] = { 8 8 . Por ejemplo. que permite ejecutar un bloque de código usando un índice. o quizás quiera ejecutar una tarea hasta que cierta condición sea verdadera. realmente. double sum.

veamos el código del programador novato.println("Grado medio = " + average). le respondemos. "Revisemos el código". Java soporta gran cantidad de operadores y puede haber problemas si se utilizan muchos en una sentencia simple. "Probablemente es un problema de precedencia de los operadores". 1 } Este código recorre todos los grados del array y los va sumando.println("E1 valor } + value). el bucle for es potente. "Java está actuando mal otra vez. value = 12 + 2 4 / 6 . Este es el resultado del código: C:\>java app ~l valor = 16. las sentencias condicionales y los bucles. Este es el resultado del código: C:\>java app Grado medio = 77. en el que intenta sumar 12 más 24 y dividir la suma entre 6: public class app I public static void main(String[] args) I double value. = " System. dice el programador novato. dejando el resultado en la variable sum. hay algo que se ha hecho de distinta forma a la que el programador novato esperaba.out.0 Claramente.83333333333333 Como se puede ver. Precedencia de operadores "Oye". De hecho.que después se divide entre el número total de elementos del array para calcular el grado medio. ¿Qué operador se ejecuta primero? Por ejemplo. Todos los elementos se recorren utilizando un índice que empieza en O y en cada paso se incrementa hasta llegar al último elemento del array. Ya es hora de empezar a usar los operadores. Estaba tratando de sumar 12 más 24 y luego dividir el resultado entre 6. La respuesta debería ser 6 y Java devuelve 16".System. Java tiene una precedencia de operado- . de hecho es uno de los muchos puntos que se tratarán en las secciones siguientes.out.

que siempre se pueden usar paréntesis para establecer el orden de ejecución de las operaciones en las expresiones de Java. primero ejecutará el operador de mayor precedencia. le dice.res muy clara. Para especificar en Java el orden que se quiere. Esto significa. Observe que en el nivel de precedencia más alto. en el que se ha puesto entre paréntesis "12 + 24". para asegurar que esta operación se ejecuta primero: public class app ( public static void main(String[l args) { double value. En este capítulo.1 explica la precedencia de operadores en Java (desde la más alta a la más baja). System. Así quedaría el ejemplo anterior. se puede usar paréntesis para agrupar las operaciones que se quieren ejecutar primero. encontrará ( ).out. no encerrada entre paréntesis). por ejemplo. "C++ tiene un operador de incremento y otro de decremento. y . por lo tanto en la expresión anterior. . Esto e s lo que ocurre aquí. lo que quiere decir que si encuentra dos operadores del mismo nivel en una sentencia (es decir. primero se divide 24 entre 6 y el resultado se divide entre 12 dando 16. [ ] (el "operador" array. que se usa para especificar los métodos y los miembros de datos de los objetos). que se usa para obtener los datos de un índice específico en un array). iJava los soporta?" "Claro". que el operador 1 tiene mayor precedencia que el operador +. value = (12 + 2 4 ) / 6 . veremos todos estos operadores de Java en orden de precedencia. 1 } Este es el resultado del código: C:\>java app ~l valor = 6. Incremento y decremento: ++ y -El zar de la Programación Exacta aparece y dice.println("E1 valor = ' + value). (el operador punto. Empezaremos por los operadores incremento y decremento: ++ y --.0 La tabla 3.

por ser operaciones muy comunes. Esto es algo que hay que comprobar. De hecho. cuando la sentencia se completa. Precedencia de operadores. Tabla 3.se lo resta. Por ejemplo. tendrá el valor 1. fueron tan populares que el operador de incremento se usó en el nombre de C++. se ejecutan después del resto de la expresión y cuando se usan como operadores prefijo. Cuando se usan como operadores sufijo.pueden ser operadores sufijo (por ejemplo. después de ejecutar v a h e + + . indicando que C++ es una versión incremental de C. se ejecutan antes que el resto de la expresión. Por ejemplo. vahe++) o prefijo (++vahe). value2 contendrá el valor original de valuel y el valor de valuel se incrementará.1.El operador de incremento ++ suma uno al operando y el operador de decremento -. veamos el siguiente código: En este caso. He quí un ejemplo de cómo funciona: . si value tiene el valor 0. Aquí hay un punto importante: ++ y -. Estos operadores se introdujeron en C para incrementar y decrementar valores fácilmente.

. System. . . value2 = 0. .es el operador unario NOT a nivel de bit y ! es el operador unario lógico NOT.out. system. System. Estos son los resultados: C:\>java app valorl = O valor2 = O Después de ejecutar value2 = ++valuel.out. . System.public class app I public static void main(String[] args) { intvaluel = 0. . valor3 = 1 valor4 = 1 NOT unario: y ! El operador . El operador cambia todos los bits de los argumentos numéricos y el operador ! cambia los valores verdaderos a falsos y viceversa.out .. int value3 = O . value4 = 0.out.println("valor2 = " + value2).out.println("va1orl = " + valuel). System. System.println("va1or3 = " + value3). ") .println("Despues de ejecutar value2 = ++valuel .println("valor1 = " + valuel). ") . - - .println ("valor2 = " + value2).println("Después de ejecutar value4 = ++value3 .out. System. valorl = 1 valor2 = O valor3 = O valor4 = O Después de ejecutar value4 = ++ vaiue3 ..out.

para obtener el valor más negativo posible de un short. se utiliza * para multiplicar y / para dividir valores. Este es el resultado: C:\>java app El valor más negativo de un short = -32768 !verdadero = false Si se inicializa intl a O y luego se cambian sus bits con el operador a 1111111111111111 en binario. "Claro. boolean booleanl = true. Se ejecuta la multiplicación y división con valores enteros para mostrar que.out. " + -shortl). y luego se hace lo mismo con valores enteros.1.println("E1 valor mbs negativo de un short = sy~tem. Java habría visualizado el resultado . "Espero que Java tenga operadores de multiplicación y división. la parte fraccionaria de los . y además se cambia un valor booleano de verdadero a falso: public class app I public static void main(String[l args) { short shortl = 32767. " le dice. En Java.println(~!verdadero =" + Ibooleanl). - Multiplicación y división: * y / El zar de la Programación Exacta dice.out. system. cuando se usan enteros. Esto significa que el bit que ocupa el primer lugar en los números negativos es 1 y O para los positivos. porque usa la notación de complemento a dos para los números negativos. Veamos un ejemplo en el que se usa * y / con valores double. como C++".Esto es un ejemplo en el que se cambian todos los bits del mayor valor positivo que puede ser almacenado en un dato de tipo short.

le contestamos. Para ver cómo funciona. 4 * 6 / 5 = 4 Módulo: % Se usa el operador módulo (%) para devolver el resto de una operación de división. Suma y resta: + y - "El operador multiplicación es un asterisco y el de la división es una barra inclinada". intResult. probablemente no se deberían usar enteros. int3 = 5. eche un vistazo a la sección "Bucle for".resultados matemáticos se truncan. más adelante. En ella hay un ejemplo completo. double3 = 5. Observe que el operador módulo es especialmente útil cuando se hace conversión entre bases. 8 Con enteros.out. Por lo tanto. doublel * double2 / double3. 4 * 6 / 5 = " + intResult). Systern. si se quiere ejecutar una operación de división y mantener la precisión. Por ejemplo. dice el programador novato. Este es el código: public class app { public static void main(String[l args) { double doublel doubleResult = = 4. 1 1 Este es el resultado: C:\>java app 4 * 6 / 5 = 4 . . porque se puede usar con la base a la que se está convirtiendo. int2 = 6 . ¿Qué utiliza Java para los signos más y menos?" "Los símbolos usuales". double2 = 6. intResult = intl * int2 / int3. int intl = 4. doubleResult.println("Con enteros. 1013 es igual a 3 con un resto de 1. "pero esos no son los signos que se aprenden en el colegio.

devuelve 11 1 1111 1 1111 111 10. nuevo-valor = valor >>> número-de-lugares. Normalmente. respectivamente.println(operand1 + " . se usan estos operadores: nuevo-valor = valor << número-de-lugares. que es lo mismo que dividir entre 4. que es . 16 >> 2 es igual a 4. sum = operandl + operandl. por lo tanto. Además.out. porque se puede sumar un número al int o long y luego desplazarlo haeia la izquierda para hacerle sitio al siguiente campo de datos. 16 >> 2 desplaza 2 bits hacia la derecha del número 16. Systern. Así. diff. operand2. que es -4 como un short. sum. 1 1 Estos son los resultados: Operadores de desplazamiento: >>. el número de bits indicado por el operando situado en el lado derecho. que es -2.println(operand1 + " + " + operand2 + " = " + sum). Es importante que sepa que el operador >> respeta el signo de su operando y dado que un valor negativo significa que el bit de más a la izquierda es 1.out. nuevo-valor = valor >> número-de-lugares. cambiar -1. diff = operandl - System. hacia la derecha sin signo (>>>) y Así hacia la izquierda (e<). el desplazamiento de un número negativo hacia la derecha introduce un nuevo 1 en su izquierda. Hay tres operadores de desplazamiento: hacia la derecha (>>). operand2 = 4. que se usan para la public static void main(String[] args) ( int operandl = 5. se usan los operadores de desplazamiento para empaquetar valores binarios en un int o long como campos. >>> y << Se usan los operadores de desplazamiento para desplazar.Los operadores numéricos más antiguos son suma y la resta. Por ejemplo. cambiar 11 11 1111 1111 1100. hacia la izquierda o derecha del operando situado en el lado izquierdo." + operand2 + " = " + diff). Por ejemplo: public class app ( + y -.

quecontinúasiendo-1. ~ystem. <.out.. if (budget < 0 ) { System.println(value + << 2 = " + (value << 2)). si el número es positivo o negativo. Este es el resultado: Operadores de relación: >.". == y != El Gran Jefe (GJ) aparece y dice. Veamos un ejemplo donde interviene el operador de desplazamiento: public class app { public static void main(String[l args) { int value = 16. Por ejemplo..println("Uh 1 else I oh. "Casi hemos gastado el presupuesto y hay que asegurarse de que no lo sobrepasamos".println(negValue + " >> 2 = + (negValue >> 2)). dice el GJ. negValue = -1. . "Hmm"."). <=. le dice. sobre lo de mi ascenso. > 1 ~ystem. "parece que es un trabajo para el operador de relación menor que.println(negValue + >>> 22 = " + (negValue >>> 22)). System.println(value + " >> 2 = " + (value >> 2)).Sirealmente quiere trabajar con los bits actuales de un número cuando se los desplaza a la derecha y no tiene uno añadido a la izquierda cuando se desplazan a la izquierda números negativos. Por cierto.out. "Olvídelo".da 1111111111111111.out. use el operador de desplazamiento sin signo hacia la derecha (>>>).out.1111111111111111. veamos lo que deberíamos evaluar para asegurarnos que el presupuesto es mayor que cero utilizando la sentencia if: public class app I public static void main(String[] args) { int budget = 1. Use los operadores relacionales para crear condiciones lógicas que puedan ser evaluadas con sentencias condicionales como if. >=. Éste introduce un cero a la izquierda.out. System.

"necesito saber si el bit número 3 de un entero está puesto a 1. Operadores lógicos a nivel de bit AND. estos operadores devolverán verdadero si sus operandos cumplen las descripciones dadas: > (mayor que. Por ejemplo. cuando se usa el operador a nivel de bit & con dos . operando1 > operando2 devuelve verdadero si el operando 1 es mayor que el operando 2) >= (mayor o igual que) < (menor que) <= (menor o igual que) == (igual a) != (distinto) Los operadores relacionales se pueden combinar con operadores lógicos (para más detalles.Este es el resultado: C:\>java app Todavía es solvente. Xor y OR: "i Socorro!" dice el programador novato. ¿Hay alguna forma fácil de hacerlo?" "Claro". Los operadores a nivel de bit permiten examinar cada uno de los bits de los valores. A continuación se muestra una lista de los operadores relacionales. ver el siguiente punto). le dice. "puede usar un operador a nivel de bit". por ejemplo.

será un cero. En pocas palabras. el operador Xor (". llamado OR exclusivo) devuelve 1 cuando un bit es O y el otro es 1 y devuelve O en caso contrario. 1 else { System. un uno aparece en ese lugar en el resultado. se realiza la operación lógica AND con cada bit de un operando y su correspondiente en el otro.println("Bit 3 no está activo. Cuando los operadores &. El operador Xor (") devuelve verdadero cuando un operando es falso y uno es verdadero.out.3.operandos. if (bit3setting ! = 0 ) { System. El operador AND (&) devuelve verdadero cuando ambos operandos son verdaderos y devuelve falso en caso contrario."). El operador AND (&) devuelve 1 cuando ambos bits son 1 y devuelve O en caso contrario. Si el resultado de la operación AND no es cero. Los operadores a nivel de bit se pueden encontrar en la tabla 3. de lo contrario. como se puede ver en la tabla 3. así funcionan los operadores lógicos a nivel de bit: el operador OR (1) devuelve falso cuando ambos operandos son falsos y devuelve verdadero en caso contrario. así es cómo funcionan: El operador OR (1) devuelve O cuando ambos bits son O y devuelve 1 en caso contrario."). Los operadores lógicos a nivel de bit funcionan igual que los operadores a nivel de bit (sustituyen falso por O y verdadero por l). y devuelve falso en caso contrario. Aquí se muestra cómo sería el código: public class app I public static void main(String[] args) { int value = 12. int bit3setting = value & 1 << 3. En pocas palabras. Si ambos bits son 1. el tercer bit del valor original era 1. se puede hacer la prueba del programador novato de si el tercer bit de un valor está a 1 haciendo el AND lógico con un número para el que se sabe que el tercer bit es l. } 1 1 Este es el resultado: C:\>java app Bit 3 está activo.println("Bit 3 está activo. Por ejemplo. . " y I operan con valores booleanos verdadero1 falso. Finalmente.out.2. se consideran operadores lógicos a nivel de bit.

3. insisto en que la temperatura está entre 60 y 90 grados.println("~odavíaes solvente. .2. boolean fired = falce. usando el operador lógico a nivel de bit &.Tabla 3. if (budget < O 1 fired == t ~ e i) ' O ) Syctem. Los operadores a nivel de bit. 1 elce { Syctem.out. > 1 1 Este es el resultado: C:\>java app ~odavía solvente. Los operadores lógicos a nivel de bit.out. es En el siguiente ejemplo. usando el operador 1: public class app I public static void main(String[] args) I int budget = 1. visualizando un mensaje en el caso de que cualquiera de ellas sea verdad.") . Falso Verdadero Falso Verdadero Falso Falso Verdadero Verdadero Falso Verdadero Verdadero Verdadero Falso Falso Falso Verdadero Falso Verdadero Verdadero falso Este es un ejemplo en el que se han puesto dos condiciones lógicas juntas. Tabla 3. antes de visualizar un mensaje: .println("Uh oh.

if (temperature < 90 && temperature > 6 0 ) I System.4 muestra cómo funcionan estos operadores. . && y II lógicos Los dos operadores lógicos que generalmente se usan en expresiones son AND (&&) y OR (11).") . en el que se usa &&: public class app { public static void main(String[l args) { int temperature = 70.").out. El operador OR (11) devuelve falso cuando ambos operandos son falsos y devuelve verdadero en caso contrario.public class app { public static void main(String[l args) I int temperature = 70. Java además incluye dos operadores lógicos: && y II.println("Podemos ir de merienda. La tabla 3. Estos operadores se usan para enlazar cláusulas lógicas. se usa AND cuando se quiere que ambas cláusulas sean verdad y OR cuando sólo se necesita que una de las dos sea verdadera. Este es un ejemplo del punto anterior. 1 1 1 El resultado es: C:\>java app Podemos ir de merienda. if (tanperature < 90 & temperature > 60) { System.out.println("Podemos ir de merienda. los operadores lógicos a nivel de bit pueden ser muy útiles. Veámoslos a continuación. El operador AND (&&) devuelve verdadero cuando ambos operandos son verdaderos y devuelve falso en caso contrario. > 1 1 Este es el resultado: C:\>java app podemos ir de merienda Como se puede ver.

en la que se calcula su inverso. no se ejecuta. la segunda parte de la expresión. no evaluarán el operando derecho. echemos un vistazo al código siguiente. Para ver cómo funcionan.println("E1 valor es demasiado pequeño. Esto es muy útil en casos como el que sigue. en el que estamos comprobando si un valor tiene O y si u inverso es menor que 1000.4. Los operadores lógicos. Tabla 3. 1 else ( System."). en el que la asignación de la sentencia $se ejecuta cuando se usa el operador & pero no cuando se usa el operador cortocircuito &&: .out. se evita un error de desbordamiento al intentar dividir entre cero.println("E1 valor no es demasiado pequeño. Si el valor es O."). 1 Verdadero 1 Falso 1 Verdadero Este es el código: public class app 1 Falso Falso Falso Verdadero Verdadero Falso Verdadero Verdadero Verdadero Falso Falso Falso Verdadero I I I I public static void main(String[] args) { double value = 0.Los operadores && y II tienen además otra propiedad interesante: son operadores cortocircuito. 1 1 1 Este es el resultado: C:\>java app ~l valor es demasiado pequeso Los operadores lógicos se diferencian de los operadores lógicos a nivel de bit en que los primeros son operadores cortocircuito. De esta forma.out. if (value I = O && 1 / value < 1000) { System. lo que quiere decir que si pueden determinar todo lo que necesitan saber evaluando el operando de la izquierda.

out.out. porque se puede usar para devolver una cadena construida a partir de un valor. int3 = 1. el operador ternario (?:).println("int3 = " + int3). Estoy preparado para las sentencias condicionales de Java". Este operador se llama operador ternario porque involucra tres operandos. como sigue: . dice el programador novato (PN). "No tan rápido". 1 1 Este es el resultado: C:\>java app int2 = 2 . el operador ?: devuelve valorl y. le dice. en caso contrario devuelve valor2.println("int2 = " + int2). Este operador es perfecto para esto. Hay un operador Java que funciona como una sentencia if-else. int2 = 1.O int3 = 1. "¿Qué hay sobre el operador condicional ternario?" "¿El qué?" pregunta PN. } else { value = valora. De esta forma. la sentencia precedente funciona como la siguiente sentencia if: if (condición) I value = valorl. if ( i n t l i = O & ( i n t 2 = 2 ) == 1) { 1 System. "soy un experto en operadores. if ( i n t l != O & ( i n t 3 = 2 ) == 1 ) { 1 System. si el valor es menor que 10 o un dígito si el valor es mayor o igual que 10. 1 Veamos un ejemplo en el que un entero entre O y 15 se convierte a hexadecimal usando el operador ?:.0 El operador If-Then-Else: ?: "De acuerdo".public class app { public static void mainíString[] args) I double intl = 0. una condición y dos valores: valor = condición ? valorl : valora: Si la condición es verdadera.

} } - 101. devuelve el valor asignado): public class app ( public static void main(String[l args) ( int valuel.println("E1 valor = " + value). value2. El operador = se puede utilizar para asignar a una variable un valor literal o el valor de otra variable. chars[] = ("a".out. "e". . 1 1 Este es el resultado: C:\>java app El valor = 12 Como en C++. " b " .public class app ( public static void main(String[l args) I int value = 15. String digit.out. " d " . System. "f"}. value3. se pueden ejecutar múltiples asignaciones en la misma sentencia (esto funciona porque el operador asignación. como sigue: public class app I public static void main(String[l args) { int value = 12. "c". Digit = valuo < 10 ? String valueOf(va1ue) : charstvalue System. Este es el resultado: C:\>java app 15 = Oxf Operadores de asignación: = y [operador]= La mayor parte de los operadores básicos son operadores de asignación (ya hemos usado estos operadores en el libro).println(value + ' = Ox" + digit).

Esto es un ejemplo que utiliza el operador de asignación de la multiplicación: public class app I public static void main(String[l args) { int value = 10: value *= 2. += es el operador de asignación de la suma. se pueden combinar muchos operadores con el operador de asignación (=). 1 1 Este es el resultado: C: \>java app value * 2 = 20 Hay bastantes combinaciones d e operadores de asignación. Por ejemplo.out.println("va1ue * 2 = " + value). como en C++. Esta es la lista: %= (asignación de módulo) &= (asignación a nivel de bit de AND) *= (asignación de multiplicación) /= (asignación de división) "= (asignación a nivel de bit de Xor) I= (asignación a nivel de bit de OR) += (asignación de suma) <<= (asignación de desplazamiento a la izquierda) .Este es el resultado: Además. que significa que value += 2 es una forma corta d e value = value + 2. System.

Esta clase es parte del paquete java.14159265358979323846) double sin(doub1e a): Seno double cos(doub1e a): Coseno . Echaremos un vistazo a esta clase en la siguiente sección.Math para ejecutar muchas operaciones matemáticas. "Se puede usar el método pow de la clase Math".pow: public class app I public static void main(String[l args) I Syritem.3 x 3 x 3 x 3 = " + ~ath. pero no hay ningún operador de Java para la potenciación".por(3. le dice. dice el programador novato (PN)". 4 ) ) s 1 1 Este es el resultado: C:\>java app 3 x 3 ~ 3 =~ 1 . Se puede usar la clase java.out.lang.7182818284590452354) double PI: La constante pi (3.quiero elevar3 a la potencia 4. " dice PN. pero hay una forma más popular de gestionar matemáticas en Java. 3 elevado a la potencia 4 es 81". Por ejemplo. "La crearé cuando Java me lo pida.println(.lang (que el compilador Java importa por defecto). "Y de esta forma. así se resuelve el problema del programador novato usando el método Math. Utilización de la clase Math "Oye". la clase Math.<= (menor o igual que) -= (asignación de resta) >>= (asignación de desplazamiento a la derecha) >>>= (asignación de desplazamiento a la derecha con relleno de ceros) Esto completa la lista de los operadores de Java. 0 8 3 Las constantes y métodos de la clase son: double E: El número 'e' (2.

int b): Máximo de dos enteros long max(1ong a. double b): Elevar el valor 'a' a la potencia 'b' double cell(doub1e a): Método ceilling double floor(doub1e a): Métodofloor double rint(doub1e a): Entero aleatorio int round(doub1e a): Redondea un double long round(float a): Redondea unfloat double random( ): Número aleatorio int abs(int a): Valor absoluto de un entero long abs(1ong a): Valor absoluto de un long float abs(float a): Valor absoluto de unfloat double abs(doub1e a): Valor absoluto de un double int min(int a. double b): Mínimo de dos double int max(int a.double tan(doub1e a): Tangente double asin(doub1e a): Arcoseno double acos(doub1e a): Arcocoseno double atan(doub1e a): Arcotangente double atan2(double a): Arcotangente (versión 2 del operando) double exp(doub1e a): Eleva el número 'e' a la potencia 'a' double log(doub1e a): Logaritmo del valor 'a' double sqrt(doub1e a): Raíz cuadrada del valor 'a' double pow(doub1e a.float b): Máximo de dosfloat double max(doub1e a. long b): Máximo de dos long float max(float a.float b): Mínimo de dosfloat double min(doub1e a. int b): Mínimo de los dos enteros long min(1ong a. long b): Mínimo de dos long float min(float a. double b): Máximo de dos double .

hay algunos métodos que se pueden usar como operadores.println("sl != s2").compareTo(s2): Devuelve un valor menor que cero si s 1 < s2. sl.equalsIgnoreCase(s2): Verdadero si s l es igual a s2 (ignorando las mayúsculas y minúsculas). 1 if (sl.equals(s2)) { System. String s4 = "bcd".out. > else { System. equalslgnoreCase y compareTo. como sigue: s l .Comparación de cadenas Cuando se está trabajando con la clase String. 1 else { System.println("s1 == s2"). String s3 = "ABC". s 1.println("s1 ! = s3 al ignorar las mayúsculas"). los métodos equals.equals(s2): Verdadero si s l es igual a s2.out. He aquí un ejemplo en el que se utilizan todos los métodos: public class app i public static void main(String[] args) { String sl = "abc". > . Por ejemplo.out. String s2 = "abc". equalsIgnoreCase(s3) { ) System.println("s1 == s3 al ignorar las mayúsculas"). cero si s l es igual a s2 o un valor mayor que cero si s l > s2.out. if (sl.

es el momento de usar las sentencias condicionales de Java. es decir. pero también se pueden ejecutar múlti- .Este es el resultado del código: C:\>java app S1 == S2 s1 == s3 al ignorar las mayúsculas s1 c S2 La sentencia if "Hmm". es empezar comprobando si el valor es mayor que cero y. "¿El qué?" pregunta PN. Una forma de obtener el valor absoluto. dice el programador novato (PN). 1 1 Este es el resultado: Observe que en este caso. cierto número de sentencias encerradas entre llaves. "Supongo que nunca ha oído hablar del método Abs de la clase Math". le responde. como el programador novato estaba tratando de hacer.println("Abs(" + value + ") = " + value). "quiero escribir una rutina en Java que calcule el valor absoluto y no sé cómo hacerlo". if (value > 0) System. Cuando se quiere controlar el flujo del código. Aquí. la sentencia que se ejecuta si la condición de la sentencia ifes verdadera es simple. Este es el formato general de la sentencia if if (condición) sentencial: else sentencia2. si es así. Observe que tanto sentencial como sentencia2 pueden ser compuestas. visualizar el resultado tal cual.out. se puede ver cómo se haría esa evaluación con una sentencia if: public class app ( public static void main(String[] args) I int value = 10. como la sentencia if.

~ut. Sin embargo. que se ejecuta si la condición de la sentencia ifes falsa. 1 1 1 Este es el resultado del código: .out. se puede extender esa sentencia if añadiendo una cláusula else. Así se haría en el código (observe que se pueden gestionar tanto números positivos como negativos): public class app { public static void main(String[l args) I int value = -10: if(va1ue > 0) { System. 1 else { SyStem. como sigue: public class app I public static void main(String[l args) { int value = 10.println(~Abs(~ value + " 1 = " + value). System.println("Abs(" + valuo + " 1 = " + -value). if(value > 0 ) { ~ystem.out.ples sentencias haciendo que formen parte de un conjunto de sentencias en un bloque de código. + Este es el resultado: C:\>java app El número era positivo Abs(l0) = 10 La sentencia else En el ejemplo del valor absoluto.").println(~~l número era positivo.out. la sentencia if sólo visualiza un valor absoluto si el valor ya es positivo.println('Ab~(" + value + " ) = " + value) .

println("Es martes. else if (day == "sábado") .").out.").println("Es lunes.5 Escalas if-else ES posible crear una secuencia entera de sentencias if-else. else if (day == "viernes") System.If anidados También se pueden tener sentencias $anidadas una dentro de otra (esto es.").out.out.out. Esto es un ejemplo que muestra cómo funciona la técnica: public class app { public static void main(String[] args) t double value = 2. else System.println("Es miércoles."). definirlas dentro de otras sentencias iJ).println("E1 resultado = " + (-1 / value))."). se evalúa el valor de una variable tipo string hasta que se encuentra el día de la semana): public class app { public static void main(String[] args) I String day = "miércoles". else if (day == "miércoles") System. A continuación veremos un ejemplo en el que se ve cómo funciona (en este caso.println("Es viernes. 1 1 Este es el resultado del código: C:\>java app El resultado = 0.out. if (value ! = 0) t if (value > 0 ) System. else if (day == "jueves") System. if(day == "lunes") System.println("Es jueves.out.println("E1 resultado = " + (1 / value) ) .out. que se conoce como escala if-else. else if (day == "martes") System.

y así sucesivamente."). la sentencia switch.out. 1 { default: sentenciaqor-defecto.System. char. se compara con los distintos valores de las sentencias case: valorl. ya llevo cinco páginas de programa"."). "¿Qué es eso?" pregunta PN. La sentencia switch "Vaya". En general. Observe que aunque se pueden crear escalas if-else de esta forma. La sentencia switch es la sentencia de múltiples selecciones de Java.println("Ec domingo. else if (day == "domingo") System.out. short o int. "estoy harto de escribir escalas if-else. valor2. dice el programador novato (PN).println("Ec sábado. el valor de la expresión. Si la expresión coincide con una de las sentencias case. [break. 1 case valor3 : sentencia3. Java incluye. tiene la misma funcionalidad que la escala if-else (ver la sección anterior) pero de una forma mucho más fácil. Veremos esta sentencia en el siguiente apartado. 1 1 En este caso. [break. se ejecuta el código asociado con esa sentencia case: senten- . 1 } Este es el resultado del código: C:\>java app Es miércoles. [break. que debe ser de tipo byte. esta es la expresión de la sentencia switch: switch (expresión) case valorl : sentencial. 1 case valor2 : sentencia2 . "¿Y si intenta utilizar la sentencia switch?" le pregunta. para situaciones como esta.

").out. Si la ejecución llega a una sentencia break."). break. Observe que si no se especifica la sentencia break al final de la sentencia case. Algunas veces."). la sentencia switch termina. etc. break.println("Ec miércoles.out.out. case 2: System. break. case 1: System. Este es el resultado: C:\>java app ES miércoles También se pueden anidar sentencias switch.println("Es domingo.cial.out. la ejecución continuará con el código del siguiente case. case 3: System.println("Es martes. switch iday) { case 0: System. break."). case 5: System. esto es útil.").out. Esto es un ejemplo en el que se visualiza el día de la semana basándose en un valor numérico y utilizando la sentencia switch: public class app { public static void main(String[] args) { int day = 3.println("Es lunes. sentencia2.println("Debe ser sábado. ya que se quiere ejecutar el mismo código para varios valores: public class app ( public static void main(String[] args) I int temperature = 68. .").").println("Es viernes.println("Ec jueves.out. case 4: System.out. default: System. break. break.

El gran jefe quiere que haga un programa comercial que calcule factoriales y.println("Templado. jni siquiera sé lo que es un factorial!" "Bien". 1 1 1 Este es el resultado del código: C:\>java app Frío. es igual a 6 x 5 x 4 x 3 x 2 x 1. Bucle while "Bien". default: System. break. que se escribe como '6!'."). break. el cuerpo del bucle no se ejecutaría ni una vez.case 60: case 61: case 62: case 63: case 64: System.out. dice el programador novato. Este es el formato general del bucle while: while (condición) sentencia Observe que si la condición no es verdadera."). le dice. A continuación hay un ejemplo con el bucle while.println("Probab1emente demasiado calor. "tengo problemas otra vez.println(~Demasiado frío. Y puede escribir su programa con un bucle while".out. case 65: case 66: case 67: case 68: case 69: Syctem. El cuerpo de un bucle while (puede ser una sentencia compuesta por un grupo de sentencias simples encerradas entre llaves) se ejecuta mientras una condición lógica sea verdadera.out. case 70: case 71: case 72: case 73: case 74: case 75: System.println("Frío. break. en .o~t.")."). "seis factorial.

println("Valor actual = 1 " + value-). temp. 1 System. 1 1 Esto es lo que el bucle while devuelve: C:\JavaBB\Test>java app Valor actual = 10 Valor actual = 9 Valor actual = 8 Valor actual = 7 valor actual = 6 Valor actual = S Valor actual = 4 Valor actual = 3 Valor actual = 2 Valor actual = 1 A continuación tenemos otro bucle while en el que se resuelve el problema del programador novato y se crea un programa que calcula factoriales: public class app { public static void main(String[] args) r int value = 6. 1 1 Así es como el programa calcula el factorial de 6: .out. //copia temporal. se le va restando 1 y después se visualiza el resultado siempre y cuando sea positivo. while (value > O) C Syetem.este caso.out. Cuando el valor llega a O. factorial *= t . temp = value.println(va1ue + " ! = " + factorial). el bucle while se para porque la condición (value > O) es falsa: public class app I public static void main(String[l args) { int value = 10. se visualiza un valor. factorial = 1.

se usa el bucle while para ponerlos en una pila de Java. Después de poner los dígitos en la pila.valueOf(temp temp >>>= 4 .A continuación. while (te. sqrt = 1.println("sqrt(" + target + " ) sqrt): . StringBuffer sb = new StringBufferO.util. En este caso. while(!st.pop0 1 )).append(new String((String) st. se les pasa por otro bucle while para cambiar el orden y producir el objeto StringBuffer que se visualiza: import java. Esta es la salida del programa: La conversión de 32 es 0x20 Aquí hay algo que puede ser útil: como en Java.emptyO) ( sb. while (++sqrt * sqrt != target) . public class app t public static void main(String[l args) { int value = 32.*. System. un bucle while no tiene por qué tener un cuerpo.push(String. Stack st = new Stack(). temp = value. = " + Syctem. se convierte un número a hexadecimal con el operador módulo. hay un ejemplo más avanzado.out. que se verá cuando discutamos las colecciones de clases. las sentencias null son válidas. A continuación vemos un ejemplo en el que se muestra una forma cruda de calcular la raíz cuadrada de un entero (observe que todo lo que se hace tiene lugar en la parte de la condición del bucle): public class app ( public static void main(String[] args) I int target = 144.println("La conversión de " + value + " es Ox" + sb). 1 % 16)). Como los dígitos van en orden inverso.> O ) ( st.out.

también tenemos ambos bucles". Bucle do-while El zar de la Programación Exacta dice. tenemos un bucle while y un bucle do-while". en Java hay un bucle while. index = 0. cuando el cuerpo del bucle no se debería ejecutar ni una vez si la condición no es verdadera. "Entonces. 15). do C test = 5 1 while (test values[index++l. "¡Anda!" contesta. Por ejemplo. Este es el formato del bucle dowhile (tenga en cuenta que la sentencia puede estar compuesta por un número de otras sencillas encerradas entre llaves): do sentencia while(condición). hay ocasiones en las que se debería usar un bucle while en lugar de do-while. no al comienzo. este es un caso en el que el valor que se está evaluando no está disponible para el test hasta el final del bucle: public class app { public static void main(String[] args) { int valuesil = 11. que se tratará en el siguiente apartado. 2. 0. 1 1 Por otro lado. La principal razón para usar do-while en vez de while es que se necesite que el cuerpo del bucle se ejecute al menos una vez. test. echemos un vistazo al siguiente código en el que un bucle do-while evalúa el inverso de un valor pero sólo puede probarlo si el valor es distinto de cero al final del bucle: . S } .Este es el resultado: c:\>java aPP sqrt (144) = 1 2 Otro tipo de bucle while es el bucle do-while. "En Java. Por ejemplo. El bucle do-while es como un bucle while. salvo en que la condición es evaluada al final del bucle. 3 . En C++.

le dice. el índice en expresión-iterativa.println("E1 1 recíproco = + 1 / value). realmente necesito un índice numérico. System. En general. En este caso. proporcionar una condición para terminar el bucle cuando dicha condición sea falsa. generalmente incrementando. y d a r alguna f o r m a para cambiar.inicialización (de hecho. El buclefor de Java es una buena elección cuando se quiere usar un índice numérico que se incremente o decremente automáticamente cada vez que se pase por el bucle. incluyendo varias sentencias simples entre llaves): for (expresión-de-inicialización.out. ¿Existe algo así?" "Claro". pero cuando se gestionan arrays no son los más fáciles de utilizar. "pruebe el bucle for".out.condición-final. .final. 1 1 Bucle for El programador novato regresa y dice. en condición.public class app t public static void main(String[l args) 1 double value do } } ) = 0. expresión-iterativa) I sentencia > Se puede inicializar el índice del bucle en la expresión-de. se pueden usar múltiples índices en un bucle for). este es el formato del bucle for (observe que la sentencia puede ser compuesta. es mucho mejor utilizar un bucle while: public class app ( public static void main(String[] args) I double value = 0. while (value > O) { System. como ocurre cuando se está trabajando con un array. while (value > O). "Me gustan los bucles while.príntln("E1 recíproco = " + 1 / value).

for (int loop-index = 0. loop-index++) = System.out.out. . loop-index++) C sum += gradesiloop-indexl. loop-index < grades. 73. sum = 0.length. = " System. loop-index i 10. double sum. el cuerpo del bucle se ejecuta exactamente 10 veces): public class app 1 public static void main(String[] args) { int loop-index. 87.println("Esta es la iteración número " + loop-index). es decir. for (loop-index = 1.length. 1 { > 1 Este es el resultado: C:\>java app Esta es la iteración Esta es la iteración Esta es la iteración Esta es la iteración Esta es la iteración Esta es la iteración Esta es la iteración Esta es la iteración Esta es la iteración Esta es la iteración número número número número número número número número número número 1 2 3 4 5 6 7 8 9 10 Este es un ejemplo que se vio al principio del capítulo.Esto es un ejemplo en el que se pone a funcionar el buclefor (observe que el bucle se empieza con el índice a 1 y se termina cuando es mayor que 10. 99. 6 4 ) . 5 6 .println("Grado medio + average). 1 average = sum / grades. average. éste calcula el grado medio de un estudiante después de recorrer todos los grados e irlos sumando (observe que se está declarando e inicializando el índice a O en la expresión de inicialización): public class app { public static void main(String[l args) { double grades[l = {88.

como veremos en el siguiente capítulo). loop-index <=lo. doubled = 0. Java permite separar expresiones con una coma.Este es el resultado del código: C:\>java app Grado medio = 7 7 . Observe que se pueden usar expresiones muy generales en un bucle for. se pueden utilizar sentencias null. En un bucle for. 8 3 3 3 3 3 3 3 3 3 3 3 3 3 Cuando se declara una variable del bucle (como loop-index en este ejemplo). loop-index++. Esto es un ejemplo en el que se suman todos los elementos de un array en un bucle for que no tiene código en su cuerpo: public class app { public static void main(String[] args) . de hecho. como se muestra en el siguiente ejemplo en el que se utilizan dos índices: public class app ( public static void main(String[l args) for (int loop-index = 0. doubled r 2 loop-index) { System. 1 1 1 Este es el resultado: C:\>java app El doble del El doble del El doble del El doble del El doble del El doble del El doble del El doble del El doble del El doble del El doble del índice índice índice índice índice índice índice índice índice índice índice En un bucle for no es obligatorio rellenar todos los elementos.println("E1 doble del índice + loop-index + es " + doubled). el alcance de esa variable está limitado al cuerpo del bucle for (el alcance de una variable es la parte del programa en la que se puede acceder a ella.out.

temp for 1 System. temp.length. = value. 2. sum = 0. 1 1 Este es el resultado: c:\>java aPP La suma = 15 También se puede convertir un bucle while en un bucle for. "Por supuesto que puede usar unos bucles dentro de otros". ) { factorial *= temp-. 3 . ( .out.out. Java permite anidar bucles. se haya el valor medio de los elementos de un array de dos dimensiones recorriendo todos los elementos con dos bucles for): public class app { . A continuación se ha adaptado el ejemplo del factorial del punto anterior "Bucle while". y me gustaría tener un bucle dentro de otro para poder recorrer las dos dimensiones". for (int loop-index = 0. dice el programador novato". eum + = array[loop-index++]) . //copia temporal. loop-index < array.t> O. public class app { public static void main(String[] args) { int value = 6. le contesta.println("La suma = " + sum).println(value + " ! = " + factorial). 51.{ int arrayil = {l. factorial = 1. 4. Esto es un ejemplo en el que se ve cómo funciona (en este caso. 1 1 Bucles anidados "Estoy trabajando con arrays de dos dimensiones". System. uno dentro de otro.

y algunas veces. 7.out. outer-index c array. total = 0. 3 ) ) .length. 5 . 1). ¿Cómo lo hago para que todos ellos terminen de forma natural?" "Usando la sentencia break". le responde. Como Java no tiene una sentencia goto. inner-index < array[outer-index1. pero la mayor parte de los lenguajes consideran que goto no es estructurada (Java es de ésos y no incluye la sentencia goto).println("Valor medio del a r r a y = " + (sum / total)) . por lo que quiero terminar todos los bucles. l { 3 . al insertarse en cinco bucles anidados. total++. 3 1 . 1 } Este es el resultado: C:\>java app Valor medio del a r r a y = 2 Sentencia break El programador novato tiene otro problema: "Estoy recorriendo un array multidimensional. 10). 2 . 2 . los resultados exceden el máximo valor permitido.public static void main(String[l args) { double array[l [ = {{l. 8. 2 . soporta la sentencia break con este propósito. 6 . System. outer-index++) { for(int inner-index = 0. como en el siguiente caso. . 3 . 2 . Algunos lenguajes incluyen la sentencia goto que se puede utilizar para saltarse alguna sentencia del código. for(int outer-index = 0.length. int sum = O . inner-index++) { sum += array[outer-index] [inner-index]. {l. en el que se termina un bucle si la suma es mayor que 12: public class app ( public static void main(String[] args) { doublearrayll int sum = 0: = 11. 4 . Se puede usar la sentencia break para terminar un bucle. 9 .

. 2 . inner-index++) ( sum += array[outer-index][inner-indexl.println("No voy a imprimir. System.")..out.println("E1 bucle ha terminado. 1 System.out. .for(int loop-index = 0. 31. outer-index < array.. bucle. 1 System. (1.out.length. bucle . 2 . ( 3 . if (sum > 3 ) break outer.println("Recorriendo el bucle. Este es el resultado: C:\>java app ~l bucle ha terminado . 1 System. 2. Esto es un ejemplo en el que se sale de un bucle doblemente anidado: public class app ( public static void main(String[l args) I double array[l [ l = {{l.length. outer-index++) { inner: for(int inner-index = O.").. loop-index++) { c sum += array [ loop-index] .out. . el valor máximo ¿Qué ocurre si se quiere salir de varios bucles anidados? En ese caso. 1 1 Este es el resultado: c:\>java app Recorriendo el Recorriendo el ~ecorriendo el ~ecorriendo el La suma excede bucle. . se pueden etiquetar los bucles e indicar de cuál se quiere salir. 11.").length.. inner-index < array[outer-index] . int sum = 0. .").println("La suma excede el valor máximo. 311. if (sum > 12) break. loop-index array. . bucle . outer: for(int outer-index = 0.

0 = -1. se puede usar la sentencia continue. 1 8s ( Este es el resultado del código (observe que esta salida se ha saltado la línea en la que el código intenta calcular el inverso de O): C:\>java app El inverso de El inverso de El inverso de El inverso de El inverso de El inverso de El inverso de El inverso de El inverso de 5. Si el índice del bucle actual es O.25 . ¿Puedo hacerlo?" "Sí. Algunas veces.0 = -0. se pasa a la siguiente iteración.out. le responde.0 = 0.0 = 0.0 = -0. Para pasar a la siguiente iteración de un bucle. loop-index-) if (loop-index == 0 ) continuo.5 -3.0 = 0.3333333333333333 2. "Puede usar la sentencia continue". Sentencia continue "Me gustan los bucles". tengo un valor que no quiero usar y querría saltármelo y pasar a la siguiente iteración del bucle sin ejecutar nada.0 -2.println("E1 inverso de " + loop-index + .Observe que si no se usa una etiqueta con la sentencia break. por supuesto".3333333333333333 -4." + (1 / loop-index)). loop-index > -5. cuando estoy recorriendo un bucle. Esto es un ejemplo en el que se obtienen los inversos y se intenta evitar el inverso de O.2 4.0 -1.0 = -0. dice el programador novato. System. Este es el código: public class app I public static void main (String[ ] args) { foridouble loop-index = 5.0 = 0.25 3.0 = 1. sólo se saldrá del bucle actual. "sólo hay un problema.5 1.

Ahora que ya conocemos la sintaxis básica de Java. ya que. que consiste en dividir un programa en subrutinas. La programación orientada a objetos es. Esto nos lleva al siguiente paso. Como ya se vió en el capítulo 1. ya que los objetos pueden contener múltiples subrutinas y datos. de forma que cada objeto sea semiautónomo. el objeto puede interactuar con el resto del programa por medio de una interfaz bien definida por sus métodos públicos (es decir. sin ella. La programación orientada a objetos fue creada para gestionar programas más grandes y descomponerlos en unidades funcionales. Así. bombas. suponga que su cocina está llena d e tuberías. de manera formal. realmente. encerrando métodos y datos privados (es decir. internos) y salvándolos del desorden general que les rodea. con la programación orientada a objetos. otra técnica para implementar el famoso dicho d e la programación: "divide y vencerás". se les puede invocar desde fuera). El resultado de encapsular partes de un programa en un objeto es que es concebido como un elemento sencillo y no hay que tratar todo lo que el objeto hace internamente. La vimos en el capítulo 1.m Programación orientada a objetos Este capítulo es común a cualquier programa de Java: programación orientada a objetos (POO). un compresor y todo tipo de interruptores para mantener la . no se puede escribir código en Java. La idea es encapsular datos y métodos en objetos. estamos preparados para trabajar.

realimentándose todas las partes de su interior de forma automática. métodos y herencia. '9 7 Todos estos conceptos son importantes para la programación orientada a objetos y entraremos en cada uno de ellos con más detalle. Herencia es el proceso que consiste en derivar una clase. habrá que encender el compresor. sin requerir ningún objeto. al igual que una variable es una7 instancia de un tipo de dato.temperatura ideal de la comida. objetos. De forma rápida. y variables de clase. abrir las válvulas y empezar a mover las bombas manualmente. El objeto soporta variables de instancia. Se puede pensar en una clase como el tipo de un objeto y se puede pensar en el objeto como una instancia de una clase. fuera de la mente". simplemente. estos términos significan: 1 Una clase es una plantilla desde la que se pueden crear objetos. miembros de datos. Ahora bien. cuyos valores son compartidos entre los objetos de esa clase. Si el primer principio de la programación orientada a objetos es "divide y vencerás". Los objetos encapsulan métodos y variables de instancia. la programación orientada a objetos gira sobre algunos conceptos clave: clases. Cada vez que esta temperatura sea demasiado alta. Esta es la idea que hay detrás de la encapsulación: parte de un sistema ' complejo que necesita mucha atención y lo convierte en un objeto que gestiona todo internamente con su propio trabajo y puede ser fácilmente. concebido. -7 Los miembros de datos son esas variables que forman parte de una clase y en ellas se almacenan los datos que usa el objeto. pero se puede usar un método de clase haciendo referencia. toda esa funcionalidad se puede cubrir con un objeto. La definición de una clase incluye especificaciones formales para la clase y cualquier dato y métodos incluidos en ella. cuyos valores son específicos del objeto. Con objetos. 7 En Java. a la clase por su nombre. de otra. en el que todas esas operaciones se gestionan internamente. se usan los métodos de instancia. llamada clase derivada. y se pueden utilizar los métodos de la clase base en la clase derivada. llamada clase base. Un método es una función construida en una clase u objeto. como un frigorífico. un frigorífico. el segundo es "fuera de la vista. 7 . Se pueden tener métodos de instancia y métodos de clase. Un objeto es una instancia de una clase.

Por ejemplo. que tiene el mismo nombre que . si se piensa en una clase como un molde de galletas.java. que gestiona toda la especificación de la clase app. se invoca al constructor de una clase. Para crear un objeto. veamos el código necesario para crear una clase llamada app. En Java. Entonces. este fichero. los objetos que se crean a partir de ella. a un objeto se le llama instancia de una clase. cada vez que se crea un programa Java. Este constructor crea un nuevo objeto de la clase. son las galletas. se convierte en el fichero de bytecode app. jcómo se crean objetos desde las clases? Veamos la siguiente sección. se llama al constructor de una clase. que se almacena en un fichero llamado app. ya hemos creado clases. En este libro. se necesita una clase.java (esta clase crea una aplicación Java): public class app { public static void main(String[] args) I System.printlní~Hola desde Java! " ) . app. se usa una clase para crear un objeto y luego se puede llamar a los métodos del objeto desde este código. 1 1 Cuando se utiliza el compilador de Java.class.out. Es decir. que es un método que se llama igual que la clase. Para crear un objeto. Se puede considerar que una clase es un tipo de objeto.Clases En la programación orientada a objetos. las clases proporcionan una especie de plantilla para los objetos.

se puede hacer referencia al miembro de dato de datal usando el operador punto (. ¿Qué se hace con un objeto cuando se dispone de otro? Se puede interactuar con él usando sus miembros de datos y métodos. como sigue: datal-data Esto significa que se pueden meter los datos en datal. system. Por otro lado. y dar acceso a 10s datos internos de un objeto desde un código externo al mismo no es buena .data). He aquí un ejemplo en el que se crea un objeto de la clase String. Los elementos de datos compartidos por todos los objetos de una clase se llaman miembros de datos de clase o variables de clase. Si Data-class define un miembro de dato que es accesible públicamente llamado data. Esto es un ejemplo en el que se muestra cómo se deberían utilizar los miembros de datos de un objeto. Los miembros de datos pueden hacerse accesibles desde fuera de un objeto. o se puede hacer que sean internos al objeto para usar. De esta forma. Miembros de datos Los miembros de datos de un objeto se llaman miembros de datos de instancia o variables de instancia. pasando la cadena que se quiere incluir en ese objeto al constructor de la clase String: String S = new String(" ¡Hola desde Java! " ) . de la siguiente forma: Data-class data1 = new Data-class(" ¡Hola desde Java!").println(datal. los métodos del interior del objeto. se verá cómo se crean variables de instancia y variables de clase. veamos las dos secciones siguientes. de forma privada.out. En este capítulo. y se crea un objeto de esta clase llamado datal: Data-class datal = new Data-class(" ¡Hola desde Java!"). recordemos que el poder invocar esos datos ocultos es una de las motivaciones de la programación orientada a objetos. Supongamos que se tiene una clase llamada Data-class.). Se verá más sobre la creación de objetos con constructores a lo largo de este capítulo. se puede hacer referencia a los miembros de datos de un objeto que lo hace accesible públicamente.ella.

sqrt(value). En su lugar. Los métodos de clase. llamados métodos protegidos (protected). se pueden usar los métodos de esos objetos. En el ejemplo siguiente. el termostato puede invocar un método interno llamado start-compressor cuando llegue el momento de enfriar. En el ejemplo del frigorífico que propusiimos al principio de este capítulo. sqrt = iath. result = calcl. Una vez que se tiene un objeto que soporta métodos. Métodos Los métodos son funciones de una clase. sqrt. comprobando los valores de los datos antes de que esos valores sean almacenados en los miembros de datos del objeto). se usa el método calculate para trabajar con los dos valores de operandl y operand2 y almacenar el resultado del cálculo en result: Calculator calcl = new Calculator( ). llamados en el interior del objeto por otras partes del mismo.out. por otro lado. Los métodos privados son. y se puede usar como sigue (no es necesario un objeto): public class app I public static void main(String[l args) ( double value = 4. Por ejemplo. llamados métodos privados (private).calculate(operandl. = " 1 1 .idea. muchas veces se da acceso a los datos de un objeto a un código externo sólo a través de los métodos del objeto (lo que significa que se puede controlar la interfaz del objeto para el resto del programa. los objetos son instancias de una clase). generalmente. Java soporta dos tipos de métodos: métodos de clase y métodos de instancia. Generalmente los métodos se dividen en aquellos que se usan internamente en la clase. los que se usan fuera de la clase. llamados métodos públicos (public) y los que son usados por la clase y sus derivadas. son invocados en objetos (es decir. operanda). como en el ejemplo calculate. la clase java.println( "La raíz cuadrada de " + value + " + sqrt). Los métodos de instancia.Math tiene un método de clase llamado sqrt que calcula una raíz cuadrada. son invocados en una clase. System.lang.

aprenderá cómo se crean métodos de clase e instancia. si se tiene una clase llamada vehículo. Se pueden declarar objetos de la misma forma que se declaran variables de tipo de datos sencillos. La idea es añadir lo que se quiera a la nueva clase para darle más funcionalidad que a la clase base. dice." "¿Sólo qué?" le pregunta. Antes de utilizar un objeto. pero se puede usar la clase como tipo de objeto. ya que se puede usar la gran librería de clases disponible. Todo este material es esencial para la programación de Java. se puede usar el operador new para crear objetos en Java. De esta forma. Herencia La herencia es uno de los aspectos de la programación orientada a objetos que se ha definido formalmente.0 = 2. Antes de entrar en el código. se ha creado una nueva clase de la clase base y hemos ampliado esa clase con un método adicional. hay un concepto más dentro de la orientación a objetos: la herencia. se podría derivar una nueva clase llamada coche y añadir un nuevo método llamado claxon que visualiza "beep" cuando se le llama. se puede derivar una nueva clase a partir de una antigua. Veremos cómo utilizar la herencia orientada a objetos en el capítulo siguiente. La clase nueva se llama clase derivada y la clase original. es hora de que vayamos a la sección siguiente y revisarlos P O 0 en detalle.0 En este capítulo. ' . clase base. derivando de ellas nuestras clases propias.. La herencia es un tema importante en Java. preparado para discutir la programación orientada a objetos. y la nueva heredará todos los métodos y miembros de datos de la antigua. "Ya sé todo sobre los objetos". Veamos un ejemplo que utiliza la clase String. Por ejemplo. "Sólo que no sé cómo crear un objeto en un programa". Declaración y creación de objetos El programador novato aparece. Además. "sólo . Ahora que ya hemos visto los conceptos de POO. por lo que conviene profundizar en él hasta que se domine. Utilizando la herencia..Esto es lo que se puede ver cuando se ejecuta el código: C:\>java app La raíz cuadrada de 4. es necesario declararlo.

s l . s 1.Para empezar. como vimos en el capítulo 2. existe y ya se puede utilizar. se puede usar el método toLowerCase de la clase String: Además se pueden combinar la declaración y creación en un solo paso. Por ejemplo. . Aunque al declarar una variable simple se crea esa variable. . como sigue: public class app I public static void mainíString[l args) { String SI. 1 1 1 . la declaración de un objeto no la crea. sl = new String("iHo1a desde Java!"). Ahora. el nuevo objeto. todo en una línea: . Se pueden pasar cadenas entre comillas a uno de los constructores de la clase String. creándolo con el operador new. para convertir todos los caracteres de s l a minúscula. s2. parámetro2 . Para crear el objeto se puede usar el operador new con el siguiente formato en el que se pasan parámetros al constructor de la clase: object = new clase([parámetrol [ . de la clase String: public class app I public static void main(String[] args) { String sl. Esto es un ejemplo en el que se declara un nuevo objeto String. por lo que se puede crear el nuevo objeto. La clase String tiene varios constructores. declararemos un nuevo objeto. s l .

lo que quiere decir que usarán internamente el operador new (y nosotros no lo tenemos). el constructor de la clase String está sobrecargado para coger arrays d e caracteres.Holadesde Java! " ) . . -11 String s3 = new String(c1). ' o n . estos constructores están sobrecargados (se verá la sobrecarga en este capítulo). así como cadenas de texto. por lo que se puede crear un objeto nuevo. -h.Hoia desde Java!"). String s2 = new String(". Algunas veces las clases tendrán métodos que devuelven objetos. sl = new String("iHo1a desde Java! " ) . para convertir un double en un objeto String: public class app { public static void main(String[] args) { String sl. 1 Char cl[] = {\H'. diferentes tipos y número de parámetros.public class app i public static void main(String[l args) I String sl. tienen varios constructores. sl = new String(". s3. ) . usando un array de caracteres: public class app i public static void main(String[] args) { String s1. En términos de orientación a objetos. el compilador sabe qué constructor es el que se quiere usar por el tipo y por el número de parámetros). con frecuencia. Las clases. cada uno de los cuales tiene diferentes especificaciones de datos (es decir. sl = new String("iHo1a desde Java! " ) . t í . Esto es un ejemplo en el que se usa el método valueOf de la clase String. Por ejemplo. String s2 = new String("iHo1a desde Java!").

Esto es importante saberlo. 'a'. ' ' .valueOf(doublel). En la práctica. String s3 = new String (cl) . Al final del código anterior. 'o'. muchas referencias a un mismo objeto pueden producir errores que son muy difíciles de detectar. se visualizan todas las cadenas creadas. ' ' . char cl[] = { ' H ' . String s3 = new Stringícl). 'o'. hay que tener cuidado. ' h p . lo que está ocurriendo realmente es que la referencia al objeto de s l se copia en s5. ' í ' ) . String s4 = String. Esto es lo que aparece al ejecutar el programa: . se puede asignar un objeto a otro. 'l'. Esto generalmente ocurre porque se cree que se está tratando con diferentes objetos. double doublel = 1. 'a'. 'h'. Si dos variables hacen referencia al mismo objeto. esto significa que s l y s5 se refieren al mismo objeto. porque si se cambian los datos de instancia de s l . 'a'. String 85.String s2 = new String("¡Hola desde Java!"). también se están cambiando los de s5 y viceversa. double doublel = 1. String s4 = String valueOf(doub1el): Además. String s2 = new String("iHo1a desde Java!").23456789. s1 = new String("iHo1a desde Java!"). char cl[] = { ' H ' . ' 1 ' . Internamente. como se puede ver aquí: public class app t public static void main(String[] args) { String SI.23456789. 'a'. t í r ) . s5 = al.

de la misma forma que se declaran y crean variables sencillas. . Con la declaración se dice a Java lo que necesita saber sobre la nueva clase. . 1 [accessl [staticl tipo variable-de-instancial. 1 La implementación de la clase es lo que se llama definición de clase. Esta es la forma general de una definición y declaración de la clase: access class nombre de clase [extends { .... como se ve en el ejemplo anterior. Esta es la forma general de la declaración de una clase: [access] class nombre de clase [extends i . con aprobación. dice el PN "¿cómo se hace?" En Java. la creación de una clase se realiza en dos pasos: la declaración de la clase y su definición.1 //aquí va la definición de la clase. [accessl [staticl tipo método1 (lista-deqarámetros) ( .. le dice. con el valor añadido de poder configurar objetos pasando datos a un constructor de la clase. [access] [staticl tipo variable-de-instanciaN. Declarar y definir clases El programador novato (PN) está nervioso y dice.C:\>java app ¡Hola desde Java! ¡Hola desde Java! Hola ahí 1. "¡LO he conseguido! ¡He creado un objeto. ] [implements . y funciona!" "Bien". .] [implernents . Ya es hora de empezar a crear nuestras propias clases y empezaremos con este proceso en el siguiente punto.23456789 . y se hace en el cuerpo de la declaración.Hola desde Java! Así es como se declaran y se crean los objetos. "ahora ¿cómo se crearía una clase?" "Uh-oh". .

println(~ola desde Java!). Para empezar. quedará claro.println(" ¡Hola desde Java! " ) . El término access especifica la accesibilidad de la clase o de un miembro de clase al resto del programa y puede ser public. como en este ejemplo. crearemos una clase muy sencilla llamada printer que define un método. > 1 Ahora se puede usar el método print en otras clases.[accessl [ s t a t i c l tipo métodoN (lista-deparámetros) ( Aquí. 1 1 public class app ( public static void main(String[ 1 args) C printer printerl = new printer( ). Se usan las palabras clave extends e implements con la herencia. se visualiza el mensaje "iH01a desde Java!" en la pantalla. Con un ejemplo.out. . como veremos más tarde. la palabra clave static convierte variables en variables de clases o métodos en métodos de clase (en contraposición a las variables y métodos de instancia). como veremos en el siguiente capítulo. en el que se está creando un nuevo objeto de la clase printer usando el operador new y el método print de ese objeto en una aplicación llamada app: class printer ( public void print0 ( System. hay un acceso por defecto si no se especifica ningún tipo. se verá más sobre esto en las páginas siguientes. Cuando se llama al método print. private o protected. print (ya vimos este ejemplo en el capítulo 1). Así sería la clase: class printer ( public void print0 C System. Además.out.

1 1 Y este es el nuevo app. ver el capítulo 1): import printert public class app ( public static void main(String[l args) ( printer printerl = new p r i n t e r 0 . . y tengo todo menos un pequeño detalle" "¿Sí?" pregunta. En un fichero sólo una clase puede ser declarada como pública y en este caso. printer y app. Este es printer. en el mismo fichero.out. se pueden tener tantas clases privadas o protegidas como se quiera dentro del fichero (y Java creará diferentes ficheros con extensión ". Sin embargo.java. "¿Cómo almaceno datos en la clase?" pregunta el PN. Crear variables de instancia "Hmm". Al fichero se le da el nombre después de esa clase. es app.java: class printer ( public void p r i n t 0 I System. observe que se están declarando y definiendo dos clases.Ahora se pone este código en un fichero.class"cuando se compile). para más detalles sobre la importación de clases. lo que quiere decir que el fichero que la contiene debe ser app. app. uno para cada clase. dice el programador novato (PN). se compila y se ejecuta como sigue: C:\>java app ¡Hola desde Java! Tomemos un momento para estudiar este ejemplo.println("iHola desde Java! " ) . "quiero crear una clase para le almacenar datos.java.java (observe que se tiene que importar la clase printer para poder utilizarla. También se puede dividir este ejemplo en dos ficheros.

las variables de clase de ambos objetos se referirán a los mismo datos y por lo tanto tendrán el mismo valor. ) Este es un ejemplo en el que se crea una clase llamada Data que gestiona una variable de instancia de tipo String llamada data-string. Así es como se almacenan datos de instancia en una clase: access class nombre de clase [extends .data-etring. Las variables de instancia son específicas para los objetos. ) public class app ( public static void main(String[l args) { Data data = new Data(). si se tienen dos objetos (es decir. echemos un vistazo a las variables de instancia. dos instancias de una clase). llamado data. se puede acceder a las variables de instancia públicas de un objeto con el operador punto. Por otro lado. . las variables de instancia de cada objeto son independientes de las variables de instancia del otro objeto. se puede crear un objeto. que contiene el texto " iHola desde Java!" : clasci Data c public String data-etring = wyHola desde Javalm. Sin embargo. ] [implements ( .En la clase. recuerde que una . 1 [access] tipo variable-de-inctancial. 1 Ahora. como variables de instancia o como variables de clase. En primer lugar. Como se puede observar.. String etring - data. se pueden almacenar datos de dos formas.. [access] tipo variable-de-instanciaN. Así es el código: class Data ( public String data-string = "iHola desde Java!". de la clase Data en main y hacer referencia a la variable de instanciadata-stringcomo data-data-string. .

Veremos esto con más detalle en la siguiente sección. es accesible desde cualquier lugar del programa. dice el programador novato.1 I [access] [static] tipo variable-de-instancial.de las motivaciones de la programación orientada a objetos es mantener la privacidad de los datos. Si se declara como private. para fijar la visibilidad de los miembros de datos de una clase a lo largo del resto del programa: access class nombre de clase [extends ..lang. Si se declara como protected. ¿cómo ese jorobado Johnson ha podido acceder a los datos de mis objetos?" "Porque utilizó un especificador de acceso erróneo para sus datos". 1 Los valores posibles de access sonpublic. se podría declarar private como sigue: class Data I > private String data-string = -1Hola desde Javalm. [access] [static] tipo variable-de-instanciaN. está disponible para la clase actual. public class app . otras clases del mismo paquete (se pueden agrupar librerías de clases en paquetes Java. "creía que los objetos encapsulaban los datos de forma privada. Acceso a variables "Hey". que la variable de instancia data-string fuera privada a la clase Data. Cuando se declara un miembro de una clase como public. a las clases derivadas de la misma que están en su mismo paquete y a otras clases del mismo paquete.. y clases que son derivadas de esa clase. si se quisiera hacer.. llamado access en el siguiente código.. Por ejemplo. le dice. el acceso por defecto es que el miembro de la clase es visible a la clase de la que es miembro. ya se han visto algunos paquetes Java como java.1. y se verá cómo crear paquetes customizados más tarde en el libro). Los detalles se pueden ver en la tabla 4. ] [implements . Si no se usa un especificador de acceso. en el ejemplo de la sección anterior. Se puede usar un especificador de acceso. sólo es accesible desde la clase de la que es miembro. private y protected.

String string = data. "Sólo necesita usar una variable de clase".data-string. y necesito llevar un contador total en una variable llamada counter para todos los objetos de esa clase.{ public static void main(String11 args) { Data data = new Data(). "tengo una nueva clase llamada counter.java:lZ: Variable data-string in class Data not accessible from class app. si se intenta acceder a la variable de instancia data-string desde otra clase. dice el programador novato. A 1 error Tabla 4. Ahora. el compilador de Java devolverá: C : \>javac app. Una variable se declara como estática con la palabra clave static (que realmente .1. "No se hunda". como se hizo anteriormente en la clase app. 1 Misma clase Subclase del mismo paquete x x x x 1 1 Subclase de otro paquete No subclase de otro paquete No subclase del mismo x paquete x x x I Crear variables de clase "Oye". le dice. String string = data.java -deprecation app. El valor de una variable de clase es compartido por todos los objetos de esa clase. Alcance del especificador de acceso ( x = dentro del alcance). lo que significa que será el mismo para todos los objetos.data-string. ¿Y ahora qué? Estoy hundido".

intdata = 1 Si se necesita ejecutar algún cálculo para inicializar variables estáticas.. como se puede ver aquí: class data ( public static int intdata = 0.o~t.intdata). b. 1 public class app ( public static void main(String[] args) I data a. Cuando se ponga la variable intdata para a con el valor 1. 1 I [access] static tipo variable-de-instancial.. que se almacenan de forma dinámica en pilas): access class nombre de clase [extends . [access] static tipo variable-de-instanciaN. se puede hacer en un bloque de código estático. a = new d a t a 0 1 b = new data0. ] [implements .especifica la forma en que el valor es almacenado. . System. que se etiqueta con la palabra .println(~E1valor de b-intdata = " + b. la variable intdata para b será también puesta a 1. 1 Ahora se pueden crear dos objetos de la clase data: a y b. en contraposición a otras variables. 1 1 Este es el resultado del código: C:\>java app El valor de b. . como dato estático. 1 Esto es un ejemplo en el que se crea una clase llamada data con una variable de datos de clase llamada intdata: class data ( public static int intdata = 0.

i System. Llevamos usando métodos desde que visualizamos nuestro primer mensaje con S~stem.clave static. "ya tengo variables de instancia.println. 1 1 Este es el resultado del código: C:\>java app El valor de a. 1 1 public class app { public static void main(String[] args) { data a. Así es cómo se crean métodos en una clase: access class nombre de clase [extends { .out. " Tome una silla y hablemos sobre la creación d e métodos".println(E1 valor de a.out. .doubledintdata = " a. . . . le dice. dice el programador novato. ejecutar ese código. static c doubledintdata = 2 * intdata. Un método es un bloque de código al que se puede transferir el control y por lo tanto. public static int doubledintdata.doubledintdata = 2 Crear métodos "De acuerdo". cuando la clase se carga por primera vez: class data { public static int intdata = 1 .doubledintdata). ¿Hay algo más que aprender sobre clases?" "Bastante".por lo que ya está familiarizado con el concepto.1 [implements . este código se ejecuta sólo una vez.1 [access] [static] tipo método1 (lista de parámetros) { . a = new data0 .

En ese ejemplo. 1 1 public class app ( public static void mainíString[] args) { printer p r i n t e r l = new p r i n t e r ( ) . Veamos un ejemplo. si el método no devuelve ningún valor. la claseprinter. como sigue: c l a s s printer í public void p r i n t ( ) S y s t e m . o u t . es obligatorio cuando se está llamando a un método en Java ya que es la forma en que el compilador Java sabe que print es un método y no un miembro de datos). Esta es la salida del código: . se creó un objeto de la claseprinter y se llamó al métodoprint. S e da el nombre del método y se sitúa la lista de parámetros que se le quieren pasar después de ese nombre. está encerrado en un bloque de código que sigue a la declaración del método. ya ha visto uno antes en este capítulo.float. se puede usar un especificador de acceso (ver el siguiente punto) y especificar el tipo de retorno del método si se quiere que devuelva un valor. De hecho. El cuerpo actual del método. 1 1 1 En este caso.print ( . se añadió un método público llamadoprint a la claseprinter. tipo object o void. printerl . p r i n t l n ( V o l a desde Java!"). Ejemplos de ellos son int. el método print no tiene parámetros y no devuelve ningún valor. pero se siguen poniendo los paréntesis después del nombre del método. el código que se ejecutará cuando se le llame.[accessl [staticl tipo métodoN (lista de parámetros) { ' Para declarar y definir un método.

el acceso por defecto es que el miembro de la clase es visible a la clase de la que es . está disponible para la clase actual. dice el programador novato (PN). le dice.C:\>java app ¡ H o l a desde Java! Hay muchas cosas que conocer sobre la creación de métodos en Java. es accesible desde cualquier lugar del programa. Uno de los aspectos más importantes de los métodos es que se puede hacer que sean puramente internos a un objeto. ¿No hay nada más riguroso que pueda utilizar para aislar a ese jorobado?" "Sí". Cuando se declara un miembro de una clase como public. 1 [ a c c e s s ] [ s t a t i c ] tipo método1 (lista de parámetros) I [access] [ s t a t i c ] tipo métodoN (lista de parámetros) Los valores posibles de access son public. con el concepto de encapsulación de la programación orientada a objetos. "ha estado utilizando los métodos internos de mis objetos. "puede usar un especificador de acceso más riguroso". ] { [implements . A los métodos de una clase se les puede añadir un especificador de acceso. Si se declara como private. . private y protected. Establecer el acceso a los métodos "Ese maldito Johnson". y por ahí es por donde vamos a empezar. otras clases del mismo paquete y clases que son derivadas de esa clase. Si no se usa un especificador de acceso. aunque yo claramente llamé al método internal-use-only... sólo es accesible desde la clase de la que es miembro. . como sigue (access es el especificador de acceso): access c l a s s nombre de clase [extends . "¡Fantástico! " dice PN. vamos a verlas a lo largo de los siguientes puntos. por lo tanto. Si se declara como protected.

1 1 public class app { public static void main(String[] args) { printer printerl = new printero. - Pasar parámetros a los métodos El especialista en soporte a clientes de la empresa le llama y le dice. ya que se reduce o se controla la accesibilidad del método al resto del código.Hola desde Javalm). Los detalles se pueden ver en la tabla 4. le contesta. a las clases derivadas de la misma que están en su mismo paquete y a otras clases del mismo paquete.~ut.println(~. "Su clase printer visualiza un mensaje. } private void internal-use-only () I System. Esto es un ejemplo en el que se ha añadido un método private a la clase printer desarrollada en las secciones anteriores. es una buena idea hacer que los métodos sean privados o protegidos. "Tenemos un problema". "Cambiaré el método print para que acepte parámetros". Cuando se llama al método print de la clase printer. pero los clientes se están quejando porque quieren poder fijar el mensaje que se va a visualizar". Este método sólo puede ser llamado desde otros métodos de la clase printer. para hacer la visualización. Este es el resultado del código: C:\>java app ¡Hola desde Java! Con frecuencia. "¿Cuál es el problema?" le pregunta. se utiliza el método internal-use-only. como sigue: class printer { public void print ( ) { internal-use-only(). .miembro.1. que no está accesible fuera del objeto. "No hay problema".

El método se declara de forma que Java sepa que aceptará un parámetro. se puede hacer referencia al objeto String que se ha pasado al método print como S: class printer { public void print(String { S ) System. 1 Este es el resultado del código: C:\>java app ¡Hola otra vez desde Java! . usando los nombres que se les ha dado en la lista de parámetros. Esto es un ejemplo en el que al método print se le pasa la cadena a visualizar. . un objeto String llamado S: class printer ( public void print(String s) { Ahora.println(s).print("¡Hola otra vez desde Java!"). en el cuerpo del método. que se pasa al método poniéndola entre paréntesis después del nombre del método: [accessl [ s t a t i c l tipo método1 ([tipo nombre-deqarámetro2.Cuando se declara un método. ) 1 public class app I public static void main(String[l args) { (new printer()). tipo Los valores que se pasan al método estarán accesibles en el cuerpo del mismo. se puede especificar una lista de parámetros separados por comas.out. 1 1 1 nombre-degarámetrol [. .

Por esa razón. por lo tanto si ese código cambia algún aspecto del array u objeto. el valor de la variable o literal es lo que se le pasa. supongamos que se inicia una aplicación de la siguiente forma: c:\>java app Ya es la hora -7 En este caso.addemí1. cuando se almacena un array u objeto en una variable. este proceso se llama paso por valor.Si hay que pasar más de un parámetro. . i n t 0 9 2 ) int result = opl + op2. lo que realmente se está almacenando es una referencia a los mismos). el tercero "la" y el cuarto "hora". arrayl. el segundo "es". separados por comas: class calculator i n t addenn(int 091. } 1 Se puede llamar a los métodos con literales. se pueden especificar en la lista. el array u objeto originales cambian. objl) Debería observarse que cuando a un método se le pasa una variable sencilla o un literal. Por otro lado. variables. como sigue: calc. intl. Veremos más sobre esto en este capítulo. realmente se está pasando una referencia a ese objeto o array (de hecho. como puede ser un elemento del array o un miembro de datos del objeto. el código del método llamado tiene acceso directo al array u objeto original. el primer elemento del array que se pasa a main es "Ya". cuando se le pasa un objeto o array. arrays u objetos. no a una copia. Por ejemplo. un array de objetos String que gestiona los argumentos de la línea de comandos que el usuario especificó cuando inició Java. Argumentos de la línea de comandos pasados a rnain i En las aplicaciones hay un array especial que se pasa como parámetro al método main.

loop-index < args. esta aplicación visualizará todos los argumentos pasados desde la línea de comandos utilizando un bucle sobre el array String que se le pasa como parámetro al método main: public class app I public static void main(String[] args) I System. 1 1 1 Así es como funcionaría la aplicación: C:\>java app Ya es la hora Argumentos de la línea de comandos. "use la sentencia return".println("Argumentos de la línea de comandos. 1 1 ) nombreqarámetrol [. "Ah". [accessl [staticl tipo método1 ([tipo nombreqarámetro2 . + args [ loop-indexl ) .length. pero . tipo .. ..println("Argumento " + loop-index 8.Esto es un ejemplo en el que se muestra cómo funciona.out. - t S.. Argumento O = Ya Argumento 1 = es Argumento 2 = la Argumento 3 = hora Devolver valores desde los métodos El programador novato regresa y dice. ." "¿Sí?"le dice. Sé cómo pasar parámetros a los métodos de esa clase.out. En un método se utiliza la sentencia return para devolver un valor desde un método y en la declaración del método se indica el tipo del valor de retorno. El gran jefe quiere que cree una clase calculadora que realice operaciones matemáticas. .. le dice. . for(int loop-index = 0 . loop-index++) { System. "bien."). "No sé devolver los resultados obtenidos después de haber hecho la operación". Bay otro problema.

1 ) public class app public static void main(String[l args) ( calculator calc = new calculator(). 2 ) ) . oJloat[] para devolver un array defloat.o~t.println(~addem(2. int. los suma y devuelve el resultado.El tipo del retorno puede ser cualquier tipo de los que Java reconoce. int op2) { return opl + op2.2) = " + calc.addem(2. int op2) ( return opl + op2. usando la sentencia return: class calculator ( int addem(int opl. int[] para devolver un array de enteros. 1 Así funciona la clase calculator en un programa: class calculator { int addem(int opl. int op2) { Así se devuelve la suma de los valores pasados aaddem. Así es como se declara addem: class calculator I i n t addem(int opl. el nombre de una clase que se ha definido. System. Esto es un ejemplo en el que la clase calculator tiene un método llamado addem que coge dos parámetros enteros. 21 = 4 . 1 Este es el resultado de la aplicación: C:\>java app addem(2. double. float. por ejemplo.

o~t. int op2) { return opl + op2.2) = + calculator. "he creado mi nueva clase calculator con un método estupendo llamado addem.- Crear métodos de clase "Vaya".println(~addem(2. se debe utilizar la palabra clave static: class calculator ( static int addem(int opl. 1 Este es el resultado del código: C:\>java app addem(2. sin crear un objeto. se puede llamar al método addem directamente usando el nombre de la clase.addemí2. Esto es un ejemplo: public class app ( public static void main(String[l args) ( system.2)). 2) = 4 Además se puede usar un método de clase de la forma usual. como un método de un objeto: class calculator ( static int addem(int opl. "si se hace que addem sea un método de clase en vez de un método de instancia". dice el programador novato. int op2) ( return opl + op2. 3 1 public class app I public static void rnain(String[] args) I . Para hacer que un método sea un método de clase. pero ¿por qué tengo que meterme en líos creando un objeto de esa clase antes de poder usar el método addem? ¿No se puede llamar al método directamente?" "Se puede". le dice. > 1 Ahora.

no puedo declarar todo como private.calculator calc = new calculator0. Esto es un ejemplo en el que se tiene un miembro de datos String llamado data-string: class data I private String data-string = "iHola desde Java!".out. dice el programador novato (PN). } Hay que hacer notar que el método main en una aplicación se declara estático porque Java debe llamarlo antes de que exista un objeto. le contesta". Si se declara un método estático (incluyendo el método main de cualquier aplicación). Crear métodos de acceso a datos 4 "Ese maldito Johnson".addem(2.println("addem(2. como veremos en este y en el siguiente capítulo. como sigue: . que hacen referencia al objeto actual y a su padre. ¿Qué puedo hacer?" "Puede fijar un método de acceso a datos". porque el resto del código necesita acceder al miembro de datos en cuestión. 7 Se puede restringir el acceso a los datos de sus objetos usando métodos de acceso a datos que deben ser invocados para obtener los datos. no puede usar las palabras claves this y super. Se puede dar acceso a este miembro de datos privado con dos métodos: getData y setData. En particular. observe que no puede hacer referencia a datos de instancia en un método estático. El métodogetData devuelve el valor de la variable privada data-string. respectivamente. 2)). Pero esta vez. sólo puede llamar a otros métodos estáticos y acceder a datos estáticos. system. 2) = m + clac. "está fisgoneando otra vez en el código de mis objetos. y restringir el acceso a sus miembros de datos de una forma bien definida". " iSe lo haré a ese Johnson! " dice PN. Además.

1 public void setData(String S) i if (a.getDataO).class data ( private String data-string public String getData0 = "¡Hola desde Java!". Este es un ejemplo en el que se muestra cómo se usa getData: public class app ( public static void main (String [ 1 args) I System.out. en particular. 1 1 1 Ahora se puede utilizar el métodogetData para obtener la cadena interna y el método setData para ponerle una nueva. se puede . el método setData restringe el acceso a los datos internos. i return data-string.length0 * 100) { data-string = S. Usando estos métodos.Hola desde Java! Es buena idea utilizar los métodos de acceso a datos para garantizar el acceso a los datos internos de los objetos. 1 1 Este es el resultado del código: C:\>java app .println((new dataO). public String getData0 t return data-string. Así sería: class data { private String data-string = "¡Hola desde Java!". escribiremos este método para que el código desde el que se invoca sólo pueda cambiar los datos internos a una nueva cadena si la longitud de la misma es menor que 100. 1 1 Sin embargo.

basta con añadir un método a una clase con el mismo nombre que la clase. ¿Cómo puedo crear constructores para mis propias clases?" dice PN. 1 1 public class app ( public static void main(String[l args) I System.out. Crear constructores "Hmm". sin ningún especificador de acceso ni tipo de retorno. como los constructores de la clase String que utilizo para meter texto en una cadena. aunque no lleve parámetros): class data { private String data-string. data ( ) c data-string = "iHola desde Java!". "sé cómo usar constructores para inicializar los datos de un objeto. 1 1 Esto es lo que se verá al ejecutar el programa: C:\>java app ¡Hola desde Java! . A este constructor se le llama cuando se crea un objeto de la claseprinter y. Vamos a ver un ejemplo en el que se añade un constructor que no tiene parámetros a la claseprinter que hemos desarrollado en este capítulo. dice el programador novato (PN). en este caso. pero . Crear un constructor para una clase es fácil..controlar la interfaz con esos datos y por lo tanto bloquear operaciones que se consideren ilegales. 1 public String getData0 { return data-string." "¿Sí?"le pregunta. inicializa los datos internos data-string a "¡Hola desde Java!" (observe que todavía se necesitan los paréntesis después del nombre del constructor cuando se declara.getDataO ) ..println((new data0 ).

dice el programador novato. Este es un ejemplo en el que se usa la clase printer del punto anterior. "¿pasó algún dato al constructor?" "Uh-oh". "Hmm". le contesta. pasar parámetros a constructores "De acuerdo".getDataO ) . pasando la cadena que se va a visualizar al constructor de la clase printer: class data I private String data-string.Este constructor es especialmente sencillo porque no utiliza ningún parámetro. pero realmente. En la siguiente sección se explica el constructor con parámetros. El siguiente ejemplo simula la progra- . Un ejemplo completo de clase En este apartado se presentará un ejemplo utilizando los conceptos que se han discutido a lo largo del capítulo. dice PN. "Java está gracioso de nuevo. data(String S) { data-string = 1 S.out. el objeto no está inicializado con los datos que quiero". 1 1 Este es el resultado del código: C:\zjava app ¡Hola desde Java! El paso de parámetros a un constructor funciona de la misma forma que el paso de parámetros a cualquier método. public String getData0 ( return data-string. Se pueden pasar datos a los constructores.println((new data("iHo1a desde Java!") ). al igual que se hace con otros métodos. 1 1 public class app I public static void main(Stringi1 args) ( System. He hecho un constructor para mi nueva clase.

. 1 public int pop ( ) I if(stackgtr == -1) / / Pila vacía .devuelve error return O. o se puede usar el método pop para quitar un elemento. else / / Si no. almacena datos stack-data[++stackqtr] = push-this. 1 public int push(int push-this) { if ( s t a c k g t r >= 99) / / La pila está llena .java. vacía stack(int size) / / s t a c k q t r = -1 -> la pila est6 I stack-data = new int[sizel. cuántos enteros se quieren almacenar en ella). se está avanzando un elemento en la pila. return 1. s t a c k q t r = -1. que apunta al artículo que actualmente está en la parte superior de la pila (y es realmente el índice que se utilizará con el array stack-data). el métodopop devuelve el artículo retirado y decrementa el puntero de la pila. El constructor ubica la memoria para la pila en un array llamado stack-data. private int s t a c k g t r . seguido de los platos 2 y 1. Cuando se pone un plato en la parte superior de la pila. Observe que los platos van en orden inverso. se está quitando un elemento de la pila. la programación de una pila funciona como una pila de platos. pero la teoría es sencilla. el código añade 10 artículos a la pila y después los retira: class stack { private int stack-data[]. Para usar la clase stack. el plato 3 será el que se quite primero.mación de una pila. devuelve datos return stack-datalstackqtr-1. si se ponen los platos 1.devuelve error return O . else ( / / Si no. Luego. Esta aplicación se llama stacker. se puede utilizar el métodopush de la pila para avanzar un elemento en ésta. cuando se quiten de la pila. stackgtr. y establece un puntero a la pila. Veremos las pilas con más detalle cuando discutamos las colecciones de Java. pasando un argumento al constructor que le indica el tamaño de la pila que se quiere (es decir. que almacena un dato e incrementa el puntero de la pila hasta la siguiente posición del array. Cuando se coge un plato de la pila. 2 y 3. se crea un objeto de la clase.

println("Valor quitado-> " + popped-value).out. loop-index i 10. for(int loop-index = 0. Valor añadido-> O Valor añadido-> 1 Valor añadido-> 2 Valor añadido-> 3 Valor añadido-> 4 Valor añadido-) 5 Valor añadido-> 6 Valor añadido-> 7 Valor añadido-> 8 Valor añadido-> 9 Quitando valores ahora.. loop-index++)I popped-value = stackl.pop0.println("Quitando valores ahora."). dice el programador novato.out. .push(loop-index). loop-index++)( stackl. System. stack stackl = new stack(100).out. for(int loop-index = 0.println("~alorañadido-> " + loop-index). 1 1 1 Así funciona el programa: ~ : \ > j a v stacker a Añadiendo valores ahora. System...public class stacker { public static void main(String args[l) ( int popped-value. 1 System. loop-index < 10..println("AÍiadiendo valores ahora. y estaba tratando .out. System. Valor quitado-> 9 Valor quitado-> 8 Valor quitado-> 7 Valor quitado-> 6 Valor quitado-> 5 Valor quitado-> 4 Valor quitado-> 3 Valor quitado-> 2 Valor quitado-> 1 Valor quitado-> O Comprender el alcance de las variables "Hmm"."). "he definido una nueva variable llamada the-answer en un método llamado get-the-answer.. .

le contestamos. . La forma más fácil de tener esto en mente es saber que las variables no" estáticas declaradas en un bloque de código comprendido entre llaves. Están cercanas a las variables globales (es decir. se almacenan en la alocación de datos propios del programa. como los parámetros pasados a esos métodos. public y protected. "¿No se puede?". como se ha visto con los especificadores de acceso private. También se puede definir un alcance local para las variables utilizadas en" bloques de código. el alcance es un concepto importante. Java define tres alcances principales: alcance a nivel de clase. El alcance de un método se inicia cuando el flujo de la ejecución entra en el método y termina cuando dicho flujo lo abandona. { int int3 = 3. ya que se pueden declarar variables en esos bloques. se crean y almacenan en una pila local cuando se entra en el bloque de código y se destruyen cuando se abandona dicho bloque (por eso se llaman variables dinámicas). por otro lado. y posiblemente más allá. Las variables que se declaran en un bloque de código sólo serán visibles en él y en los bloques de código que estén contenidos en el primero. Si se define un miembro de dato en una clase. pregunta PN. //visible para todo el código de este método. en otro método". y por tanto no están fuera del alcance. //visible sólo en este bloque de código. { i f(intl ! = int21 int int4 = 4. Los miembros de datos de la clase también son visibles en los métodos de la clase. //visible para todo el código de la clase public void methodiint int2) //visible para todo el código de este método.de usar esa variable en un método llamado get-a-clue. estará disponible en la clase. no se pueden usar variables declaradas en un método. a nivel de método y a nivel de bloque de código. He aquí un ejemplo en el que se muestran varios niveles de alcance (clase. y como se puede ver desde el punto de vista del programador novato. pero Java dice que la variable no está definida". Las variables declaradas en el método sólo son visibles en el propio método. variables para todo el programa) que Java permite. Las variables estáticas. Parece que es cuestión del alcance de la variable. no en cualquier pila. método y bloque de código): class Class ( int intl = 1. El alcance de una variable consiste en las partes del programa en las que esa variable puede utilizarse.

porque cada estado de la recursividad puede calcular una operación en la que multiplica el número que se ha pasado por el factorial del número menos 1. Esto es lo que se ve cuando se ejecuta el código: C:\>java app intl = 1 int2 = 2 int3 = 3 int4 = 4 Recursividad El programador novato entra muriéndose de risa y dice. lo implementaremos aquí. a esta técnica se la llama recursividad. le contesta.System. Cuando el número llega a 1 después de las sucesivas llamadas. Para calcular el factorial de un entero positivo n. ejecutando una multiplicación en . Lo que es más. El ejemplo clásico de recursividad es calcular un factorial. "También en Java". que se escribe como "n! ". el método vuelve.println("int1 = " + intl + " int2 = '' + int2 + " int3 = " + int3 + " int4 = " + int4).out.se calcula lo siguiente: Este proceso se presta a la recursividad fácilmente. "nunca pensé que el zar de la Programación Exacta me lo dijera: en C++. 1 1 1 public class app { public static void main(String[l args) I Class c = new Class ( ) . Java sitúa nuevo espacio en su pila interna para todas las variables del método. por lo tanto. y el control regresa a través de las sucesivas etapas. lo que quiere decir que no hay razón para que no se pueda llamar al mismo método otra vez. los métodos se pueden llamar a sí mismos". Cada vez que se llama a un método en Java. pues un nuevo conjunto de variables será alocado en la pila automáticamente. "iEh?" dice PN. un método puede llamarse a sí mismo en Java.

pero es bueno saber que está disponible. Así es el código: class calculator ( public int factorial(int n) I if (n == 1) { return n. Entonces. se aloca más memoria con el operador new. hay que contar con un proceso ya construido llamado coleccion garbage. Java dispondrá de la memoria alocada que no tenga más referencias. Java no tiene un operador delete. Sin embargo. Colección garbage y gestión de memoria 7 "Bien". 1 else { return n * factorialín } - 1). 1 1 Esto es lo que devolvería el programa: En la práctica. 1 public class app J t public static void rnain(String[] args) { calculator calc = new calculator(). ¿cómo se libera la memoria alocada cuando ya no es necesaria? . se usa el operador new para alocar memoria y luego se usa el operador delete para liberarla cuando no se la necesita más.out. 7 En algunos lenguajes. 4 En Java. "contesta.cada etapa hasta que todas las llamadas anidadas han vuelto y se obtiene el factorial. pero ¿cómo se libera cuando no es necesaria? ¿Hay un operador old?" "¡Qué va!". probablemente no se quiera usar la recursividad con mucha7 frecuencia. Systern. dice el programador novato. aunque no se pueda predecir cuándo va a tener lugar. Para que funcione la colección garbage.. como C++.println("6! = " + calc. Este proceso es automático.factorial(6) ) . "Java lo hace todo". se puede poner un artículo a .

. la colección garbage empezará a funcionar al ejecutar el programa). 1 1 public class app { public static void main(String[] args) t Data d = new Data(). que cuando algún elemento de datos. . . //algo de código . se pueden poner sus referencias a null. se obtiene una referenci. 1 1 Recordemos. Sin embargo. En lugar de punteros. se tiene que tener cuidado y evitar las referencias circulares. comenzará el proceso de la colección garbage. Veamos un ejemplo en el que se está creando un nuevo objeto y luego se pone su variable a null. por tant. Este es el código: class Data { public int intdata = 0. y si Java necesita más memoria. Dado que no hay más referencias a ese objeto. $0 dónde estgn los punteros en Java. el proceso de la colección garbage lo liberará más pronto o más tarde.tn como punteros de forrna ocul ta. para asegurarse que los programadores no podían acceder a la memoria mas allá de los limites legales. y la respuesta es que no tiene. Los diseñadores de Java omitieron tos punteros por razones de seguridad. se ha situado con el operador new. Cuando se cirea un nuevo.t a ese o se usa ferencia Java: . incluyendo objetos y arrays. //más código . . Data { () intdata = 1. si llega el caso.null (aunque hacer esto tampoco permite predecir cuándo. Java usa referenjue actú. d 3 null.

Cuando se liberan todas las referencias a estos objetos en un programa. 1 1 class b ( a al. esto generalmente quiere decir que se 1 . cada uno todavía tiene una referencia interna al otro. se deberían evitar las referencias circulares en las que un objeto hace referencia a otro y el segundo al primero. y es liberar las referencias circulares antes de ir a la aventura. consumiendo recursos. tiene uno de estos objetos anull. Este es el código: class a ( b bl. -7 //¡existen referencias circulares inaccesibles! > 1 Sólo hay una forma de evitar esto. a 0 ( bl = new b 0 . Ambos objetos estarán en memoria. como no hay referencias externas al objeto. la clase a tiene una referencia interna a un objeto de la clase b. y la clase b. 1 } public class app I public static void main(String[] args) ( a obj = new a(). arranca automáticamente. una referencia interna a un objeto de la clase a. hasta que el programa finalice. Peor todavía es que. Sin embargo. no se puede llegar a ese objeto para cambiar la situación. y estos objetos continuarán ocupando memoria hasta que el programa finalice. Cuando el código de main pone la referencia. Este es un ejemplo en el que se muestra lo que hemos querido decir: en él. liberación de memoria de aquello que no tiene más referencias en el programa.Evitar las referencias circulares La colección garbage. En la práctica. obj = null. lo que significa que la colección garbage no puede actuar en el otro objeto. b 0 ( al = new a().

a null. Colección garbage y el método fínalíze "Hmm". con frecuencia. 1 1 public class app ( public static void main(String[] args) . "Garbage llama a un método especial. Esto es un ejemplo: 1 class Data ( public int intdata = 0. Cuando un objeto está dentro del proceso de garbage (ver el punto anterior). es posible hacer esto en el métodofinalize (para más detalles. ver el siguiente apartado). Mientras estamos viendo la gestión de memoria. Algunas veces. si existe.ponen las referencias de un objeto a otros objetos a null antes de poner la referencia del objeto. Data ( ) ( intdata = 1. super~iantSizeCiasssgsc. en sí mismo. este recolector llama a un método del objeto llamadofinalize. hay que notar que se tiene algún control sobre la alocación de memoria como un todo (ver la opción de la línea de comando -J en el capítulol. y se puede usar este método para limpieza de última hora '. dice el programador novato. sgsc = new SuperGiantSizeClass(100000000). que permite fijar la cantidad de memoria total alocada cuando el programa se ejecuta). si existe. 1 protected void finalizeo { sgsc = null. En general. Java gestiona la memoria en los programas. En este método se puede ejecutar el código de limpieza y. ¿Hay algo más que yo debería saber sobre este proceso?" "Una cosa". "entonces Java tiene un recolector de basura que retira de la memoria los artículos que no están referenciados ya. finalize. es buena idea liberar cualquier referencia a otros objetos que tenga el objeto actual para eliminar la posibilidad de referencias circulares (también visto en este capítulo). le responde.

1 1 Sobrecarga de métodos "Todavía estoy trabajando con mi nuevo programa. int op2) . d = null. le dice.I Data d = new Data ( ) . Veamos un ejemplo. Cada lista de parámetros debe ser diferente de cualquier otra de alguna forma. SuperDuperMathPro". el número de parámetros o el tipo de uno o más de ellos. por lo que creo que tendré que escribir un nuevo método". i n t 092) I return opl + 092. "¿Cómo se hace eso?" pregunta PN. Cuando se usa un método sobrecargado. sólo hay que definirlo más de una vez. La sobrecarga de métodos es una técnica de la orientación a objetos que permite definir diferentes versiones de un método. dice el programador novato. Primero. por ejemplo. "y tengo una gran clase llamada calculator con un método llamado addem que suma dos números. el compilador de Java sabrá cuál es el que se quiere utilizar por el número y10 tipo de parámetros que se le pasen. 1 Luego se añade otra versión del mismo método que acepte tres operandos: class calculator ( int addem(int opl. "En absoluto". . me gustaría sumar tres números juntos. Crearemos el ejemplo sobre el que el programador novato estaba preocupado. se añade una versión del método addem a la clase calculator que manejará dos operandos: class calculator I i n t atitieem(int opl. Para sobrecargar un método. especificando una nueva lista de parámetros en cada una de ellas. y buscará la versión del método con la lista de parámetros correcta. todos con el mismo nombre pero con diferentes listas de parámetros. "Puede sobrecargar el método addem para que maneje dos o tres operandos". Además.

que tiene un constructor al que se le pueden pasar cadenas. ¡se pueden sobrecargar métodos en Java para que manejen diferentes listas de parámetros! ¿También se pueden sobrecargar constructores?" "Por supuesto". le dice. 2 ) = 4 addem(2. 1 1 Ahora se pueden usar ambos métodos en el código. Este es el resultado del programa: C:\>java app addem(2. 1 i n t addem(int opl. (ver el siguiente punto para más detalles). Además se pueden sobrecargar los constructores. haciéndolo más fácil de usar de diferentes formas en el código. especialmente en el código que se entrega a otros desarrolladores. " Es cierto". 2) = 6 Como se puede ver.return opl + op2. dice PN. i n t 093) E return opl + o92 + 093. i n t 092. 2. La sobrecarga de constructores funciona como la sobrecarga de otros métodos (ver el punto anterior para más detalles): sólo hay que definir el . porque permite pasar diferentes listas de parámetros a un método. como sigue: public class app r I public static void main(String[] args) I calculator calc = new calculator(). arrays de caracteres y otro tipo d e datos". la sobrecarga proporciona una técnica potente. Sobrecarga de constructores Dice el programador novato: "Entonces. "Considere la clase String de Java.

constructor un número de veces. . 1 Lo único que queda es añadir el método getData: class data I private String data-string. 1 ciata(String S) í data-string = 1 S. dataíchar[l c) t data-string = new String(c). Veamos un ejemplo que imita los constructores de la clase String de Java en el que esta nueva clase. tendrá un constructor al que se le puede pasar un array de caracteres o una cadena. 1 1 Así es como se declara el constructor que acepta una cadena de texto: class data 1. data-string = new String(c). private String data-string. Así es cómo se declara y define el constructor que toma un array de caracteres: class data t private String data-string. Esta clase simplemente almacenará los datos que se le pasen y hará que los datos estén disponibles con un método getData. cada una con una lista de parámetros diferentes. ciata(char1 1 c) i data-string = new String(c). 1 data(String S) { data-string = S. la clase data.

out. " le contesta. Pasé un objeto a un método porque quería hacer una prueba de destrucción en ese método. "Otra vez Java está en plan gracioso. System. 'a'}.get~ata() ). ~ata(String data) . "Eso es lo que ha ocurrido". 'o'. 'l'. Cuando se pasa un elemento de un tipo de dato sencillo a un método. crear objetos y visualizar el texto almacenado. Java pasa una copia de los datos. 1 1 Este es el resultado del código: C:\>java app Hola ¡Hola desde Java! Pasar objetos a métodos El programador novato aparece y dice. Dado que el método sólo obtiene una copia del elemento de los datos. 1 1 Ahora se pueden usar ambos constructores en el código.grintln( (new data(chararray)). que se llama paso por valor. Este es un ejemplo en el que se pasa un objeto de la clase printer para visualizar los datos del objeto: class Data { public String data-string. el objeto original estaba destruido.out.grintln((new data('iHo1a desde Java!") ). ~ystem. como sigue: public class app { public static void main(String[] args) { char chararray[] = {'H'.public String getData0 c return data-string.getData()). el código del método no puede afectar al elemento del dato original. ¿Qué ha ocurrido?" "Java pasa objetos por referencia. pero al devolver el control.

Data(String S) ( data-string = new String(s). el objeto pasado cambia el objeto original. Aquí tenemos un ejemplo en el que se pasa el objeto de la clase Data a un método llamado rewrite que cambia la variable de instanciadata-string del objeto.data-string = "iHola a Javal").data-string = data. printer p = new printero. 1 1 public class app .out.println(d.data~string). dado que los objetos se pasan referencia. Este es el resultado del código: C:\>java app iHola desde Java ! Como se mencionó anteriormente. 1 1 class printer ( public void print (Data d) f ~ystem. 1 1 class Class I public void rewrite(Data d) { d. pero el método rewrite es capaz de cambiar la cadena a "i Hola a Java!" en este código: class Data ( public String data-string. esta variable empieza con la cadena "iH01a desde Java!". 1 1 public class app ( public static void main(String[l args) I Data data = new Data("1Hola desde Javal").

dice el programador novato. Veamos un ejemplo. "Todavía no". a [ loop-indexl *=2. Dado que los arrays se pasan por referencia. Se puede pasar un array a un método tan fácil como se pasa una variable simple. en Java. 1 1 1 public class app { public static void main(String[] args) . "Hay un tipo más de elemento que se pasa por referencia.{ public static void main(String[l args) I Data d = new Data(niRola desde Java!"). contestamos. lo que significa que si se cambia un array pasado a un método. ahora ya está todo encaminado". Este es el resultado del código: C:\>java app ¡Hola a Java! Pasar arrays a métodos "Entonces. los datos del array original también serán duplicados. Este sería el código (observe que se visualiza un array antes y después de llamar al método doubler): class Calculate { public void doubler(int a[ 1) I for (int loop-index = 0. los arrays". loop-index < a-length. las variables simples se pasan por valor y los objetos por referencia. pero hay que tener en cuenta que los arrays se pasan por referencia. el array original también se ve afectado. se pasará un array a un método llamado doubler que duplica cada elemento del array. En este caso. Class c = new Class 0 . no por valor.

out. que irr me los datos del objeto actual pasando el objeto al método print de otro objeto. por ejemplo. 4. 5 ) . la clase Data tiene un método. loop-index++) ( System.printlní"Después de llamar a doubler . . array[O] = 2 array [l] = 4 arrayL21 = 6 arrayL31 = 8 array 1 1 = 10 4 Usar la palabra clave this Los objetos de Java incluyen un miembro de datos llamado this. ") .println("Antes de llamar a doubler . printData. "1 .out. 1 1 1 Este es el resultado del código: C:\>java app Antes de llamar a doubler.out. loop-index < array. Calculate c = new Calculate(). for (int loop-index = 0. . loop-index++) I Systern.length. que realmente es una referencia al objeto actual.println("array[" + loop-index + " 1 = " + array[loop-index] ) . .I int array[l = (1. arrayL01 = 1 arrayrl] = 2 array[2] = 3 arrayr31 = 4 array[4] = 5 Después de llamar a doubler.println("array[" + loop-index + "1 = " + System. . cuando se quiere p el objeto actual a un método. loop-index c array. La palabra clave this se usa para hacer referencia al objeto actual. Así sería el código: 7 .length. for (int loop-index = 0. Systern. 3. 2. En el siguiente caso.out. . . La palabra clave this es útil si se necesita hacer referencia al objeto actual.

1 1 Observe que cuando se llama a p. surge una pregunta: cuando el método que .print. 1 1 class printer ( void print(Data d) System.out. 1 1 public class app I public static void mainíString[ 1 args) ( (new Data("iHo1a desde Java!")). se pasa una referencia al objeto actual a p. de forma que el código de p.getData()).println(d.print (this). Sin embargo. Data(String s i I data-string = S.printData(). que devuelve los datos internos que se van a visualizar. Este es el resultado del programa: C:\>java app ¡Hola desde Java! Devolver objetos desde métodos Se pueden devolver objetos desde métodos.print da acceso al método getData del objeto actual. 1 public String getData0 1 return data-string. 1 public void printData0 t printer p = new printero.class Data I private String data-string.print. igual que ocurre con otros tipos de datos. p.

Cuando se llama a getNewArray. éste devuelve un nuevo objeto de la clase CreatedClass y puede visualizar los datos de ese objeto. Cuando se crea un nuevo objeto usando el operador new.7 devolvió el objeto se queda fuera del alcance. éste devolverá un array de enteros. 1 Cuando se llama al método getNewObject. ¿el objeto que él devolvió también se queda fuera del alcance? 7 La respuesta es no. En el ejemplo siguiente.". ese objeto no es destruido cuando el método que lo creó queda fuera del alcance. por sí mismo. Esto es lo que muestra el programa al ejecutarlo: C:\>java app Esta es la etiqueta de datos 1 Devolver arrays desde métodos Se pueden devolver arrays desde métodos igual que se pueden devolver objetos y tipos de datos sencillos.getNewObject0. CreatedClass c = o. 1 1 class CreatedClass I public String tag = "Esta es la etiqueta de datos. Veamos un ejemplo en el que se crea una clase llamada ArrayFActory con un método llamado getNewArray. y el objeto. no está a disposición del recolector de basura hasta que no haya más referencias a él. 1 public class app public static void main(String[] args) I ObjectFactory o = new ObjectFactoryO. la clase llamada ObjectFactory tiene un método llamado getNewObject que devuelve un objeto de la clase CreatedClass: class ObjectFactory I public CreatedClass getNewObject0 I return new CreatedClassO. Observe que el -4 .

println("array[" + loop-index + " 1 = " + array [loop-index] ) . return array.out.tipo de retorno que se especifica en la declaración degetNewArray es int[]. lo que indica que es un array de enteros.length. 1 1 1 Este es el resultado del código: C:\>java array[O] array[ll array[2] array[31 array [4] app = 1 = 2 = 3 = 4 = 5 . loop-index < array. 1 1 Así funcionaría la clase ArrayFactory. Este es el código: class ArrayFactory ( public int 1 1 getNewArray ( ) ( int array[l = 11. 5 ) . int array[l = af. System.getNewArray(). creando un nuevo array y visualizándolo: public class app { public static void main(String[] args) { ArrayFactory af = new ArrayFactory(). 3 . 2. for (int loop-index loop-index++) { = 0. 4.

la clase "vehículo" podría tener un método llamado g o que visualice "Conducir. que contiene la funcionalidad básica de algunos elementos de transporte. y la clase helicóptero puede sobrescribir ese método. si se tiene una clase llamada. . sustituyéndolos con su propio código. Se trata de añadir lo que se quiera a la nueva clase para darle mayor funcionalidad que a la clase original.m Herencia.".. llamada clase derivada o subclase. tener un miembro de datos llamado "ruedas".. La clase "coche" puede. El capítulo anterior empezó con la discusión sobre la programación orientada a objetos y. supongamos. redefiniéndolo y visualizando "Volar. Por ejemplo.". se puede usar esa clase como base de todas aquellas que se deriven de la misma. tema muy importante en la programación con lenguaje Java. "vehículo".. Usando la herencia se puede derivar una clase.. Todas las subclases tendrán acceso a los miembros no privados de la superclase y podrán añadir los suyos propios. de otra. llamada clase base o superclase. como se mencionó allí. por ejemplo. De hecho. clases internas e interfaces Este capítulo trata la herencia. Además se puede usar la misma clase "vehículo" como la clase base para otras. como "coche" y "camión". pero el mismo miembro de datos en la clase "camión" debería estar inicializado a 18. inicializado a 4. pueden sobrescribir los miembros no privados de la superclase. como puede ser la clase "helicóptero".

class AppPramo extends Fr- -T . De hecho. se puede derivar la applet de la clase Applet del paquetejava. en su lugar se debe derivar una nueva clase de la primera. Esta es una visión rápida de lo que hace la herencia. se puede tener un método abstracto llamado printError. porque se quiere que los desarrolladores suministren su propio código para este método. y está muy rela? cionado con la herencia. import java. La siguiente pregunta es. que crea una superclase basada en la clase Applet usando la palabra clave extends (en el siguiente capítulo se verá más sobre applets): import java. por ejemplo. personalizado esa clase para su propio uso. se quiere crear una applet en Java. Frame: import java. porque en ese caso.applet. Se puede usar o redefinir los miembros de la superclase como guste.*. por ejemplo. 100). Los desarrolladores de Sun Microsystems han creado enormes paquetes. Estas clases se llaman abstractas. 1 1 Este es otro ejemplo que se vio en el capítulo 1.event. de forma que sea apropiado para las subclases que ellos crean.drawString("iHoladesde Java!".awt.Entonces.*.awt.Applet. sobrescribiendo los miembros que son específicamente declarados como abstractos. por medio de la herencia.awt.applet. public clase applet extends Applet ( public void paint(Graphics g) { g. import java. *. llenos de clases que se pueden usar como superclases. librerías de clases. en este caso. reutilizando y añadiendo código. En un objeto. se pueden crear clases que deban ser tratadas como superclases. no se puede instanciar directamente una clase abstracta. Esto es importante si.awt. Aquí está laapplet que se vio en el capítulo 1. 60. se crea una aplicación ventana basándose en la clase de Java java. Las clases abstractas se utilizan para forzar a los desarrolladores a customizar algunos o todos los miembros de una clase. puede basar sus clases en otras clases. ¿por qué es tan importante en Java? ¿Por qué la herencia? Java es verdaderamente un lenguaje orientado a objetos.

addWindowListener(new WindowAdapterO { public void windowClosing(WindowEvent e) (System. Para resolver este problema. y esta vez. sino las interfaces. eso significa que la applet se puede extender de la clase Applet y usar la palabra clave implements para añadir la gestión del clic en los botones. se puede derivar una clase de la clase java. 60. Así quedaría la applet: . esto quiere decir que sólo se puede usar la palabra clave extends con una clase. Basar una subclase en dos o más superclases se llama herencia múltiple. hay que tener mucho contacto con los paquetes de Java. ¿Por qué las interfaces? Supongamos que se quiere crear una applet que gestione los clics que se hacen en un botón. 100). se usa otra clase. En la práctica. Java implementa las clases como ActionListener como interfaces. 1 1 public class app ( public static void main(String [ ] args) ( AppFrame f = new AppFrame ( ) . En el siguiente caso. la applet se tendrá que basar en ambas clases Applet y ActionListener. Como se puede ver. por ejemplo. y Java no soporta la herencia múltiple (aunque sí lo hacen lenguajes como C++). De hecho. ActionListener. cuando se manejan elementos visuales en los programas. Por lo tanto. si se quiere gestionar las acciones del ratón o los clics en los botones.Hola desde Java!". se derivan sus clases.drawString(".}i). tienen sus propias clases y para personalizados.applet.( public void paint(Graphics g) I g. Para crear una applet estándar.exit(O). se tiene que usar la herencia. no se usan las superclases. Los botones. f.Applet y para gestionar los clics que se hacen en un botón.

event. se verá cómo se crean las interfaces.addActionListener(this). buttonl = new Button("iHacer clic aquí!"). ¿Por qué las clases internas? Java permite crear clases dentro de clases. java.*. por ejemplo. if(event . import java.lang.import java. Button buttonl.*. Todavía queda un punto por cubrir en este capítulo: las clases internas. public void init ( ) ( textl = new TextField(20).applet. public class clicker extends Applet implements ActionListener { TextField textl.awt. SetText (msg) . 1 public void actiopnerformed(ActionEvent event){ String msg = new String ("Bienvenido a Java"). MouseMotionListener { Más adelante.getSource() == buttonl) { textl .*. 1 Se puede implementar tantas interfaces como se quiera. import java .awt. Sin embargo. java. awt . add(text1). add(button1) .Math.Graphics. * .Applet. java.event. buttonl. aquí hay parte de un programa que implementa tres listeners para permitir que el programa gestione los clics en los botones y las acciones del ratón: import import import import import java. MouseListener.applet. public class dauber extends Applet implements ActionListener. Quizás no T . veremosuna introducción a las mismas en este capítulo para que podamos utilizarlas después.awt.awt. y la clase encerrada se llama clase interna.Applet. Empezaremos a trabajar con ellas en este capítulo. java.

Para gestionar un evento de interfaz de usuario de cualquier tipo. que ya tienen implementaciones vacías de los métodos requeridos. pero lo verá más claro cuando se empiecen a gestionar los eventos de la interfaz de usuario. Ahora que ya conocemos los conceptos relacionados con la herencia.>>). cuando el usuario cierra una ventana. Seguiremos este código con detalle cuando trabajemos con eventos. f. es común tener una subclase de las clases adaptador como clase interna. y cuando se implementa una interfaz.. Los eventos se gestionan con las interfaces.. Java proporciona las clases adaptador. Este es un ejemplo en el que el código finaliza una aplicación cuando el usuario cierra la ventana de la misma: public class app { public static void main(String [ ] args) I AppFrame f = new AppFrameO. también se debe proporcionar la implementación de varios métodos abstractos en el interior de la misma. sobrescribiendo los métodos que se quiera de una forma muy compacta. y más tarde. como. que se puede utilizar para arrancar el vehículo y que visualiza "Arrancar. "quiero aprender todo lo que hay sobre la herencia.exit(O).": . Suponga que tiene una clase llamada "vehículo" que tiene un método start. ¿Puede explicármelo en dos palabras o menos?" Mientras cuenta con los dedos. introduciremos clases internas para que este código tenga mucho más sentido. "No hay forma".addWindovlistener(neor windowAdapter0 {public void windoffClosing(WindarrEvent e) <System. Veamos un ejemplo en el que se muestra cómo se crea una subclase usando le herencia. las interfaces y las clases internas.vea mucha necesidad de definir clases dentro de clases en este momento. le dice. Para que este proceso sea más fácil. por ejemplo. dice el programador novato. es hora de empezar con la siguiente sección. Crear una subclase "De acuerdo".

start0..println(~Conducir.out. c.println(~~rancar. Coche c = new coche(). > 1 Hay otro tipo de vehículos... > 1 Ahora se puede acceder a ambos métodos start y drive en los objetos de la clase "coche". Este es un ejemplo en el que se añade un método llamado drive a la clase "coche": class coche extends vehiculo I public void drive0 { syat~."). Además se pueden añadir los miembros de datos y métodos propios en las subclases.. Así se declara "coche" como una subclase de "vehículo": class coche extends vehiculo { La sintaxis indica que "coche" es derivada de la clase "vehículo". por lo tanto si se quiere especializar la clase "vehículo" en una clase "coche". se puede usar la herencia con la palabra clave extends."). 1 } Esta es la salida del código anterior: C:\>java app Crear un coche.. lo que significa que en este caso. . . como se ve en el ejemplo: public class app ( public static void main(String[] args) I System. c.drive0."). "coche" heredará el método start de "vehículo".class vehiculo I public void start() Systern.~ut.println("Crear un coche. ..o~t.

miembros de datos y métodos para especificar la visibilidad de esos elementos en el resto del programa. Especificadores de acceso y herencia "Otra vez. Hay mucho más en todo este proceso. ¿qué pasa si se define un método en una subclase con el mismo nombre que un método de la superclase? ¿Cómo se pasan los datos al constructor de una superclase? Todo esto lo veremos en el siguiente capítulo.. dice el programador novato. Cuando se declara un miembro de una clase como public. Por ejemplo. Java está gracioso". que muestra cómo se usan los especificadores de acceso: access class nombre de clase [extends ( ... ] [implements . Los especificadores de acceso se usan con clases. dice PN. quiero usar algunos métodos de la superclase. Este es un ejemplo básico de subclase.. Conducir . private y protected. "Ese es el problema". "En una subclase.Arrancar . . [access] [staticl tipo variable-de-instanciaN.. ] [access] [staticl tipo variable-de-instancial. . [access] [staticl tipo método1 (lista de parámetros) [access] [static1 tipo métodoN (lista de parámetros) { Los valores posibles de access son public. Esta es la forma general de declarar y definir las clases. "Privado". es accesible desde cualquier . pero Java dice que no existen" "¿Cuál es el especificador de acceso para los métodos?" le pregunta..

coche c = new coche ( ) .start0..out.out.1. Alcance para el especificador de acceso (x = en el alcance).println("Arrancar .. sólo es accesible desde la clase de la que es miembro. echemos un vistazo al código del programador novato. c.println("Conducir . está disponible para la clase actual. " ) . otras clases del mismo paquete. . Si no se usa un especificador de acceso. en el que el método srarr se declara como private pero además se accede a é1 en main: class vehiculo { private void start0 I 1 1 System.drive ( ) .1.out. Si se declara como protected. ") . c. class coche extends vehiculo { public void drive () I 1 System. el acceso por defecto es que el miembro de la clase es visible a la clase de la que es miembro. Misma clase Subclase en el mismo paquete No subclase en el mismo paquete x x x x . . Si se declara como private.").lugar del programa. Por ejemplo. a las clases derivadas de la misma que están en su mismo paquete y a otras clases del mismo paquete. y clases que son derivadas de esa clase. . 1 1 Tabla 5.println("Crear un coche. 1 public class app I public static void main(String[l args) I System. Se pueden ver los detalles en la tabla 5. .

coche c = new coche ( ) .2\bin\javacapp. . . usando private.java:47: No method matching start() found in class coche c."). Java dice que no puede encontrar el método start cuando se usa en main: ~:\>c:\jdkl. . el siguiente código funciona: class vehiculo ( protected void start0 I 1 System.. " 1 .I Subclase en otro paquete No subclase en otro paauete Dado que la declaración de un método.out. . "1 .java -deprecation app.println("Crear un coche. restringe ese miembro a su clase.start ( ) .2.out. 1 class coche extends vehiculo { public void drive ( ) ( System. Esta es la salida de la aplicación: C:\>java app Crear un coche.println("Conducir . la declaración de un miembro como protected restringe su alcance al código del mismo paquete y de la subclase de la clase en la que está declarado. A 1 error Por otro lado.println("Arrancar .. . Sin embargo. .out. 1 1 public class app ( public static void main(String[l args) ( System..

Sé que puedo crear una subclase a partir de una superclase. pensativo.. supongamos que se añade un constructor sin parámetros a la clase b: class a ( a 0 ( .Arrancar . pero ¿qué pasa si la superclase tiene un constructor?" "Hay que pensar un poco".. cuando se crea un objeto de la clase b.. se llama automáticamente al constructor de la clase a: public class app { public static void main(String[l args) ( b obj = new b 0 . dice el PN. 1 1 Luego se deriva una subclase b de a: class b extends a ( 1 Ahora..out. dice el programador novato. "tengo un problema. Conducir . > 1 Este es el resultado del código precedente: C:\>java app En el constructor de a...println("En el constructor de a. Supongamos que tiene una clase llamada a que tiene un constructor sin parámetros: class a { a() I Systern. Ahora. "Hmm".").. Llamar a los constructores de la superclase "De acuerdo"..

1 .) public class app { public static void main(String[] args) ( b obj = new b("iHo1a desde Java!"). ... 1 1 En este caso.")... se llama a los constructores de a y b: C:\>java app En el constructor de a .out. 1 1 class b extends a { b(String e) f systam. 1 1 class b extends a { b 0 { system. En el constructor de b . " ...System. .println("En el constructor de b-").out. . Ahora supongamos que se cambia el constructor de b para que acepte un parámetro: class a I a0 I System.").println("En el constructor String de b . public class app { public static void mainíStringl1 args) I b obj = new b 0 .out.println("En el constructor de a. cuando se crea un objeto de la clase b..out.println("En el constructor de a.

¡Hola desde Java! Un constructor sin parámetros se llama constructor por defecto de una clase. .out..out..println("En el constructor de a.").out... se llama a los constructores de ambas clases..println(~n constructor String de a. System. ¿Cómo se hace esto? Se llama al método super del constructor de la clase b. a menos que se haga otro tipo de peticiones. el -) System.println(~~n constructor string de a. > a(String S) í ~ystem. 1 1 Ahora digamos que se quiere llamar al constructor de la clase a con el parámetro String en lugar de llamar a los constructores por defecto..out.").println("En el constructor de d.").. como sigue: class a { a( ( ) System.. el System.En este caso. y lo veremos más tarde en este capítulo): class a { a 0 I System. 1 1 class b extends a b(String S) ( super(s) ..").out. ya que Java lo llamará automáticamente cuando se instancien subclases de esa clase.println(s).println(s)... En el constructor String de b. a y b: C:\>java app En el constructor de a. ¿Qué significa eso? Supongamos que se añade otro constructor a la clase a para gestionar las cadenas (esto se llama sobrecarga..println("Enel constructor de b.out. 1 a(String S) ( System.out.

" ¿se pueden crear subclases de subclases?" "Sí".println(s)... 1 1 Si se usa super para llamar al constructor de una superclase.out... se creó una clase llamada "vehículo" y una subclase de "vehículo" llamada "coche": . ¡Hola desde Java! ¿Por qué se llama al constructor que tiene un parámetro String en Ia clase a y no al constructor por defecto de la clase a? La razón es sencilla. Java ve que se está usando el método super para llamar al método de la superclase: class b extends a { b(String S) { super(e).out. que es donde Java lo buscará (si es cualquier otra línea distinta de la primera. se llama al constructor de la clase a que tiene un parámetro String.?" "¿Qué tal un café?". Crear multiniveles de herencia "Entonces". no al constructor por defecto: C:\>java app En el constructor String de a. la línea en la que se hace esto debe ser la primera del constructor."). .. System. Ahora cuando se instancia un objeto de la clase b. "Y ¿se puede crear subclases de subclases de subclases?" " Sí". 1 ). System. Java lo ignora). dice el programador novato.. "y ¿puedo yo.println("En el constructor String de b. le dice. PN está dispuesto a continuar y pregunta. ¡Hola desde Java! En el constructor String de b. le dice. En el primer punto de este capítulo..public class app I public static void main(String[l args) { b obj = new b("iHo1a desde Java!"). le dice.

.println("Conducir . . ") . 1 1 class coche extends vehiculo public void d r i v e 0 ( system. 1 1 Hay todo tipo d e aviones.out. .println("Girar . por ejemplo.println("Subir verticalmente. 1 1 Esa jerarquía de clases sólo incluía dos niveles.out. y jet. 1 1 Esta es la jerarquía de la clase ahora: vehiculo 1- coche .. que es una subclase de vehículo y añade un método llamadofly: class avion extends vehiculo { public void f ly ( ) ( System.class vehiculo ( public void s t a r t 0 ( System. class jet extends avion ( pub1 ic void zoom ( ) { System.out. " ) .println("Vo1ar . que define un nuevo método llamado whirl. . . .out.println("Arrancar . ") . avión. " 1 . que define un método llamado zoom: class whirlybird extends avion I public void w h i r l 0 I 1 1 System."). . . que tenemos una nueva clase.out. pero se puede profundizar más. la superclase y la subclase. Digamos. y derivará dos clases d e "avión": whirlybird. .

Volar. donde a es la superclase de la que deriva todo. Crear un jet. System. luego al de c. clases de la a a la d. dice el PN. j. j. . implementaremos el programa del programador novato con cuatro niveles de subclasificación.out.start0. c. ."). le dice. . "Sí".fly0. System. . como se hace en este ejemplo en el que se crean objetos de la clase "coche" y jet: public class app { public static void main(String[] args) I System. dice el PN. Miremos en un ejemplo el uso de los multiniveles de constructores. .println0 . Aquí. coche c = new coche ( ) . "Java los llama exactamente en orden inverso". . . 1 1 Esta es la salida del código: C:\>java app Crear un coche.. . j. . jet j = new jet() .. Gestionar multiniveles de constructores "iEh!" dice el programador novato.drive(). ¿correcto?" "No". "¿Está en plan gracioso Java otra vez?" le pregunta. "Sabía que estaría de mi lado". Arrancar. Tiene sentido pensar que el constructor de d será al que se llame primero..").zoom0. c. Arrancar . Conducir ..out. .out. . .println("Crear un jet.start0.. luego al de b y después al de a.println("Crear un coche. "he creado cuatro niveles de subclases. empezando con la clase a: . Subir verticalmente .1- avion -1 -1 w h i rlybird jet Ahora podemos instanciar objetos de estas clases..

class a ( a 0 ( System. 1 1 class c extends b I c o { System. luego al de c y después al de d..").println("Construcción de d...println("Construcción de 1 a. b.. d."). 1 class b extends a { b0 { System..out. se creará un objeto de la clase d.. 1 1 class d extends c ( d() { System..."). la última clase de la cadena de subclases: public class app ( public static void rnain(String[ l args) { d obj = new a ( ) ...out.. se .out.").println("Construcción de c.. c.println("Construcción de b. 1 1 Esto es lo que se ve cuando se ejecuta el código: C:\>java app Construcción Construcción Construcción Construcción de de de de a. después al de b... ¿Por qué Java lo hace de esta forma? Porque cuando se crean subclases.out.. no en el orden inverso como se podía esperar.. llamó primero al constructor de a. En otras palabras. 1 Después.

le dice. todos los constructores de la cadena de subclases deben llamarse en orden ascendente.. etc. vimos que se puede sobrecargar métodos con diferentes implementaciones que tienen diferentes listas de parámetros. "¿Puedo hacer eso?" pregunta PN. sin embargo. observe que se pueden pasar parámetros a los múltiples niveles d e las formas que se vieron en el punto correspondiente en este capítulo.println("Recpirar . S e decide que sería mejor visualizar "Burbujear. Cuando se prueba el método breathe en la clase "pez". Sin embargo.". Por esa razón.". pero quería crear un método llamadogetlabel. "No hay problema". . supongamos que se quiere derivar una nueva clase de "animal" llamada "pez". se ve que se visualiza "Respirar. después al siguiente. "creía que podía usar la clase Button de Java en mi nuevo programa.. > 1 Ahora. Como la clase b sabe de la clase a. lo que quiere decir que los sustituye con una nueva versión.. Sobrescritura de métodos "Bien". empezaremos con una clase base general llamada animal que tiene un método. También se puede sobrecargar métodos que se heredan de una superclase. ésta no sabe nada d e la c y así sucesivamente. se visualiza "Respirar .. Además. . se podría contar con tener ciertas partes de a inicializadas antes d e completar su inicialización. y lo mismo para la clase c respecto a la b. breathe. etc. dice el programador novato.procede desde lo general a lo específico. "puede sobrescribir el método getLabe1 de la clase Button con una nueva implementación de ese método".out. En el ejemplo siguiente. Java llama al constructor de la subclase original primero.. "i ." Este es el código: class animal { public void breatheo { System. se puede sobrescribir el método breathe en la clase "pez" simplemente definiendo una nueva versión con la misma lista de parámetros: . lo que significa que la clase a no sabe nada de la clase b. En el último capítulo. . Cuando se llama a breathe. Para hacerlo. y la clase Button ya tiene un método con ese nombre".

y funciona bien la mayor parte del tiempo.... "creo que he encontrado un problema' que nadie más ha encontrado en Java".. "Sí".out . . Respirar. pero algunas veces necesito acceder al método original sobrescri- . animal a = new animal(). le pregunta. a. "he sobrescrito un método de una superclase. dice el programador novato.") .println("Burbujear. .println(). Burbujear.~ut. > 1 class pez extends animal I public void breathe ( ) { System.out. pez f = new pez ( ) .println("Crear un pez."). . dice PN. 7 Acceso a los miembros sobrescritos "Bien".class animal I public void breathe ( ) C System.println("Crear un animal.breathe ( ) ..out.")... . f..out. "Ah ¿sí?". System.."). Crear un pez.breathe ( ) .println(~Respirar. mostrando que el método breathe está sobrecargado: C:\>java app Crear un animal. System. 1 1 Esta es la salida del código. 1 1 Ahora se puede instanciar nuevos objetos de las clases "animal" y "pez" y llamar a sus métodos breathe como sigue: public class app I public static void main(String[l args) { System. .

": class animal { public void breathe ( i class pez extends animal { public void breathe ( ) { System... Ahora. O ) . le gustaría utilizar el método breathe de la superclase.println("Respirar . y se puede hacer eso con la palabra clave super. En este método. . por lo que se añade un nuevo método a la clase pez. supongamos que se da cuenta de que cierto tipo de peces pueden respirar como los animales. sin embargo. "Es un problema común". . 1 public void newbreathe ( ) ( super.out. newbreathe. . excepto que super no se refiere al objeto actual. Por ejemplo. echemos un vistazo al código del punto anterior en el que la clase "pez" es una subclase de la clase "animal" y sobrescribe el método breathe para que se visualice "Burbujear . sino a su superclase.breathe0.. .. 1 class pez extends animal I public void breathe ( ) ( System. 1 1 . "y se puede resolver con la palabra clave super". como sigue: class animal { public void breathe0 { System. .out.println("Burbujear .out.to". " 1 . Se puede usar super igual que se usa la palabra clave this. .println( Burbujear. "1 . le dice." en lugar de "Respirar.

. se puede asignar una referencia a un objeto de una subclase a un tipo de variable de una superclase. . . Usar variables de superclase con objetos de subclases El zar de la Programación Exacta (ZPE) aparece y dice. Crear un pez. Digamos.println("Crear un animal. . breathe ( ) . ¿Se puede hacer eso en Java?" El programador novato dice "¿Lo hace por mí?" "Sí". . Respirar . por ejemplo. . Este es el resultado del código: C:\>java app Crear un animal .Ahora se puede instanciar objetos de las clases "animal" y "pez" y usar el ' método newbreathe. . . out . . animal a = new animal ( ) . que la clase a es la superclase de b y tiene una variable de la clase a. " ) pez lf = new pez(). así como referencia a objetos de la clase a. a. "En C++. Esto significa que se puede asignar referencias de objetos de clase b a esa variable. . System.println("Crear un pez. Veamos un ejemplo. como sigue: public class app ( public static void main(String[l args) ( System. le responde el ZPE.. T Un aspecto interesante de la programación orientada a objetos (POO) en Java. Aquí usaremos el multinivel de la jerarquía de clases que ya vimos en este capítulo: class vehiculo ( 7 public void start () . " ) . . es que se puede asignar una referencia a un objeto de subclase a un tipo de variable de una superclase. que pondremos a funcionar en el siguiente punto.out . Respirar . .

c. jet j = new j e t o .println("Crear un jet.start0.. .out .start0.. ") . c.. 1 1 class avion extends vehiculo I public void fly ( ) ( System.println("Crear un coche.println("Girar .class coche extends vehiculo I public void drive0 I System.drive0.out. . System.println("Conducir . 1 1 . car c = new car ( ) . 1 1 Por ejemplo.. j. " ) .").").out.println("Subir verticalmente.. 1 1 class whirlybird extends avion I public void whirl ( ) ( System. .. 1 1 class jet extends avion { public void zoom ( ) ( Syctem. ..println ("Volar. se puede usar este código: public class app I public static void main(String[] args) ( System.out. System. .out.out."). ") .out. para crear nuevos objetos de las clases "coche" y jet.println0.

. . Arrancar ."). Arrancar . start ( ) . ¿Tendré que escribir el código principal del programa tres veces. sólo permitirá acceder a los elementos de su propia clase. Ahora se comentaron las líneas j. En general. una variable de objeto. . vehiculo j = new j e t 0. Esta es la salida del código: C:\>java app Crear un coche. c. cuadrado y círculo. . .out. Mi de dibujo crea objetos de las clases triángulo."). . coche c = new coche ( ) . Conducir .zoom() porque esos métodos están definidos en las clases "avión" y jet.out. una por cada tipo de objeto?" ..Sin embargo. Crear un jet . en particular.println("Crear un coche. .. dice el programador novato. lo que quiere decir que esos métodos no se pueden usar con una variable de la clase "vehículo". como sigue: public class app ( public static void main(String[J args) I System.drive0. también se puede asignar el nuevo objeto jet a la variable de clase vehiculo.println0. no necesariamente a todos los miembros. no se podrá acceder a ningún miembro que no lo sea de la clase a. pero no estoy seguro del tipo de objeto que el usuario querrá hacer hasta que el programa no se ejecute.. . que son subclases de "vehículo".out. a..println("Crear un jet. cada una de ellas tiene un método Dibujar. 7 Dispatching dinámico de métodos (Polimorfismo en tiempo de ejecución) "Vaya".. "tengo otro problema. c. System. . System.Jly() y j.

. 1 } class d extends a ( public void print () I System.. System. dispatch dinámico de métodos."). una subclase de b llamada c y una subclase de c llamada d. En el siguiente ejemplo se clarifica todo esto. le dice. class b extends a ( public void print ( ) 1."). en Java. 1 1 ."). El polimorfismo en tiempo de ejecución. llamado. Esto quiere decir que..").. 1 1 class c extends a I public void print ( ) 1."No del todo". puede escribir su código llamando al método Dibujar en varias variables y decidir el tipo de objeto.out. System.. permite hacer esto.println("Aquí está a. "¿Cómo?" contesta PN.. se puede asignar una referencia a un objeto de subclase a un tipo de variable de una superclase. cuadrado o círculo. triángulo. System. public void print ( ) 1. La respuesta es soportar el polimorfismo en tiempo de ejecución. Puede que se esté preguntando porqué Java. Como vimos en la sección anterior.println("Aquí está b. "Puede usar el polimorfismo en tiempo de ejecución".out.out.out. permite esperar hasta que el programa se esté realmente ejecutando para especificar el tipo de objeto que estará en una variable particular del objeto. que es tan estricto con el tipo de datos. En este caso. que está almacenado en esas variables en tiempo de ejecución.println("Aquí está c.. en el caso del programador novato. una subclase de a llamada b. cada una de las cuales tiene un métodoprint: class a 1.println("Aquí está d. se creará una superclase llamada a..

bl = new b 0 . a aref. 9 Ahora.Ahora se puede crear una referencia al objeto de cada tipo de clase: public class app I public static void main(String[l args) ( a a l = new a ( ) .print ( ) . cl = n e w c 0 . crearemos además una variable llamada aref que gestiona una referencia a un objeto de la clase a: public class app ( public static void main(String[l args) { a b c d al = new a(). aref. d d l = new d o . dl = new d( ) . aref = e l . aref = bl. el método print de la clase correspondiente será el llamado: public class app I public static void main(String[l args) I a b c d a al = new a().print ( ). se puede hacer referencia a los objetos de todas las clases diferentes en aref. dl = new d o . c c l = new c 0 . y cuando se llame al método print. cl = n e w c 0 . Para mostrar cómo funciona el polirnorfisrno en tiempo de ejecución. aref . aref . bl = new b 0 . aref = a l . b b l = new b 0 . .

también deberá serlo la clase. ¡justo allí. de lo contrario Java se quejará. . Usando el polimorfismo en tiempo de ejecución. A q u í está d . Por lo tanto.aref . no se podrá acceder a los miembros que no son miembros de la clase de a. . Para hacer un método abstracto. que visualiza una cadena y obtiene la cadena para visualizar llamando al método getData: . A q u í está c . "¡Ese Johnson!". . 1 1 Este es el resultado del código: C:\>java app ~quí está a. "¿Qué ocurre?". le dice.print ( 1 . en particular. . Crear clases abstractas El programador novato aparece.print ( ) . no necesariamente a todos los miembros de la variable objeto que gestiona. . . se usa la palabra clave abstract. . y ese Johnson tendrá que personalizarla". aref . no funcionó. "Ese Johnson estaba utilizando una de mis clases que es necesario personalizar antes de que se pueda usar. Si se hace algún método abstracto en una clase. aref = c i l . sólo permitirá acceder a los elementos que son miembros de su propia clase. se crea una clase llamada a que tiene un método llamado print. En este caso. Cuando se escriben clases. dice PN. "la próxima vez. . Para asegurarse de que el desarrollador personalice el código. lo que significa que el desarrollador tendrá que sobrescribir el método. haga una clase abstracta. y es necesario que el desarrollador que crea subclase de la clase las personalice. ~quí está b . a. se puede escribir código que funcionará con diferentes tipos de objetos y se decidirá el tipo de objeto actual en tiempo de ejecución. le pregunta. se pueden ejecutar casos donde sólo se pueda proporcionar código general. Observe que todavía se aplican las restricciones mencionadas en el punto anterior: una variable de objeto. He aquí un ejemplo. delante del gran jefe!" "Bien". se puede hacer que el método sea abstracto. pero no lo hizo.

String getData0; public void p r i n t 0

I
System.out.println(getData0 1 ;

1 1

Observe que no hay ninguna implementación del método getData porque se quiere que los desarrolladores especifiquen qué datos van a visualizar. Para asegurarse de que saben que deben proporcionar una implementación del método getData, se puede hacer que sea abstracto, lo que significa que también la clase debe ser abstracta:
abstract class a
(

abstract String getData0;
public void p r i n t 0
(

System.out.println(getData0);

1

1

Ahora, cuando se crea una subclase de a, hay que proporcionar un; implementación de getData, como sigue:
class b extends a
(

String getData0 í return n;Hola desde Javal*; 1

1

Así es como funcionaría la subclase (observe que no se puede instancia7 directamente un abstracto):
public class app
{

public static void main(String[l args)

I
b bl = new b 0 ;

Este es el resultado del código:
C:\>java app ¡Hola desde Java!

Abandonar la sobrescritura con final
El programador novato dice, "¡Ese maldito Johnson!" "¿Qué ocurre?", le pregunta. "Ese Johnson sobrescribió el método dibujar de mi clase painter y lo lió todo", se queja PN. "No se preocupe, PN", le dice, "puede marcar ese método como final, y nadie puede sobrescribirlo". " iBien! ",dice PN. Anteriormente en este capítulo, vimos un ejemplo en el que la clase "pez" sobrescribía el método breathe de la clase "animal":
class animal
{

void breathe
{

()

System.out.println("Respirar . . . ") ;

1
1 class pez extends animal
{

public void breatheo
{

System.out.println("Burbujear . . . ") ;

1 1

Si por alguna razón no se quiere permitir la sobrescritura del método breathe, se le puede declarar final, como sigue:
class animal

I
final void breathe0
{

System.out.println("Recpirar

. . . ") ;

1 1
class pez extends animal
{

public void breathe ( )
{

System.out .println("Burbujear. . . "

);

1
1

Ahora, supongamos que se intenta usar estas clases en algún código:
public class app
(

public static void main(String[] args)
{

System.out.println("Crear un animal...");

animal a = new animalo; a.breathe(); System.out.println();
System.out.println('Crear un pez...");

pez f = new pez(); f.breathe ( ) ;

1 1

Java avisará de que no se puede sobrescribir breathe, de la siguiente forma?
C:\>javac app.java -deprecation app.java:ll: The method void breatheo declared in class pez cannot 7 override the final method of the same signature declared in class animal. Final methods cannot be overridden. public void breathe ( )
A

1 error

Abandonar la herencia con final
Se puede prevenir la creación de subclases de una clase declarando toda la clase comofinal, como se ve a continuación:
final class animal
{

-7

public void breathe ( )
(

System.out.println("Respirar
}
}

. . . ") ;

class pez extends animal
(

public void breatheo
( }

System.out.println("Burbujear . . . ") ;

1
public class app
{

public static void main(StringC1 args)

{

System.out.println("Crear un animal..."); animal a = new animal ( 1 ;

a.breathe í )

;

System.out.println();
System.out.println("Crear un pez..."); pez f = new pez ( ) :

f.breathe í )
1 1

;

Esto es lo que ocurre cuando se intenta ejecutar este código:
app.java:g: Can't subclass final classes: class animal class pez extends animal
A

1 error

Crear constantes con final
En los dos puntos anteriores, se mostró dos formas de usar final: para prevenir que un método sea sobrescrito y para crear subclases de una clase. En Java, hay otro uso definal: se puede usar para declarar constantes. Este es un ejemplo en el que se convierte una variable en constante con final y después se le intenta asignar un valor:
public class app
{

public static void main(String[] args) I final int a = 5 ;

Esto es lo que el compilador de Java diría:
C:\> javac app.java -deprecation app.java:7: Can't assign a value to a final variable: a a = 6;
A

1 error

Relación es-a frente a tiene-a
El zar de la Programación Exacta llega y dice, "En C++, en la herencia se pueden tener relaciones es-a y tiene-a". "También en Java", le dice.

Se pueden ver los términos es-a y tiene-a al trabajar con la herencia1 porque especifican dos de las formas en que las clases pueden relacionarse. La herencia estándar es en la que generalmente se piensa en términos de una relación es-a, como en el ejemplo siguiente. En este caso, la clase a extiende la clase b, por lo que se puede decir que la clase a es-a b:
class a extends b

I
a 0
{

print 1
}

();

class b
{

void p r i n t o
(

System.out.println("Esto viene de la clase b...");

1
1
public class app
{

public static void main(String[] args)

I
a obj = new a ( ) ;

1 1

Cuando se llama al método print de a, realmente se está llamando a 7 método print de a heredado de b, y es este método quien hace la visualización:
C:\>java app Esto viene de la clase b...

Por otro lado, en una relación tiene-a, un objeto incluye una referencia 7 otro, como en este caso, en el que los objetos de la clase a incluirán un objeto interno de la clase b:
class a
(

b bl:

a 0
(

bl = new b 0 ; bl .print ( ) ;
}
}

class b

{

void print ( 1
{

System.out.println("Esto viene de la clase b...");

1
}

public class app
{

public static void main(String[] args) t a obj = new a();

1
}

Ahora, el método print de la clase b está accesible desde el objeto b l del objeto de la clase a:
C:\>java app .. Esto viene de la clase b.

-

~a'clase Object de Java
"Lo que quiero", dice el programador novato, "es escribir una clase sencilla, sin herencia ni nada y..." "Demasiado tarde", le dice. "En Java, todas las clases son subclases de una clase maestra, java.lang.Object, por lo que en todo está involucrada la herencia". En Java, toda clase se deriva automáticamente de la clase java. lang. Object, y hay ciertas ventajas de saber esto, ya que significa que todos los objetos ya han heredado algunos métodos que están preparados para usarlos. Los métodos de la clase Object aparecen en la tabla 5.2. Este es un ejemplo en el que se usa el método getClass para determinar la clase de una referencia a un objeto en una variable de superclase; esto es útil porque una variable de superclase puede gestionar referencias a objetos de cualquiera de sus subclases. Empezamos con una superclase llamada a y tres subclases: b, c y d. El métodoprintde cada una de estas clases visualiza el nombre de la clase. Este es el código:
class a

I
public void print
{ ()

System.out.println("Aquí está a...");

1 1

Tabla 5.2. Los métodos de la clase Obiect de Java.

protected Object clone()

Proporciona una copia del objeto. El recolector de basura lo llama en un objeto, cuando la coleccióngarbagese va a deshacer del objeto. Proporciona la clase de un objeto en tiempo de ejecución. Proporciona un valorhashcode para el objeto. Activa un hilo (thread) sencillo que está esperando en este objeto. Activa todos los hilos (threads) que están esperando en este objeto. Proporciona una representación en cadena del objeto. Hace que el hilo (thread) actual espere hasta que otro invoque el métodonotifyo el notifyAl1. Hace que el hilo (thread) actual espere hasta que otro invoque el métodonotify o el notifyAll o pase una cierta cantidad de tiempo. Hace que el hilo (thread) actual espere hasta que otro invoque el métodonotify o el notifyAll para este objeto, algún otro hilo interrumpa a éste o pase una cierta cantidad de tiempo.

boolean equals(0bject obj) Indica si otro objeto es igual a éste. Protected void finalize()

Class getClass() int hashCode() void notify() void notifyAll() String toString() void wait() void wait(1ong timeout)

void wait(1ong timeout, int nanos)

class b extends a
{

public void print
(

()

System.out.println("Aquí está b...");

1
1
class c extends a
{

public void print

()

I
Systern.out.println("Aquí está c...");

1

class d extends a
{

public void print0
{

Systern.out.println("Aquíestá d...");

Lo siguiente, es crear una instancia de cada clase y una variable de la clase a llamada are8
public class app
{

public static void mainiStringI] args)
{

a b c d a

al = new bl = new cl = new dl = new aref;

a0; b 0; c0; do;

Ahora, se puede determinar la clase del objeto en aref, no importa cuál sea la subclase:
public class app
{

public static void main(String[] args)

I
a b c d a al = new bl = new cl = new dl = new aref;

a(); b0; c(); do;

aref = al: System.out.println("Ahora, la clasedearefes " + aref.getClass0); Aref. print ( ); aref = bl: System.out.println("Ahora. Aref .print ( );

laclasedearef es " + aref.getClass0);

aref = cl; System.out.println("Ahora, la clase de aref e s " + aref.getClasS0); Aref. print ( ): aref = dl: System.out.println("Ahora, laclase dearefes " + aref.getClass()); Aref. print ( ) :

Este es el resultado:
C:\>java app Ahora, la clase Aquí está a.. . Ahora, la clase Aquí está b.. . Ahora, la clase Aquí está c.. . Ahora, la clase Aquí está d... de are£ es a de are£ es b de are£ es c de are£ es d

Como se puede observar, los métodos construidos en cada objeto, como" getclass, pueden ser muy útiles.

Usar interfaces para herencia múltiple
"Hmm", dice el programador novato, "tengo una clase llamada "animal" una clase totalmente separada llamada "mineral" y quiero heredar de ambas clases al mismo tiempo para crear algo totalmente nuevo". "Lo siento, " le dice, "Java no soporta la herencia múltiple directamente, tendrá que hacer que una de esas clases sea una interfaz". -" En otros lenguajes, como C++, una clase puede heredar de múltinl~c clases de una vez, pero esta técnica no funciona en Java directamentt decir, sólo se puede usar, de una vez, la palabra clave extends con una cl Por lo tanto, no se puede hacer esto:
class a extends b, c
{

/ / ; N o funcionará!

Sin embargo, hay dos formas de implementar la herencia múltiple en ~ a v a ; ~ La primera es usar herencia sencilla por etapas (funcionará para las clases de las que se quiere heredar), como sigue:
class c

I

class b extends c
(

class a extends b

I

La otra manera es usar interfaces. Las interfaces empezarán a ser importantes en el siguiente capítulo, por lo tanto, aquí sólo haremos una introducción. Una interfaz especifica la forma de sus métodos pero no da ningún detalle de su implementación; por lo que se puede pensar en ella como la declaración de una clase. Como veremos más tarde en el libro, se pueden crear interfaces con la palabra clave interface:
interface c

I

interface b

I

Ahora, se pueden usar estas dos interfaces con la palabra clave implements:
class a implements b, c

I

Dado que las interfaces declaran pero no definen métodos, es labor de cada uno implementar los métodos de las interfaces. Por ejemplo, en la applet que se mostró al principio del capítulo, se implementó la interfaz de Java ActionListener para gestionar los clics de los botones (se verán todos los

detalles de las applets en el siguiente capítulo). Esa interfaz declara un método, actiopnerformed, que se define como sigue:
import java.applet.Applet; import java.awt.*; import java.awt.event.*;
public class clicker extends Applet implements ActionListener

C

TextField textl; Button buttonl; public void init ( ) I textl = new TextField(20); add(text1); buttonl = new Button("iHacer clic aquí!"); add(button1) ; buttonl.add~ctionListener(this); 1
public void action~erformed(ActionEvent event)C String msg = new string("Bienvenid0 a Javam);

Si no se define el método actionperforrned, el cornpilador de Java dará 3 mensaje como este:
C: \>javac clicker.java -deprecation

clicker.java:5: class clicker rnust be declared abstract. It does n o n de£ine void actionPerformed(java.awt.event.ActionEvent) from interface java.awt.event.ActionListener. public class clicker extends Applet implements ActionListener {
A

1 error
9

Se pueden implementar tantas interfaces como se quiera, como en este ejemplo, en el que se implementa la interfaz ActionListener para los clics de los botones y las interfaces MouseListener y MouseMotionListener para trabajar con el ratón:
import import import import java.awt.Graphics; java.awt.* ; java.awt.event.*; java.applet.Applet;

public class dauber extends Applet implements ~ctionListener, MouseListener, MouseMotionListener { Button buttonDraw, buttonline, buttonoval, buttonRect,

point ptsll = new Point[10001; point ptAnchor, ptDrawTo, ptOldAnchor, ptOldDrawTo; int ptindex = 0;

- -

-

ar clases internas
"De acuerdo", dice el programador novato, "ahora soy un experto. ¿Hay algo más sobre clases que no sepa?" Usted sonríe y dice, "Bastante. Por ejemplo, ¿qué sabe de las clases internas?" "¿Qué clases?", pregunta PN. Al empezar en 1.1, se podían anidar definiciones de clases unas dentro de otras. Las clases anidadas pueden ser estáticas o no estáticas; sin embargo, las clases estáticas no pueden hacer referencia a los miembros de las clases que tiene en su interior directamente, sino que deben instanciar y usar un objeto en su lugar, por lo que con frecuencia no se usan. Las clases internas, por otro lado, son clases anidadas no estáticas, y son bastante más populares por ser útiles en la gestión de eventos, como veremos en el siguiente capítulo. Esto es un ejemplo de clases internas; en esta clase, la clase b está definida en el interior de la clase a y se instancia un objeto de la clase b en el constructor de la clase a:
class a
(

b obj;
a 0

I
obj = new b 0 ; obj .print ( );

1
class b C public void printo
(

System.out.println("En
1 1

el interior de b . " ; ..)

1
public class app
(

public static void main(String[l args)
(

a obj = new a();

1
1

Cuando se ejecuta este código, se instancia un objeto de la clase a, que instancia un objeto interno de la clase b y llama al métodoprint de ese objeto. Este es el resultado:
C:\>java app En el interior de b...
7

Más allá de las clases internas, como se ha visto en este ejemplo, se pueden tener clases internas anónimas (sin nombre) (ver el siguiente punto para más detalles).

Crear clases internas anónimas
Un forma corta que es útil para trabajar con la gestión de eventos, es usa? clases internas anónimas. Las vamos a introducir aquí y las usaremos en el siguiente capítulo. Una clase interna anónima es aquella que no tiene nombre y se crea usando la siguiente sintaxis:
new SuperType ( cons tructor pararneters)
(

//métodos y datos

1

Aquí, SuperType es el nombre de una clase o interfaz de la que se estáfl creando subclases (se debe especificar un tipo de superclase cuando se crean clases internas anónimas), y se puede definir los métodos y los datos de las clases internas anónimas en un bloque de código. Veamos un ejemplo. En este caso, crearemos una clase interna anónima e? el interior de una nueva clase, clase a. Esta clase interna anónima subclasificará otra clase, clase b y definirá un método llamado print, al que se llamará inmediatamente:
class a
{

aí)
(

(new bí) (public void print ( ) (System.out.println("iHola desde Java!");)]) . p r i n t o ;

1 1

class bI}

Lo único que queda es crear un objeto de la clase a y llamar al constructor de esa clase:
public class app
(

public static void main(String[] args)
{

a obj = new a ( ) ;

1 1

Este es el resultado del código:
C:\>java app ¡Hola desde Java!

En el siguiente capítulo, aprenderemos más sobre las clases internas anónimas.

aplicaciones y gestion de eventos
Hemos trabajado mucho con la sintaxis de Java para llegar a este punto, que es uno de los capítulos principales. Aquí empezaremos a trabajar con los programas de gráficos, las applets y las aplicaciones. Este capítulo introduce Java Abstract Windowing Toolkit (AWT), la forma original de Java para trabajar con gráficos. Ahora, AWT está complementado con el paquete Swing, que veremos dentro d e unos cuantos capítulos. AWT proporciona la base para trabajar con gráficos en Java e incluso el paquete Swing está basado en él. En este capítulo, trabajaremos con AWT, creando applets y ventanas de aplicación. Antes de empezar, situaremos AWT en la historia. AWT fue desarrollado muy rápidamente para la primera release de Java, de hecho, en sólo seis semanas. Los desarrolladores del AWT original usaron una ventana para cada uno de sus componentes, es decir, para cada botón, cuadros de texto, casilla de activación, etc., y por lo tanto, tenían su propia ventana cuando al sistema operativo le interesaba. Esto producía un consumo considerable d e los recursos del sistema cuando los programas llegaban a ser grandes. Recientemente, Sun introdujo el paquete Swing, en el que los componentes se visualizan usando métodos gráficos de laapplet o aplicación que los contiene, ellos no tienen sus propias ventanas del sistema operativo. Los componentes AWT se llaman componentes pesos pesados debido al uso

significativo que hacen de los recursos del sistema y los componentes Swing se llaman componentes peso ligero, ya que no necesitan sus propias ventanas. ¿Qué significa esto? Está claro que para Sun, Swing es el futuro. Hay más componentes Swing que AWT, y de hecho, hay un componente Swing para cada componente AWT. En el futuro, probablemente, Sun no ampliará el conjunto de componentes AWT mucho más, mientras que sí se espera que Swing crezca. Por otro lado, Swing, en sí mismo, está basado en AWT; las ventanas que Swing utiliza para visualizar sus componentes, es decir, ventanas, marcos de ventanas, applets y diálogos, están todos ellos basados en cqntenedores AWT. AWT no va a desaparecer y para trabajar con Swing, se necesita AWT. Por esa razón, y porque gran parte del desarrollo está hecho con AWT, y más que habrá en el futuro, dedicaremos éste y los siguientes capítulos a AWT. Empezaremos con una visión de AWT en sí mismo.

Abstract WindowingToolkit
No es una exageración decir que la aparición de Abstract Windowing Toolkit fue obligada tras la popularidad de Java. Se puede crear y visualizar botones, etiquetas, mentís, cuadros de lista desplegables, cuadros de texto y otros controles de la interfaz de usuario que se esperan utilizar en la programación basada en ventanas utilizando AWT. Esta es una lista de las clases de AWT más populares: Applet: Crea una applet. Button: Crea un botón. Canvas: Crea un área de trabajo en el que se puede dibujar. Checkbox: Crea una casilla de activación. Choice: Crea un control de opción. Label: Crea una etiqueta. Menu: Crea un menú. ComboBox: Crea un cuadro de lista desplegable. List: Crea un cuadro de lista. Frame: Crea un marco para las ventanas de aplicación. Dialog: Crea un cuadro de diálogo. Panel: Crea un área de trabajo que puede tener otros controles.

PopupMenu: Crea un menú emergente. RadioButton: Crea un botón de opción. ScrollBar: Crea una barra de desplazamiento. ScrollPane: Crea un cuadro de desplazamiento. TextArea: Crea un área de texto de dos dimensiones. TextField: Crea un cuadro de texto de una dimensión (en otros lenguajes se llama TextBox). TextPane: Crea un área de texto. Window: Crea una ventana.

La clase Applet de AWT es aquella en la que están basadas las applets AWT. Primero veremos esta clase.

¿Qué es exactamente una applet AWT? Una applet es un fichero de clase que se escribe específicamente para visualizar gráficos en la red Internet. Las applets se incluyen en las páginas Web utilizando la etiqueta HTML <APPLET>. Cuando se ejecutan en una página Web, las applets de Java se descargan automáticamente y el browser las ejecuta, visualizándose en el espacio de la página que se ha reservado para ellas. Pueden hacer de todo, desde trabajar con gráficos hasta visualizar animaciones, gestionar controles (como los que veremos funcionar en este capítulo), cuadros de texto y botones. El uso de las applets hace que las páginas Web sean activas, no pasivas, que es su principal atracción. Cuando se trabaja con AWT, el proceso es como sigue: se crea una applet nueva, basándola en la clase java.applet.App1et que, a su vez, está basada en la clase Component de AWT. He aquí un ejemplo que hemos visto antes y que haremos de nuevo en este capítulo. Este ejemplo visualiza el texto "¡Hola desde Java!" en una página Web:
import java.applet.App1et; import java . awt . * ; public class applet extends Applet
{

public void paint(Graphics g )
{

g.drawString("iHola desde Java!", 60, 100);

La applet se compila en un fichero de bytecode con extensión ".class". Una vez que se tiene este fichero, se sube a un proveedor de servicios de la red Internet (ISP). A una applet se le puede dar la misma protección que se daría a una página Web, asegurándose de que cualquiera pueda leer el fichero de la applet con extensión ".class"(por ejemplo, en Unix, se debería dar a laappletel permiso 644, que permite a todo el mundo leer el fichero).

rmato o( rtario de

La nueva applet se puede insertar en una página Web con la etiqueta cAPPLET>, indicando el nombre del fichero con extensión ".classW como así decirle al browser cuánto espacio (en pixels) requiere la applet. Esto es un ejemplo:

<CENTER> <APPLET CODE = "newApplet.classn WIQTH = 300 HEIGHT = 200

En este caso, hemos establecido un espacio centrado de 300 x 200 pixels en una página Web que visualiza la applet, y decimos al browser que descargue el fichero newApplet.class y lo ejecute. En este capítulo, se incluirán 10s detalles de la etiqueta cAPPLET>. Cuando el browser abra esta página, se visualizará la applet.

f. En este capítulo se verá. Este es un ejemplo que se verá más adelante en este capítulo.*.exit(O). 60. esta aplicación visualiza "¡Hola desde Java!" en una ventana: import java. class AppFrame extends Frame { public void paint(Graphics g) I g.*.1)) . que crea una ventana con un marco que visualiza botones y un título.awt.awt. 1 1 public class app { public static void main(String [ l args) 1 AppFrame f = new AppFrameO..de rowser t Java : lentos 'UVO en Aplicaciones Las ventanas de aplicación AWT están basadas en la clase Frame de AWT. 100). . con más detalle.drawString("iHola desde Java!".event. la creación de las ventanas de aplicación. import java. Al igual que la applet anterior.addWindowListener(new WindowAdapterO { public void windowClosing(WindowEvent e) {System.

dice el programador novato. La clase Component incluye un gran número de métodos. "estoy preparado para trabajar con Abstract Windowing Toolkit. Esta es una tabla larga. En este capítulo aparecerán todos los detalles de estos controles. como es escribir texto en un cuadro de texto. java. aplicaciones y gestión de eventos. lo que inicia alguna acción en el programa. Component. Usar Abstract WindowingToolkit 7 "De acuerdo". Java lo considera un evento.awt. Tabla 6. Para empezar a trabajar con eventos. Component. Gestionaremos eventos en el resto del libro y echaremos un vistazo al funcionamiento de la gestión de eventos en este capítulo.awt. "Cojamos un café y revisémoslo".Button. Todos ellos se han incluido en la tabla 6.Uno de los aspectos más importantes de la creación de applets y aplicaciones es permitir al usuario interactuar con el programa por medio de los eventos. que se vio en el capítulo anterior. por ejemplo). lang. pero es bueno tenerla y regresar a ella más tarde como referencia.1. Para ver cómo funciona la gestión de eventos en Java. 1 boolean action(Event evento. en la que se-' basan todos los componentes visuales de AWT. Métodos de la clase Cornponent de AWT. La clase java. De hecho. El usuario puede utilizar el ratón para hacer clic sobre botones. Ahora que ya se tiene una visión general de las applets. es quizás el evento más básico que Java soporta. cerrar una ventana. se deriva directamente de java. (hacer clic sobre un botón. se deriva directamente de la clase java. el clic sobre los botones. Component. . en este capítulo se crearán programas que soportan botones y cuadros de texto.1 como referencia. La clase más básica de AWT es la clase java. ¿Por dónde empezamos?" "Por la clase Component". Object. le dice. Por ejemplo.awt. muchos de ellos se verán en este y en los siguientes capítulos. Se debería registrar el componente conActionListener. introduciremos dos controles básicos en este capítulo: botones y cuadros de texto. Object objeto) Obsoleto. ya es hora de entrar en detalles con la siguiente sección. la clase Button. awt. seleccionar un elemento de una lista o usar el ratón. Cuando el usuario ejecuta alguna acción.

listener) Rectangle bounds() int checklmage(1mage image. Añade KeyListener para recibir eventos de clave. Obtiene el estado de la representación en pantalla de la imagen. int y) boolean contains(Point p) Obsoleto. Sustituido por getBounds(). void addMouseListener(MouseListener1) Añade el MouseListenerpara recibir eventos de ratón. voidaddComponentListener(ComponentListener 1) void addFocusListener(FocusListener 1) Añade el FocusListener para recibir eventos de foco. . voidaddMouseMotionListener(MouseMotionListener 1) void addNotify() Añade el MouseMotionListener para recibir los eventos de rnovimiento del ratón. Añade un componente visualizable para conectarlo a un recurso de pantalla nativo. PropertyChangeListener tener. Comprueba si este componente contiene el punto indicado. void addlnputMethodListener(inputMehtodListener 1) void addKeyListener(KeyListener 1) Añade el inputMethodListener para recibir los eventos del rnétodo de entrada. voidaddPropertyChangeListener(String Añade un PropertyChangeLispropertyName. InmageObserver observer) protected AWTEvent coalesceEvents (A WTEvent evento-existente. Añade el ComponentListener para recibir los eventos del componente. AWTEvent nuevo-evento) boolean contains(int x.voidadd(PopupMenurnenu-emergente) Añade al componente el menú emergente indicado. Fusiona un evento para ser enviado con otro evento. Comprueba si este componente contiene el punto indicado.

Sustituido porsetEnabled(boo1ean). Object valor-nuevo) float getAlignmentX() float getAlignmentY() Color getBackground() Rectangle getBounds() Fija el soporte para reportar los cambios de las propiedades encerradas. Sustituido por dispatchEvent(AWTEvent e).componente en un objeto rectángulo. protected void fire PropertyChange (String propertyName. Crea una imagen offscreen para usarla como doble buffer. Despacha un evento a este componente o a uno de los subcomponentes. Deshabilita los eventos definidos por el evento indicado como parámetro. Hace que el gestor de esquemas ponga este componente. 1 Obsoleto. Sustituido porsetEnabled(boo1ean). void doLayout() void enable() void enable(boo1ean b) protected void enableEvents(1ong eventos-a-habilitar) voidenablelnputMethods(booleanenable) Habilita o deshabilita el soporte del método de entrada. Establece los límites de e-. I . Habilita los eventos definidos por el evento indicado para enviarlo a este componente. Object v a l o r antiguo.lmage crea telmage(1mageProducer productor) lmage createlmage(int anchu ra. Sustituido porsetEnabled(boo1ean). Obsoleto. int altura) void deliverEvent(Event e) void disable() protected void disableEvents(1ong eventos-a-deshabilitar) void dispatchEvent(A WTEvent e) Crea una imagen desde el productor de imagen indicado. Alineación a lo largo del eje x. Obsoleto. Obsoleto. Alineación a lo largo del eje y. Obtiene el color del fondo este componente.

Obtiene el cursor puesto en el componente. y) y obtiene el componente contenido. Componente getComponentAt(Pointp) Obtiene el componente o subcomponente que contieneel punto indicado. Obtiene la instancia de ColorModel usándolo para visualizar el componente. ComponentOrientation getcomponent OrientationO DropTarget ge tDrop Target() Fon t ge tFont() Obtiene el DropTargetconectado a este componente. ColorModelgetColorModel() Component getComponentAt (int x. FontMetrics getFontMetrics(F0nt fuente) Obtiene la métrica de la fuente indicada.Rectangle getBounds(Rectang1e rv) Almacena los límites de este componente en rv y devuelve rv. Color getForegorund0 Graphics getGraphics0 Obtiene el color de primer plano de este componente. int y) Determina si el componente o uno de sus subcomponentes inmediatos contiene la localización (x. Devuelve laaltura actual de este componente. Crea un contexto gráfico para este componente. Obtiene el método de entrada solicitado. InputContext getlnputContext() Obtiene el contexto de entrada usado por este componente. InputMethodRequestsgetlnputMethodRequests() . Obtiene la fuente de este componente. Establece la orientación sensible al lenguaje para ordenar los elementos o el texto dentro de este componente.

peer. Toolkit getToolkit() Object getTreeLock() int get Width() . Obtiene el objeto locking para el árbol de componente AWT.Obtiene el locale de este componente. Obtiene el tamaño de este componente de un objetoDimension. especificandola esquina superior izquierda del componente. Almacena el origen x. ) dimension getPreferredSize() Dimension getSize() Dimension getSize(Dimension rv) Obtiene el tamaño preferido de este componente. Obtiene el kit de herramientas de este componente. Obtiene la anchura actual de este componente. y de este componente en rv y devuelve rv. Obtiene la localización de este componente en forma de punto.awt. Almacena el ancho y el alto de este componente en rv y devuelve rv. Point getLocale() Obtiene la ubicación de este componente en la forma de un punto especificandolaesquina superior izquierda del componente. Obtiene el tamaño máximo de este componente. Obtiene el nombre del componente. Sustituido porboolean isDisplayable ( .ComponentPeergetPeer() Obsoleto. Point getLocation(Poin t rv) Point getLocationOnScreen() Dimension getMaximumSize() Dimension getMinimumSize() String getName() Container getParent() java. Obtiene el tamaño mínimo de este componente. Obtiene el padre de este componente.

int getX() int getY() boolean gotFocus(Event evento. Sustituido porprocessFocusEvent(FocusEvent). SustituidoporprocessEvent(A WTEvent) . int). int w. Repinta el componente cuando cambia la imagen. Obsoleto. int x. Obtiene la coordenada actual y del componente original. int flags. Obsoleto. Obsoleto. lndica si este componente está habilitado. boolean isEnabled() boolean isFocustra versable() boolean isLightweight() boolean isOpaque() boolean isshowing() . Determina si el componente se puede visualizar. lndica si el componente es peso ligero. lnvalida el componente. falso por defecto. int h) boolean inside(int x. Sustituido porcontains (int. Verdadero si este componente se pinta en una imagenoffscreen que se copia en la pantalla más tarde. lndica si el componente puede ser recorrido usandoTab o Shift+ Tab. Determina si este componente es visible en pantalla. Verdadero si este componente tiene el foco del teclado. int y. Verdadero si este componente es completamente opaco. Reemplazado porsetVisible(boo1ean). Object objeto) boolean handleEvent(Eventevent0) boolean hasFocus() void hide() boolean imageUpdate(image img. Obsoleto. int y) void invalidate() boolean isDisplayable() boolean isDoubleBuffered() Obtiene la coordenada actual x del componente original.

Void list(PrintWriter out) lmprime un listado en el printWriter indicado. int key) Void layout() Void lis t() Void list(PrintStream out) Void list(PrintStream out. Determina si el componente debería ser visible cuando el padre lo es. Component locate(int x. Void Iist(PrintWriter out. Boolean lostFocus(Eventevento. Reemplazado porproobjeto) cessFocusEvent(FocusEvent). Reemplazado porprocessKeyEvent(KeyEvent). Reemplazado porprocessKeyEvent(KeyEvent). int x.boolean is Valid() boolean isVisible() Determina si el componente es válido. lmprime un listado de este componente en el flujo de salida indicado. int indentación) lmprime una lista. Reemplazado porprocessMouseEvent(MouseEvent). int y) Obsoleto. Reemplazado porgetMinimumSize(). int indentación) lmprime una lista. Obsoleto. Dimension minimumSize() Boolean mouseDown(Eventevento. . int). Obsoleto. en el PrintWriterindicado. Obsoleto. Reemplazado porgetComponentAt(int. int y) Point location() Obsoleto. en el flujo de salida indicado. empezando en la indentación indicada. lmprime un listado de este componente en el sistema de salida. Reemplazado porgetLocation(). Reemplazado por doLayout(). empezando en la indentación indicada. Boolean keyDown(Event evt. Obsoleto. Obsoleto. Object Obsoleto. int key) Boolean keyUp(Event evt.

Obsoleto. en la posición indicada. Obtiene una cadena que representa el estado del componente. Reemplazado por transferFocus(). int). Imprime el componente y todos sus subcomponentes. Obsoleto. Pinta el componente. in ty) Boolean mouseUp(Event evento. Pinta el componente y todos los subcomponentes. Reemplazado porprocessMouseEvent(MouseEvent). int x. Obsoleto. int x. Reemplazado pordispatchEvent(A WTEvent). int anchura. int altura. Reemplazado porgetPre ferredsizef). int y) Boolean mouseMove(Eventevento. Procesa los eventos del componente que ocurren en este com- . Prepara una imagen para enviar a ese componente. lmprime el componente. Obsoleto.Boolean mouseDrag(Event evento. lmageobserver observador) Void print(Graphics g) Void printAII(Graphics g) Protected void processCornponente-) Event(CornponentEvent e Obsoleto. int x. Obsoleto. int y) Boolean mouseEnter(Eventevento. int y) Void rnove(int x. int y) Boolean mouseExit(Event evento. Reemplazado porsetLocation(int. int S. Prepara una imagen para enviar a ese componente. Obsoleto. int y) Void nextFocus() Void paint(Graphics g) Void paintAII(Graphics g) Protected String paramString() Boolean postEvent(Event e) Dimensionpreferredsizef) Boolean preparelmage(1mage irnage. Obsoleto. i nt x. Reemplazado por pro essMouseMotionEvent(MouseEvent). Obsoleto. Reemplazado porprocessMouseEvent(MouseEvent). Reemplazado porprocessMouseEvent(MouseEvent). ImageObserver observer) Boolean preparelmage(1rnage imagen. Reemplazado porprocessMouseMotionEvent(Mouse Event).

Procesa los eventos de foco que ocurran en este componente enviándolos a cualquiera de los objetosFocusListenerregistrados. Procesa los eventos del método de entrada que ocurran en este componente enviándolos a cualquiera de los objetos InputMethodListener registrados. Procesa los eventos clave que ocurran en este componente enviándolos a cualquiera de los objetos KeyListenerregistrados. Protected void processlnputMethodEvent(1nputMethodEvente) Protected void processKeyEven1 (KeyEvent e) Protected void processMouseEvent (MouseEvent e) Protected void processMouseMotionEvent(M0useEvent e) Void remove(MenuComponent popup) Void removeComponentListener (ComponentListener 1 ) Void removeFocusListener(FocusListener 1 ) Void removelnputMethodListener (InputMethodListener 1 ) . Retira del componente el menú emergente indicado. Retira el componente listener indicado para que no reciba más eventos de componente. Protected void processEvent(A WTEvent e) Protected void processFocusEvent (FocusEvent e) Procesa los eventos que ocurran en este componente. Procesa los eventos de movimiento de ratón que ocurran en este componente enviándolos a cualquiera de los objetos MouseMotionListenerregistrados. Procesa los eventos de ratón que ocurran en este componente enviándolos a cualquiera de los objetosMouseListenerregistrados.ponente enviándolos a cualquiera de los ComponenteListeners registrados. Retira el método de entrada indicado para que no reciba más eventos del método Input. Retira el focus listener indicado para que no reciba más eventos de foco.

int. Obsoleto. int anchura. int y. int. int anchura. Repinta el componente. Retira el listener de movimiento de ratón indicado para que no reciba más eventos de ratón de este tipo. Repinta el componente. int y. Retira el listener de ratón indicado para que no reciba más eventos de ratón. Establece el color de fondo. int x. int altura) void resize(Dimension d) void resize(int anchura. PropertyChange Listener listener) void repaint() void repaint(int x. int). void removeMouseListerner(MouseListener 1) void removeMouseMotionListener (MouseMotionListener 1) void removeNotify() void removePropertyChangeListener (PropertyChangeListener listener) void removePropertyChangeListener (String propertyName. Repinta el rectángulo indicado dentro de tm. int y. Reemplazado por setBounds(int. int y. int altura) void repaint(1ong tm) void repaint(1ong tm. int altura) . Reemplazado porsetSize(Dimensi0n). destruyendo su recurso de visualización nativo. int altura) void requestFocus() void reshape(int x. Deshabilita la posibilidad de visualizar el componente. Obsoleto. int). Obsoleto.void removeKeyListener(KeyKistener 1) Retira la key listener indicada para que no reciba más eventos de este tipo. Mueve y redimensionael componente. int anchura. Repinta el rectángulo indicado. Retira un PropertyChangeListener. Retira un PropertyChangeListener para una propiedad dada. Solicita el foco de entrada. int altura) void setBackground(Color c) void setBounds(int x. Reemplazado porsetSize(int. int anchura.

void setComponentOr~entation(Componentorientation o) Establece la orientación sensible al idioma que se usará para ordenar los elementos o el texto. void setCursor(Cursor cursor) void setDrop Target(Drop Target dt) void setEnabled(boo1ean b) void setFont(Font f) void setForeground(Co1or c) void setLocale (Locale 1) void setLocation(int x. Fija el locale del componente. Reemplazado porsetVisible(boo1ean). Establece la imagen del cursor al cursor indicado.height. Asocia un DorpTarget con este componente. Reemplazado porgetSize(). Redirnensiona este componente para que tenga la anchura y la altura indicadas. Fija la fuente del componente. int y) void setLocation(Point p) void setName(String nombre) void setSize(Dimension d) void setSize(int anchura. dependiendo del valor del parárnetro . Redirnensiona este componente para que tenga la anchurad. Reemplazado porsetVicible(boo1ean). Fija el color de primer plano del componente. Fija el nombre del componente a la cadena indicada. Muestra o esconde este componente tal y como se especifica con el valor del parámetro b. int altura) void setVisible(boolean b) void show() void show(boo1ean b) Dimension size() . width y la altura d. Obsoleto. Obsoleto. Mueve este componente a una nueva localización. Habilita o deshabilita este componente. Obsoleto. Mueve este componente a una nueva localización.

Métodos de la clase Container. int indice) Añade el componente indicado al contenedor. Object constraints. en el índice. se basan en la clase Container. Añade el componente indicado al contenedor. Esta clase se deriva de la clase AWT Component y es la base de los contenedores AWT. Component add(String name. void addContainerListener(Contaíner Añade un container listenerpara obtener los eventoscontainerdel conteListener 1) nedor. Object constraints. . en la tabla 6. void addNotify() Permite visualizar el contenedor conectándolo a un recurso de pantalla nativo.String to Strjng() void transferFocus() void update(Graphics g) void validate() Obtiene una representación en cadena del componente. Transfiere el foco al siguiente componente. Com. int index) void add(Component comp. en el índice dado. Añade. Object constraints) void add(Component comp. Tabla 6. que pueden visualizar componentes AWT. Otra clase importante de AWT es la clase Container. Actualiza el componente. Añade el componente indicado al contenedoren una posición concreta. Dado que en la programación con AWT se utiliza con frecuencia la clase Container. el compocomp. int indice) nente indicado al contenedor. el componente indicado a este contenedor con las restricciones indicadas.2 aparecen listados sus métodos. Asegura que el componente tiene un esquema válido.2. que puede gestionar otros componentes. Component add(Component comp) Component add(Component comp.Añade un componente a este conteponent comp) nedor. Las applets y las ventanas de aplicación. como se ve en el siguiente apartado. protected void addlmpl(Component Añade.

int y) void deliverEvent(Event e) void doLayout() Component findComponentAt Obsoleto. Component getComponentAt(Pointp) Obtiene el componente que contiene el punto indicado. Obtiene el tamaño mínimo del contenedor. Obtiene el componente enésimo del contenedor. Hace que el contenedor coloque sus componentes. Obtiene el tamaño preferido del contenedor. Reemplazado por dispatchEvent(A WTEvent e). int y) Obtiene la alineación a lo largo del eje x. y. Obtiene todos los componentes del contenedor. float getAlignmentX0 floa t getAlignmentY() Component getComponent(int n) Component getComponentAt(int x. int ge tcomponentCount() Component[]getComponents() lnsets getlnsets() Obtiene el número de componer en este panel.int countComponentes() (int x. Determina las intercalaciones del contenedor. Obtiene el gestor de esquemas del contenedor. LayoutManagergetLayout() Dimension getMaximumSize() Dimension getMinimumSize() Dimension getPreferredSize() . Obtiene la alineación a lo largo del eje y. que indican el tamaño del borde del mismo. Reemplazado porgetcomponentCount(). Localiza el componente hijo visible que contiene la posición indicada. Obtiene el tamaño máximo del contenedor. Obsoleto. Component findComponentAt(Pointp) Localiza el componente hijo visible que contiene el punto indicado. Localiza el componente que contiene la posición x.

Component locale(int x. en la salida indicada. Reemplazado por doLayouto. Reemplazado porgetcomponentA t(int. enviándolos a Containerlistener. Visualiza una lista. Pinta cada componente del contenedor. int). lnvalida el contenedor boolean isAncestorOf(Component c) Chequea si el componente está contenido en la jerarquía del contenedor. Procesa eventos de este contenedor. Retira del contenedor el componente indicado. Imprime un listado de este contenedor a la salida indicada. int indent) Obsoleto. empezando en la indentación indicada. Procesa los eventos del contenedor que ocurren en este. void /ayout() void list(PrintStream out. Visualiza el contenedor. Obtiene la cadena que representa el estado del contenedor. Obsoleto. Obsoleto.lnsets insets() void inva /idate() Obsoleto. Pinta el contenedor. Retira el componente del contenedor que está en el índice marcado. Reemplazado por getlnsets(). Reemplazado porgetpreferredSize0. int y) Dimension minimumSize() void paint(Graphics g) voidpaintComponents(Graphics g) protected String paramString() Dimension preferredSize() void print(Graphics g) void printComponents(Graphics g) protected voidprocessContainer Event(ContainerEvent e) protected void processEvent (A TEvent e) void remove(Component comp) void remove(int indice) . Obsoleto. Visualiza cada uno de los componentes del contenedor. Reemplazado porgetMinimumSize(). int indent) void list(PrintWriter out.

jcuál le gustaría?" "Hmm". Valida este contenedor y todos sus subcomponentes. Fija la imagen del cursor al cursor indicado. 1 I Hace que el contenedor no seavisible retirando su conexión a sus recursos de pantalla nativos.awt. "Ya estoy preparado para crea?"] una applet". void setCursor(Cursor cursor) void setFont(Font f) void setLayout(LayoutManager mgr) Fija el gestor de esquemas para este contenedor.Component 1java. que es en s í misma. dice el programador novato.Applet.applet. De forma recursiva.3.Container: java.awt. void upda te(Graphics g) void validate() protected void validateTree() Actualiza el contenedor. ~ ~ ~ l e t Para utilizarlos como referencia. "Cierto". una subclase de la clase java.awt.awt. dice PN. I Crear Applets "¡Por fin!". Retira el container listener indicado para que no reciba más eventos container de este contenedor.lang.Container 1 java. 7 .Pane1 I j a v a .void removeAll() void removeContainerListener (ContainerListener 1) void remove Notify() Retira todos los componentes de este contenedor. encontrará los métodos de la clase Applet en la tabla 6. Fija la fuente del contenedor. Usted basa sus applets en la clase java.0bject Ijava. desciende por el árbol del contenedor y recalcula el esquema para todos los subárboles marcados según los necesite (aquellos marcados como inválidos). le dice. "Ahora. a p p l e t .

Locale getLocale() String getParameter(String name) Obtiene el locale para la applet. Obtiene unaudioclipde la URLdada. . El contexto permite a la applet solicitar el entorno en el que se ejecuta. Obtiene información de esta applet Obtiene el objeto AudioClipespecificado por el argumento URL. Llamado por el browser o el visualizador de applets para permitir la inicialización de la applet Determina si esta appletestá activa.. String[][]getParameterlnfo() void init() boolean isActive() static AudioClip newAudioClip (URL url) void play(URL url) void play(URL url. Obtiene el valor del parámetro Ilamado en la etiqueta HTML. Reproduce el audio clipdada la URL y un especificador relativo a él. Obtiene el documento URL. Obtiene una imagen que puede ser pintada en la pantalla. void destroyo AppletContext getAppletContext() Se le llama cuando nos queremos deshacer de la applet. Determina el contexto de estaapplet. Obtiene la base URL. Obtiene el objeto AudioClip especificado por los argumentos URL y nombre. String name) void resize(Dimension d ) . String getAppletlnfo() AudioClip getAudioClip(URL url) AudioClip getAudioClip(URL url. String name) Obtiene una imagen que puede ser pintada en la pantalla. Solicita que esta applet sea redimensionada. Obtiene información de los parámetros de la applet. Stringnombre) URL getCodeBase() URL getDocumentBase() lmage getlmage(URL url) lmage getlmage(URL url. Reproduce el audio clip en la URL absoluta especificada.Tabla 6 3 Métodos d e la clase Applet.

Applet. Solicita que la cadena sea visualizada en la ventana de estado de la applet Llamado por el browsero visualizador de applet para decir a la applet que debería empezar la ejecución. int altura) void setSub(App1etStub stub) void showStatus(String msg) void start() Solicita que esta applet sea redimensionada.awt.applet. public class applet extends Applet { public void paint (Graphics g ) { . se puede situar el código para dibujar la applet. y en ese método. applet. se usará el método paint. que visualiza el texto "¡Hola desde Java!" en el fichero applet. se creará la applet.*. Aquí. Este objeto soporta un método llamado drawString. que se 1usará para dibujar una cadena de texto en la applet. se llama a su método paint. Establece el stub de esta applet. que 1 3 applet hereda de la clase Component. que se vio al principio del capítulo. Llamado por el browsero visualizador de applet para decir a la applet que debería parar la ejecución. La clase Graphics es una nl AWT.void resize(int anchura. void stop() Veamos un ejemplo. Al método paint se le pasa un objeto de la clase Graphim que se verá en los próximos capítulos.Applet.applet. como sigue: import java. Cuando se visualiza una applet.java. por lo que se importarán las clases AWT cuando se sobrescriba el método Applet paint por defecto: '. Esta es la base del trabajo gráficco en las applets. de la clasejava. "CP ~ I C L J ~ import java.í*C".Applet. Se empieza derivando una nueva clase. public class applet extends Applet I Para visualizar el mensaje en la applet. i q o r t java.applet.

se puede compilar app1et. (60. Las coordenadas de la applet están en pixels. directamente en esta área de trabajo.Applet. se puede crear una página Web usando la etiqueta <APPLET> para visualizar la applet. Ya es el momento de ver cómo funciona. También se verá cómo se hace esto en este capítulo.class". como botones y campos de texto.class. "he creado una applet y la he compilado obteniendo el fichero de extensión ". awt . dice el programador novato. Así es el formato de la etiqueta <APPLET>: <APPLET [CODEBASE = URL] CODE = nombre de fichero [ALT = Texto alternativo] [NAME = nombre de instancia] . Con javac. Observe que. A continuación. * . 100) en laapplet. 1 1 Este nuevo método paint dibuja directamente en el área de trabajo de la applet. también. Usar la etiqueta HTML <APPLET> "De acuerdo". se puede cargar a un ISP (o verlo en la propia máquina) y fijarle su protección (ver la introducción de este capítulo) para que se pueda leer. public class applet extends Applet { public void paint(Graphic8 g) { g. ¿Cómo lo veo realmente?" "Hay que usar la etiqueta HTML <APPLET>". por lo tanto. 100). Una vez que se ha creado un fichero con extensión ". Este es el código: import java.drawString("1Hola desde Javalm. 100) está a 60 pixels de la esquina izquierda de la applet y 100 pixels más abajo del final de la barra de título. y así se acaba de crear una applet.java para obtener java. se puede situar controles.Ahora se personaliza el método sobrescritopaint para que escriba el texto "¡Hola desde Java!" en la posición (60.class".applet. import java. 60. le responde.

WIDTH = pixels HEIGHT = pixels [ALIGN = alineación] [VSPACE = pixels] [HSPACE = pixels] > [<PARAM NAME = nombre VALUE = valor>] [<PARAM = NAME nombre VALUE = valor>] < /APPLET> Estos son los atributos de la etiqueta <APPLET>: CODEBASE: URL que especifica el directorio en el que se busca el código de la applet. BOTTOM (abajo). -7 Esta es una página Web. 1 NAME: Nombre de la applet en el browser Web. ALT: Texto que se va a visualizar si un browser soportaapplets pero no puede ejecutarse por alguna razón. WIDTH. Deben darse nombres a las applets si se quiere tener la posibilidad de buscar otras applets e interactuar con ellas. RIGHT (derecha).class . VSPACE: Espacio ubicado sobre y desde la applet.3 . PARAM NAME: Nombre del parámetro que se pasa a la applet. incluyendo la extensión ". HSPACE: Espacio ubicado a la derecha y a la izquierda de la applet. TEXTOP. TOP (arriba). ABSMZDDLE o ABSBOTTOM. que visualiza la applet creada en el apartado anterior (observe que sólo son obligatorios los atributos CODE. 7 -7 ALIGN: Especifica la alineación de la applet: LEFT (izquierda). y HEIGHT): . BASELINE. MIDDLE (medio). PARAM VALUE: Valor de un parámetro. CODE: Nombre del fichero de laapplet. applet. WIDTH: La anchura del espacio reservado para la applet. HEIGTH: La altura del espacio reservado para la applet.htrn1.

para ver la applet. El visualizador de applets siempre soporta la última versión de Java.En este caso. Una applet funcionando con Netscape Navigator. Abra la página Web como sigue: El resultado aparece en la figura 6. abierta con Netscape Navigator. por si el browser Web no lo hace.2. aparece en la figura 6. .class en el mismo directorio que applet. no se está especificando un código base. Esta página Web. y no quiere instalar el Java plug-in.1.htm1. Id Horne Search Net:cape Pmt Secunty Chnp hola desde Javal Figura 6. que viene con Java. También se puede utilizar el visualizador d e applets de Sun.1. Siempre se puede usar el visualizador de applets para probar sus applets. por lo tanto se sitúa applet.

2.. ¿Hay alguna forma de informar a los usuarios de que están perdiendo algo?" "Claro. le dice.hola desde Javal I Figura 6. así es como se avisaría a los usuarios de las cosas que se están perdiendo de su applet: <APPLET code = " a p p l e t . y es u n poco complicado". "Coja una silla y lo veremos". "Escribir una página Web con una etiqueta cAPPLET> para probar la salida de la misma. ese? texto será visualizado si el browser Web no soporta Java. "He estado escribiendo applets. Por ejemplo. dice el programador novato. ¿no algo más fácil?" "Claro". Una applet funcionando con el visualizador applets. por lo que si . Los desarrolladores de Sun se dieron cuenta de que algunas veces esg molesto tener que crear una página Web para probar una applet. Si se encierra este texto en el interior de una etiqueta <APPLET>. Gestionar browsers no Java "Uh-oh". "se puede introducir la etiqueta <APPLI directamente en el código fuente". no puedevermimaravillosaappletc/APPLET> Introducir etiquetas <APPLET> en el código El programador novato suspira." "Eso suena ligeramente no estándar". "¿Qué quiere decir?" le pregunta. "Y". "le dice. "no soporta Java. Algunos u s ~ a .~ rios están usando un browser ligeramente n o estándar llamado SuperWildcatl4b. le dice. "hay un problema. c l a s s " width = 1 0 0 h e i g h t = 100> 7 Lo s i e n t o . n o t i e n e J a v a y p o r l o t a n t o .. continúa el programador novato.

classW. se llama otra vez al método start.App1et.awt. como sigue: import java.event. le dice.drawString("iHola desde Java! " . se puede cambiar añadiendo algún tipo de código de inicialización en la applet en el método init". "Sin embargo.App1et. A este método se le llama. se puede situar una etiqueta <APPLET> directamente en el fichero de la applet con extensión "java" en un comentario. puede iniciar el se visualizador de applets con el fichero de extensión ".*.awt. destroy. import java.applet.*. start. stop. 1 1 Después de crear el fichero de extensión ". ¡dibuja mis applets en gris!" "Eso es lo que hacen por defecto muchos browsers Web". Hay un número importante de métodos de applets que se deberían conocer: init: Es el primer método a llamar. Esto es.awt. "Mi browser se ha vuelto graciosillo. . 100).applet. Aquí se inicia la applet. cada vez que una applet aparece de nuevo en la pantalla. import java.se usa el visualizador de applets. si el usuario se va a otra página y luego regresa. paint y update El programador novato regresa y dice.java" directamente: Usar los métodos init. import java.*. 60. public class applet extends Applet ( public void paintíGraphics g) ( g. sólo se le llama una vez. import java. start: Llamado después de init.

stop: Llamado cuando el browser se mueve a otra página. además. Ya se ha sobrescrito el métodopaint para dibujar una cadena de texto.' La versión por defecto rellena la applet con el color de fondo antes de volver a dibujarla. import java. Estaapplet.applet. aquí se sobrescribe el método init para cambiar el color de fondo de la applet a blanco.App1et. Este es el código: import java. destroy: Llamado cuando laapplet va a ser eliminada de la memoria. Se puede usar este método para parar la ejecución adicional de threads que su applet puede haber arrancado. lo que puede llevar a la fluctuación cuando se ejecuta animación. public class applet extends Applet { public void i n i t 0 public void start ( () } public void paint(Graphics g) { g. update: Llamado cuando se va a volver a dibujar una parte de la applet. en cuyo caso se sobrescribiría este método. proporciona un esqueleto de una implementación de los otros métodos previamente listados.awt. usando el método de applet setBackground y pasándole el campo white de la clase Color de Java. 100): . y se puede usar en los métodos del objeto para dibujar en la applet. 60. Este método pasa un objeto de la clase Graphics. paint: Llamado cuando se va a volver a dibujar la applet. T q Se pueden sobrescribir estos métodos para personalizarlos como se quiera.*.drawString("iHola desde Java!". Se puede ejecutar la limpieza en este momento.

En gráficos. hay que destacar a las applets. pero veremos antes algunos de los métodos de gráficos que usaremos aquí: paint: Llamado cuando se va a volver a dibujar la applet. La siguiente sección proporciona una visión general de la gestión de gráficos en las applets. . En este caso. dado un array de bytes.public void stop() ( 1 public void destroyo ( 1 1 El método init es muy útil. setBackground: Fija el color de fondo. drawlmage: Dibuja una imagen. se ha cambiado el color de fondo de gris (el color por defecto en muchos de los browsers) a blanco. setForeground: Fija el color de primer plano. dado un array de caracteres. drawlhars: Dibuja texto. drawoval: Dibuja un óvalo (incluyendo círculos). drawPolyLine: Dibuja una línea con múltiples segmentos. Dibujar gráficos en applets Aprenderá mucho más sobre el dibujo en applets en unos pocos capítulos. draw3Drect: Dibuja un rectángulo 3D. y normalmente se sobrescribe porque permite inicializar su applet. drawString: Dibuja una cadena de texto. drawArc: Dibuja un arco. drawRoundRect: Dibuja un rectángulo redondeado. repaint: Se llama a este método para forzar que la applet sea pintada. drawBytes: Dibuja texto. drawline: Dibuja una recta.

Se puede obtener elplug-in de Java en http:/ /java. usando el convertidor HTML de Sun.drawPolygon: Dibuja un polígono.sun.Se instala automáticamente al instalar JDK. que fuerza a que se llame al método paint. "tengo un problema.3. convertidor de HTML es un fichero Java El de extensión ". . Elplug-in Java le permite ejecutar las applets de la última versión de Java en Netscape Navigator y Microsot Internet Explorer implementando el entomo de ejecución de Java como un plug-in para Netscape y un control ActiveX para Internet Explorer. Usar el plug-in de Java del browser "Hey". ¿Qué puedo hacer?" "Hay una solución fácil". El convertidor HTML de Sun. con el que se pinta laapplet. se necesita convertir primero su HTML.3. le contesta. 5 ard (IE a Navigator) ior Wiiindows a solans 0n-j I Figura 6.com/products/plugin. "Use elplugin Java". Estoy usando los dos grandes browsers de Java. pero no soportan las últimas características de Java. Para usar las páginas Web con elplug-in. y el método repaint. dice el programador novato.sun. Se puede ver el convertidor de HTML en la figura 6.class" que se ejecuta en las páginas HTML para convertir la etiqueta <APPLET> de forma que pueda usarse por el plug-in.com/products/plugin. drawRect: Dibuja un rectángulo. que se puede obtener en http:/ /java. Dos métodos que particularmente hay que destacar son el método paint.

2/jinstall-12win32.48.Para convertir una página Web y usar el plug-in.2.class WIDTH = 200 HEIGHT = 200 > El nuevo fichero HTML usará el plug-in Java en lugar de la máquina virtual de Java del browser por defecto.2/plugininstall.2"> <COMMENT> iEMBED type="application/x-java-applet. El convertidor cambiará una etiqueta <APPLET> como en algo como esto: "CONVERTED-APPLET" -> CONVERTER VERSION 1.version=1.com/products/plugin/1.class > <!<!- <PARAM NAME="typen VALUE="application/x-java-applet.4 muestra la applet de demostración de Swing TicTacToe en http://192. ¿Qué le dirá? Se puede pasar parámetros a las applets en la etiqueta <APPLET>.9/products/ plugin/l. le dice. se selecciona un fichero HTML o ficheros en el convertidor HTML y se hace clic sobre el botón Convert.9.~ab#Version=l.2/demos/applets~icTa~Toe/e~amp1e.0.class WIDTH = 200 HEIGHT = 200 pluginspage="http://java.sun.0"> <PARAM NAME = CODE VALUE = adder. "No podemos recompilar la applet para cada uno y almacenar cada versión nueva en el sitio Web".html en Internet Explorer.2"java-CODE = adder. "Pero hay miles de clientes". lo que significa que .0 -> cOBJECT classid="clsid:8AD9C840-044E-llD1-B3E9-00805F499D93" wIDTH = 200 HEIGHT = 200 codebase="http://java. Por ejemplo. "¿Qué sugiere?". "Necesitamos personalizar el saludo de nuestra applet para cada cliente". la figura 6.sun. Leer parámetros en applets El gran jefe (GF) aparece mascando un cigarro y dice.2.html"><NOEMBED>~/COMMENT> < !- <APPLET CODE = adder.version=1. y el código applet puede leer los valores de esos parámetros. pregunta GF.com/products/ plugin/l.

para conseguir el valor de un parámetro. Este es un ejemplo en el que se pasa un parámetro llamado cadena a unaapplet.para personalizar la applet.class WIDTH=2 00 HEIGHT=200 > cPARAM NAME = string VALUE = "iHola desde Java!"> </APPLET> */ public class applet extends Applet { public void paint(Graphics g ) { . sólo necesita dar los diferentes parámetros en la etiqueta <APPLET>. import java. awt. /* <APPLET CODE=applet. Realmente. Figura 6. el valor de este parámetro es el texto que la applet debería visualizar. Así es el código: import java.applet.Applet. se usa el método getparameter de la clase Applet. El método gerParameter devolverá el valor del parámetro que fue establecido en la etiqueta <PARAM>. pasándole el nombre del parámetro como se especifica en la etiqueta <PARAM>. * .4 Utilizando el plug-in de Java.

"ahora se puede dibujar texto en una applet.*. "pero ¿qué hay de la consola de Java? ¿Y si uso Systern. hacer clic sobre la lengüeta Avanzadas. aunque normalmente hay que habilitarlas antes de usarlas. "de su browser". Los browsers Web. y se verá " i Hola desde Java!" en la ventana de la consola. de un browser a otro y de una versión a otra.drawString("iHoladesde Java! " . Esto es unaapplet que visualiza un mensaje y usa System. Pero. se puede abrir la consola de Java ejecutando el comando Java Console (Consola de Java) del menú Communicator. tienen también una consola Java. En Netscape Navigator. 60.out.println para visualizar en la consola: import java. public class applet extends Applet { public void paint(Graphics g) I g. La manera de habilitar la consola Java difiere.5 muestra el resultado de laapplet anterior tal y como aparece en la consola de Java de Znterner Explorer. import java. que emerge cuando se visualiza. > } Si se ejecuta esta applet con el visualizador de applets Sun. la applet se abrirá en una ventana separada. La figura 6. Systern.Usar las consolas de Java en los browsers "Todo este material de drawString está bien".out.println en una applet?" "Eso depende".Applet. desafortunadamente. Actualmente.~rintln(~~Hola desde Java!").out. le dice. con frecuencia. ¿y si quiero que el usuario pueda meter algo de texto?" . 100). dice el programador novato.awt. dice el programador novato. y seleccionar la casilla de activación Java Console Enabled (Consola de Java habilitada). Añadir controles a las applets: Campos de texto "De acuerdo".applet. en Internet Explorer se habilita ejecutando el comando Internet del menú Ver.

5. "se puede usar cualquier clase de controles de texto. pero también podremos usarlos aquí al hablar de la gestión de eventos. Un cuadro de texto visualiza una línea sencilla y permite al usuario editarlo. import java. formalmente. Los cuadros de texto están entre los controles más básicos que se pueden usar en AWT. . Figura 6. como los cuadros de texto". en el siguiente capítulo. Esto es un ejemplo de cuadro de texto en el que se crea uno de 20 caracteres en un método init de la applet (observe que se están importando las clases AWT para poder usar los cuadros de texto): import java. " le dice."Para eso.*. Veremos los cuadros de texto. public clase applet extends Applet ( public TextField textl. Usar la consola de Java de lnternet Explorer.applet. public void init0 I textl = new TextField(20) .App1et.awt.

Después de crear un nuevo control. El resultado de este código aparece en la figura 6. por lo tanto.6. introdu- . Otro control básico es el control de AWT Button. El usuario además puede editar este texto. add(text1). donde se puede ver el cuadro de texto con el mensaje que se ha puesto en él. Añadir un campo de texto a una applet. Echaremos un vistazo más profundo a los cuadros de texto en el siguiente capítulo. que decide donde se debería situar el control (se verán los detalles sobre los gestores de esquemas en el siguiente capítulo).setText(~~Hola desde Java!"). Ahora que el cuadro de texto se ha añadido a la applet. add(text1). > El método add añade el control al gestor de esquemas actual. 1 Figura 6. Usaremos los botones y los cuadros de texto para discutir la gestión de eventos. He aquí un ejemplo: public void init í ) { textl = new TextField(20) .6. te~tl. se le debe añadir a la applet para que se visualice. como sigue: public void init í ) { textl = new TextField(20). se puede situar el texto "iH01a desde Java!" en el cuadro de texto con el método setText.

por ejemplo. realmente. está en que ocurra algo cuando el usuario haga clic ' sobre el botón. se hace de la misma forma que se añade un cuadro de texto. public void init ( 1 ( textl = new TextField(20). que discutiremos en detalle en el siguiente capítulo. ¿Qué es lo siguiente?" "Botones". aprenderemos más detalles sobre los botones y los cuadros de texto. se puede tener un botón llamado "Cambiar color" que. y para eso. . Gestión de eventos "Hey". cambie el color de fondo de la applet usando el método setBackground. tendremos que echar un vistazo a la gestión de eventos (ver el siguiente punto). Los usuarios pueden hacer clic sobre los botones de su appler para indicar que quieren ejecutar alguna acción. "Tome una silla y hablaremos de ellos". En el siguiente capítulo. Añadir controles a las applets: botones "Estoy preparado para el siguiente paso". butonl = new Butt~n(~iHaga clic aquí!"). Button buttonl.Button. Los botones son soportados por la clase java. "he puesto un botón en mi applet. El truco. Aquí se está creando y añadiendo un botón con el texto " i Haga clic aquí! ": public class applet extends Applet TextField textl. "es que tiene que implementar la gestión de eventos". ¿Qué pasa?" "Lo que pasa. como se demostró en el ejemplo anterior.ciremos el control Button en el siguiente apartado. add(button1). cuando se haga clic sobre él. dice el programador novato. add(text1) . no ocurre nada.awt. pero cuando hago clic sobre él. dice el programador novato. Es bastante fácil añadir un botón a una applet. " le dice. "He añadido cuadros de texto a mis applets. le responde.

desactivada. y se deben implementar los métodos de la interfaz (para más detalles sobre las interfaces. AdjustementEvent: Gestiona los movimientos de la barra de desplazamiento. como hacer clic sobre los botones. como puede ser hacer clic sobre un botón. AdjustementListener: Gestiona los casos en los que un componente es escondido. Desde Java 1. movido. la gestión de eventos ha cambiado significativamente. En este modelo. etc. MouseMotionListener: Recibe en el caso en que se arrastra o mueve el ratón. KeyListener: Recibe los eventos de teclado. A cada uno de estos métodos se le pasa un tipo de objeto que corresponde al tipo de evento: ActionEvent: Gestiona botones.1. ContainerListener: Gestiona el caso en el que un componente coge o pierde el foco. abierta. el hacer doble clic en la lista o hacer clic en un elemento del menú. ver el capítulo anterior). ItemListener: Gestiona el caso en el que cambia el estado de un elemento. Los eventos se registran implementando una interfaz de listener de eventos. proceso de respuesta que se genera al hacer clic sobre el botón. Cada listener es una interfaz. El modelo actual se llama gestión de eventos delegado. . se debe registrar específicamente en Java si se quiere gestionar un evento. ha llegado a ser un tema complejo en Java. Estos son los eventos de listeners disponibles y los tipos de eventos que gestionan: ActionListener: Gestiona los eventos de acción. mete un componente. WindowListener: Gestiona los casos en que una ventana está activada. sale un componente o es presionado. cerrada o se sale de ella. TextListener: Recibe los cambios de valor de texto. MouseListener: Recibe en los casos en que es pulsado el ratón. La idea es que se mejora la ejecución si sólo se informa de los eventos al código que necesita gestionarlos y no al resto. los movimientos del ratón.La gestión de eventos. con o sin forma de icono. redimensionado o mostrado.

Gestión de eventos estándar Ya es hora de poner a funcionar algo de lo que hemos visto hasta ahora. Trataremos ambas variaciones aquí. desactivada. cerrada o abandonada. pasándole un objeto que imprementa los métodos de la interfaz ActionListener. enviando notificaciones de eventos al objeto de la applet actual (observe que indicamos que la clase applet ahora implementa la interfaz ActionListener): . movido.ComponentEvent: Gestiona el caso en el que un componente es escondido. hacer selecciones en los controles de opción y las selecciones de los elementos de un menú. Este objeto puede ser un objeto de la clase principal de la applet o de otra clase. sin forma de icono. KeyEvent: Gestiona la entrada desde el teclado. Empezaremos añadiendo un nuevo botón con el texto "¡Haga clic aquí!" en una applet. WindowEvent: Gestiona el caso en el que una ventana está activada. se suelta o entra o sale un componente. Para añadir un listener de acciones al botón. se presiona. TextEvent: Gestiona el valor de un cuadro de texto o si ha cambiado. redimensionado o llega a ser visible. Aquí vemos cómo se añade un listener de acciones a un botón. en forma de icono. así como añadir un listener de acciones que será notificado cuando se haga clic sobre el botón. InputEvent: Gestiona la marca de activación en una casilla de activación y el hacer clic en un elemento de la lista. FocusEvent: Gestiona el caso en el que un componente coge o pierde el foco. se pulsa. MouseEvent: Gestiona los casos en que se arrastra el ratón. abierta. empezando con el envío de las notificaciones de eventos a la clase main de la applet. se usa el método addActionListener del mismo. se mueve.

public void init0 { textl = new TextField(20). Eso quiere decir que se puede comprobar si este evento fue producido por el botón. public void h i t 0 { textl = new TextField(20). import java. import java. buttonl. Button buttonl.addActionListener(thia). buttonl. add(text1). add(button1).public class applet extends Applet implements Actionlistener { TextField textl.*. y en ese caso.App1et.event. . buttonl = new Button("iHaga clic aqui! " ) . Button buttonl.awt.applet. situar el texto "¡Hola desde Java!" en el cuadro de texto textl de esta forma: import java. y este método devuelve el objeto que produjo el evento. * . al que se le pasa un objeto de la clase ActionEvent cuando se hace clic sobre el botón: void actionPerformed(ActionEvent e) Los objetos ActionEvents (que veremos en el siguiente capítulo) heredan un método 1lamadogetSourcede la clase EventObject. public class applet extends Applet implements ActionListener ( TextField textl. buttonl = new Button(" ¡Haga clic aquí! " ) . actionPerformed.awt . 1 1 Ahora hay que implementar los métodos de la interfaz ActionListener. add(text1) . Esta interfaz sólo tiene un método.

próximamente. 1 !Hola desde Javal I Figura 6. aunque ahora es la práctica común).public void actionPerformed(ActionEvent event) { String msg = new String (niHola desde Java!"). La clase que se registra para recibir los eventos no necesita ser la clase principal de la applet (y de hecho. los desarrolladores de Sun originalmente intentaron que no lo fuera.getsource() == buttonl){ textl. 1 1 ) Esta applet aparece en la figura 6. porque se quiere trabajar con el cuadro de texto y los controles de botón en el objeto principal de la applet. Uso de clases delegadas Veamos un ejemplo en el que se está creando una nueva clase para implementar la interfaz ActionListener. if(event.7. el texto "¡Hola desde Java!" aparece en el cuadro de texto. Soporte de hacer clic sobre botones. Observe que esto es un poco pesado. Cuando se hace clic sobre el botón. Veremos el uso de otras clases para recibir eventos. por lo que hay que pasar y almacenar referencias a ese objeto e n el nuevo constructor de la clase: .setText(msg).7.

no la clase principal de la applet. . a obj = new a(this).Applet. public void init0 I textl = new TextField(20) . por ejemplo. 1 public void actionPerformed(ActionEvent event) { String msg = new String ("iH01a desde Java!"). add(button1). Además.awt.Haga clic aq~i!").event.import java. if(event. buttonl = new Button(". class a iqlements ActionListener applet c : a(app1et appletobject) { { c = appletobject.awt. se pueden usar comandos.setText(msg). add(text1) .textl. hay otras formas de determinar el objeto que causó el evento. como cuando se tienen muchos eventos para gestionar y no se quiere agrandar la clase principal de la applet. import java. 1 Este código funciona igual que la versión anterior de esta applet.applet . public Button buttonl.*.getSource0 == c. Hay veces que esto es útil. public class applet extends Applet { public TextField textl. import java.*. salvo que internamente usa una nueva clase para gestionar eventos.buttonl){ c.

Se puede obtener el comando para un botón con el método getActionCommand. . le echaremos un vistazo en el siguiente punto.event. import java.*.awt.addActionListener(this).emala("flaga clic a ~ í l " ) ) i Esto le introduce en el proceso de la gestión de eventos de una manera moderna.0 todavía se ejecuta en Java. add(button1). 1 public void actionPerformed(ActionEvent event) ( String mag = new String (mlHola desde Javal*). buttonl = new Button(". Sin embargo. aunque se considera obsoleto.applet. public void hit() { { textl = new TextField(20). String caption = event. Por motivos deexhaustividad. Button buttonl.getActionCommand0. add(text1). Aquí vemos cómo se implementa la applet anterior usando los comandos: import java.Uso de los comandos de acción Java permite asociar comandos con eventos causados por los botones' AWT y los elementos del menú. public class applet extends Applet implements ActionListener TextField textl. buttonl.App1et. Cuando se trabaja con botones.Hagaclic aquí!"). el comando por defecto es la inscripción del botón (veremos cómo se crean los comandos personalizados en el siguiente capítulo). la antigua forma de Java 1.awt. if(caption. import java.*. así podemos determinar en qué botón se ha hecho clic mirando su inscripción (no es una buena idea si su programa cambia las inscripciones).

awt. se pueden gestionar eventos derivando nuevas clases de componentes y sobrescribir los métodos de los componentes que . Object o) 1 String caption = ( S t r i n g ) ~ . 1 1 return true. 1 public boolean action (Event e. addítextl). por lo que los diseñadores de Java introdujeron el modelo de eventos delegad o en el que se pueden pasar eventos donde se quiera si estar restringidos a un método action. Por ejemplo.Applet. public void h i t 0 I textl = new TextField(20). > 1 El problema era que el método action con frecuencia llegaba a ser enorme. if(e. no se necesita registrar la obtención de eventos. add(button1). import java. hay otra forma de gestionar eventos. y se pueden gestionar en un método llamado action. por extensión de los componentes.applet. se pasan de cualquier forma.setText(msg).O. Extender componentes Si le gusta ser furtivo. aquí tenemos cómo aparecería la applet anterior usando el modelo de eventos antiguo: import java.O usa un acercamiento no delegado a los eventos.*. buttonl = new Button("Pú1seme").target instanceof Button) { if (caption = = "Púlseme") { textl. String msg = "¡Hola desde Java!". En el modelo de eventos de Java 1 . public class First extends Applet ( TextField textl.La forma antigua de gestionar eventos Java 1 . Button buttonl. De hecho.

1 protected void processActionEvent (ActionEvent e) ( super.processActionEvent(e). lo veremos aquí para completar el tema. De hecho.*.' e n una clase derivada llamada n e w B u t t o n . a. E n e s t a nueva clase. Q . public void init0 ( { textl = new TextField(20). Aquí vemos cómo implementamos la applet extendiendo la clase ~ u t t o n .textl.awt. class newButton extends Button I applet a.gestionan eventos.*. import java.applet. porque toda la gestión de eventos tiene lugar en un método.awt.ACT1ON-EVENT-MASK). esta forma de hacer las cosas termina con la técnica de gestión de eventos de Java 1. esto es descorazonador. a = aref.0.Applet. String S) í euper(8). visualizando el texto "¡Hola desde Java!" en el campo de texto de la applet después de llamar al método processActionEvent de la clase Button: import java. A pesar de ello.event. add(text1). sobrescribiremos el método processActionEvent de la clase Button. Button buttonl. 1 ) Ahora todo lo que tenemos que hacer es crear un nuevo botón de esta clase y añadirlo a la applet: public class applet extends Applet TextField textl. newButton(app1et aref. enableEvents(AWTEvent.~etText(~~Hola desde Javal"). import java. sin embargo.

la interfaz MouseListener tiene cinco métodos que deben implementarse. ahora esta applet funciona como las otras. import java. se quiere usar el método mouseClicked para gestionar el hecho de que se haga clic en el ratón. add(button1). Veamos un ejemplo. "Es cierto". public class applet extends Applet .awt. Sun introdujo las clases adaptador. Sin embargo.bttonl = n e w newButton(this.Haga clic aquí]"). ". Esta clase crea una subclase de la clase MouseAdapter. "entiendo que el modelo de eventos delegado lo utilizan las interfaces listener. por lo que usaremos la clase MouseAdapter en su lugar. dice el programador novato. y visualiza esa cadena en el método paint. Empezaremos añadiendo una clase que implementa un listener de ratón al programa. aparezca el mensaje "iHola a Java!". empezaremos con unaappletque almacena una cadena. pero algunas veces es una pena tener que implementar todos los métodos de una interfaz cuando se quiere usar uno solo". le dice. " iHola desde Java!".applet. por defecto. Al igual que la interfaz ActionListener. import java. Luego se va a añadir un listener de ratón (aprenderá más sobre ello en el siguiente capítulo) a la applet. 1 } Eso es todo. para que cuando el usuario haga clic en la applet. En este caso. y todo lo que se necesita hacer es sobrescribir el método o métodos que se quiera. Las clases adaptador son clases que ya han sido implementadas en varias de las interfaces de eventos disponibles.Applet.*.*.event. "por eso. sin ningún código.awt. en una clase adaptador. y lo llamaremos ma: import java. Usar las clases adaptador "Ugh". Cada método de una interfaz está implementado como método vacío. para hacer que todo el proceso sea mucho más fácil".

ma(app1et appletobject) { { a = appletobject.8. public void init ( ) { addMouseListener(new ma(this)). haciendo que la nueva cadena aparezca en la pantalla: class ma extends MouseAdapter applet a.repaint0. Hacer clic sobre el botón con las clases adaptador.8 = n f H ~ la Java!". 1 public void paintiGraphics g ) I g. observe que esto era un poco complicado porque teníamos que pasar el objeto applet al constructor de la clase ma para que la clase pueda alcanzar los campos de la clase applet. se reemplaza la cadena de texto en la applet con el texto "¡Hola a Java!" y luego se repinta la applet. 1 1 El resultado de este código aparece en la figura 6. 100). Cuando se hace clic en el ratón. 1 1 " l Se pasa un objeto de la clase principal de la applet al constructor de la clase ma por lo que se puede llegar a los campos de laapplet. 60.I public String s = " ¡ H o l a desde Java!".drawStringis. 1 public void mouseClicked(MouseRrent me) { a. a a. . 7 Figura 6.8.

SuperType es la clase o interfaz de la clase interna anónima que es derivada. import java. 1 public void paint(Graphics g) ( . Estas clases tienen el siguiente formato especial: new SuperType ( constructor parameters) ( //métodos y datos } Aquí.*. que hace que el código sea mucho más compacto: import java. con frecuencia. public void h i t 0 { addMouseListener(new MoueeAdapter() { public void ~>usePressed(MouseEventme) e = "yBola a Java!". las clases internas tienen acceso a los campos de sus clases encerradas.awt.*. repaint0.awt. Veremos esto a continuación.Por otro lado. pero ya es hora de usar una clase interna anónima. 11).applet.Applet. se va a derivar una clase interna anónima de la clase MouseAdapter para implementar la applet que vimos en el apartado anterior. import java. F - Usar clases adaptador internas anónimas En el capítulo anterior vimos las clases internas anónimas. por lo que los adaptadores están. public class applet extends Applet public String S = "iHola desde Java! " . En este caso.event. Observe que se está sobrescribiendo el método mouseClicked como se hizo en el punto anterior. implementados como clases internas.

Crear ventanas de aplicación
El programador novato aparece y dice, "De acuerdo, ahora se pueden c r e y applets, pero ¿qué hay de las aplicaciones que usan ventanas?" "Correcto, " ]e dice. Al igual que se escribían applets, cuando se escribe una aplicación de1 ventana, se es responsable de crear su propia ventana en la que se visualiza esa aplicación. El tipo de ventana más común para usar esto es la ventana de Java Frame, soportada en la clase java.awt.Frame. Este es el diagrama de herencia para esa clase (esta clase se deriva de la clase java.awt. Window, que trataremos dentro de unos pocos capítulos):

Encontrará los constructores de la clase Frame en la tabla 6.4 y su? métodos en la tabla 6.5.

He aquí un ejemplo en el que se deriva una clase nueva, AppFrame, de la' clase Frame y se personaliza para visualizar la cadena "¡Hola desde Java!", para hacer que aparezca la applet desarrollada anteriormente.
Tabla 6.4. Constructores de la clase Frame.

-

Construye una nueva instancia de Frame que es inicialmente invisible.
Frame(String título) Construye un nuevo objeto Frameque es invisible, con el título dado.

Tabla 6.5. Métodos de la clase Frame.

void addNotify() protected void finalize() int getCursorType() statíc Frame[]getFrames() lmage getlconlmage() MenuBar getMenuBar() int getState() Stríng getTitle() boolean isResizable() protected String paramString()

Hace que este marco sea visible conectándolo a un recurso nativo de pantalla. Llamado cuando elframeva a ser eliminado por la colección garbage. Obsoleto. Reemplazado por Component. getCursor(). Obtiene un array que contiene todos los frames creados por la aplicación. Obtiene la imagen que se va a visualizar en el icono minimizado. Obtiene la barra de menú. Obtiene el estado de la ventana. Obtiene el título de la ventana. Indica si esta ventana es redimensionable por el usuario. Devuelveel parámetrostringdeestaventana.

void remove(MenuComponentm) Retira la barra de menú especificada de esta ventana. void removeNotify() Hace que este frame no sea visible, retirando su conexión de sus recursos de pantalla nativos.

void setCursor(int cursorType) Obsoleto. Reemplazado por Component. setCursor(Cursor). void setlconlmage(lmage image) Fija la imagen que se va a visualizar en el icono minimizado de esta ventana. void setMenuBar(MenuBar mb) Fija la barra de menú de estaventana para que sea la barra de menú indicada. void setResizable(boo1ean resizable) void setState(int estado) void setTitle(String título) Establece si esta ventana es redimensionable por el usuario. Fija el estado de esta ventana. Fija el título de esta ventana a la cadena indicada.

Como con la clase java.applet.Applet, la clase java.awt.Frame es derivay da de la clase java.awt.Component, se puede usar el método paint para visualizar gráficos en la clase Frame. De hecho, el métodopaint sería como lo hemos creado anteriormente en el fichero de la aplicación, app.java. Este es el código:
import java.awt.*; import java.awt.event.*; class AppFrame extends Frame
(

public void paint(Graphics g)
{

g.drawString("1Hola desde Javalm, 60, 100);

>

1

Se necesita un método main para arrancar la aplicación, por lo que crea? mos ese método en una nueva clase llamada app:
public class app
(

public static void main(String [ 1 args) í

1

1
7

Para visualizar elframe de una ventana de aplicación, se crea un objeto de la clase AppFrame, como sigue:
public class app

I
public static void main(String
(

[]

args)

ApQFra~m f = new AppFrame();

'"*

Ahora se da al objeto un tamaño de 200 x 200 pixels y se visualiza en la pantalla con el método show:
public class app public static void main(String
[

1 args)

I

AppFrame f = new AppFrameO:

Figura 6.9. Crear una ventana de aplicación.

Los resultados de este código aparecen en la figura 6.9. Como se puede ver, el mensaje "¡Hola desde Java!" aparece en la aplicación, como se intentaba. Además se pueden añadir controles a esta aplicación, como se hizo con la applet del botón antes, en este capítulo. Hay algo más que mencionar aquí: primero, si se lanza una aplicación con la utilidad java (es decir, comojava app), esa herramienta esperará hasta que la aplicación devuelva el control a la consola. Desde el punto de vista del usuario, la consola parece estar colgada hasta que se abandone la aplicación. Si se quiere controlar el retorno inmediatamente a la consola después de que la aplicación sea lanzada y visualice su propia ventana, hay que usar la utilidad javaw en su lugar. Ver el capítulo 1 para más información. Otro punto importante es que si se quieren distribuir las aplicaciones a los usuarios que no tienen el JDK instalado, se puede usar el entorno de ejecución de Java (JRE). De nuevo, ver el capítulo 1 para más detalles. Finalmente, es importante apuntar que no hay forma fácil de salir de la aplicación en la figura 6.9; hacer clic sobre el botón Cerrar no tiene efecto. Se puede pulsar Ctrl-C para finalizar la ejecución de la herramienta java en la ventana de la consola, pero eso es bastante complicado. En su lugar, se tiene

que gestionar los eventos de cierre de ventana para terminar la aplicacióJ cuando la ventana se cierra. Echemos un vistazo a eso en el siguiente punto.

I
1

Salir de una aplicación al cerrar su ventana
"Hey", dice el programador novato, "fue un poco difícil acabar con my, primera ventana de aplicación, hacer clic sobre el botón Cerrar no tiene ningún efecto". "Entonces, ¿cómo se termina la aplicación?", le pregunta. "Apagando mi ordenador", dice el PN suspirando. Java espera que se gestione el caso en el que el usuario haga clic en e? botón Cerrar en una ventana de aplicación (aunque esto hubiera sido más fácil con ventanas Swing). Para finalizar una aplicación cuando el usuario haga clic en el botón Cerrar, se deben capturar los eventos ventana, con la ayuda de la interfaz WindowListener. Aquí veremos una forma compacta de hacerlo, modificando la aplicación desarrollada en el capítulo anterior usando la clase WindowAdapter, que implementa la interfaz WindowListener con una implementación vacía de cada método. En este caso, usaremos una clase adaptador interna anónima (ver el apartado correspondiente en este capítulo para más detalles) y sobrescribir el evento windowClosing. En ese método del evento, añadiremos código para salir de la aplicación System.exit(0). Esto finaliza la aplicación con un código de salida de O (que significa una terminación normal). Este es el código:
import java.awt.*; import java.awt.event.*; class AppFrame extends Frame I public void paint(Graphics g)
{

g.drawString(";Holadesde Java!", 60, 100);

1
public class app
{

public static void main(String [ ] args) I AppFrame f = n e w AppFrameO;

f.adBWindmListener(new windowAdapter0 Cpublic void windowClosing(Wind0wEvent e) {system.exit(O);>));

Esto es todo. Ahora cuando se hace clic en el botón Cerrar de la aplicación, la ventana se cierra y la aplicación finaliza.

Aplicaciones que se pueden ejecutar como
El gran jefe (GF) llega y dice, "tenemos que recortar los costes de desarrollo. De ahora en adelante, todas las applets deben ser también aplicaciones". "Hmm", le dice, "¿para cuándo tiene que estar eso?" "¿NO está todavía? pregunta GF. Si se añade un método main a unapplet, esa applet se puede ejecutar como applet y aplicación; Java ignorará el método main cuando se ejecuta como una applet, y se ejecutará el método main cuando se ejecuta como una aplicación. Este es un ejemplo en el que se han combinado la applet y la aplicación desarrollada en este capítulo en un programa:
import java.applet.Applet; import java.awt.*; import java.awt.event.*;

import java.applet.Applet; import java.awt.*; public class applet extends Applet

I
public static void main(String [ ] args)
{

AppFrame f = new AppFrameO;

f.addWindowListener(new WindowAdapterO {public void windowClosing(Window~vente) {System.exit(O) } ) ) ; ;

public void paint(Graphics g)
(

g.drawString(''iHola desde Java!", 60, 100);

class AppFrame extends Frame
(

public void paint(Graphics g)
(

g.drawString("iHola desde Java! " , 60, 100);

1

' Este código se puede ejecutar como applet y también como aplicación (el 9 gran jefe estará orgulloso).

7

m AWT: Cuadros
ae texto, botones, casillas de activación y plantillas
Este capítulo trata un número importante de componentes AWT: cuadros de texto, botones, casillas de activación y botones de opción. Ahora que ya estamos habituados a los componentes visibles, echaremos un vistazo a los gestores de esquemas o plantillas de Java que permiten ordenar los componentes en una applet o aplicación. Además revisaremos los paneles en Java, que permiten unir componentes en una superficie y mandarla al gestor de esquemas. Empezaremos echando un vistazo a los cuadros de texto.

Cuadros de texto
Los cuadros de texto son los componentes básicos de AWT para soportar texto. Estos componentes gestionan cadenas de texto de una dimensión; permiten visualizar el texto que el usuario escribe, poner máscaras de texto cuando se introduce una clave secreta, leer el texto que el usuario ha incluido y mucho más. Dentro de AWT, estos componentes son los fundamentales, junto con los botones.

Botones
Los botones proporcionan al usuario una forma rápida de iniciar alguna acción. Hay que hacer clic sobre todos ellos. Cualquier usuario está familiarizado con los botones y ya vimos cómo funcionan al discutir la gestión de eventos en el capítulo anterior. A los botones se les puede dar una inscripción, como "iPúlseme!". Cuando el usuario hace clic sobre el botón, el código recibe una notificación, siempre que se haya registrado la gestión de eventos desde el botón.
7

Casillas de activación
Las casillas de activación son como los botones, salvo que tienen un doble estado, es decir, pueden estar seleccionadas o no. Cuando se seleccionan, aparecen con algún tipo de marca, como puede ser una marca de activación o una X (el tipo de indicación visual depende del sistema operativo en que se haya programado AWT, que es una de las razones por las que Sun introdujo Swing, que puede visualizar componentes con la misma forma independientemente del sistema operativo). El usuario puede marcar una casilla de mi- --vación para seleccionar un tipo de opción, como los ingredientes cle un sandwich, habilitar la revisión de ortografía automáticamente o habili tar la impresión mientras se está haciendo otra cosa. Se usan las casillas de a -tivac ción para permitir al usuario opciones de selección no exclusivas; por f:jemplo, la revisión automática de ortografía y la impresión en backgroundpiieden ov.. , estar habilitados al mismo tiempo. Los botones de opción, sin e m b a r g ~rnn otra historia.
d.&

41

v .

\

Botones de opción
Utilizando los botones de opción, se puede permitir al usuario se1ecc:--"' una entre un conjundo de opciones mutuamente excluyentes. Sólo u 1 esas opciones puede seleccionarse al mismo tiempo. Por ejemplo, u: botones de opción, se puede dejar al usuario seleccionar un color de irnpresión y el día de la semana. En AWT, los botones de opción son un ti]PO de mdo, casilla de activación, y cuando se seleccionan, visualizan un punto red( un cuadrado o algún otro tipo de indicación (de nuevo, la indicación \risual depende del sistema operativo). Veremos cómo funcionan en este capít ulo.
7

plantillas
Hemos añadido componentes a las applets y aplicaciones usando el método add. Este método es, realmente, un método del gestor de esquemas que hay por defecto, elfZow layout manager. Por defecto, este gestor es el responsable de ordenar los componentes en las applets AWT. Elflow layout manager ordena los componentes de la misma forma que un procesador de texto debería ordenar las palabras a lo largo de la página y pasar a la siguiente línea cuando sea necesario, creando lo que Sun llama un flujo de componentes. Veremos que se pueden personalizar los esquemas de flujo de forma extensiva. Sin embargo, las limitaciones son claras, especialmente si se trata de mantener alguna posición de componentes respecto a otros, porque si el usuario cambia el tamaño de la applet o aplicación, todos los componentes tendrán que moverse. Por otro lado, hay otros gestores de esquemas en AWT (y algunos nuevos en Swing), y veremos el grid AWT, border, card y grid layout en este capítulo. ¿Por qué no se puede poner un componente donde se quiera y luego olvidarse de él? Los programadores novatos de Java con frecuencia se frustran al tratar con los gestores de esquemas de AWT, y quieren saber por qué no pueden dar las coordenadas de los componentes que quieren utilizar. De hecho, se puede, aunque cada uno sería responsable de gestionar el caso en el que las ventanas sean redimensionadas y hacer que los componentes se muevan. Para posicionar los componentes donde se quiera, se puede indicar que no se quiere ningún gestor de esquemas, y luego medir y ubicar los componentes como se quiera, usando add para visualizarlos como sigue:
setLayout(nul1); textl = new TextField(20); textl. setSize (200, 50) ; textl.setLocation(20, 20); add(text1);

Esto añade un cuadro de texto de tamaño ( 2 0 0 , 5 0 )en la localización ( 2 0 , 20) de un contenedor, como por ejemplo una ventana de una applet. Como veremos, se pueden añadir componentes a contenedores sin un gestor de esquemas, algo que es útil tener en mente si los esquemas de AWT le frustran demasiado. Un contenedor AWT muy útil es el componente Panel. Se pueden ordenar los componentes en un panel y luego añadir el panel, en sí mismo, al esquema de una applet o aplicación. En este capítulo veremos cómo se hace. Esto es todo. Ahora que ya hemos revisado lo que veremos en este capítulo, es el momento de pasar a la siguiente sección.

Usar cuadros de texto
"Hey", dice el programador novato, "quiero permitir a los usuarios escribir una clave secreta, pero ese maldito Johnson se queda mirando por encima del hombro de la gente y ve lo que escriben". "Eso tiene fácil arreglo", le dice. "Basta con poner el carácter de echo del cuadro de texto a un asterisco u otro carácter similar. iProblema resuelto!" En el capítulo anterior, vimos y usamos los cuadros de texto; estos com? ponentes pueden visualizar una sola línea de texto, y el usuario puede editarlo. Este es el diagrama de herencia de la clase de cuadros de texto, TextField:
7

-T Se pueden ver los constructores de esta clase en la tabla 7.1 y sus métodos en la 7.2.
Tabla 7.1. Constructores de la clase TextField.

TextField() TextField(intcolumnas) TextField(String texto) TextField(String texto, int columnas)

Construye un nuevo cuadro de texto. Construye un nuevo cuadro de texto vi con el número de columnas indicado. Construye un nuevo cuadro de texto cc texto indicado. Construye un nuevo cuadro de texto inicializado con el texto indicado y con el núrriero de columnas especificado.

Tabla 7.2. Métodos de la clase TextField.

void addActionListener (ActionListener 1 ) void addNotify() boolean echoCharlsSet()

Añade el ActionListenerindicado para recibir eventos. Crea el compañero del objeto cuadrc texto. Indica si el cuadro de texto tiene puestc carácter para utilizarlo como echo.

1

int getColumns() char getEchoChar() Dimension getMinimumSize() Dimension getMinimumSize (int columnas) DimensiongetPreferredSize() DimensiongetPreferredSize (int columnas) Dimension minimumSize() Dimension minimumSize (int columnas)

Obtiene el número de columnas del cuadro de texto. Obtiene el carácter que se utiliza como echo. Obtiene las dimensiones mínimas para el cuadro de texto. Obtiene las dimensiones mínimas de un cuadro de texto con el número de columnas indicado. Obtiene el tamaño preferido del cuadrode texto. Obtiene el tamaño preferido del cuadrode texto con el número decolumnas indicado. Obsoleto. Reemplazado porgethninimumSize(). Obsoleto. Reemplazado porgethninimumSize(int) .

protected String paramString() Obtiene la representación en cadena del estado del cuadro de texto. DimensionpreferredSize() Dimensionpreferredsize (int columnas) protected void processActionEvent(ActionEvent e) protected void processEvent (A WTEvent e) void removeActionListener (ActionListener 1 ) Obsoleto. Reemplazado porgetpreferredSize(). Obsoleto. Reemplazado porgetpreferredSize(int). Procesa los eventos ocurridos en el cuadro de texto, enviándolos a los objetosActionListener. Procesa eventos en el cuadro de texto. Elimina el action listener indicado, para que no reciba más eventos.

void setColumns(int columnas) Establece el número de columnas del cuadro de texto. void setEchoChar(char c) Establece el carácter echo para el cuadro de texto.

void setEchoCharacter(char c)
void setText(String t)

Obsoleto. Reemplazado porsetEchoChar(char).
Indica el texto que va en el cuadro de tex-

to. Veamos un ejemplo. En este caso, se creará un cuadro de texto para unaclave que visualizará un asterisco (*) cada vez que el usuario escriba un carácter. Puede que se pregunte cómo se podrá leer la clave escrita. La respuesta es utilizando el método getText del cuadro de texto, que hereda de la clase Component. De hecho, se añadirá un segundo cuadro de texto en este programa y se visualizará la clave cuando el usuario pulse la tecla Intro. Empezamos añadiendo dos cuadros de texto, de 30 caracteres cada uno:
import java.applet.Applet; import java.awt.*; import java.awt.event.*;

public class clave extends Applet implements ActionListener

I
public TextField textl; public TextField text2;

public void init0

I
texti = new TextField(30); add(text1); text2 = new TextField(30); add(text2) ;

A continuación, se establece que el carácter echo en textl (el cuadro de texto de la clave) es * y se añade un action listener a ese cuadro de texto:
public void init í )
(

7

textl = new TextFieldí30); add(text1); text2 = new TextField(30);

add (text2) ;

Cuando el usuario pulsa la tecla Intro, se llama al método actionPerjiormed, por lo que sobrescribimos dicho método para establecer que el texto en el segundo cuadro de texto es el del componente de la clave:
public void actionPerformed(ActionEvent e )
{

if (e.getSource0 == textl) f
text2.setText(textl.getText());

1
)

applet

7
open sesarne

Applet started
b -

Figura 7.1. Leer claves en cuadros de texto.

El resultado de este código se muestra en la figura 7.1. Cuando el usuario escribe una clave en el cuadro de texto de la parte superior y pulsa la tecla Intro, esa clave aparece en el otro cuadro de texto (no es exactamente lo que se llamaría seguridad). Se puede ver este ejemplo en el CD de ejemplo de este libro, en el fichero clave.java.

Usar etiquetas
Las etiquetas AWT son como los cuadros de texto, salvo que el usuario no puede editarlas. Se pueden utilizar las etiquetas para presentar texto que no se

puede editar, o, como su nombre indica, para etiquetar otros componentes. Este es el diagrama de herencia de la clase Label:
java. lang.0bject Ijava.awt.Component Ijava.awt.Labe1

En la tabla 7.3 se pueden ver los constructores de la clase Label, y sus métodos en la tabla 7.4.
Tabla 7.3. Constructores de la clase Label.

Labelo Label(String texto)

Construye una etiqueta vacía. Construye una nueva etiquetacon el texto indicado, justificados la izquierda. Construye una nueva etiqueta que presenta la cadena especificada con la alineación indicada.

Label(String texto, int alineación)

Tabla 7.4. Métodos de la clase Label

void addNotify0 int getAlignment0 String getText() protected String paramString() void setAlignment(intalineación) void setText(String text)

Crea el compañero de esta etiqueta. Obtiene la alineación actual de esta etiqueta. Obtiene el texto de esta etiqueta. Devuelve la cadena que representa el estado de la etiqueta. Fija la alineación de esta etiqueta a la que se especifica. Establece el texto de esta etiqueta al texto indicado.

El texto de una etiqueta se puede justificar pasándole al constructor de la etiqueta los campos Label.LEFT, Label-CENTER y Label-RIGHT. Esto es un ejemplo que crea tres etiquetas con las posibles alineaciones de texto:
import j a v a . a p p l e t . A p p 1 e t ; import j a v a . a w t . * ;

import java.awt.event.*;

public class etiqueta extends Applet
(

Label labell; Label label2; Label label3; public void i n i t 0
{

labell = new Label(";Hola desde Java!", Label. LEFT); add ( labell ); label2 = new Label("iHo1a desde Java!", Label. CENTER); add(label2); label3 = new ~abel("iHo1adesde JavaiU, Label. RIGHT); add(label3);

1

Applet

hola desde Javai hola desde Javal hola desde Javal

Applet started

Figura 7.2. Justificación de texto en una etiqueta.

El resultado de esta applet se muestra en la figura 7.2. Este ejemplo se puede encontrar en el CD, en el fichero etiqueta.java.

Usar botones
"Quiero hacer que los usuarios interactúen con mi programa", dice el programador novato. " Quiero dejarles que indiquen lo que quieren hacer simplemente con un clic de ratón, quiero que puedan seleccionar una acción rápida y fácilmente, quiero ..." "Botones", le contesta. "Lo que quiere son botones". "Cierto, " responde PN.

Todo usuario de GUI está familiarizado con los botones, esos controles elementales sobre los que se hace clic para indicar a un programa que debe empezar a realizar alguna acción; por ejemplo, podría permitir al usuario hacer clic sobre un botón para cambiar el color de fondo de una aplicación. Los botones están soportados en la clase java.awt.Button. Esta es la jerarquía de la clase:

Los constructores de la clase Button se muestran en la tabla 7.5, y sus métodos en la tabla 7.6. Para gestionar los eventos de los botones se usa la interfaz ActionListener, como vimos en el capítulo anterior. Esta interfaz tiene un único método, actionPerformed, al que se le pasa un objeto de la clase ActionEvent cuando se hace clic sobre el botón:
void actionPerformedíActionEvent e )
(

1

Tabla 7.5. Constructores de la clase Button.

1

1

Button Button(String etiqueta)

Construye un botón sin etiquet: Construye un botón con la etiqueia indicada.

Tabla 7.6. Métodos de la clase Button.

,~

void addActionListener(ActionListener 1) Añade el ActionListener indicdn para recibir eventos del botón. void addNotify() String getActionCommand() String getLabel() protected String paramString()
Crea el compañero del botón. Obtiene el comando del evento producido por el botón. Obtiene la etiqueta del botón. Obtiene la cadena que representa el estado del botón

1

1

protected void processActionEvent(ActionEvent e) protected void processEvent (A WTEvent e) void removeActionListener(ActionListener 1 ) void setActionCommand(String comando) void setLabel(String etiqueta)

Procesa los eventos que tienen lugar en el botón, enviándolosa los objetos ActionListenerregistrados. Procesa eventos del botón. Elimina el actionListenerpara que no pueda recibir eventos del botón. Establece el nombre del comando para el evento producido por el botón. Fija la etiqueta del botón para ser la cadena indicada.

Este es el diagrama de la herencia de la clase ActionEvent:

Todos los métodos de la clase ActionEvent se muestran en la tabla 7.7.
Tabla 7.7. Métodos de la clase ActionEvent.

String getActionCommand() int getModifiers() String paramString()

Obtiene la cadena del comando. Obtiene las claves del modificador, mantenidas durante el evento. Obtiene una cadena que identifica el evento.

Como vimos en el capítulo anterior, hay dos formas principales de determinar qué botón se seleccionó, usando el método getSource y usando comandos. Primero, veremos cómo se hace esto con getSource.He aquí un ejemplo con un botón que, cuando se hace clic sobre él, se visualiza el mensaje " iHola desde Java!" en un cuadro de texto (observe que se ha registrado un action listener con el botón y se investiga cuál es el botón sobre el que se ha hecho clic usando el método getSource antes de poner el texto apropiado en el cuadro de texto).
import java.applet.App1et; import java.awt.*;

butonl.add~ction~istener(this). public void init ( ) { textl = new ~extField(20). buttonl = new Button("¡Haga clic aqui! " 1 .3. Button buttonl. Figura 7. . if(event. 1 1 1 El resultado de este código se muestra en la figura 7. add(button1).setText(msg).getSource() == button1)C textl. 1 public void actionPerformed(ActionEvent event) { String msg = new String ("¡Hola desde Java!"). add(text1).3. boton.java. Gestionar el hacer clic en los botones. Esta applet se puede encontrar en el CD.public class boton extends Applet implements ActionListener { */ <APPLET TextField textl.

buttonl = new Button("iHaga clic aquí! " ) .También se pueden usar comandos con botones. add(text1). dado que estas inscripciones pueden cambiar durante la ejecución del programa (por ejemplo. 1 } Ahora.awt.*. usando el métodogetActionCommand. vimos que el comando asociado por defecto a cada botón es su inscripción. import java. s e t A c t i o n C ~ n d ( ~ B o apretado").add~ctionListener(thic). public void i n i t 0 ( { textl = new TextField(20). import java.applet. add(button1). en el método actionPerformed. Si el botón sobre el que se hizo clic es el de la derecha. .getActionC-nd0. se debería asociar un comando con el botón en sí mismo. se puede situar el mensaje en el cuadro de texto. */ <APPLET public class boton2 extends Applet implements ActionListener ~ e x t F i e l dtextl.awt. Button buttonl. Sin embargo. t6n buttonl. Se puede dar a un botón un comando de tipo string con el método setActionCommand como sigue: import java.*. b ~ t t o n l .Applet. se puede obtener el comando para el botón sobre el que se hizo clic. usando el método setlabel). en el capítulo anterior.event. como sigue: public void actionPerformed(ActionEvent eventi I String msg = new String (myBoladesde Javal"). String command = event.

boolean estado) . Crea una casilla de activación en el grupo indicado y fija el estado. éste aparezca pulsado para que los usuarios sepan lo que ya han seleccionado". boolean estado. Crea una casilla de activación con la etiqueta especificada y fija el estado.java. Cuando el usuario hace clic en una casilla de activación. CheckboxGroupgrupo) Checkbox(Stringetiqueta. se deselecciona. Crea una casilla de activación con la etiqueta especificada.Esta applet se puede encontrar en el CD en boton2. le dice. algún tipo de indicación visual. r Checkbox() Crea una casilla de activación sin etiquetas. Constructores de la clase Checkbox. como una marca de activación (el indicador varía con el sistema operativo cuando se usa AWT). Checkbox. por lo que me gustaría que cuando se haga clic sobre un botón. Construye una casilla de activación con la etiqueta indicada en el grupo especificado. Checkbox(Stringetiqueta) Checkbox(Stringetiqueta. tengo otro problema". Una casilla de activación permite al usuario seleccionar opciones. dice el programador novato. Usar casillas de activación "Ahora. se utiliza para indicar que la opción está seleccionada. "No. "No hay ningún problema". "Utilice casillas de activación en su lugar". " le dice. "No utilice botones". CheckboxGroup grupo. "¿No?" pregunta PN.awt. que tiene el siguiente diagrama de herencia: Tabla 7. las casillas d e activación están soportadas por la clase java.boolean estado) Checkbox(Strjngetiqueta. En AWT. Si se hace clic otra vez en la casilla de activación.8. "Quiero que los usuarios puedan seleccionar de qué quieren una pizza.

enviándolos a cualquiera de los objetos ItemListener registrados. Crea un grupo de casillas de activación. Fija el estado de la casilla de activación en el estado dado. que se puede poner el . Obtiene la etiqueta de la casilla de activación. en particular. Determina si la casilla de activación está en estado seleccionado o no seleccionado. Procesa eventos en la casilla de activación.8 se pueden encontrar los constructores de la clase Checkbox y sus métodos en la tabla 7. Obtiene una cadena que representa el estado de la casilla de activación. Observe. boolean getState() protected String paramString0 protected void processEvent (A WTEvent e) protected void processltemEvent (IternEvent e) void rernovelternListener (ItemListener 1 ) void setCheckboxGroup (CheckboxGroup g) void setLabel(String etiqueta) void setState(boo1ean state) En la tabla 7. Procesa los eventos de itemsque se producen en la casilla de activación.Tabla 7. Retira el item listener indicado. void addltemListener(1temListener 1) Añade el item listener indicado a la casilla de activación.9. Establece el grupo de casillas de activación para el grupo dado.9. MBtodos de la clase CheckBox. para que no reciba más eventos de la casilla de activación. Fija la etiqueta de la casilla de activación en esta cadena. void addNotify() CheckboxGroupgetcheckboxGrou~O String getlabelo Object[]getSelectedObjects() Crea el compañero de la casilla de activación. Obtiene un array (de longitud 1) que contiene la etiqueta de la casilla de activación (o null si no se ha seleccionado).

1 ItemSelectable getltemSelectable() Obtiene el originador del evento.*. import java. usan la interfaz ItemListener.10. se utiliza un cuadro de texto para indicar que se ha seleccionado.*.awt. import java. itemStateChanged. que sirve para gestionar los componentes que pueden ser seleccionados o deseleccionados.applet. La interfaz ItemListener sólo tiene un método. y cuando el usuario hace clic sobre una de ellas. en su lugar. checkboxl = new Checkbox("lW).Applet. add(checkboxl ) : checkboxl. al que se le pasa un parámetro de la clase ItemEvent: void itemStateChanged(1temEvent e) Los métodos de la clase ItemEvent se pueden encontrar en la tabla 7. Obtiene el elemento afectado por el evento.estado de una casilla de activación con setState y obtener el estado con getState.10. TextField textl. Tabla 7. Métodos de la clase ltemEvent. Veamos un ejemplo en el que se añaden cuatro casillas de activación a una applet. checkbox3. checkbox2. Observe que las casillas de activación no utilizan la interfaz ActionListener como lo hacen los botones. Así es como se añaden casillas de activación en una applet y un ItemListener a cada una de ellas: import java.addItemGistener(this).event. checkboxl. public void i n i t 0 { I checkboxl = new Checkbox ( "1 m ) . 1 .awt. public class casillas extends Applet implements ItemListener Checkbox checkboxl.

1 Ahora.setText(" ¡Casilla de activación 1 pulsada! " ) .setText("~Casil1a activación 2 pulsada!"). de ) else if(e. checkbox4 = new Checkbo~("4~).addItemListener(this). Este método devuelve Checkbox. Obtiene la cadena que coincide con el evento.getItemSelectable() == checkboxl)( textl. Debido a que es tedioso tener tantas sentencias ifen la escala if-else del código anterior. DESELECTED. usando el método getItemSelectable del objeto ItemEvent: public void itemStateChanged(1temEvent e) ( if(e. por supuesto. textl = new TextField(30). ) else if(e.addIt~istener(this). String paramString() add (checkbox2 : ) checkbox2. se puede usar el método getState de la casilla de activación para hacer la misma determinación. ) else if(e. Y.getItemSelectable0 == checkbox2){ textl. Además se puede establecer el estado de la casilla de activación con el método setState. } } Ahora. en casillas. add (checkbox4 : ) checkbox4. ya sabemos cómo utilizar el método getStateChanged del objeto ItemEvent para determinar si una casilla de activación está seleccionada o no. Se puede encontrar en el CD. seleccionado o quitada la selección). add (checkbox3 : ) checkbox3. checkbox3 = new Checkbo~("3~). add(text1).int getStateChange0 Obtiene el tipo de cambio de estado (es decir.setText("¡Casilla de activación 4 pulsada! " ) . sobrescribimos el método itemStateChanged.4. El resultado de esta applet se muestra en la figura 7.SELECTED o Checkbox. para determinar sobre qué casilla de activación se pulsó.getItemSelectable() == checkbox3)( textl.setText("iCasil1a de activación 3 pulsada!").addItemListener(this). como sigue: .java.getItemSelectable0 == checkbox4){ textl. se puede visualizar únicamente la casilla de activación sobre la que se ha hecho clic obteniendo su etiqueta directamente.

import java. checkbox4 = new Checkbox("4").addItemListener(this). public class casillas2 extends Applet implements ItemListener Checkbox checkboxl. > public void itemStateChanged(1temEvent e) { textl.event. import java.*. import java. checkbox2.addItemLictener(this).addItemListener(this). checkbox3.4. Gestionar el hacer clic sobre las casillas de activación.awt. checkbox3. checkbox2 = new CheckboxíM2"). add(checkbox3) . checkboxl. textl = new TextField(35). checkbox3 = new Checkboxín3").Applet.setText("rCasi11a de activación " + . awt . add(checkbox1) . add (checkbox2 . add(text1). ) checkbox2. checkbox4. rl v2 1-3 r4 ~Castlla aclivacion 2 pulsada1 de Applet stafied Figura 7. checkbox4. add(checkbox4). TextField textl: public void init ( ) { { checkboxl = new Checkbox("1").addItemListener(this).applet. * .

AWT soporta grupos de casillas de activación con la clase CheckboxGroup.java en el CD. Sólo un botón d e opción de un grupo puede ser seleccionado de una vez. los botones de opción. que no tiene parámetros.getItemSelectable()). Checkbox getSelectedCheckbox() Obtiene la casilla d e activación que actualmente esta seleccionada dentro del grupo. y los revisaremos en la siguiente sección. . Tabla 7. Reemplazado porsetselectedCheckbox(Checkbox). En la programación AWT. Métodos de la clase CheckboxGroup.((Checkbox) e. le contesta. Hay otro tipo de casilla de activación que se puede utilizar. Puse casillas de activación en mi programa para que los usuarios pudieran seleccionar el día de la semana. se convierten en botones de opción de forma automática. Observe que. se pueden usar los métodos Checkbox. "debería usar botones de opción.11. y un usuario seleccionó miércoles y viernes". void setCurrent(Checkbox box) void setSelectedCheckbox (Checkbox box) Obsoleto. "tengo otro problema. + "pulsa- Esta nueva versión de la applet aparece en casillas.getLabel() da!"). cuyos métodos se verán en la tabla 7. puesto que los botones d e opción son realmente casillas de activación. Checkbox getCurrent() Obsoleto. v Usar botones de opción "Uh-oh". Cuando se añaden casillas de activación a un grupo. dice el programador novato. Establece la casilla d e activación actualmente seleccionada en este grupo. como el día de la semana". Sustituido por getselectedCheckBox(). como getState y setstate. el resto del grupo es automáticamente desactivado. "Bien". en lugar de casillas de activación para visualizar opciones excluyentes. y se usan en grupos. los botones de opción son un tipo especial de casilla de activación. CheckboxGroup. cuando el usuario selecciona un botón de opción en un grupo.11. Esta clase sólo tiene un constructor.

. radio).Applet.*. radios = new CheckboxGroup(). que se puede determinar qué botón de opción está' seleccionado en un grupo.String toString() Devuelve una representación tipo stringdel grupo. radio3. radio4 = new CheckboxGroup(*4*. radio3 = new Checkbo~Group(~3". add(radio1). radio4.applet. incluyendo el valor de s u selección actual. radio). import java. y se añaden cuatro botones de opción a ese grupo. public class botondeopcion extends Applet implements ItemListener { CheckboxGroup radios. radiol = new CheckboxGroup("l". add(radio3).addItemListener(this). Se añade un botón de opción a un grupo de casillas de activación añadiéndolo al grupo.*. pasándolo como parámetro al constructor de la casilla de activación.awt. add (radio2 . radio). y se puede inicializar con uno seleccionado con el método setSelectedCheckbox. con el método getSelectedCheckbox de la clase CheckboxGroup. radiol. Este es un ejemplo en el que se crea un grupo de casillas de activación llamado radios. public void h i t ( ) 1.awt. radio). false. por ejemplo. radio3. false. TextField textl. radio2 = new CheckboxGroup("2". que convierte la casilla de activación en un botón de opción. radio2. false. Observe.addItemListener(thie). false. ) radio2.addItemListener(this). Checkbox radiol.event. Este es el código: import java. import java.

5. y trataremos de hacerlo en los siguientes puntos.Observe que se ha añadido unItemListener a cada botón de opción. "de nuevo Java está graciosillo". PN dice. + "pulsa- 1 El resultado de este código se muestra en la figura 7. r3 C4 botón de opcion 2 pulsado1 Applet staried Y Figura 7. Gestionar el hacer clic en botones de opción. "Bien. es hora de tener en cuenta cómo se ordenan estos componentes. dice el programador novato. Ahora que estamos trabajando con componentes en programas visuales. .Botón opción " + de ((Checkbox) e. por lo que se puede implementar el método itemStateChanged para indicar qué botón de opción ha sido seleccionado. estoy creando una calculadora para multiplicar y quiero que todos los cuadros de texto se almacenen verticalmente. como sigue: public void itemStateChanged(1temEvent e) { textl. y podrá encontrar esta applet en el CD como botondeopcion.java. "¿Qué ha hecho ahora?" le pregunta. "Eso se debe a que está utilizando un esquema de flujo (flow layout)". Esquemas de flujo (flow layout) "Uh-oh".getLabelO aOlm). pero se ordenan en filas".setTe~t(~.getItemSelectable()). le dice.5. r1 6 2 .

las applets usan elfíow manager. con la alineación dada y los márgenes horizontal y vertical dados entre los componentes. Obtiene la separación vertical entre los componentes. Por defecto. FlowLayout(int align.13.Java tiene un número de gestores de esquemas AWT que gestionan cómo s e visualizan y se instalan los componentes en los contenedores. int vhap) Crea un nuevo flow layout. incluyendo la ruptura de la palabra al pasar de línea.12. Devuelve las dimensiones preferidas para el esquema. Constructores de la clase FlowLayout. int hgap. Construye un nuevo flow layout con alineación centrada. Tabla 7. Cornponent cornp) int getAlignment() int ge tHgap() int ge tVhap() void layoutContainer(Container target) Dirnension minirnurnLayoutSize (Container target) Añade al esquema el componente. Pone el contenedor. Obtiene la alineación del esquema. Tabla 7. Dirnension preferredLayoutSize (Container target) . FlowLayout(int align) Construye un nuevo flow layout con la alineación dada. dados los componentes en el contenedor target. especificado. Devuelve las dimensiones mínimas necesarias para poner los componentes en el contenedor targe t. voidaddLayoutComponen t(String nombre. El margen horizontal y vertical será de 5 pixels. El margen horizontal yverticalserá de 5 pixels. Obtiene la separación horizontal entre los componentes. que ordena los componentes igual que lo hacen los procesadores con e l texto. Métodos de la clase FlowLayout.

applet. TRAILING: Indica que cada fila de componentes debería estar justificada a la siguiente esquina del contenedor.12 y sus métodos en la tabla 7. LEADING: Indica que cada fila de componentes debería estar justificada a la primera esquina del contenedor. Fija la separación horizontal entre los componentes.Applet. . RIGHT: Indica que cada fila de componentes debería estar justificada a la derecha. 1 String toString() Los constructores de la clase FlowLayout aparecen en la tabla 7. import java. Por defecto. awt. * . Devuelve la representación de tipo stringde este objeto FlowLayout. Fija la alineación.13. el flow layout centra cada componente de la fila. pero aquí podemos ver cómo se crea un nuevoflow layout que justifica los componentes a la derecha usando el método setlayout: import java. Para tener algún control sobre cómo elflow layout ordena los componentes.voidremoveLayoutComponent (Component comp) void setAlignment(int align) void setHgap(int hgap) void setVgap(int vgap) Elimina el componente del esquema. LEFT: Indica que cada fila de componentes debería estar justificada a la izquierda. se puede especificar su alineación utilizando los siguientes campos FlowLayout: CENTER: Indica que cada fila de componentes debería estar centrada. Fija la separación vertical entre los componentes.

como se muestra en la figura 7. text2 = new TextField(l0) . public void init ( ) { setLayout(new Flow~ayout(FlowLayout. text3.applet. import java. import java.6. que presenta la calculadora que el programador novato estaba intentando crear: import java.event. Figura 7. Sin embargo. Por ejemplo: echemos un vistazo a esta applet. 1 1 Una vez que se han añadido algunos cuadros de texto a este nuevo gesto? se puede ver que están justificados a la derecha.awt. Componentes de un flow layout justificados a la derecha.RIGIiT) ). text2.*. .awt.6. add (text2i .public class flow extends Applet ( ~extFieldtextl.*. textl = new TextField(l0). algunas veces un flow layout no es correcto. add (text3) . text3 = new TextField(l0). add(text1).Applet.

text2 = new TextField(l0). public void i n i t 0 { ( textl = new TextField(l0).public class multiplicadora extends Applet implements ActionListener TextField textl. add (text3) . text2. y cuando se .parseInt(textl. y esta applet está e n multip1icadora. Como se puede ver en la figura. bl. y el resultado es lo que el programador novato buscaba. posicionándolos en una cuadrícula. El grid layout p e r m i t e a ñ a d i r c o m p o n e n t e s a u n c o n t e n e d o r . 1 public void action~erformed(ActionEvent e) { if (e. Label multiplylabel.valueOf(product)) . los cuadros de texto están ordenados según elflow layout.7. 1 } * } El resultado se muestra e n la figura 7. " le contesta. ButtOn bl. add ( text2) . add(multiplylabe1).getSource() == bl) I int product = Integer.java en el CD. multiplylabel = new Label("*"). text3. "Tiene que usar un gestor d e esquemas diferente.getText0) Integer. Grid layouts "Entonces. cinco filas y cinco columnas. Al grid layout se le dan las dimensiones d e la cuadrícula. "el grid layout".setText(String. pregunta el programador novato. el grid layout.parseInt(text2. text3. próximamente. text3 = new TextField(l0). Echaremos un vistazo a otro gestor de esquemas.addActionListener(this). ¿cómo arreglo mi calculadora para multiplicar? Los cuadros de texto no están en su sitio". como por ejemplo. bl = new Button("=").getTextO 1 . additextl) . add(b1).

voidaddLayoutComponent(String nombre. plet statied Figura 7. int columnas) GridLayout(int filas. Métodos de la clase Gridlayout. Observe que cada componente tiene el mismo tamaño y dimensiones.añadan componentes a este esquema. 7 Crea un grid layout en una fila. Este es el diagrama de herencia para el grid layout: En la tabla 7. Obtiene el número de columnas del esquema. los componentes se sitúan en 1 . Una vez que la primera fila esté rellena. .7. columnas y separación dados. int columnas. con una columna por componente.14. Tabla 7.14 se encuentran los constructores de la clase GridLayout sus métodos en la tabla 7. GridLayout(int filas. primera columna d e la segunda fila y así sucesivamente. se hará empezando por la izquierda de la primera fila. Componentcomp)dado int getColumns() Añade al esquema el componente. 1 .15.15. Crea ungridlayoutcon el número de filas. Primer intento de una calculadora para multiplicar. int hgap. int vgap) Crea un grid layout con el número de filas y de columnas indicados. Tabla 7. Constructores de la clase GridLavout.

. Establece el número de columnas en el esquema. import java.awt.I). Establece la separación vertical entre los componentes.adición de componentes a este esquema.event.*. Determina el tamaño preferido del contenedor usando el grid layout. Cuando se inicia la . Este es un ejemplo en el que se crea una cuadrícula de cinco filas y una columna. Elimina del esquema el componente indicado.*. Obtiene la separación vertical entre los componentes.Applet. Establece la separación horizontal entre los componentes. pasando esas dimensiones al constructor del gestor grid layout como GridLayout(5. Pone el contenedor usando el esquema. serán almacenados uno encima de otro.int getHgap() int getVgap() void layoutContainer(Container padre) Dimension minimumLayoutSize (Containerpadre) DimensionpreferredLayoutSize (Containerpad re) void removeLayoutComponent (Component comp) void setColumns(int cols) void setHgap(int hgap) void set Vgap (int vgap) void setRows(ínt filas) String toString() Obtiene la separación horizontal entre los componentes. Obtiene una representación de tipo string del esquema. Determina el tamaño mínimo del contenedor usando el grid layout. import java.applet. import java.awt. Establece el número de filas del esquema.

8. ). buttonl = new Button("="). multiplylabel = new Label("*". add(button1). .addActionListener(this).getSource0 == buttonl) { int product = Integer. Button buttonl.< /APPLETa public class multiplicadora2 extends Applet implernents ActionListener 7 Text~ieldtextl. add(multiplylabel) . Label-CENTER).getText0) * Figura 7. text3. add(text2).parseInt(textl. Segunda versión de la calculadora para multiplicar. 1 public void actionPerformed(ActionEvent e) { if(e. text2. text2 = new ~extFieid(l0). add(text3). Label multiplylabel. public void init0 ( setLayout(new GridLayout(5. add(text1). buttonl. text3 = new TextFieid(l0).1) textl = new TextFieid(i0).

los componentes de esta applet se almacenan verticalmente.17.0bject Ijava. Constructor de la clase Panel.17. lang. addNotify() Crea el compañero del panel. Una forma de trabajar con esquemas es dividir los componentes del programa en paneles y añadir dichos paneles a los esquemas. Echaremos un vistazo a los paneles en el siguiente punto.8. "iEstupendo! Cuénteme todo eso". se pueden fijar sus gestores usando los métodos setlayout. como se suponía. no tienen bordes. Dado que los paneles son contenedores. por ejemplo. Los paneles. por sí solos.16.~omponent 1java. Tabla 7. Método de la clase Panel.Container Ijava. Este es el diagrama de herencia para la clase Panel: java. " le dice.awt.1 6 y su método en la tabla 7.awt. no son contenedores visuales.El resultado de este código se muestra en la figura 7. tengo muchos componentes que visualizar". Panel(LayoutManager layout) Crea u n nuevo panel con el layout especif icado. "De acuerdo. "Necesito afinar el control en mi esquema. Se añaden componentes a un panel y luego se añade ese panel al esquema. contesta PN. Como se puede ver en la figura. Esto hace que se tenga más control sobre dónde van a ir los controles. puede usar los paneles de Java". .awt. La clase Panel de Java es un contenedor que se puede usar en los esquemas. "para tener más control. y sólo existen para contener componentes. Tabla 7. Usar paneles El programador novato todavía no está satisfecho con los problemas que tiene con los esquemas y dice.~anel El constructor de la clase Panel se muestra en la tabla 7.

panei2. Button("ln). panel5 = new buttonpanel0. buttonpanel ( ) { buttonl = new add(button1). panel6. panel5. de la clase Panel.applet. buttonl = new add(button4). panel4 = new buttonpanel0.awt . . button3 = new add(button3). button4.31). buttonl = new add(button2). panel2 E new buttonpanel0. button3. 1 } Ahora. button2. Button("2"). panel3.Applet. class buttonpanel extends Panel I Button buttonl. y se añaden algunos botones al panel en el constructor buttonpanel: import java. * . import java. Buttonín3").? como sigue: public class paneles extends Applet { buttonpanel paneli. panel4. Buttonin4"). buttonPane1. public void init ( ) { setLayout(new GridLayout(2. se pueden ordenar paneles de esta nueva clase en un grid layo. panel6 S new buttonpanelo. panel1 = new buttonpanel0.7 Este es un ejemplo en el que se deriva una nueva clase. panel3 new buttonpanel0 .

le dice. etc. Es útil si se quieren soportar. digamos.El resultado d e este código se muestra en la figura 7. y cuadros de diálogo. Este es el diagrama de herencia para BorderLayout: Los constructores de la clase BorderLayout se encuentran en la tabla 7. "Debería conocer el border layout. Ordenar componentes usando paneles. barras de desplazamiento y desplazar un componente central.18 y sus métodos en la tabla 7. Border Layout El programador novato vuelve y dice. . usando paneles se da un control más fino al esquema. "¿hay más esquemas que deba conocer?" "Por supuesto. ventanas frame. por ejemplo". "East".19. y el código de esta applet se puede encontrar en paneles. Los border layouts son las ventanas de AWT por defecto. PN pregunta.9. Figura 7. Como s e puede ver en esta figura. "¿Ordena los límites?" "Un poco". Se indica dónde se quiere que vaya un componente pasando al constructor BorderLayout cadenas como "North". " le dice. El border layout permite ordenar los componentes alrededor del borde de un contenedor. se ha añadido cada panel al grid layout.java en el CD.9.

Construye un nuevo border layout. void addLayoutComponent(Componenf comp. int getVgap() void invalidateLayout(Container target) void layoutContainer(Container target) Dimension maximumLayoutSize (Container target) Dimension minimumLayoutSize (Container target) Dimension preferredLayoutSize (Container target) void removeLayoutComponent (Component comp) Obtiene la separación vertical entre componentes. Pone el contenedor Obtiene las dimensiones máximas del esquema dados los componentes en el target. floatgetLayoutAIignmentX(Container Obtiene la alineación a lo largo del eje x. padre) floatgetLayoutAlignmentY(Container Obtiene la alineación a lo largo del padre) eje y.18. 1 Tabla 7. . Obtiene las dimensiones mínimas del esquema usando el gestor de esquemas. Elimina del esquema el componente dado. lnvalida el esquema. Métodos de la clase BorderLayout. Component comp) int getHgap() Añade el componente al layout. Añade al layoutel componentedado. Object constraints) void addLayoutComponent(String nombre. usando el objeto dado. con el nombre indicado. Obtiene la separación horizontal entre componentes. Obtiene las dimensiones preferidas del esquema usando el gestor de esquemas. int vgap) Construye un border layout con las separaciones entre componentesindicadas. Constructores de la clase BorderLayout. BorderLayout(int hgap.19.Tabla 7.

void set Vgap(int vgap) String toString() Este es un ejemplo en el que se crea un panel que contiene un cuadro de texto y se añaden cuatro botones alrededor del borde del panel. la applet indicará. button3. el botón que se pulsó. button2. situando el panel del cuadro de texto en el centro y añadiéndole cuatro botones alrededor del borde. 1 1 Ahora se crea un border layout. Se puede especificar dónde se quiere situar un componente con cadenas como "North".awt.awt.event. en el cuadro de texto. Obtiene una representación tipo string del esquema. add(Text1). Así es como se crea el panel que visualiza un cuadro de texto: import java.Applet. class textpanel extends Panel c TextPield Textl. "West".void setHgap(int hgap) Establece la separación horizontal entre los componentes. Establece la separación vertical entre los componentes. textpanel Panell: public void init0 . import java. "Center". textpanel ( ) i Textl = new TextField(30).*. button4. Se crea el esquema como sigue: public class border extends Applet implements ActionListener I Button buttonl. etc. Cuando el usuario hace clic sobre un botón.app1et. import java.*.

getSource0) . buttonl. buttonl).addActionListener(this).buttonl = new B ~ t t o n ( ~ 1 ~ ) .addActionListener(this).Textl. 1 } Figura 7. button3 = new Button("3").setLocation(0."). Como se puedeT ver en esta figura.Textl. Panell = new textPanel0. button4 = new Button("4"). los botones aparecen alrededor del perímetro central del panel. Paneil. button2 = new Button("2').getLabelO + " pulsado. Crear un border layout. button3). buttonl. O). button2). add("Northm. button3.setText("Botón " + ((Button) e. add("South".10. add("Centern. add("Eastm. button4). Panell). button2. El resultado de este código se muestra en la figura 7.addActionListener(this). 1 public void actionPerformed(ActionEvent e) I Panell .10.addActionListener(this). . add("Westm.

Añade el componente al layout.Card Layouts "¿Hay más esquemas AWT?" dice el programador novato. Obtiene la alineación a lo largo del eje x. Tabla 7. Los constructores de la clase CardLayout se encuentran en la tabla 7.21. Component comp) void first(Container padre) int getHgap() float getLayoutA lignmentX(Container padre) float getLayoutAlignmentY(Container padre) int getVgap() Añade al layoutel componente dado. se pueden visualizar tarjetas específicas usando los métodosfirst. . Obtiene la alineación a lo largo del eje y. int vgap) Crea u n nuevo card layout. Crea u n nuevo card layout con las separaciones horizontal y vertical marcadas. CardLayout() CardLyout(int hgap. dice PN. Métodos de la clase CardLayout void addLayoutComponent(Compo. "card layout".21.20 y sus métodos en la tabla 7. con el nombre indicado. last. void addLayoutComponent(String nombre. Este es el diagrama de herencia para la clase CardLayout: j a v a . Tabla 7.CardLayout Además del métodoshow. Vaala primera tarjeta del contenedor.awt. Obtiene la separación horizontal entre componentes. A cada una se le da un nombre. El gestor card layout visualiza los contenedores que se le pasan como tarjetas. Object constraints) usando el objeto dado. le dice. "Claro que los hay". "Veámoslo". next y previous de la clase CardLayout. 1ang. Constructores de la clase CardLayout. Obtiene la separación vertical entre componentes.20.Object Ijava. nent comp. luego se puede mover de una a la otra con el método show de card layout.

El constructor de esta clase tiene dos parámetros: un objeto de la clase principal de applet. Establece la separación vertical entre los componentes. y una etiqueta para indicar el número de la tarjeta actual. Va a la siguiente tarjeta del contenedor dado. Obtiene una representación tipo string del esquema. por lo que la applet. Va a la tarjeta anterior del contenedor dado.applet.voidinvalidateLayout(Container target) lnvalida el esquema. Obtiene las dimensiones preferidas del esquema usando este card layout. puede gestionar los clics sobre el botón que se produzcan en cada panel y una representación en cadena del número del panel actual: import java. String nombre) String toString() Veamos un ejemplo en el que se crea una clase panel. Obtiene las dimensiones máximas del esquema dados los componentes en el target. visualiza un botón. Va a la última tarjeta del contenedor.*. Calcula el tamaño mínimo para el panel dado. en sí misma. Establece la separación horizontal entre los componentes. que.Applet: . sobre el que el usuario puede hacer clic para moverse a la siguiente tarjeta. import java.awt. void last(Container padre) voidlayoutContainer(Container padre) Dimension maximumLayoutSize (Container target) DimensionminimumLayoutSize (Containerpadre) void next(Container padre) DimensionpreferredLayoutSize (Containerpadre) void previous(Containerpad re) void removeLayoutComponent (Component comp) void setHgap(int hgap) void setVgap(int vgap) void show(Container padre. cardPanel. Va al componente que se añadió al esquemacon el nombre especificado. Pone el contenedor dado usando este card layout. Elimina del esquema el componente dado.

"uno"). se crean tres paneles de la clase cardpanel.*.awt. panel3. String cardnumber) I button = new Button("Tarjeta siguiente"). 1 Cuando el usuario hace clic sobre un botón. set~ayout(card1ayout). 1 + cardnumber). 1 En la clase main de la applet. panel2. cardPanel(card applet.event. "primero"). cardpanel panell. y "tercera": public class card extends Applet implements ActionListener I int index = 1. Después se les añade a un card layout.shov(this. "segunda". class cardpanel extends Panel I Button button. public void init ( ) { cardlayout = new CardLayoutO. Label label. dándoles los nombres "primera". label = new Label("Esta ea la tarjeta n Q add(labe1). panel2 = new cardpanel(this. panel3 = new cardPanel(this. CardLayout cardlayout. "tres"). -dosm). se puede repetir sobre las tarjetas disponibles.import java. add(button). panell = new cardPanel(this.addActionListener(applet). cardlayout. button. usando un índice que se incrementa y se evalúa con la sentencia switch: .

1 1. "No hasta que sea un experto en grid bag layout". "primerom). break. Cuando el usuario hace clic sobre el botón "Tarjeta siguiente". "segundo"). 1 if(index == 3) index = 0.show(this. "tercero").1 1.public void actionPerformed(ActionEvent eventi i switch (++index) { case 1 : cardlayout. dando vueltas sobre las tarjetas. todavía no".show(this. Y permiten especificar. repainto. Veamos un card layout y cómo funciona. Grid bag layouts "De acuerdo". esta applet se puede encontrar en card. 7 Sioplet Tar~eta siguiente 1 Esta es la tarjeta no tres Figura 7.java en el C D . dice el programador novato. Usar un card layout. > } El resultado se muestra en la figura 7. más exactamente que cualquier otro gestor de esque" 1 1 . break. grid bag layours. break. la applet cambia a la siguiente tarjeta del esquema. le dice. case 3: cardlayout. "Ya soy un experto en 10s esquemas de AWT". case 2: cardlayout. Grid bag layouts son los esquemas AWT más complejos y flexibles. Hay un esquema más que vamos a revisar.show(this. "No.

Rectangle r) protected void ArrangeGrid(c0ntainer Obtiene la cuadrícula del padre.awt. protected java. Tabla 7. Constructor de la clase GridBagLayout. Métodos de la clase GridBagLayout. .22. floatgetLayoutAlignmentY(Container Se obtiene la alineación a lo largo padre) del eje y . int[][] getLayoutDimensions() Determina la anchura de la columna y las alturas de la fila para el layout grid. el lugar donde se quiera que vayan los componentes. voidaddLayoutComponent(String nombre. padre) GridBagConstraints getconstraints (Component comp) Obtiene los constraints del componente dado. Añade al esquema el componente dado. Object 1java. Tabla 7. Component comp) protected void AdjustForGravity (GridBagConstraints constraints. GrídBagLayout() Crea un gestor de grid bag layout. l a n g .22 y sus métodos en la tabla 7. voidaddLayoutComponent(Component comp.23.23.mas.awt. Este es el diagrama de herencia para la clase GridBagLayoutClass. floatgetLayoutAlignmentX(Container Se obtiene la alineación a lo largo padre) del eje x. Ajusta las características de gravedad.GridBagLayout El constructor de GridBagLayoutClass se encuentra en la tabla 7. usando el objeto constraint. java. Obtiene el layout constraints. GridBagLayoutln to GetLayoutlnfo(Container padre. int sizeflag) 1 Point getLayoutOrigin() Determina el origen del layoutgrid. Object constraínts) Añade el componente dado al esquema.

String toString() Obtiene una representación tipo string de este esquema. java. Determina el tamaño mínimo del contenedor. por ejemplo. La inicialización de un grid bag layout es un proceso de dos pasos: primero se configura la posición relativa de un componente respecto a los otros. void layoutContainer(Containerpadre) Pone el contenedor. . los campos de esa clase aparecen en la tabla 7. Recupera los constraints para un componente dado. Los componentes se configuran utilizando la clase GridBagConstraints. usando el esquema. usando este esquema. Point location(int x. Añadir componentes a un contenedor usando un grid bag layout se hace igual que con un grid layout. Obtiene el tamaño mínimo del contenedor. Retira del esquema.24. sus constructores en la tabla 7. salvo que se tienen más opciones. lnvalida el esquema. GridBag Layoutlnfo info) void invalidate Layout(Container target) Determina los pesos de las filas y columnas del layout gríd. Determina el tamaño preferido del contenedor. y luego se añade el componente al esquema.25 y su método en la tabla 7.26. int y) protected GridBagConstraints lookupConstraints(Component comp) Dimension maximum LayoutSize (Container target) Dimension minimumLayoutSize (Container padre) Determina qué celda del layout contiene un punto. el componente dado.double[fl getLayout Weights() protected Dimension GetMinsize (Container padre. Establece los constraints para los GridBagConstraints constraints) componentes dados en el esquema.a wt. DimensionpreferredLayoputSize (Container padre) void removeLayoutComponent (Component comp) void setConstraints(Component comp. se pueden poner las alturas y anchuras relativas de los componentes. Obtiene las dimensiones máximas del esquema dados los componentes del contenedor.

Pone el componente en la esquina superior derecha de su área de visualización. Pone el componente en el lado derecho de su área de visualización. o que . centradoverticalmente. Pone el componente en la esquina superior derecha de su área de visualización. Campos d e la clase GridBagConstraints. int gridheight int gridwidth int gridx int gridy static int horizontal lnsets insets int ipadx int ipady static int NONE static int NORTH static int NORTHEAST static int NORTHWEST static int RELATIVE lndica el número de celdas en una columna para el área de visualizacióndel componente. Este campo se usa cuando el área de visualización del componente es más grande que el tamaño solicitado por él. Redimensiona el componente. lndica el padding externo del componente. lndica que este componente es el siguiente al último componenteen su columna o fila. horizontalmente.24.Tabla 7. lndica el padding interno x del componente.centrada horizontalmente. Pone el componente en la parte superior de su área visualizable. lndica el número de celdas en una fila para el área de visualización del componente. lndica que no se redimensione el componente. Pone el componente en el centro de su área de visualización. lndica la celda en la parte superior del área de visualización del componente . lndica la celda a la izquierda del área de visualización del componente. - int anchor static int BOTH static int CENTER static int EAST Usado cuando el componente es más pequeño que su área de visualización. lndica el padding interno y del componente. Redimensiona el componente horizontal y verticalmente.

Constructores de la clase GridBagConstraints. GridBagConstraints(intgridx. Pone el componente en el fondo de su área visualizable. Especifica cómo se distribuye el espacio vertical extra. int fill. in t ipady) Tabla 7. int gridwidth. Método de la clase GridBagConstraints. 1 GridBagConsfraints() Crea un objeto GridBagConstraint. centrado verticalmente.este componente está situado a continuación del componente previamente añadido. pero no horizontalmente. Especifica cómo se distribuye el espacio horizontal extra. centrado horizontalmente. Pone el componente en la esquina inferior izquierda de su área de visualización. Pone el componente en el lado izquierda de su área de visualización. Pone el componente en la esquina inferior izquierda de su área de visualización. int ipadx. Tabla 7. insets. insets. double weightx. double weighty. Redimensiona el componente verticalmente. sados. int los campos inicializados con los valores pagridheight. I - 1 0bject clonej) Crea una copia de este grid bag constrainf. int anchor. 1 .25.26. static int REMAINDER static int SOUTH static int SOUTHEAST static int SOUTHWEST static int VERTICAL double weightx double weighty static int WEST Especifica que este componente es el último en su columna o fila. Crea un objeto GridBagConstraintscon todos int gridy.

pero al segundo botón se le da el doble de peso x que a los otros.Boton 2 Boton 3 Figura 7.12. la applet devuelve el botón que se ha pulsado. haciendo que el botón del medio sea el doble que los otros. se dará a cada componente el mismo peso y. En este caso.event. public class gridbag extends Applet implements ActionListener ( Button buttonl. se han puesto tres botones en la fila superior del esquema. Crearemos la applet que se muestra en la figura 7.App1et.BOTH.awt. public void init0 { GridBagLayout gridbag = new GridBagLayoutO. . y se añade un cuadro de texto debajo. import java. Cuando el usuario hace clic sobre un botón.*. Comencemos creando un grid bag layout y las restricciones de un objeto: import java.awt. TextField textl. GridBagConstraints constraints = new ~ r i d ~ a g ~ o n s t r a i n t s o . Usar un grid bag layout. constraints. Estos valores representan los pesos relativos que se quieren dar a los componentes en la misma fila o columna.*. constraints.weighty = 1. import java. Veamos un ejemplo de cómo funciona un grid bag layout. setLayout(gridbag).12.applet. button2. Se puede especificar las coordenadas x e y para los componentes que se añadan a un grid bag layout usando los campos weightx y weighty. como se puede ver. button3. aquí.fil1 = GridBagConstraints.

constraints.BOTH. gridbag. button2. gridbag.weighty = 1. constraints. constraints.gridwidth = ~ r i d ~ a ~ ~ o n s t r a i n t s .setConstraints(button1.addActionListener(this). . como sigue: public void init ( ) ( GridBagLayout gridbag = new GridBagLayoutO. constraints).R E M A I N D E R . constraints). setLayout(gridbag).BOTH. add(button2). GridBagConstraints constraints = new GridBagConstraintsO. se creará el primer botón y se añadirá al esquema.setActionConmuind("Botón 1").BOTH.setConstraints(button1. constraints. buttonl. button3 = new ~utton("Botón " ) . button2 = new Butt~n(~Botón 2").weightx = 1. 3 constraints.set~ction~ommand(BotÓn 1").weightx = 1. GridBagConstraints constraints = new GridBagConstraintsO. pero al siguiente botón se le dará un peso x de 2. add(button1).setConstraints(button2. conatraints.fill = GridBagConstraints. constraints). constraints. setLayout(gridbag). constraints. para hacer que sea el doble de ancho que los otros dentro de la misma fila: public void init ( ) 7 I Grid~ag~ayout gridbag = new GridBagLayoutO.weightx = 2. gridbag.setConstraintc(button3. buttonl.addActionListener(this). constraints). constraints. gridbag.setActionCommand("Botón 2"). buttonl = new Button("B0tÓn 1"). button2. A continuación.weigthx = 1.weighty = 1.addActionListener(this). buttonl = new Button("Botón 1").Observe que el campofill de constraints del objeto se está inicializando lo con GridBagConstraints. El primer botón tiene un peso x de 1. que significa que el gestor de esquemas extenderá sus componentes en ambas dimensiones para rellenarlas. add(button1). buttonl. buttonl.fil1 = GridBagConstraints.

20.gridwidth = GridBagConstraints. int left. Con los intercalados se puede añadir espacio entre los bordes del contenedor y los componentes. dice el programador novato. Ahora este código creará la applet que se muestra en la figura 7. 1 Y eso es todo. 20.REMAIN~~~. "¿hay alguna forma de añadir un borde alrededor de los componentes del esquema?" "Claro que la hay".textl = new TextFieldO.setConstraintc(text1.13. Esto se puede hacer con los métodos setHgap y setVgap de los card layout. Este ejemplo se puede encontrar en el fichero gridbag. ) Lo único que queda es gestionar los clics sobre el botón y hacer que se visualice el número del botón sobre el que se ha hecho clic: public void actionPerformed(ActionEvent e) I textl. int right) Este es un ejemplo en el que se añaden intercalados de 20 pixels en todos los bordes de la applet desarrollada en el apartado anterior: public Insets getInsets ( ) { return new Insets(20. constraints. que tiene el siguiente constructor: insets (int top. hay un espacio de 20 pixels alrededor de los componentes del contenedor. ) El resultado se muestra en la figura 7. Estos intercalados se crean con la clase Insets. flow layout y . ir intercalados y rellenos "Veamos". int bottom. constraints). Como se puede ver en esta figura. "Se pueden usar los intercalados y los rellenos". le responde.12.java en el CD.getActionCommand~)).setText("Hiz0 clic en " + ((Button) e.getSource()). addítextl). gridbag. 20). Además se pueden rellenar los componentes individuales.

CENTER). public class multiplier2 extends Applet implements ActionListener TextField textl.awt.event. import java. multiplylabel = new Label("*". así como usando los miembros ipadx e ipady de los grid bag layouts.*.Label. textl = new TextField(l0). . Label multiplylabel. import java. text2. buttonl = new Button("=").Applet. add(text1).applet. public void init0 g = new GridLayout(5.*.grid layout.13. 1). GridLayout g. se puede modificar la calculadora de multiplicar que se escribió anteriormente en este capítulo para añadir un espacio vertical de 10 pixels entre los componentes. Por ejemplo. text2 = new TextField(l0). Button buttonl. como sigue: import java. add (buttonl) .awt. { Figura 7. add(text2). add(multiplylabe1). . Usar intercalados. answertext. g setvgap (10) .

getTextO ) .setText(String.getSource( == buttonl) ( ) int product = Integer. Estos son los métodos de LayoutManager2 que se tendrán que sobrescribir: public void addLayoutComponent(String nombre. answertext. Usar relleno. } 1 1 El resultado se muestra en la figura 7.parseInt(text2.14. La clase contenedor le llama.14. si se implementa la interfaz LayoutManager2 en una clase (la interfaz LayoutMarzager no soporta las restricciones).answertext = new TextField(l0). Crear el propio gestor de esquemas Uno mismo puede poner los componentes en un contenedor si desinstala el gestor de esquemas del contenedor (ver la introducción de este capítulo para más detalles).va1ueOf(product)). podrá incluso crear su propio gestor de esquemas. sobrescribe este método si se quieren saber los nombres de los componentes del esquema. De hecho. ) public void actionPerformed(ActionEvent e) { if (e. Figura 7. Component componente): este método añade un componente al esquema.parseInt(textl. add(answertext1 .getText0) * Integer. .

move y reshape para gestionar los componentes. public Dimension minimuLayoutSize(Container target): Devuelve el tamaño mínimo del componente. public Dimension maximumLayoutSize(Containertarget): Devuelve el tamaño máximo del componente.5 al centrar el componente.public void removeLayoutCornponent(Componentcomponente): elimina un componente del esquema. devolviendo 1 al alinearlo tan lejos como se pueda del origen y devolviendo 0. public void invalidateLayout(Container target): Invalida un esquema. public float getLayoutAlignmentX(Container target) and public jloat getLayoutAlignmentX(Container target): Especifica cómo alinear los componentes en las direcciones x e y. devolviendo un valor de O al alinear los componentes en el origen. . lo que significa que se debería borrar cualquier información oculta si se llama a este método. public void layoutContainer(Container padre): Utiliza los métodos resize. public Dimension preferredLayoutSize(Container padre): Devuelve el tamaño ideal del contenedor padre.

ya que usando las barras de desplazamiento. cadenas de texto. barras y cuadros de desplazamiento Este capítulo trata un número importante de componentes AWT: listas.m AWT: Listas. por lo que es una buena idea colocar elementos en listas. en la que puede hacer una selección. resultan familiares para casi todos los usuarios GUI. el espacio es un premio. Observe que uno de los temas principales de este capítulo es el desplazamiento. y los veremos rápidamente en esta sección. por grandes documentos. todos los controles de este capítulo lo soportan de una u otra forma. barras de desplazamiento y cuadros de desplazamiento. En los entornos de trabajo con ventanas. cuadros de texto. Estos componentes son fundamentales para la programación AWT. cuadros de lista desplegables. se pueden tener listas largas en componentes de . con frecuencia. Listas Como su nombre indica. áreas de texto. permitiendo al usuario moverse. cuadros de lista. un control de tipo lista presenta al usuario una lista de elementos. fácilmente.

por lo que se puede visualizar más texto. El usuario puede seleccionar el elemento de la lista que quiera e ' iniciar alguna acción. . Además. Sin embargo. si se soporta la selección múltiple.lista cortos. Los cuadros de lista desplegables se parecen a los cuadros de texto. Si la lista de elementos es larga. aunque no se pueden editar. hay que pensar en cómo utilizar el ratón dentro de una lista. Si el usuario abre otra vez la lista. Áreas de texto Las áreas de texto son como los cuadros de texto. con el doble clic. Cuando se quiere trabajar con documentos enteros. las listas pueden soportar la selección múltiple.' tos para seleccionar. y el usuario puede seleccionar una de ellas. Una vez hecha la selección. Usando las teclas Mayús o Control y haciendo clic al mismo tiempo se obtiene el mismo efecto que si se hace clic en un elemento. el resto se deselecciona. Al hacer doble clic sobre un elemento. la selección actual aparece resaltada. Para resolver este problema. Cuadros de lista desplegables Los cuadros de lista desplegables presentan al usuario una lista de elemen. con filas y columnas. El resultado es un cuadro de 1 que tiene el número de filas y columnas que se haya especificado. como puede ser hacer clic sobre un botón. se inicia algún tipo de acción. porque al hacer clic sobre un elemento se selecciona y luego. salvo que soportan textoen dos dimensiones. en vez de con líneas de texto. para iniciar una acción cuando se trata de selecciones múltiples. se abre una lista que contiene todas las selecciones disponibles. hay que indicar su tamañi filas y columnas (medido en caracteres). se cierra la lista y se visualiza la selección actual. Cuando el usuario hace clic sobre la flecha. Observe que estos cuadros sólo están diseñados para visualizar al mismo tiempo una única selección. Sun sugiere el uso de algún otro evento. haciendo doble clic sobre él. usando las teclas Mayús y Control. con un pequeño botón a la derecha que tiene una flecha apuntando hacia abajo. Como el resto de componentes de este capítulo. los cuadros de listas desplegables soportan el desplazamiento. se usan las áreas de texto. En el momento de crear el área de texto. pero hay una diferencia. son más compactos que las listas. lo que significa que no se puede seleccionar a la vez más de un elemento. las barras de desplazamiento aparecerán al lado de la lista automáticamente.

es el momento de pasar a la siguiente sección. el usuario puede hacer clic sobre el recorrido de la propia barra de desplazamiento (es decir. podemos capturar los eventos generados por la barra de desplazamiento para leer este nuevo valor. por supuesto. la opción de ajuste de palabras se habilita automáticamente. de una vez. Eso es todo. elevador o burbuja) de la barra de desplazamiento seleccionado un valor dentro de un intervalo continuo.Al igual que el resto de los componentes de este capítulo. y todos los usuarios de interfaces gráficas conocen su existencia y su funcionamiento. Se usan las áreas de desplazamiento para añadirles componentes y permitir que el área de desplazamiento los gestione. FT Barras de desplazamiento Las barras de desplazamiento son. . ambas o ninguna. los controles de Java las soportan pero no del todo. sólo será visible una parte de él. vertical. Java tiene la clase ScrollPane. los elementos de desplazamiento más importantes. como puede ser un cuadro de texto largo. Ahora que ya hemos revisado el contenido de este capítulo. Para hacer que el desplazamiento en otros componentes sea más fácil. Los usuarios utilizan el ratón para manipular el indicador (también denominado cuadro de desplazamiento. cuando el usuario selecciona un valor diferente. Se puede especificar si se quiere una barra de desplazamiento horizontal. Paneles de desplazamiento Es posible que se quieran utilizar las barras de desplazamiento para moverse en otros componentes. Si no se tiene una barra de desplazamiento horizontal (y sólo si no tiene una barra de desplazamiento horizontal). El usuario también puede hacer clic sobre los dos botones de flecha que hay en los extremos de la barra de desplazamiento para aumentar o disminuir el valor en cantidades fijas que habremos establecido previamente. Una vez que se haya añadido un gran componente a un área d e desplazamiento. las áreas de texto soportan el desplazamiento. la zona comprendida entre el cuadro de desplazamiento y los botones de desplazamiento) para aumentar o disminuir el valor en cantidades fijas (normalmente mayores que las anteriores) que también habremos establecido previamente. Este intervalo se establece al crear la barra de desplazamiento y. y se podrán usar las barras de desplazamiento del área para ir a otras partes de ese componente. Por último.

este tratamiento de las palabras al final de la línea quedará deshabilitado. dice el programador novato. sus constructores en la tabla 8. "Pruebe las áreas de texto". "¿Y se ha quedado sin espacio?" "Claro". Tabla 8. una barra de desplazamiento horizontal.3. Añade. le sugiere.1. En este caso.1. se pueden visualizar todos los documentos en áreas de texto. -T static int SCROLLBARS-BOTH static int SCROLLBARS-HORIZONTALONL Y static int SCROL L BARS. se creará un área de texto de 10 filas y 20 columnas (observe que estas dimensiones se miden en caracteres).2 y sus métodos en la 8." Usted sonríe y le dice.. "tengo un problema. . que si ha habilitado una barra de desplazamiento horizontal. "no es muy conveniente escribir una novela entera como si fuera una línea de texto". Este es el diagrama de herencia de la clase AWT TextArea: Verá los campos de la clase TextArea. static int SCROLLBARSVERTICAL Sólo visualiza una barra de desplaONL Y zamiento vertical. Un área de texto es un cuadro de texto de dos dimensiones. y. dice el programador novato. que se usan en los constructores de la clase TextArea. de hecho': tienen una gran ventaja.NONE Añade las barras de desplazamiento horizontal y vertical. únicamente. Además se añadirá un botón sobre el que el usuario puede hacer clic para visualizar el texto "¡Hola desde Java!" en el área de texto. He escrito mi4 novela en un cuadro de texto de Java.Usar las áreas de texto "Uh-oh". en la tabla 8.. sin embargo. incluyendo el tratamiento de las palabras al final de las líneas. Campos de la clase TextArea. 1 Veamos un ejemplo. Indica que no se creará ninguna barra de desplazamiento en el área de texto. Además se pueden usar las barras de desplazamiento para moverse por el texto. Observe.

int filas. con el texto dado ycon el número de filas y de columnas dado. Establece el tamaño mínimo del área de texto. Construye una nueva área de texto. columnas y barras de desplazamiento. . int columnas) Construye una nueva área de texto. Fija el tamaño mínimo del área de texto con el número de filas y de columnas dado. vacía. int filas. Añade texto al texto actual del área de texto.Tabla 8. int columnas) TextArea(String texto. int columnas. Métodos de la clase TextArea. Establece el tamaño preferido de un área de texto con el número de filas y de columnas indicado. Establece el tamaño preferido del área de texto. con el número de filas y columnas indicado. / void addNotify() void appendText(String str) void appendText(String str) int getColumns() Dimension getMinimumSize(1 Dimension getMinimumSize(intfilas. Reemplazado append(String1. intbarras-de-desplazamiento) Tabla 8. por Obtiene el número de columnas del área de texto.2. TextArea() TextArea(int filas. Construye una nueva área de texto. Construye una nueva área de texto con el texto dato y fija la visibilidad de las filas. int columnas) Crea el compañero del área de texto. Constructores de la clase TextArea. int columnas) Dimension getPreferredSize() Dimension getPreferredSize(intfilas.3. TextA rea(String texto) TextArea(String texto. Construye una nueva área de texto con el texto dado. Obsoleto.

Por ejemplo. Así es cómo se usa el método insert: import java. import java. void insert(String str. Cambia el texto entre las posiciones intfinal) de inicio y final.*. Obtiene un valor enumerado que indica la visibilidad de la barra de desplazamiento. Devuelve una representación en cadena del estado del área de texto. Reemplazado porgetpreferredSize().awt. . int). Fija el número de filas. Reemplazado por insert(String. Obsoleto.int getRows() int getScrollbarVisibility() Obtiene el número de filas del área de texto. int. o se puede usar el método append para añadir texto a continuación del actual. int). int pos) Dimension minimumSize() Dimension minimumSize(intfilas. Reemplazado porreplaceRange(String. Obsoleto. intcolumnas) void replaceRange(String str. Inserta el texto dado en la posición del área de texto indicada. Reemplazado porgetMinimumSize(). int). se puede usar el método insert para poner texto en una posición específica (comenzando en O) de la cadena que el área de texto gestiona. intcolumnas) protected String paramString() Dimension preferredSize() Dimension preferredSize(intfilas.awt. Obsoleto. void replaceText(String str.applet. int pos) void insertText(Sring str. int). Reemplazado porgetMinimumSize(int. int final) Obsoleto. Fija el número de columnas.event. Reemplazado porgetpreferredSize(int.Applet. Obsoleto. 1 void setColumns(int columnas) void setRows(int filas) I Hay varias formas de situar texto en un área de texto.*. import java. int inicio. int inicio. Obsoleto.

buttonl. str e s la cadena con la que se quiere reemplazar el texto antiguo. por ejemplo. dice.SCROLLBARS-BOTH). Con las áreas de texto se pueden hacer más cosas.addActionListener(this). int start.public class areadetexto extends Applet implements ActionListener TextArea textareal. add(button1). start es el comienzo del rango de caracteres a reemplazar y end es el final del rango. 0 ) . 10. pub1ic void init ( ) { I textareal = new TextArea("". add(textareal) . se puede seleccionar y reemplazar texto. if(e. "Quieren que sea posible seleccionar y reemplazar texto". El resultado aparece en la figura 8. int end).insert(msg. "Algunas personas". y le dice. dice ESP. como es usual. "Los usuarios se están quejando del nuevo procesador de textos que ha escrito en Java". Donde. buttonl = new Button("¡Haga clic aquí!"). 1 1 1 Además. . Ver el siguiente apartado para más detalles. } public void actionperformed (ActionEvent e) { String msg = "¡Hola desde Java! " . TextArea. 20. "¿Sí?" pregunta. getsource ( ) == buttonl) { textareal. Button buttonl. observe que se han añadido al área de texto barras de desplazamiento horizontal y vertical. "nunca están satisfechas". Se puede usar el método replaceRange para reemplazar un rango de texto en un área de texto: void replaceRangeíString str.1. Reemplazar texto en áreas de texto El especialista en soporte de productos (ESP) no está contento.

applet." en un área de texto. public void init() { textareal = new TextArea("Ya es la hora.event. buttonl = new Button("~ambiar texto seleccionado").": import java. import java . import java.". Button buttonl. * .awt.1. Empezamos creando la nueva área d e texto e inicializándola con el texto "Ya es la hora. 7 public class reemplazar extends Applet implements ActionListener { TextArea textareal. awt .Figura 8. 5 . 20. el addíbuttonl) . Este es un ejemplo en el que se visualiza el texto "Ya es la hora. El usuario puede seleccionar parte o todo de ese texto y hacer clic sobre un botón para reemplazar el texto seleccionado con el mensaje "¡Hola desde Java!". buttonl.Applet. Usar un área de texto.addAction~istener(this).*. add(textareal) . 1 .

se puede buscar. Además d e reemplazar el texto. La clase TextArea no soporta ningún método directo para buscar texto pero la clase String sí. } El resultado se muestra en la figura 8. y encontrará este ejemplo en el CD como reemplazar-java. exasperado. "¿Qué hacemos?". Empezaremos creando una nueva área de texto.getSelectionStart~). Por lo tanto. se puede determinar el texto seleccionado utilizando los métodos getSelectionStart y getSelectionEnd y luego reemplazar el texto seleccionado con "¡Hola desde Java!".getSource0 == buttonl) ( textareal. "Ahora.2.2. Figura 8. los usuarios quieren poder buscar texto cuando usan su procesador de textos".replaceRange("iHola desde Java!" textareal. Este es un ejemplo en el que se permite al usuario hacer clic sobre un botón para buscar y seleccionar la palabra hora en el texto "Ya es la hora. "¿Verificar letra por letra?".Cuando el usuario hace clic sobre el botón.": . Ver el siguiente apartado. Reemplazar el texto seleccionado en un área de texto. le pregunta. usando el método indexOf. se puede copiar el texto de un área d e texto en un objeto String y buscar ese objeto en el texto que se quiera. como sigue: public void actionPerformed (ActionEvent e){ if(e. y luego lo inicializaremos con el texto "Ya es la hora.getSelectionEnd0) ." de un área de texto. informa. textareal. Buscar y seleccionar texto en áreas de texto El especialista en soporte de productos regresa descontento de nuevo.

Ahora. String s2 = new String("hora"). cuando el usuario hace clic sobre el botón. 5.event. import java. 20. la hora.getText0.applet.class WIDTH=200 HEIGHT=200 > </APPLET> */ public class buscar extends Applet implements ~ction~istener I TextArea textareal.getSource() == buttonl) { String s = textareal.SCROLLBARS-BOTH).awt.getSource0 == buttonl)I String S = textareal. se puede buscar el texto "hora" usando el método indexOf de la clase String: public void actionperformed (ActionEvent e){ if(e.indexOf(s2). el texto del área se carga en una cadena llamada S: public void actionperformed (ActionEvent e){ if(e. int location = s. .import java. add(textarea1) . public void init ( ) { textareal = new TextArea("Y8 es TextArea. import java. add(button1). Ahora.*.". buttonl.getText0.awt.Applet. buttonl = new Button("Buscar \"hora\" " ) .add~ctionListener(this) . Button buttonl.*. /* <APPLET CODE=buscar.

Applet started Figura 8.getSource0 == buttonl){ String s = textareal.Una vez que se haya encontrado la cadena "hora".indexOf(s2). "Aproximadamente dos mil pies de larga".3. el código busca y resalta el texto "hora" en el área de texto.lengthO) . Buscar y seleccionar texto en un área de texto. int location = s.le pregunta. "Correcto". le dice prudentemente.select(location. textareal. "¿Sí?".getText0. la lista es más larga que la pantalla". 1 1 El resultado de este código aparece en la figura 8. int selectionEnd). "Por supuesto.3.java en el CD. - Usar listas El especialista de soporte de productos regresa y dice. le dice ESP. Este ejemplo se llama buscar. location + s2. Así es como usaríamos el método select en el código: public void actionperformed (ActionEvent e) { if (e. String s2 = new String("horaW). "Es sobre su último programa de catálogo de CD de música clásica. Así es como se usa select en general: void select (int selectionstart. Cuando el usuario hace clic sobre el botón. hay más de cien mil listas". . se usará el método TextAreaselect (heredado de la clase AWT TextComponent) para resaltar el texto. "Hay un problema".

muchos de ellos son útiles. Este es el diagrama d e herencia de la clase List: Los constructores de la clase List se encuentran en la tabla 8.4 y su? métodos en la tabla 8.Si se tiene una lista larga de elementos para presentar. List (int filas. Añade el action listener dado pala obtener los eventos de acción de la lista. Reemplazado por add (String). S e puede rellenar una lista con muchos elementos de texto. void add(Stringelement0) void add(String elemento. Obsoleto. que devuelve el número de elementos de la lista. normalmente haciendo clic sobre un botón. Listo List(int filas) Crea un nuevo cuadro de desplazamiento. si multipleMode es verdadero.5. como getltemcount. Crea un nuevo cuadro de desplazamiento. El usuario puede resaltar un elemento de la lista haciendo clic sobre él y puede hacer doble clic para iniciar alguna acción. int índice) void addActionListener(ActionListener 1 ) void addltem(String elemento) Añade el elemento dado al final de la lista. con el número de líneas visibles que se indica. usando el método add de la clase List y presentar al usuario sólo unos pocos al mismo tiempo (se puede seleccionar cuántos). Hay que prestar especial atención a la tabla de métodos. hay que pensar e? utilizar un control de tipo lista. De hecho. boolean multipleMode) Crea una nueva lista con el número de filas especificado y se habilita la selección múltiple. Añade el elemento dado a la liSta en la posición marcada por el índice. el usuario puede seleccionar múltiples elementos de una lista e iniciar alguna acción. Constructores de la clase List. .4. Tabla 8.

Obtiene los elementos de la lista. int índice) Obsoleto. int end) void deselect(int índice) String getltem(int índice) int getltemCount() String[] getltemso Dimension getMinimumSize() Crea el compañero de la lista. Dimension getPreferredSize() Obtiene el tamaño preferido de esta lista. Obsoleto. Reemplazado por remove (String) y remove(int). void addltemListener(itemListener 1) Añade el item listener dado para obtener eventos de elemento de la lista. Reemplazado por add (String. Deselecciona el elemento asociado al índice dado. void addNotify() boolean aIlowsMultipleSelections() void clear() int countltems() void delltem(int position) void delltem(int start. Obsoleto. Obsoleto.void addltem(String elemento. Obtiene el número de elementos de la lista. int getRows() Obtiene el número de líneas visibles de la lista. Obtiene el elemento asociado al índice dado. Dimension getMinimumSize(intfilas) Obtiene las dimensiones mínimas de la pantalla para una lista con el número de filas dado. . Dimension getPreferredSize(int f ilas) Obtiene las dimensiones preferidas para una lista con el número de filas dado. int). Determina el tamaño mínimo de la lista. Reemplazado por removeA//(). Obsoleto. Reemplazado poris MultipleMode(). Obsoleto. Reemplazado por getltemCount(). No es de uso público.

Reemplazadopor getMinimurnSize(). Obsoleto.int getSelectedlndex() int[] getSelectedlndexes() String getSelectedltern() String[] getSelectedltems() Object[] getSelectedObjects() Obtiene el índice del elemento seleccionado en la lista. Obsoleto. Obtiene los índices seleccionados de la lista. Obsoleto. Obsoleto. Obtiene los elementos seleccionados de esta lista. Obtiene el índice del último elemento que se hizo visible con el método makeVisible. Obsoleto. Reemplazado por getPreferredSize(). Determina si la lista permite hacer selecciones múltiples. Obtiene el string que representa el estado de esta lista. ~ a c eque el elemento del índice ' dado sea visible al principio de la lista. Reemplazado poris IndexSelected(int). Reemplazado por getpreferredsize(int). Determina si el elemento dadode la lista está seleccionado. Procesa los eventos de acción que ocurren en este componente envián- int get Visiblelndex() boolean islndexSelected(int índice) boolean isMultipleMode() boolean isSelected(int índice) void rnakeVisible(int índice) Dirnension rninimurnSize() Dimension rninimurnSize(int f ilas) protected String pararnString0 Dirnension pre ferredSize() Dimension preferredSize(intf ilas) protected void processActionEvent (ActionEvent e) . Obtiene el elemento seleccionado de esta lista. Obtiene los elementos seleccionados de la lista en un array de objetos. Reemplazadopor getMinimurnSize().

Reemplazado porsetMultipleMode(boo1ean). Cuando el usuario haga doble clic sobre uno de ellos. Obsoleto. Veamos un ejemplo. Establece el indicadorque determina si la lista permite selección múltiple. Procesa eventos de elemento que se produzcan en la lista enviándolos a los objetos ItemListener registrados. se añadirán elementos a una lista. Reemplaza el elemento de la lista int índice) que ocupa el índice dado con la nueva cadena. En este caso. Elimina todos los elementos de la lista. Elimina la primera ocurrencia de un elemento de la lista. se notificará en un cuadro de texto que uno de . void select(int índice) void setMultipleMode(boolean b) void setMultipleSelections(boolean b) Selecciona el elemento de la lista que ocupa el índice dado. void remove(int posición) void remove(String elemento) void removeActionListener(ActionListener 1) void removeAll() void removeltemListener(ltemListener 1) void removeNotify() void replaceltem(String valor-nuevo. para que no reciba más eventos de acción de la lista. Elimina el actionlistenerdado. Elimina el item listenerdado para que no reciba más eventos de elemento de la lista Elimina el compañero de la lista. protected void processEvent (A WTEvent e) protected void processltem Event (ItemEvent e) Procesa los eventos de esta lista. Elimina el elemento de la lista que está en la posición dada.dolos a los objetos ActionListener registrados. haciendo que sólo cuatro de ellos se vean de una vez.

ellos se ha seleccionado.add('Elemento 9") . se añaden nueve elementos usando el método add: public void init ( ) { textl = new TextField(20). . Empezaremos creando la lista y después haremosT que sólo cuatro líneas sean visibles.applet. listl.add(~Element0 " ) .add("Elemento 3 " ) .Applet. listl = new List(4). add(list1).add("Elemento 1"). awt . import java. add(text1). li~tl.add("Elemento 2 " ) . add(text1). listl = new List(4).add("Element0 5 " ) . public class lista extends Applet implements ActionListener List listl. listl. listl.add("Element0 6 " ) . listl. TextField textl: public void init ( ) { textl = new TextField(20).add("Elemento 8 " ) . listl.event. listl. { 1 1 Ahora.awt. import java .*. 7 listl.add("Element0 4 " ) . listl. * . como sigue: import java.

listl.add("Elemento 9 " ) . listl. Esto significa que las listas utilizan las interfaces ActionLisrener.add("Element0 2 " ) . listl. 1 1 El resultado de este código se muestra en la figura 8.Después de añadir la lista a este esquema. que es cuando se seleccionan los elementos en una lista): public void actionPerformed(ActionEvent e ) { En este caso. listl. al igual que los botones. addítextl) .add("Element0 4 " ) . listl. listl. Ahora necesitamos añadir un método actionPerformed al main de la clase applet para gestionar los dobles clic (a este método no se le llama con clic simples. porque la lista actual es más larga que el .add("Elemento 3 " ) . listl = new List(4).add("Element~7 " ) . se le añade un listener.add("Elemento 6 " ) . ese elemento se visualiza en el cuadro de texto. son visibles en la lista. Cuando el usuario hace doble clic en un elemento de la lista. ~ e t ~ e l e c t e d I t )e.add("Element0 1"). como sigue: public void actionPerformed(ActionEvent e ) { if(e.4. listl. m ~ ) e. Observe además que sólo cuatro elementos de los nueve que hay en total. add(list1). s e t ~ e x t ( ( ( ~ i s t ) g e t S o ~ r c e ( ) ) . listl. se obtendrá el elemento sobre el que el usuario ha hecho doble clic usando el método getSelectedlrem de la clase List (el primer clic del doble clic selecciona el elemento) y luego se visualiza ese elemento en el cuadro de texto.add("Elemento 5 " ) . Así es como añadimos esto al código: public void init ( ) { textl = new TextField(20).getSource() == listl) { t e x t l . listl.add("Elemento 8 " ) .

4. Se pueden hacer más cosas con las listas. Usar listas de selección múltiple q "Uh-oh". se creará una lista que soporta la selección múltiple. se puede permitir al usuario que haga selecciones múltiples. import java. le contesta.event. El usuario puede seleccionar múltiples elementos pulsando la tecla Control y a la vez haciendo clic o seleccionar un rango de elementos pulsando la tecla Mayús y haciendo clic.*.Applet. Usar una lista. "No es problema". Figura 8. Echaremos un vistazo a esto en el siguiente punto.- número de elementos visibles. pero lo tienen que hacer uno por uno". import java. . Mi nuevo programa permite a los usuarios ordenar los alimentos utilizando una lista. Este ejemplo se llama 1ista. El control lista ha añadido automáticamente una barra de desplazamiento vertical. permitiremos al usuario seleccionarvarios elementos y cuando haga clic sobre un botón. "basta con habilitar la selección múltiple en la lista". Si al constructor d e la clase L s se le pasa un segundo parámetro con elw it valor verdadero.java en el CD.applet. En este caso.awt. Veamos un ejemplo. por ejemplo. tengo un problema".*.awt. Empezaremos creando una lista de selección múltiple: import java. dice el programador novato". listaremos los elementos seleccionados en un cuadro de texto.

buttonl.add(~Elemento3").add("Elemento 6 " ) . 1 .add("Elemento 8 " ) . buttonl. listl.'publicclass seleccionmult extends Applet implements ActionListener List listl.add("Elemento 3 " ) . ( > A continuación.add("Elemento 7 " ) .add("Elemento 1"). listl. listl. add(button1). listl = new List(4. listl.add("Elemento 5").add("Elemento7"). String selections [ 1 . listl.addActionListener(this). Button buttonl. ~extField textl.add("Elemento 4 " ) .add("Elemento 5 " ) . listl. listl. true).add("Elemento9"). se añade un ActionListener a la lista y el botón sobre el que el usuario puede hacer clic para visualizar las selecciones hechas en la lista: public void init ( ) { textl = new TextField(40).addActionListener(thic). listl. listl. buttonl = new Button("Mostrar las selecciones"). listl. listl. li~tl.add("Elemento 2 " ) .add(~E1emento9 " ) .add("Element0 1"). buttonl = new Butt~n(~Mostrar las selecciones"). add(text1).add(~Elemento4 " ) . listl. listl = new List(4. add(button1). public void init0I textl = new TextField(40). add(list1) . listl. true).add("E1emento 6 " ) . add(text1). listl. li~tl. add(list1). li~tl.add("Elemento 2").add("Elemento 8 " ) . listl.

añadiendo todos los elementos a una-' cadena que comienza con "Usted seleccionó:": public void actionperformed (ActionEvent e) I String outstrinq = new String("Usted seleccionó:").length. 1 . if (e. for(int 1oopIndex = O . public void actionPerformed(ActionEvent e) { if(e. A continuación. loopIndex++){ outstring += + selections[loogIndexl.getSource() == buttonl) { selections = listl.getSource0 = = buttonl) { selections = listl. for(int loopIndex = O. es necesario usar un botón para mostrar las selecciones múltiples que se han hecho (observe que no se permite al usuario iniciar una acción que involucre selecciones múltiples utilizando el ratón. Finalmente.getSource0 == button1)I selections = listl. if(e. loopIndex++)( outstring += " " + selections[loopIndexl. loopIndex < seiections.getSelectedItems0.qetSelectedIterns0. se usa el método getSelectedltems del componente List para obtener un array de tipo String de los elementos seleccionados: String selections [ 1 . se recorre ese array. loopIndex < selections. se sitúa la cadena con todas las selecciones en el cuadro de texto: public void actionPerformed(ActionEvent e) ( String outstrinq = new String("Usted seleccionó:").getSelectedItems0. Cuando el usuario hace clic sobre e l botón. porque el hacer clic o doble clic sobre cualquier elemento deseleccionará el resto).length.Ahora.

el usuario puede hacer selecciones múltiples en esta nueva lista.5.java en el CD. las selecciones aparecerán en el cuadro de texto. en su lugar". ¡Pero el control lista que estoy utilizando es ya bastante pequeño!" "No hay problema". El resultado aparece en la figura 8.Y eso es todo. "el gran jefe está recortando costes de nuevo. Este hace que se muestre una lista desplegable y que luego se pueda seleccionar un elemento con el ratón. Este es el diagrama d e herencia de los cuadros de lista desplegables: . le dice. y cuando haga clic sobre el botón. y dice que todos los controles deben tener la mitad de su tamaño original. la lista se cierra. Como se puede ver en esta figura. Después. "basta con usar un cuadro de lista desplegable. Los cuadros de lista desplegables son como las listas que sólo visualizan un elemento. Para visualizar toda la lista en un cuadro de este tipo. Este ejemplo se llama seleccionmult. Usar la selección múltiple en una lista. Usted selecciono Elemento 2 Elemento 4 I Figura 8. La selección actual aparece en el cuadro de lista desplegable cuando se cierra la lista (observe que no se puede hacer selección múltiple en este tipo de cuadros).5. se hace clic sobre el botón que se muestra en la parte derecha del control. Usar cuadros de lista desplegables "Vaya". dice el programador novato.

protected String paramString() protected void processEvent (A WTEvent e) protected void processltemEvent (ItemEvent e) Obtiene la representación tipo string del estado de este control. Obtiene el índice del elemento seleccionado actualmente. int índice) Inserta el elemento en la posición dada. Añade un elemento a este control.7. Tabla 8.6 y sus métodos en l a tabla 8. Métodos de la clase Choice. Obtiene la cadena de este control que ocupa el índice dado. Constructor de la clase Choice. Obtiene el número de elementos de este control. Procesa los eventos en este control. Obsoleto. envián- . 1 - void add(Stringelement0) void addltem(String elemento) Añade un elemento a este control. Crea un nuevo cuadro de lista desplegable. Procesa los eventos de elemento que ocurren en este control. ) void addltemListener(1temListener 1 void addNotify() int countltems() String getltem(int índice) int getltemCount() int getSelectedlndex() String getSelectedltem() Object[] getSelectedObjects() void insert(Stringelemento. Crear el compañero de este control. Tabla 8.7.El constructor de la clase Choice se encuentra en la tabla 8. Obtiene un array (longitud 1) que contiene el elemento seleccionado actualmente.6. Reemplazado porgetltemCount(). Obtiene una representación de tipo string de la selección actual. Añade el item Iistener dado para obtener los eventos de este control.

*. public void init ( ) { { .event. y no tiene parámetros): import java. Veamos un ejemplo. Cuando el usuario haga una selección. import java.awt.dolos a cualquiera de los objetos ItemListener registrados. public class choice extends Applet implernentc ItemListener TextField textl.Applet. Fija el elemento seleccionado de este control a la posición indicada. Fija el elemento seleccionado de este control al elemento que tiene el mismo nombre que la cadena dada. void remove(int posición) void remove(Stringelemento) void removeAll() void removeltemListener(ltemListener 1) void select(int pos) void select(String str) Elimina el elemento que está en la posición indicada. Elimina un item listener para que no obtenga más eventos de elemento de este control. se visualizará esa nueva selección en un cuadro de texto. sólo hay un constructor. Elimina todos los elementos del control. se añadirá un cuadro de lista desplegable a un programa y se usará el método add para añadir los elementos a su lista interna. En este caso. import java.awt. Empezaremos creando una nueva lista desplegable y su lista interna (observe que no se tienen muchas opciones para crear este tipo de controles.applet.*. Choice choicel. Elimina la primera ocurrencia de un elemento de este control.

choicel. Indica que un elemento estaba seleccionado.8. choicel = new Choice(). add ("EleIftent0 3" ). El primer número del rango de ID'S usado para los eventos de elemento. no las ActionListener como se hace con los controles de tipo lista.add("Elemento 1"). .add("E1emento 9"). choicel. 1 Con un gran número de elementos como ocurre aquí.add("E1emento 10").add("Element0 7").add("Element0 11"). su constructor en la tabla 8. Indica que el estado de u n elemento cambió. choicel. choicel.add ("Elemento 8" ).9 y sus métodos en la 8. choicel. choicel. Ahora.10. itemStateChanged: void itemStateChanged(1temEvent e) A este método se le pasa un objeto de la clase ItemEvent. Campos d e la clase ItemEvent. choicel.8. Con este tipo de controles. La interfaz ItemListener sólo tiene un método. choicel . Los campos de7 esta clase se muestran en la tabla 8. el cuadro de lista desplegable añadirá automáticamente una barra de desplazamiento vertical. usaremos las interfaces ItemListener. static int DESELECTED static int ITEM-FIRST static int lTEM-LAST static int ITEM-STATE-CHANGED static int SELECTED Indica que un elemento seleccionado ha sido deseleccionado. choicel.add("E1emento 12").add("E1emento 2"). choicel. add(text1). gestionaremos los eventos del cuadro de lista desplegable. choicel. add("Elemento 4" ).textl = new TextField(20). choicel. Tabla 8. add ( "Elemento 5" ). El último número del rango de ID's usado para los eventos de elemento.add("E1emento 6").

9. choicel. choicel. choicel. add(text1). usaremos el método getselectedltem del cuadro de lista desplegable para determinar qué elemento se seleccionó y luego lo visualizaremos en un cuadro de texto: . choicel. Object item.add("Elemento 5 " ) .add("E1emento 6 " ) . choicel. choicel. choicel. choicel. ItemEvent(ltemSelectable source. Cuando el usuario hace una selección de la lista interna.Tabla 8. Constructor de la clase ItemEvent. Métodos de la clase ItemEvent. choicel. choicel. int statechange) Tabla 8.add("E1emento 8 " ) . String paramString0 A continuación se añade un ItemListener al cuadro de lista desplegable. seleccionado o deseleccionado).add("E1emento 4 ") . Obtiene el que origina el evento. Obtiene una cadena que identifica este evento.add("Elemento 3 " ) .add("Elemento 2 ") . Obtiene el tipo de cambio de estado (es decir. Object getltem() ltemSelectable getltemSelectable() int getStateChange0 Obtiene el elemento afectado por el evento. addíchoicel).add("Elemento 7 " ) .add("Elemento 1"). int Construye un objeto ItemEvent.add("Elemento 1 1 ") .add("E1emento 12").add("Elemento 9 " ) . como sigue: public void init { () textl = new TextField(20). id. choice1 = new Choice(). choicel.10.add("Elemento 10"): choicel.

pero están hartos de escribir los valores del color en formato hexadecimal". y cuando lo hacen. Todos los usuarios GUI están familiarizados con las barras de desplazamiento.6.public void itemStateChanged(1temEvent e ) I if(e. que tiene el siguiente diagrama de herencia: .setText("Usted eligió + ííChoice)e. "Tengo un problema. 7 Usar barras de desplazamiento El programador novato' aparece y dice. "Suena bien". "¿Por qué no usa las barras de desplazamiento? Son el componente perfecto cuando se quiere que los usuarios puedan seleccionar de un rango numérico continuo". Se sonríe y le dice. en mi nuevo programa. el color para dibujar.getItemSelectable0 == choicel) { textl. Las barras AWT se soportan con la clase Scrollbar. dice PN. las barras de desplazamiento están formadas por unas flechas de desplazamiento (los botones que hay en cada extremo de la barra de desplazamiento). Usar cuadros de lista desplegables. Como se puede ver en esta figura.getItemSelectableO). El resultado aparece en la figura 8. 1 1 Usted eligio Elemento Ei I Figura 8.6. Quiero que los usuarios puedan seleccionar. En Java.getSelectedItem()). un cuadro de desplazamiento (cuadro que se puede deslizar) y un área de desplazamiento (parte de la barra de desplazamiento por la que se desliza el cuadro d e desplazamiento). los usuarios pueden seleccionar un elemento del cuadro de lista desplegable. el programa visualiza ese elemento en el cuadro de texto.

para obtener los eventos de ajustes.java.Scrollbar . Métodos de la clase Scrollbar. Obsoleto. Las barras de desplazamiento no usan las interfaces ActionListener ni ItemListener. void addAdjustmentListener(AdjustmentListener 1 ) void addNotify0 int getBlocklncrement() int getLinelncrement() int getMaximum() int getMinimum() int getOrientation() Añade el adjustment listenerdado. adjustmentValueChanged: Tabla 8. valor inicial. . Los constructores de la clase Scrollbar se encuentran e n la tabla 8. Scrollbar(int orientación. Constructores de la clase Scrollbar. Obtiene el valor máximo de la barra de desplazamiento.12. . Crea una nueva barra de desplazamiento con la orientación dada.lang.12. Crea el compañero de la barra de desplazamiento.11. Obtiene el valor mínimo de la barra de desplazamiento.-- Tabla 8. Reemplazado porgetunitIncrement(). tamaño de la página yvalores mínimo y máximo dados. int máximo) miento con la orientación.awt.Object 1j ava awt . utilizan las interfaces AdjustmentListener. Obtiene el incremento de bloque de la barra de desplazamiento. en su lugar. Crea una nueva barra de desplazamiento vertical. Component (java.11 y sus métodos en l a tabla 8. Esta interfaz sólo tiene un método. int valor. int mínimo. Obtiene la orientación de la barra de desplazamiento. int Crea una nueva barra de desplazavisible.

Elimina el Adjustmentlistenerdado. Procesa los eventos de ajuste que tienen lugar en esta barra de desplazamiento enviándolos a cualquiera de los objetos AdjustmentListener registrados. Obtiene una representación de tipo string del estado de la barra de desplazamiento. Establece el valor máximo. Obsoleto. Fija el incremento de bloque para la barra de desplazamiento. Obtiene la cantidad visible de la barra de desplazamiento. Fija la unidad de incremento. protected void processAdjustment Even t(AdjustmentEvent e) protected void processEvent (A WTEvent e) void removeAdjustmentlistener (AdjustmentListener 1) void setBlocklncrement(int v) void setBlocklncrement(int v) void setMaximum(int newMaximum) void setMinimum(int newMinimum) void setOrientation(intorientación) void setPageincrement(int v) void setUnitlncrement(int v) void setValue(int newvalue) . Reemplazado por setBlocklncrement(). Obtiene el valor actual de la barra de desplazamiento. para que no se obtengan más eventos de ajuste de la barra de desplazamiento. Reemplazado por getBlocklncrement(). Obsoleto. Fija la orientación. Fija el valor de la barra de desplazamiento. Reemplazado porsetunitIncrement(int). Obtiene la unidad de incremento para esta barra de desplazamiento. Procesa los eventos de la barra de desplazamiento. Establece el valor mínimo.int getPagelncrement() int getUnitlncrement() int getValue() int getVisible() int getVisibleAmount() protected String paramString() Obsoleto. Obsoleto. Reemplazado por getVisibleAmount().

Observe. según l o especificado en los campos de la tabla 8. se l e pasa un objeto de la clase AdjustmentEvent. int máximo) Fija cuatro valores para la barra de desplazamiento. Campos de la clase AdjustmentEvent. void setVisibleAmount(int newAmount) Fija qué cantidad de barra de desplazamiento es visible. El usuario hizo clic sobre la flecha de desplazamiento hacia la derecha o sobre la de desplazamiento hacia abajo (o ejecutó la acción equivalente con el teclado).13.13. ADJUSTMENT-FlRST ADJUSTMENT-LAST ADJUSTMENT-VALUE-CHANGED TRACK Primer ID entero del rango de ID'Sde eventos de ajuste. int visible.void setValues(intvalor. El usuario hizo clic sobre la flecha de desplazamiento hacia la izquierda o sobre la de desplazamiento hacia arriba (oejecutó la acción equivalente con el teclado).15. . Valor de ajuste cambiado cuando se produce un evento.14 y sus métodos en l a tabla 8. A este método adjuternentValueChanged. BLOCKINCREMENT El usuario hizo clic sobre la barra de desplazamiento. en particular. su constructor en la tabla 8. int mínimo.13. Marca el último ID entero del rango de ID's de eventos de ajuste. hacia la izquierda del cuadro de desplazamiento en una barra de desplazamiento horizontal. que se puede usar el método getAdjustmentType de la clase AdjustmentEvent para determinar el tipo de evento de barra de desplazamiento que se ha producido. El usuario arrastró el cuadro de desplazamiento. Los campos de esta clase se encuentran en la tabla 8. Tabla 8.

Obtiene una representación tipostring del estado del evento. La tecla Avpág es equivalente. Veamos un ejemplo. con el id ajustable fuente. 1 Adjustable getAdjustable0 int getAdjustmentType() int getValue() String paramString() Obtiene el objeto ajustable en el que se originó el evento. Constructor de la clase AdjustmentEvent. int value) Event. tipode ajuste yvalor dados.1 4. su valor inicial. Cuando se construye una barra de desplazamiento. como se puede ver en los procesadores de texto cuando se trabaja con documentos de . Construye un objeto Adjustmentint type. Métodos de la clase AdjustmentEvent. tamaño de página y su rango numérico. añadiremos dos barras de desplazamiento a u n programa y visualizaremos sus propiedades cuando el usuario se desplaza por ellas. La tecla Repág es equivalente. hacia la derecha del cuadro de desplazamiento en una barra de desplazamiento horizontal. Aquí.15. o por encima del cuadro en una barra de desplazamiento vertical. se puede especificar su orientación (horizontal o vertical).o por encima del cuadro en una barra de desplazamiento vertical. El tamaño de página indica el tamaño del cuadro de desplazamiento (se tiene por costumbre utilizar el tamaño del cuadro de desplazamiento para indicar el rango total. Obtiene el tipo de ajuste que produjo el evento que cambió el valor. BLOCK-DECREMENT El usuario hizo clic sobre la barra de desplazamiento. se usa un cuadro más pequeño para un rango más grande y uno más grande para un rango más pequeño. Obtiene el valor actual del evento de ajuste. tipo de evento. Tabla 8.source. Tabla 8. 1 AdjustmentEvent(Adjustable.

event. 1. 10 puede devolve:r valore en este: caso). tjue e s ig uanao se crea La barra de desplazamiento también se puede configurar usando los métodos setUnitIncrement y setBlocklncrement. El método setUnitIncrement establece la cantidad de cambios de propiedades de la barra de desplazamiento cuando el usuario hace clic sobre una fecha de desplazamiento (el defecto es I). un tamaño de página de 20 y un rango de 1 a 200: import java.addAdjustmentListener(this). 200).distintos tamaños).*. 2 0 .Applet. un valor inicial de 1. add(scroll1). 1. public class desplazamientoextends Applet implements AdjustmentListener { TextField textl. Así es cómo se añade una barra de desplazamiento a un programa. ralor det azamien 1. Scrollbar scrolll.applet. Observe que además hemos añadido un AdjustmentListener a esta nueva barra de desplazamiento. dándole una orientación horizontal.awt. scrolll. y el método setBlockIncrement fija la cantidad de cambios de propie- . * . import java . import java. scroll2: public void init0 ( scrolll = n e w Scrollbar(Scrollbar.HORIZONTAL. awt .

getAdjustable0 == scroll2) ( textl. 20. add(scroll2). en el caso de que sea vertical: public void init ( ) I scrolll = new Scrollbar(Scrollbar. En este caso.7. 60) donde ajustaremos x cuando se mueva la barra de desplazamiento: u .VERTICAL. Este ejemplo está en el CD en desplazamiento.dad que tienen lugar cuando el usuario hace clic en el cuadro de desplazamiento (el defecto es 10). 200). scroll2 = new ~crollbar(Scrollbar.getAdjustable0 == scrolll 1 1 e.getValueO). veremos otro ejemplo que recorre una cadena de texto en un applet.addAdjustmentListener(this). 1 1 Todo lo que queda es actualizar lo que se visualiza en el cuadro de texto cuando el usuario utiliza las barras de desplazamiento. A continuación. verificando el método getAdjustable del objeto AdjustmentEvent para asegurarse que se está tratando una de las barras de desplazamiento. Empezaremos creando la barra de desplazamiento y pintando la cadena en la coordenada (x. 1.java. 1. 1. y usando el método getValue de la barra de desplazamiento para visualizar las nuevas propiedades del cuadro de texto. 1 Eso está bien si se quieren usar barras de desplazamiento que permit~n 91 usuario especificar fácilmente los números de cualquier rango continuo. textl = new TextField(20). scroll2. 200). 20. add(text1). 1 3 El resultado se muestra en la figura 8. moveremos la cadena "¡Hola desde Java!" con un applet paray obtener las propiedades de una barra de desplazamiento.addAdjustmentListener(this). 1 .getValue() + " Vertical: " + scroll2. Como se puede ver en esta figura.HORIZONTAL.setText("Horizonta1: " + scrolll. scrolll. se añade un cuadro de texto que visualiza las nuevas propiedades de las barras de desplazamiento. add(scroll1). Esto lo hacemos con el método adjustmentValueChanged. pero ¿qué pasa si se quieren usar barras de desplazamiento para recorrer algo? A continuación. Así sería el código: public void adjustmentValueChanged(AdjustmentEvent e ) { if(e. el usuario puede mover las barras de desplazamiento y sus nuevas propiedades aparecerán en el cuadro de texto.

7. 1.addAdjustmentListener(this). import java . Usar barras de desplazamiento. 100). y se puede fijar el valor de la variable x para reflejar la nueva situación horizontal de la cadena y volver a dibujar la applet (observe que se está usando el método getSize de la clase Applet para determinar la anchura de la applet y escalar los movimientos de la cadena de texto de acuerdo con ello): . 1 public void paintíGraphics g) 1 g. public classdesplazamiento2extends Applet implements AdjustmentListener { gd 1 Horizontal 4 Vertical 11 6 Figura 8. add(ecroll1). 60).awt. scrolll. 1.awt. scroll2.import java. event . Scrollbar scrolll.applet.Applet. lo notificaremos en el método adjustmentValueChanged. import java. x. int x = 0. public void init ( ) 1 scrolll = new Scrollbar(Scrollbar.HORIZONTAL. * . Cuando se produzcan los eventos de desplazamiento. 10.drawString("yRola desae Javaln.*.

el usuario puede desplazarse por la cadena de texto simplemente manipulando la barra de desplazamiento horizontal.java. Desplazamiento por una cadena de texto.8. dice el programador novato. 1 1 1 El resultado se muestra en la figura 8. Este panel visualiza el texto "¡Hola desde ~ a v a ! " en la posición (x.getValue ( ) / 100). Barras de desplazamiento y border layouts "Vaya".8. es natural utilizarlos con barras de desplazamientoEste es un ejemplo en el que añadiremos cuatro barras de desplazamiento alrededor del panel central. como sigue: 7 . "ahora el gran jefe quiere que añada a mi programa barras de desplazamiento horizontal y vertical. repaint ( ).width * ( f loat) scrolll. y). 7 ola desde Java! Figura 8. pero no se mantienen en el lugar en que yo las puse". Este ejemplo se encuentra en el CD como desplazamiento2. Como se puede ver en esta figura. "Eso se debe a que debería usar un border layout". Veremos con más detalle el desplazamiento por textos con las barras de7 desplazamiento en el siguiente punto. Dado que los border layouts permiten añadir controles alrededor del p e r F metro de un programa. le contesta.public void adjustmentValueChanged(AdjuctmentEvent e) { if(e.getAdjustable0 == scrolll) { 1 x = (int ) (getSize( ) .

*. hscrolll. 1.class textpanel extends Panel ( TextField Textl. vScroll1). 1. public void init ( ) I setLayout(new BorderLayout()).HORIZONTAL. vScrolll = new Scrollbar(Scrollbar. 100). vscrolll. 1. y = 0. vScroll2). public class desplazamientoenborde AdjustmentListener extends Applet implements I Scrollbar hscrolll. como sigue: import java.addAdjuetmentListeneríthis). 1. add("Southm. . import java. 1.applet.HORIZONTAL. vScroll2. 1. add("EastW. hScro112 = new Scrollbar(Scrollbar. 1. se puede añadir un objeto de esta nueva clase panel en el centro del border layout. 1 1 A continuación. hScrolll = new Scrollbar(Scrollbar. 1. add("Westn. hScroll2). public int x = O . * . . 1. public void paint (Graphics g) ( g. rodeándolo con barras de desplazamiento. 1 1.drawString("iHoladesde Java!". hscroll2. v~crolll.VERTICAL. 100). x.Applet.VERTICAL. textpanel tl. add(nNorth".adaAdjustmentListener(this). 100). import java.awt . v~croll2= new Scrollbar(Scrollbar. 1. 100).awt. hScroll2. hscrolll). y).event.addAdjustmentListener(this).

set~alue(vScrolll.setValue(hScrolll.tl = new textPanel0.setValue(hScr0112~getValueO). El proceso es el siguiente: public void adjustmentValueChanged(AdjustmentEvent e) { if(e.getValueO).getAdjustable0 == vScroll2){ vScrolll. add("Centern.get~alueO).getVa1ueO).setValue(vScroll2.getValueO). 1 Lo único que queda es obtener las propiedades de las nuevas barras d? desplazamiento. 1 if(e. 1 El único truco es que cuando el usuario mueve una barra de desplazamien? to.setValue(hScroll1.getAdjustable() == hScrolll){ hScroll2. hay que mover la correspondiente en el otro lado del panel central para mantener la coordinación entre las barras de desplazamiento.setValue(vScrolll. 1 if(e.getAdjustable0 == vScroll2)C vScrolll. Así es como se haría con el método adjustmentValueChanged: public void adjustmentValueChanged(AdjustmentEvent e) { if(e.getAdjustable0 == vScrollli{ vScroll2.getValueO). tl). 1 if(e.getAdjustable0 == hScro112)C hScrolll. 1 if(e.getValue~)).set~alue(h~croll2. .getAdjustable0 == hScrolll)< hScroll2. 1 if(e.getAdjustable( == hScroll2){ hScrolll. 1 if(e.setValue(vScroll2.getAdjustable0 == vScr0111)C vScroll2.getValueO). ajustar la posición x e y de la cadena de texto en el panel y luego volver a dibujar el panel.

(float) hScrolll. Hay otra forma fácil de desplazarse por el texto en paneles: se pueden usar las áreas de desplazamiento.getValue() / 1 Y eso es todo. le dice. Este ejemplo está en el CD como desplazamientoenborde.9.ScrollPane . "pero la configuración de las barras de desplazamiento es demasiado trabajo. dice PN. Barras de desplazamiento en un border layout. Si el componente es más grande que el cuadro de desplazamiento. dice el programador novato.x = (int) (getSize(). y le permitirá desplazarse alrededor del componente. "Puede usar los cuadros de desplazamiento". sólo será visible de una vez una parte del componente. "¡Bien!".width 100). ¿NOhay una forma más fácil?" "Claro".height * (float) vScrolll.java.getValue() / = (int) (getSize(). Se puede añadir un componente a un cuadro de desplazamiento. lang.y 100).regaint0. Usar cuadros de desplazamiento "Quiero desplazar algo de texto".0bject 1java. El resultado se muestra en la figura 8.9. tl.Container Ijava. las barras de desplazamiento aparecen alrededor del perímetro de la applet.awt. que lo veremos después.awt. t1.t1. Este es el diagrama de herencia de la clase ScrollPane: java. Como se puede ver en ella. Hola desde Java! Figura 8.awt.Component 1java.

static int SCROLLBARS-AS-NEED lndica que las barras de desplazamiento horizontal/vertical deberían aparecer sólo cuando el tamaño del hijo sea mayor que el del panel de desplazamiento.7 Se pueden encontrar los campos de la clase ScrollPane en la tabla 8. Tabla 8. ~- Crea un nuevo cuadro de desplazamiento. Métodos de la clase ScrollPane.17 y sus métodos en la 8.18.1 8. Adapta este contenedor redim donando el componente conten a su tamaño preferido. Object constraints. Tabla 8. ScrollPane(intscrollbarDisplayPolícy) Crea un nuevo cuadro de desplazamiento.16. Obtiene la barra de desplazamiento horizontal. lndica que las barras de desplazamiento horizontal/vertical no se deberían mostrar nunca.17. int índice) void addNotify() void doLayout() Añade al cuadro de desplazamiento el componente dado. Crea el compañero del cuadro desplazamiento. Adjustable getHAdjustable() .' sus constructores en la tabla 8. utilizando una política de visualización. static int SCROLLBARS-NEVER Tabla 8. protected void addlmpl(Component como. de que las barras de miento deberían aparecer. Constructores de la clase ScrollPane.1 6. Carn~os la clase ScrollPane.

Fija el layout manager para este contenedor.*. Visualiza el componente en este cuadro de desplazamiento. int y) void setScrollPosition(point p) Veamos un ejemplo. Obtiene una representación de tipo stringdel estado de este contenedor.int getHScrollbarHeigh t() Obtiene la altura que debería ocupar una barra de desplazamiento horizontal.awt. ydentro del hijo. Reemplazado por doLavouto. Obtiene la barra de desplazamiento vertical. que es visualizado en el origen de la parte visible del panel de desplazamiento. Así es como se haría cuando se quiere añadir un cuadro de texto a un cuadro de desplazamiento: import java. import java. Es bastante fácil añadir un componente a un cuadro de desplazamiento. Obtiene la anchura que debería ser ocupada por la barra de desplazamiento vertical. simplemente hay que usar el método add de l a clase ScrollPane. . Obsoleto.Applet.applet. Obtiene la posición actual x. Desplaza a la posición dada dentro del componente hijo. Obtiene el tamaño actual de la vista del panel de desplazamiento. Obtiene la política de visualización de las barras de desplazamiento. Desplaza a la posición dada dentro del componente hijo. int getScrollbarDisplayPolicy() Point getScrollPosition() Adjustable getVAdjustable() Dimension getViewportSize() int getVScrollbarWidth() void layout() String paramString() void printComponents(Graphics g) void setLayout(LayoutManager mgr) void setScrollPosition(int x.

. se tiene que dar un tamaño. es curioso cuando sólo una parte del cuadro de texto es visible en un cuadro de desplazamiento. Hay un punto importante que la mayoría de los libros nunca tratan: cuand? se usa un objeto que no tiene un tamaño predefinido... En este caso. y ahora veremos un ejemplo. 400): .public class cuadrodedesplazamiento extends Applet I ScrollPane scrollpanel. como un panel e. sólo tiene dos miembros de datos.drawString ("Esta es una cadena de texto larga que " + "parece continuar y continuar y continuar.". En el caso d 2 los contenedores y de los paneles. add(scrollpane1). 1 1 4 Sin embargo. textl = new TextField("iHo1a desde Java!"). anchura y altura. TextPanel.addítext1). que visualiza una larga cadena de texto: class TextPanel extends Panel { public void paint (Graphics g ) t g. Aquí se devuelve un objeto de la clase Dimension. TextPanel tl: public void init0 t scrollpanel = new ScrollpaneO. scrollpanel.n un c cuadro de desplazamiento. Estos valores se esti cen como sigue: class TextPanel extends Panel I public Dimension getPreferredSize0 { return new Dimension(400. 0. eso quiere decir que hay que sobrescrik)ir el método getPreferredSize para que se pueda llamar al método desde el cu de desplazamiento. Más interesante sería incluir desplazamiento de texto en un panel. crearemos una nueva clase panel. 60).

awt .. . public class scrollpane extends Applet { ScrollPane scrollpanel.". como sigue: import java.public void paint (Graphics g ) { g.. import java .add(t1).Applet. añadiremos un objeto de la clase TextPane a un cuadro de desplazamiento.applet. > 1 Ahora. add(scrollgane1). public void init ( ) ( scrollganel = new s ~ ~ ~ ~ ~ P ~ ~ ~ ( s ~ ~ ~ ~ ~ P ~ ~ ~ . ) 1 Figura desplazamiento.drawString ("Esta es una cadena de texto larga que " + "parece continuar y continuar y continuar. 0.. scrollpanel. * . S C R O L L B t l = new TextPanelO. TextPanel tl. 60).

java.10. en lugar de desplazarse por algún control como es un cuadro de texto.El resultado se muestra en la figura 8. Este ejemplo se encuentra en el CD como cuadrodedesplazamiento. . Como se puede ver en esta7 figura. el usuario finaliza el desplazamiento por el texto en el interior de un cuadro de desplazamiento.

polígonos y algunos otros. Además. Dicha clase se puede utilizar para dibujar cualquier tipo de figuras. Java es un lenguaje muy visual y todas estás áreas son conocidas por los programadores. texto y fuentes Este capítulo trata sobre los temas potenciales de Java: gráficos. rectas. Canvas. Veremos todo esto en este capítulo. óvalos. es posible seleccionar los colores. Imágenes En AWT hay que destacar la gestión de imágenes y veremos lo que es capaz de hacer a lo largo de este capítulo. rectángulos. puntos. los modos de dibujo y colorear las figuras. Empezaremos con una visión rápida de estos elementos. que existe expresamente para que se pueda dibujar en él. incluyendo también un componente especial. Gráficos La capacidad de gráficos de AWT es bastante sólida y se basa en la gran clase Graphics.imágenes. Echaremos un vistazo a las diversas . imágenes. gestión de textos y el trabajo con las fuentes.

veremos un poco más sobre el trabajo con textos como si fueran gráficos. Empezaremos este capítulo revisando el uso del ratón y del teclado. De hecho. y cómo medir el tamaño de una cadena. espera hasta que las imágenes estén totalmente cargadas antes de visualizarlas. 7 Eso es todo. se está creando un gráfico y Java lo trata como tal. pero cuando se escribe texto directamente.veremos aquí la gestión de la entrada de datos por el teclado. Por ejemplo. sin insertarlo en un control como un cuadro de texto. es posible acceder a cada uno de los pixels de las imágenes. en este capítulo crearemos un programa de dibujo con ratón. redimensionamiento de imágenes. dibujar imágenes antes de visualizarlas (proceso llamado double buffering). . copiando imágenes. Ya hemos revisado rápidamente lo que hay en este capítulo. el ratón es una herramienta útil. Teclado y ratón 7 En este capítulo. Por lo tanto. Adicionalmente. de hecho. y animación de imágenes. como cursiva o negrita. mover el cursor de inserción . En este capítulo. por lo que se puede centrar en una ventana. el usuarm puede seleccionar texto con Control-Alt-F8. echaremos un vistazo a cómo se codifica el uso del ratón. Usar el ratón "De acuerdo". se verá cómo fijar la fuente y el estilo del texto. por lo tanto. dice el programador novato. Pasemos a la siguiente sección. cuando se está permitiendo al usuario la creación de gráficos. escribiremos código que permita visualizar texto directamente.formas de cargar imágenes de diferentes formatos como GIF y JPG. lo que quiere decir que tendremos que leer ese texto directamente del teclado. convirtiéndolas a una escala de grises dándoles una apariencia de grabado. dándoles brillo. y haremos eso aquí. sin ningún control como cuadros de texto o áreas de texto. "en mi programa.de texto en la pantalla. Texto y fuentes Quizás le resulte sorprendente ver que se tratan el texto y las fuentes eniEF capítulo de gráficos.

.1. void mousePressed(MouseEvent e) Se le llama cuando se presiona un botón del ratón en un componente.. el apretar o soltar sus botones. que gestionan los clics con el ratón. void mouseClicked(MouseEvent e) Métodos de la interfaz MouseMotionListener. "¿Ha pensado en incorporar el soporte del ratón a su programa? Será más fácil para el usuario". Tabla 9. con el ratón. voidmouseReleased(MouseEvente) Se le llama cuando se suelta un botón del ratón en un componente. que gestiona los movimientos de ratón y las operaciones de arrastre." "Espere un minuto". así como el caso en que el ratón introduzca un componente y luego lo abandone. le dice.1 y los de MouseMotionListener en la tabla 9.con Mayús-Alt-F3. dice el programador. recapacitando. y.2..2. Los métodos de la interfaz MouseListener se recogen en la tabla 9. Se puede trabajar con el ratón usando dos interfaces AWT. MouseListener. Se le llama cuando el ratón se ha movido sobre un componente (sin apretar botón). void mouseExited(MouseEvent e ) Se le llama cuando el ratón sale de un componente. void mouseEntered(MouseEvent e) Se le llama cuando el ratón introduce un componente. en un componente. y MouseMotionListener. S e le llama cuando s e ha hecho clic. voidmouseDragged(MouseEvent e) S e le llama cuando s e aprieta un void mouseMoved(MouseEvent e ) botón del ratón en un componente y luego s e arrastra. Métodos de la interfaz MouseListener. Tabla 9. "Hmm".

Event0bject 1java. sobrescribimos el correspondiente método rnouse listener.n los métodos getX y getY. Esta applet. a p p l e t . I 1 static int MOUSE-MOVED 1 static int MOUSE. BUTTON3_MASK.3. Indica el evento "rnouse moved" lndica el evento 'rnouse pressed. import j ava. lndica el evento "rnouse entered". .InputEvent Ijava. 1java. META-MASKy SHIFT-MASK. ALT-MASK. mouse-java. Tabla 9. Indica el primer número del rango de ID'S usado para los eventos de ratón. mouse.java: t import j a v a . Indica el último número del rango de I usado para los eventos de ratón.event. * . Para saber qué botón se presionó.event. static int MOUSE-CLlCKED static int MOUSE-DRAGGED static int MOUSE-ENTERED static int M O U S E EXITED static int MOUSE. visualizará la mayor parte licab de lo que se puede hacer con el ratón. lndica el evento "rnouse dragged'.awt. Para capturar las acciones especír'--del ratón. Campos de la clase MouseEvent. se usa.ComponentEvent 1java. CTRL-MASK.awt. BUTTON2_MASK. Para obtener la posición actual del ratón de un objeto MouseEvent.util. y el diagrama de herencia de esa clase es como sigue: j ava lang O j ec t b Ijava. Los campos de esta clase se encuentran en la tabla 9. awt .MouseEvent La clase MouseEvent añade sólo los campos a sus clases base. .A cada uno de los métodos de las interfaces de ratón se le pasa un objeto de la clase MouseEvent.FIRST static int M O U S E L A S T Indica el evento "rnouse clicked". Indica el evento "mouse exited". Así es el código de estaapplet. BUTTONI-MASK.event. se puede usar el método getModifiers de la clase MouseEvent y luego se añade el resultado con los campos siguientes de la clase InputEvent:ALT-GRAPH-MASK. Indica el evento "rnouse released'.awt.AWTEvent . A p p 1 e t .PRESSED 1 static int MOUSE-RELEASED Veamos un ejemplo.3.awt.

setText("Botón izquierdo del ratón apretado en " + e.getY0). + e. } public void mouseExited(MouseEvent e) I textl. addMouseListener(this). 1 .setText("Hizo clic sobre el ratón en " + e. 1 else< textl.awt.set~ext("~atón para salir.getY0).event.~etText(~Ratón para introducir. 1 public void mouseEntered(MouseEvent e) I textl. } public void mousePressed(MouseEvent e) I if((e."). addMouseMotionListener(this). 1 public void mouseReleased(MouseEvent e) { textl. + e.getX0 + "". public void init ( ) { textl = new TextField(35). TextField textl.BUTTOU1-MASK)( textl.getX0 + "". 1 1 public void mouseClicked(MouseEvent e ) I textl.*.import java. add (textl).getY0).").setText("Botón derecho del ratón pulsado en m + e.getModifiers0 & InputEvent. public class raton MouseMotionListener ( extends Applet implements MouseListener.BUTTON1-MASK) == InputEvent.getX0 + "".").setText("Se soltó e1 botón del ratón.+ e.

SuperDuperTextPro.public void mouseDragged(MouseEvent e) t textl.1. Se puede ver esta applet funcionando en la figura 9. Usar el teclado "Bien". } public void mouseMoved(MouseEvent e) { te~tl.java. ¿Cómo funciona eso?" "Con el key listener". "estoy escribiendo un procesa dor de texto. Se usa la interfaz keyListener para trabajar con el teclado. Usar el ratón. le dice. como raton.").1.setText("Se arrastró el ratón. dice el programador novato. dice PN. la applet permite saber lo que ocurre.4."). en Java y quiero leer el texto directamerite del teclado. "Sabía que habría algo que me gustaría". Figura 9.setText(~Se movió el ratón. -- . Este ejemplo está en el CD que acompaña a este libro. y se p u e d s encontrar sus métodos en la tabla 9. Cuando se mueve el ratón o se usa uno de sus botones.

Tabla 9. VK-Fl para la tecla F1. Este es el diagrama de herencia para esta clase: Tabla 9. S e le llama cuando se escribe con una tecla.6 y sus métodos en la tabla 9. soltar la tecla y escribir. Métodos de la interfaz KeyListener. Además.4. META-MASK y SHIFT-MASK. que se pueden ver en la tabla 9. CTRL-MASK. CHAR-UNDEFINED KEY-PRESSED KEY-FIRST KEY-RELEASED KEY-LAST KEY-TYPED . poro ejemplo. ALT-MASK. S e le llama cuando s e suelta una tecla.. lo que se puede hacer con el objeto KeyEvent que se le pasa a los métodos de eventos de teclas. los constructores de esta clase se recogen en la tabla 9. como se enumera en los campos de la clase KeyEvent. VK-A para el carácter A. en los métodos KeyPressed y KeyReleased se puede usar el método getKeyCode (no getKeyChar) para obtener un código virtual de la tecla. etc. En general.Observe que hay tres eventos de tecla diferentes: tecla pulsada.5. este código sólo dice que la tecla fue presionada o soltada. se puede usar el método getModifiers del objeto KeyEvent y luego añadir el resultado con los campos de la clase InputEvent: ALT-GRAPH-MASK. Por otro lado. no es muy fácil trabajar con los códigos virtuales porque hay una constante separada de los códigos que devuelve getKeyCode para cada tecla. Campos de la clase KeyEvent.5. void keyPressed(KeyEvent e) void keyReleased(keyEvent e) void keyTyped(keyEvent e ) Se le llama cuando se pulsa una tecla. Generalmente se usa el evento de escritura cuando se está trabajando con el teclado. VK-5 para el número 5. Control u otra tecla.7. cada uno es responsable de averiguar si se pulsaron la tecla Mayús. porque se puede usar el método getKeyChar en keyTyped para obtener el carácter Unicode que se escribió. Para saber las teclas modificadoras (como Mayús) que se pulsaron.

VK-A a VK-ADD VK-ALPHANUMERIC VK-AMPERSAND VK-Z VK-AGAIN VK-ALT VK-ALT VK-DEAD-CIRCUMFLEX VK-DEAD-DOUBLEACUTE VK-DEAD-DIERESIS VK-DEAD-VOICEDSOUND VK-DECIMAL VK.EXCLAMA TIONMARK VK-HELP VK-INSERT Vk-JAPANESE-HIRAGANA VK-JAPANESE-KATAKANA VK-Hl RAGANA VK-INVERTED-EXCLAMATION-MARK VK-JAPANESE-ROMAN .

7. int id. Métodos de la clase KeyEvent. char getKeyChar0 int getKeyCode0 Obtiene el carácter asociado con la tecla en este evento. Constructores de la clase KeyEvent.VK-KP-UP VK-LESS VK-LEFT VK-M ETA VK-LEFT-PARENTHESIS VK-MlNUS VK-RIGHT VK-RIGHT-PAREN THESIS VK-ROMAN-CHARACTERS VK-SHIFT VK-STOP VK-UNDEFINED VK-SLASH VK-SU BTRACT VK-UNDERSCORE VK-SPACE VK-TAB VK-UNDO Tabla 9. Obtiene el código entero de la tecla asociado a este evento. KeyEvent(Componentfuente. long Crea un objeto KeyEvent. long Crea un objeto KeyEvent. int id.6. . char KeyChar) Tabla 9. int keyCode) KeyEvent(Componentfuente. cuándo. int modificadores. cuándo. int keyCode. int modificadores.

M F l o H H A. Control.awt. M Determina si la tecla de este evento es una tecla de acción.applet.*. Fija el valor KeyCharpara indicar un carácter.static String getKeyModifiersText(int boolean isActionKey() Obtiene un Stringque describe el modificador)keycode .*. Veamos un ejemplo. Fija los modificadorespara indicar la teclas adicionales que fueron mantenidas (Mayús. { public void h i t 0 I addKeyListener(this).Applet. Fija el valor de keyCode para indicar una tecla física.awt. import java.event. como se define en Event. el carácter correspondiente se añade al final de la cadena visualizada. Cada vez que el usuario pulsa una tecla para escribir. usando e l evento keyTyped y el método getKeyChar para leer cada tecla. como UlnicioM. etc. requestFocus ( ) . Definidocomoparte de InputEvent. import java.). Así es la applet: import java.java. . public class tecla extends Applet implements KeyListener String text = "". Alt. String pararnString() void setKeyChar(char keychar) void setKeyCode(in t keycode) void setModifiers(int modificadores) Obtiene una cadena identificando este evento. Esta applet sencilla lee y visualiza las teclas.

Hacemos esto con el método requestFocus de la applet. > public void keyTyped(KeyEvent e) C text = text + e. "¿Por qué no?". repaint ( ) . Este ejemplo está en el CD con el nombre tecla. (En un GUI. en sí misma. dice el gran jefe (GJ). Esto es sólo el comienzo del trabajo con texto. reciba las pulsaciones. Usar fuentes "El hanner que se creó para la empresa Pride Picnic era bueno". no se verá ninguno de los caracteres escritos. le . Los resultados de este código se muestran en la figura 9.getKeyChar0. en el que empezaremos con las fuentes. Como se puede ver. hay que darle el foco. que funciona como se esperaba. [Este texto se ha escrito directamente en esta appletl Figura 9. un elemento que tiene el foco es el que recibe las pulsaciones). si no se da el foco a la applet de forma explícita. "pero no parece estar hecho con orgullo". 100).public void paint(Graphics g ) I g.java. el usuario puede escribir texto directamente en esta applet. > public void keyPressed(KeyEvent e) 0 public void keyReleased(KeyEvent e) { } 1 Aquí hay que observar una cosa: para que laappler.2.drawString(text.2. Ahora veamos el siguiente tema. Usar el teclado. 0 .

pregunta. Nombre lógico de esta fuente. sus constructores en la tabla 9. fijar su tamaño y especificar si está en negrita. Uno de los usos más comunes de la clase FontMetrics es determinar la altura del texto cuando se visualizan varias líneas de texto.10.13. "Por una cosa". Tamaño del punto de esta fuente en un float.11. etc. aria1 o courier). El campo de esta clase aparece en la tabla 9. Revisemos las tablas para ver aquello de lo que disponemos cuando trabajamos con fuentes. "Hmm".8. la clase FontMetrics. Estilo de esta fuente. su constructor en la tabla 9. Tabla 9. cursiva. se puede seleccionar una fuente (como helvética.8. Línea base usada en la mayor parte de los scripts roman cuando se esquematiza el texto. que trata de las dimensiones físicas de las fuentes. protected int tamaio protected int estilo .10 no son suficientes. Estilo negrita. Campos de la clase Font. le dice. "me quiere decir que sería mejor usar una fuente más grande". Usando esta clase. Por si todos los métodos de la tabla 9. dice GJ. hay otra clase importante.9 y sus métodos en la tabla 9. Línea de base usada en los scripts ideográficos (como la japonesa). "medía sólo un cuarto de pulgada de alto". static int HANGING-BASELlNE Línea de base usada cuando se esquematizan los scripts como Devenagari.12 y sus métodos en la 9. Se puede seleccionar el tipo y el estilo de las fuentes del texto con la clase Font. protected Font fuente static int BOLD static int CENTER-BASELINE Fuente desde la que se crean las métricas. Medida del punto de esta fuente. Estilo liso. static int ITALIC protected String nombre static int PLAlN protected float pointsize static int ROMAN-BASELINE Estilo cursiva. Encontrará los campos de la clase Font en la tabla 9.

int inicio.10. Crea un nuevo objeto Font. int[] glyphcodes) Obtiene un nuevo objeto GlyphVector con el carácter iterador dado. GlyphVectorcreateGlypVector Obtiene un nuevo objeto GlyphVector.9. duplicando el objeto Fontactual y aplicando una nueva transformación que convierte un conjunto de coordenadas en otras. int límite) int canDisplayUpTo(String str) lndica si esta fuente puede visualizar una cadena. Constructores de la clase Font Crea una nueva fuente con los atributos dados. duplicando el objeto Font actual y aplicando un nuevo tamaño. boolean canDisplay(charc) Verifica si la fuente tiene algúnglyph para el carácter dado. char[] chars) GlyphVector createGlypVector (Font RenderContext frc. GlyphVector createGlyphVector Obtiene un nuevoobjeto GlyphVectorcrea(Font RenderContext frc. intcanDisplayUpTo(Characterlterator iter. int tamaño) Crea una nueva fuente con el nombre. str) 1 static Font decode(String str) Font deriveFont(AffineTransform trans) Obtiene la fuente que describe la cadena. Font(String nombre. lndica si esta fuente puede visualizar los int inicio. Characterlterator ci) GlyphVector createGlypVector (Font RenderContext frc. estilo y tamaño de punto dados. (Font RenderContext frc. Tabla 9. int límite) caracteres del texto dado. Font deriveFont(f1oat tamaño) . Crea un nuevo objeto Font. Métodos de la clase Font. lndica si esta fuente puede visualizar una cadena dada. int canDisplayUpTo(char[]texto. Obtiene un nuevo objeto GlyphVector con el array de enteros y FontRenderContext dados.Tabla 9. int estilo. String do con el FontRenderContext dado.

Obtiene el nombre de la familia de esta fuente. . Elimina el objeto Font nativo. float Crea un nuevo objeto Font. byte getBaselineFor(char c) String getFamily() String getFamily(Loca1e 1) static Font getFont(Map atributos) static Font getFont(String nm) static Font getFont(String nm. Font fuente) String getFontName() String getFontName(Loca1e 1) Obtiene la línea base para visualizar este carácter. duplicando el y Transform trans) objeto Font actual aplicando un nuevo estilo y transformación. Obtiene el nombre de la familia de esta fuente.Font deriveFont(int estilo) Crea un nuevo objeto Font duplicando el objeto Font actual y aplicando el nuevo estilo. Font deriveFont(int estilo. Obtiene el nombre de la fuente localizada en el locale dado. Affine Crea un nuevo objeto Font. duplicando el tamaño) objeto Font actual y aplicando un nuevo estilo y tamaño. Obtiene la fuente dada de la lista de propiedades del sistema. boolean equals(0bject obj) protected void finalize() Map getAtributes0 Compara este objeto Font con el objeto dado. Obtiene el nombre de la fuente. Obtiene una fuente apropiada para los atributos. Font deriveFont(Map atributos) Crea un nuevo objeto Font duplicando el objeto Font actual y aplicando un nuevo conjunto de atributos de fuentes. Obtiene las teclas de todos los atributos de la fuente. Obtiene un mapa de los atributos de esta fuente. Obtiene un objeto Fontde la listade propiedades del sistema. Font deriveFont(intestilo. localizada en el locale dado.

FontRenderContext la cadena y el FontRenderContextdados. int límite. FontRenderContext frc) LineMetrics getLineMetrics (Characterlterator ci. FontRenderdercontext. Obtiene el nombre lógico de la fuente. Obtiene un objeto LineMetrics. int beginIndex. int begin. Ahora se supone que las fuentes son independientes de la plataforma.awt.el iterador de carácter dado en FontRenIndex.float getltalicAngel() Obtiene el ángulo para el estilo cursiva de esta fuente. Obtiene el nombre Postscriptde la fuente. Obtiene el número de glyphs de esta fuente. int getMissingGlyphCode() Obtiene el código glyph usado cuando esta fuente no tiene un glyph para un carácter Unicode dado. Context frc) . Obtiene el tamaño del punto de la fuente. String getName() int getNumGlyphs() java. int límite. Obtiene las fronteras del array de caracteres en FontRenderContext.usando los LineMetrics getLineMetrics argumentos dados. FontRenderContext frc) RectangIePDgetStringBounds Obtiene las fronteras de los caracteres en (Characterlterator ci.creado con (String str. int beginlndex. int beginlndex. Obtiene el tamaño del punto de esta fuente en un valor float. (chari] chars. int Iímite. Obsoleto. FontPeer getPeer() String getPSName() int getSize() float getSize2D() RectangIePDgetStringBounds (char[] chars. frc) Obtiene los límites del carácter con los IíRectangleZD getMaxChar Bounds(FontRenderContextfrc) mites máximos. int Iímite. como se definió en el FontRenderContextdado. LineMetrics getLineMetrics Obtiene un objeto LineMetrics. FontRenderContext frc) Obtiene un objeto LineMetricsusando los argumentos dados.peer.

Rectangle2D getStringBounds Obtiene los límites de la cadena dada en (String str. frc) Rectangle2D getStringBounds (String str. Tabla 9. int Iímite. int beginlndex. en una 1 protected Font fuente Determina la fuente de la que se crean las métricas. int bytesWidth(byte[] datos. Affine Transform getTransform() Obtiene una copia de la transformación asociada con esta fuente. Obtiene el estilo de esta fuente. lndica si el estilo de este objeto Font es negrita. Campo de la clase FontMetrics.12. int hashCode() boolean hasUniformLineMetrics() boolean isBold() boolean isltalic() boolean isPlain() String toString() Obtiene un hashcode para esta fuente. Convierte el objeto Font representación de tipo string.13. lndica si el estilo de este objeto Font es plano. 1 1 Tabla 9. FontRenderContext un Fon tRenderContext. FontRenderContext frc) int getStyle() Obtiene los límites de la cadena dada en un FontRenderContext. Verifica si esta fuente tiene líneas métricas uniformes. int len) Obtiene la anchura de avance total para mostrar el array de bytes dado en esta fuente. int len) esta fuente. . int off. int charsWidth(char[] datos. int Obtiene la anchura de avance total para mostrar el array de caracteres dado en off. Métodos de la clase FontMetrics. lndica si el estilo de este objeto Font es cursiva.

Obtiene el objetoLineMetricspara el iteraLineMetrics getLineMetrics (Characterlterator ci. . Graphicscontexto) int getMaxAdvance0 int getMaxAscent() Obtiene el objeto LineMetrics para la cadena dada en el contexto dado. Obtiene la fuente descrita por el objeto FontMetrics.int charWidth(char ch) int char Width(int ch) int getAscent() int getDescendt() Font getFont() int getHeight() int getLeading() LineMetrics getLineMetrics (char[] chars. lndica el máximo descendente de la fuente descrita por este objeto FontMetrics. int Iímite. Graphics contexto) dena dada. Obtiene la anchura de avance del carácter dado en esta fuente. LineMetrics getLineMetrics (String str.dor de caracteres dado. Reemplazado por getMaxDescendt(). int Iímite. Obtiene la altura estándar de una línea de texto en esta fuente. Obtieneel objeto LineMetrics para elarray de caracteres dado. Index. int begin. Obtiene la máxima anchura de avance de cada carácter de esta fuente. lndica la fuente ascendente de la fuente. Obtiene los límites del carácter con los límites máximos en el contexto de gráficos dado. Graphics contexto) Obtiene la anchura de avance del carácter dado en esta fuente. Graphics contexto) Obtiene el objeto LineMetrics para la caLineMetrics getLineMetrics (Strings str. lndica la fuente descendente de la fuente. lndica el máximo ascendente de la fuente descrita por este objeto FontMetrics. lndica el principal de la fuente. graphics int beginIndex. int Iímite. int getMaxDecent() int getMaxDescent() Obsoleto. int beginlndex.

concentrado todo en un applet. boolean hasUniformLineMetricsQ Verifica si la fuente tiene líneas de métrica uniformes. Para instalar la fuente. Obtiene los Iímites de la cadena dada en el contexto gráfico. int string Width(String str) String toString0 Obtiene la anchura de avance total para mostrar la cadena dada de esta fuente. de forma que se pueda utilizar cuando se visualice texto.applet.contexto gráfico. Graphics con. import java. int límite. import java. int beginlndex. Graphics contexto) RectanglePDgetStringBounds (String str. . así como el estilo.event.*. Obtiene los valores de este objeto FontMetrics como una cadena.awt.RectangleZD getStringBounds (char chars. usando los métodos stringwidth y getHeight de la clase FontMetrics y la anchura y altura de la applet con el método getSize de la applet. Veamos un ejemplo. En este caso. se permitirá al usuario escribir caracteres y visualizarlos en la fuente Courier. cursiva o negrita. Graphics contexto) Obtiene los límites del arrayde caracteres dado en el contexto gráfico. y establecer un objeto Font acorde con ello. determinando el tamaño de la pantalla del texto. texto) RectanglePDgetStringBounds (String str. se usa el método setFont del objeto Graphics. Graphics contexto) int[] get Widths() Obtiene los Iímites de la cadena dada en el contexto gráfico. RectanglePDgetStringBounds Obtiene los Iímites de los caracteres inde(Characterlterator ci.Applet. Obtiene la anchura de avance de los primeros 256 caracteres de la fuente. int Iímite. Esta es la applet: import java.xados en el iterador del carácter dado del Index. int Iímite. int beginlndex. int begin. Además se permitirá al usuario especificar el tamaño del texto.*.awt.

if(1arge) size = 72. if(event. if(event. italicbutton. boolean italic = faise. 1 public void paint (Graphics g) I String fontname = "Courier". if(ita1ic) type = type 1 Font. add(bo1dbutton). boolean large = faise. largebutton. FontMetrics fm. Font font.PLAIN. .getSource() == largebutton) large = !large.getSource() == italicbutton) italic = !italic. public void k i t 0 ( boldbutton = new Button("Fuente en negrita"). Button boldbutton. requestFocus( ) . int type = Font.ITALIC.public class fuentes extends Applet implementsActionListener. type.BOLD. KeyListener { String text = " ". font = new Font(fontname. if(b01d) type = type 1 Font. g. add(1argebutton).getSource() == boldbutton) bold = !bold. boolean bold = falce. int size = 36. public void actionPerformed(ActionEvent event) I if(event. add (italicbutton) .setFont(font). size). italicbutton = new Button("Fuente en cursiva"). repaint ( ) . largebutton = new Button ("Fuente grande").

3. "Hmm".int xloc = (getSize0 . 1 public void keyTypedíKeyEvent e ) ( text = text + e. "parece que es un trabajo para la clase Image". que también se muestran en la figura 9.getKeyChar().fm.3. pregunta GJ. cuando se usan los botones fuente en negrita. int yloc = (getSize0 .stringWidth(text)) / 2.height + fm. "En esta tentativa de reportaje que escribió para el periódico de la empresa .3." "¿Sí?". le dice.drawString(text. que se" deriva directamente dejava.width . el soporte de las imágenes se hace con la clase Image. Object: .. En AWT. repaint ( ) .le pregunta.Eang. Cuando el usuario escribe texto. el texto aparece con los atributos correspondientes. fuente en cursiva y fuente grande. Ahora es el momento de ponerse a trabajar con imágenes. Usar imágenes -7 El gran jefe dice. ese texto aparece centrado en la applet. g.getHeight0) / 2. xloc. public void keyPressed(KeyEvent e ) ( 1 public void keyReleased(KeyEvent e ) ( 1 1 El resultado se muestra en la figura 9. yloc). Además.. I Fuente en negnta 1 Fuente e n curwa 1 Fuente grande 1 Figura 9. veámoslo en e 7 siguiente punto. "¿Dónde están las fotografías?". Usar fuentes.

Métodos de la clase Image. Indica que se utiliza el algoritmo por defecto para la escala de la imagen. Indica que se usa el algoritmo de la clase ReplicateScaleFilter para la escala de imagen.awt.16.java.14.14. Constructor de la clase Image. Tabla 9. lndica que se ha elegido un algoritmo para la escala de imagen que da mayor prioridad a la velocidad de escalamiento. Tabla 9. Crea un objeto Image. Object 1java. abstract void flush() Vacía todos los recursos utilizados por la imagen. su constructor en la tabla 9.16.Image Los campos de la clase Image se encuentran en la tabla 9.15. lang. static int SCALE-DEFAULT 1 static int SCALE-FAST static int SCALEREPLICATE static int SCALE-SMOOTH static Object UndefinedProperty Tabla 9. Campos de la clase Image. . En el caso de que no se definiera una propiedad para una imagen particular solicitada. Indica que se ha elegido un algoritmo para la escala de imagen que da más prioridad a la suavidad de la imagen. se debería devolver el objeto UndefinedProperty. static int SCALE-AREA-AVERAGING lndica que se utiliza el algoritmo del área media para la escala de la imagen.15 y sus métodos en la tabla 9.

int y . observer) abstract Object getProperty(String nombre. En la clase Applet.2). String nombre) Aquí. abstract int getHeight(lmage0bserver lndica la altura de la imagen. int indicaciones) imagen. A continuación se indica la forma general que utilizaremos para drawlmage.sun. Para leer la imagen. Crea una versión a escala de esta int altura. usaremos los métodos getCodeBase y getDocumentBase de la clase Applet para obtener la URL de la applet. se puede usar el método g e t ~ m a gde e la clase Applet: Image getImage(URL url) Image getImage(URL url. ver la sección "Dibujar gráficos". En este capítulo. y utilizar la misma dirección para buscar el fichero de imagen. como se verá más tarde en este libro. Los objetos ImageObserver permiten monitorizar el progreso de las operaciones de carga de imágenes. se usa el método getlmage. y luego la visualiza. abstract int getWidth(lmage0bserver Indica la anchura de la imagen. abstract lmageProducergetSource() Obtiene el objeto que produce los pixels de la imagen. y las veremos más tarde en este capítulo. más adelante en este capítulo.jpg.abstract Graphics getGraphics() Crea un contexto gráfico para dibujar una imagen por detrás de la pantalla. lmage getScaledlnstance(intanchura. image. que nos permite especificar el objeto imagen que se va a dibujar y su posición en la applet: T boolean drawImage(1mage img. ImageObserver observer) 7 Observe que a drawlmage hay que pasarle un objeto que implemente la interfaz ImageObserver. Para dibujarla. ImageObserver observer) Obtiene una propiedad de esta imagen por nombre. hay una implementación por defecto de esta . Para saber más de esta clase.com/product/jdk/l. Este es un sencillo ejemplo que lee una imagen. utilizamos el método drawZmage de la clase Graphics. usando la clase URL. Se puede crear un objeto URL usando el constructor de la clase URL como sigue: URL(http://java. se puede especificar la URL del fichero de imagen que se q i e r 7 leer. observer) Para cargar una imagen en un applet. int x.

awt. Por ejemplo. Este ejemplo lo encontrará en el CD como imagen. donde se puede ver la imagen cargada.applet. } public void paint (Graphics g) i .drawImage(image.4.*. public void init0 ( image = getImage(getDocumentBase(). . se pueden redimensionar (ver el siguiente punto). hay muchas más cosas que se pueden hacer con las imágenes. g. sólo utilizamos la palabra clave this como objeto ImageObserver: import java. public class imagen extends Applet 1 image image.*.jpgn).4. 1 1 El resultado se muestra en la figura 9. 10. 10. "Quiero que el usuario pueda redimensionar imágenes". Por supuesto.interfaz y por ello. import java. "image. this). Redimensionar imágenes El programador novato está trabajando en un programa de gráficos y necesita su ayuda. Visualizar una imagen.java. Figura 9.

Math.dice NP.min(e.min(e. java. y ) ) . e . Para redimensionar una imagen.getX(). addMouseListener(this). En estaapplet.getY0.max(e. start = new Point(Math.event.*. end = new ~oint(~ath. "Sólo hay qu? especificar la nueva altura y anchura de la imagen en el métododrawlmage". end. start.~)).~).max(e. java. se puede usar esta versión del método drawlmage de la clase Graphics. Start. int y . que permite especificar la anchura y la altura de una imagen: drawImage(Image img. Point start. redimensionada de forma que ocupe el rectángulo que se ha definido: import import import import java. Math.*. sólo se necesita presionar el ratón e? un punto y soltarlo en otro. public class resizer extends Applet implements MouseListener I Image image. int anchura.jpgM). int x .lang. "image. 1 public void mouseReleased(MouseEvent e) ( mouseup = true.getY( ) ) . java.awt. public void h i t ( ) { image = getImage(getDocument~ase~). int altura.applet.getX0.~). ~ m a g e ~ b s e r v e g observer) Aquí hay un ejemplo. "¿Cómo se hace?" "No hay problema". Math. start. le dice. boolean mouseUp = falce. sobrecargado. 1 public void mousePressed(MouseEvent e) { start = new Point(e.awt.Applet.getX0.getY0 . laapplet dibujará la imagen que se vio en el punto anterior. start . .

start.y. Veamos el siguiente apartado para los detalles. Dibujar gráficos El gran jefe aparece envuelto en el humo del cigarro y dice. donde se puede ver que se ha redimensionado la imagen mostrada en el punto anterior. le responde. } El resultado de este código se muestra en la figura 9. "Permite al usuario dibujar rectas. . así como dibujo libre con el ratón". start-y. Redirnensionar una imagen. width. this). Figura 9. height.5.~.5. "¿De qué se trata?". 1 public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) ( 1 public void mouseExited(MouseEvent e) { } public void paint (Graphics g ) I if(mouseUp) { int width = end. le pregunta. Ahora.repaint ( ) . "El equipo de diseño tiene preparado un programa ganador que quiero que escriba". Hemos utilizado algunas variaciones del método drawlmage. int height = end.start. rectángulos y óvalos. "Realmente es una bomba".drawImageiimage.y . que forma parte de la clase Graphics.x . es el momento de echar un vistazo a esta clase en sí misma y a todo lo que contiene (gran cantidad de métodos).start.x. g. dice GJ.

int dy) una región dada por dx y dy. int altura) con el color de fondo. int y) de caracteres. int x.Object. Se deshace de este contexto gráfico. int startAngle. abstract void copyArea(int x. int y. Visualiza el contorno de un arco de círculo o elipse. Visualiza un contorno resaltado de 3D de un rectángulo. int Copia un área del componente a anchura. . int y. void drawBytes(byte[] data. int y.17 y sus métodos en la 9. int anchura.lang. int altura) abstract void dispose() void draw3Drect(int x. ImageObserver observer) Muestra la parte de la imagen dada que está disponible. int y. abstract Graphics create() Graphics create(int x. Observer observer) abstract boolean drawlmage(1mage img.18. El constructor de esta clase se encuentra en l a tabla 9. int y) de bytes. Constructor de la clase Graphics. int altura) lntersecta la región actual cortada con el rectángulo.17. int y. int altura.que es una copia de éste. int offset. protected Graphics() Crea un nuevo objeto Graphics. int achura. lmage que está disponible. Color bgcolor. int Limpia un rectángulo.E l núcleo de los gráficos AWT está formado por la enorme clase ~ r a ~ h i c s ? que se deriva directamente de java. int x. int offset. int anchura. Métodos de la clase Graphics. Tabla 9. Crea un nuevo objeto Graphicsbasado en éste. int altura. int arcAngle) Crea un nuevo objetoGraphics. boolean raised) abstract void drawArc(int x. int y. Tabla 9. int altura. rellenándolo anchura. int anchura. con una nueva área de traslación y de corte. Visualiza el texto dado por el array int longitud. abstract void clipRect(int x. abstract void clearRect(int x. Visualiza el texto dado por el array int longitud. abstract boolean drawlmage(1mage Muestra la parte de la imagen dada img. int y. int dx. int x. int x. int y. void drawChars(char[] data.18.

int y. int nfoints) por Iosarraysde coordenadas x e y. abstract void drawOval(int x. Muestra el contorno de un rectánint altura) gulo dado. int x. poniéndola en escala para que quepa en el interior del área dada de la superficie de destino. ImageObserver observer) abstract boolean drawlmage(1mage img. int sx2. int x. int y) abstract void drawString(String str. int s x l . ha sido puesta en escala para que Colorbgcolor. int nPoints) Muestra el contorno de un polígono definido por el objeto Polygon dado. int y. int altura. lmageobserver observer) abstract boolean drawlmage(1mage img. int y) Muestra el texto dado por el iterador especificado. int sy2. int dx2. Muestra la parte de la imagen que está disponible. Muestra el texto dado por la cadena especificada. abstract void drawRoundRect(int x. int y. Muestra una recta. int s x l . anchura. void dra wPolygon(Polygon p) abstract void drawPolyline(int[] xPoints. int altura) abstract void drawPolygon(int[lxPoints. int altura. int[] yfoints. int d x l . int s y l . usando el color actual. int x2. int Muestra el contorno de un óvalo. int anchura. int arcwidth. ImageObsen/erobsen/er) quepa en el interior del rectángulo. . y l ) y (x2. int s y l . int arcHeight) abstract void drawString(Attributed Characterlterator iterator. int d y l . entre los puntos ( x l . int dy2. int y l . poniéndola en escala para que quepa en el interior del área dada. int sx2. int anchura. int altura. int d y l . Muestra una secuencia de líneas unidas definidas por los arrays de coordenadas x e y. y2). gulo con las esquinas redondeadas. int anchura. int x. int x. int dy2. int y. int anchura. Muestra un polígono cerrado definido int[] yPoints. i Muestra el contorno de un rectánnt y. int dx2. abstract boolean drawlmage(1mage img.Muestra la parte de la imagen que abstract boolean drawlmage(1mage img. int sy2. lmageobserver observer) abstract void drawLine(int x l . Color bgcolor. int d x l . Muestra la parte de la imagen que está disponible. void drawRect(int x. int y2) Muestra la parte de la imagen que ha sido puesta en escala para que quepa en el interior del rectángulo.

Rectangle getClipRect() abstract Color getColor() abstract Font getFont() FontMetrics getFontMetrics() abstract FontMetrics getFontMetrics (Font f) boolean hitClip(int x. Obtiene las métricas de la fuente dada. Obtiene el rectángulo que limita el área recortada. int arcHeight) void finalize() abstract Shape getClip() abstract Rectangle getClipBounds() Gestiona la colección garbagede este contexto gráfico. Rellena un polígono cerrado definido por losarraysdecoordenadasxey. Rellena el contorno de un óvalo del rectángulo dado. . int altura) abstract void fillRoundRect(int x. Obtiene el área recortada. int anchura. int anchura. int n Points) void fillPolygon(Polygon p) Rellena un arco de círculo o elipse cubriendo el rectángulo dado. Rellena el polígono definido por el objeto Polygon con el color actual del contexto gráfico. int y. Obtiene las métricas de la fuente. int[] yPoints. Obtiene el color actual del contexto gráfico. int altura. int anchura. int y. boolean raised) relleno con el color actual. Reemplazado porgetclipBounds(). int startAngle. Rectangle getClipBounds(Rectang1e r) Obtiene el rectángulo que limita el área recortada.void fil/3Drect(int x. int altura. con el color actual. int anchura. intaltura) abstract void fillPolygon(int[] xPoints. int y. int y. nas redondeadas. int arcAngle) abstract void fillOval(int x. int altura) Obsoleto. abstract void fillArc(int x. Devuelve verdadero si el área rectangular intersecta al rectángulo del área recortada. int y. Obtiene la fuente. Pinta un rectángulo 3D resaltado. int y. int arcwidth. int altura. Rellena el rectángulo dado. Rellena el rectángulo con las esquiint anchura. int anchura. abstract void fillRect(int x.

int altura) abstract void setClip(Shape clip) abstract void setColor(Color c) abstract void setFont(Font fuente) abstract void setPaintMode() Fija el área recortada actual al rectángulo dado por las coordenadas especificadas. Traslada el origen del contexto gráfico al punto (x. y). como se muestra en la figura 9.6. vamos a utilizar la clase Graphics para crear el programa que el gran jefe quería. Establece el color del contexto gráfico al color dado. rectángulos redondeados y dibujo libre con el ratón. int y. Establece el modo de pintar para sobrescribir el destino con el color actual de este contexto gráfico. abstract void setXORMode(Co1or c 1) String toString() abstract void translate(int x. Establece la fuente del contexto gráfico a la fuente dada. int y) Aquí. Devuelve el área recortada de forma arbitraria. Dibujo libre con el ratón.6. un programa de gráficos que permita al usuario dibujar rectas. rectángulos. inl achura. ~ t b u l a rectas r 1 Dtb~tar &los 1 Mbu~arrettángulos1 Dtbujar rectánoulos redondeados j l ~ a a l e started t 1 Figura 9.abstract void setC/ip(int x. óvalos. Establece el modo de pintar a alternar entre el color actual de este contexto gráfico y el nuevo color dado. . usando XOR. Obtiene un objeto tipo String para representar este objeto Graphics.

event . java. En ese caso. basta con unir los puntos con líneas (observe que no se genera un evento de ratón por cada pixel sobre el que se mueve el ratón. rectángulo o rectángulo redondeado. El dibujo libre con el ratón es diferente. se almacenan hastfl 1. .awt. por lo tanto es necesario dibujar líneas entre las distintas posiciones del ratón que Java comunica).awt. y así es como funciona: usuario hace clic sobre un botón indicando qué clase de figura quiere dibujar. ésa ubicación se almacena como start. se en el indicador boleano fijado al hacer clic sobre los botones. bline.*. rounded = false: public void i n i t 0 ( bLine = new Button(*Dibujar rectas").lang. usando un objeto Point (que tiene dos miembros de datos: x e y). óvalo. Al soltar el ratón. oval = false. Cuando se suelta el ratón en una nueva posición. una recta.Graphics. Así es dibujar.. rectangle = false. draw = false. ~oucelistener7 ~ouseMotionListener { Button bDraw. En el momento de dibujar. boolean boolean boolean boolean boolean boolean mouseUp = false.000 puntos sobre los que se mueve el ratón.Math. Point start. e7 public class draw extends Applet irnplernentc ~ctionListener. b~ounded.Este programa se llama dibujarejavaen el CD. end.App1et. también se vuelve a pintar el programa. boval. java. y el usuario puede seleccionar la figura a dibujar. esta se almacena como end. * . bRect. con lo que se activa un indicador booleano en el programa. java . Point dot [ ] = new Point [ 1 0 0 0 1 . java. int dots = 0 . entre las posiciones start y end basándo.applet. line = false.java (echaremos un vistazo a las secciones de dibujos cofl más detalle en las siguiente páginas): import import import import import java. Cuando después el usuario presiona el ratón en la superficie de dibujo. awt .

add (bRounded) . start = new Point(Math.min(e. e.getX0. 1 public void mouseReleased(MouseEvent e) { if (line) { end = new Point(e. 1 public void mouseDraggedíMouseEvent e) I if (draw) { dot[dotsl = new Point(e.max(e.~). add (bOval .min(e.getY()). start. e. } mouseup = true. bRect = new Button("Dibujar rectángulos").max(e.getY0). start. start. add (bLine).getY()). l 1 public public public public void void void void mouseClicked(MouseEvent e){} mouseEntered(MouseEvent e) ( 1 mouseExited(MouseEvent e) { l mouseMoved(MouseEvent e)(} .getY0.getY0. bRounded = new Button("Dibujarrectángulos redondeados"). bDraw = new ButtoníWDibujo libre"). start.y)) .getX0. add (bDraw). public void mousePressed(MouseEvent e) I mouseUp = falce. repaint ( ) .y)) . add(bRect) . } else { end = new Point(Math.getX0. e. dots++.bOval = new ButtonímDibujaróvalos").~). repaint ( ) . Math. Math.getX0. start = new Point(e.getX0.

y).drawOval(start.drawRect(start. start.y. start. dot[loop-index + 11 .x. if(line) { g. que el usuario indica al arrastrar el ratón. Ahora.start. permiten dibujar una figura entre las posiciones start y end.getSource( ) == if(e. void setE'lagsFalse ( ) ( rounded = false. dot[loop-index + 11 . b~ounded)rounded= true.drawLine(dot[loop-index].~. dot[loop-index].y. 1 else if(oval){ g. loop-index < dots . b0val)oval = true. draw = false. start.drawLine(start. excepto la de dibujo libre. 1 0 7 1 else if(draw){ 7 for(int loop-index = 0. 1 else if (rounded){ g.x.y.java.x . oval = false. Todas estas funciones. height) .x.y. end.1 g.start.~. line = false.getSource ) == ( if (e.getSource() == if(e. start. bRect)rectangle = true.getSource() == 1 bDraw)draw = true. width.x.y. height).public void paint (Graphics g) I if (mouseup) { int width = end. int height = end. veremos algunas de sus funciones de dibujo. 1 else if(rectang1e){ g. width. '"1 .x. height . bline)line = true. 1 1 Así es dibujar.drawRoundRect (start.x. y ) 1 7 1 public void action~erformed(ActionEvent e) { setFlagsFalse~). width.~. end.getSource ) == ( if (e. rectangle = false.y . if (e.

int y. y 1) y (x2. incluyendo los círculos. : ~ ~ b $ a < r é i i ~~ioinarbmlos Dibuiarrectángulos ~] 1 1 ~ibu~atrecffinguios redondeados 1 ~ i b u j libre 1 e Figura 9.java en la figura 9. en la figura 9. int width. Dibujar una recta con el ratón. se puede dibujar una recta entre los puntos (x 1.y). int height). int height).drawLine(start. width.java. Se puede ver el resultado de dibujar. height). . int y.drawOval(start. int height = end. start.y. Se puede ver el resultado de dibujar. Dibujar óvalos Las elipses.y.x. end.Dibujar rectas Usando el objeto Graphics.java: g. int yl.x.start.y . int width. y2) con el método drawline: drawLine(int xl.x . Dibujar rectángulos Se pueden dibujar rectángulos utilizando el método drawRecr de la clase Graphics: draw~ect(intx.end. y se pueden dibujar con el método drawOval de la clase Graphics: drawOval(int x.x.7.s t a r t .java: int width = end. int x2.7.8. ~ . Así es como aparecía en dibujar. g. Así es cómo se dibujan los óvalos cuando se ejecuta dibujar. se denominan óvalos en AWT. int y2). s t a r t . ~ .

java: int width = end.8. rectángulos con las esquinas r p dondeadas) se pueden dibujar utilizando el método drawRoundRect de la clase Graphics: 7 drawRoundRect (int x. ~ . int y .9. en pixels.y. 7 A continuación. Dlhular rectas 1 [c%ii. Así es como se c rectángulo redondeado en dibujar.x . i n t arcHeight). int height.java: . height). Dibujar rectángulos redondeados Los rectángulos redondeados (es decir. se especifican la anchura y la altura del arco. Dibujar un óvalo con el ratón.start. int width. start. g. width. int height = end.~a~&i&~j DlaUjac lsetang~ios) Dtbuja~rectán~UlIJS redonde8dos ( ~ t b u ¡lbre . 10 cual especifica cuánto hay que redondear las esquinas.y. Figura 9.Así se hace en dibujar.s t a r t .9.x. int arcwidth.drawRect(start.y . El resultado de dibujar'java se muestra en la figura 9.~ 1 Figura 9. Dibujar un rectángulo con el ratón.

pero hay que implementarlo en el código.getX0.1. e. width. dots++.10.x. int height = end. start. Se puede ver el resultado de dibujar-java en la figura 9. 10).x.drawRoundRect(start. dot[loop-index + 1I. loop-index < dots . loop-index++) { g. repaint ( ) . Dibujar un rectángulo redondeado con el ratón.10. comprobando que el indicador draw es verdadero. dot[loop-index] . como sigue: foríint loop-index = 0 .y: g.y. se salvan todas las posiciones del ratón en un array llamado dot[] al arrastrarlo: public void mouseDragged(MouseEvent e) { if (draw){ dot[dotsl = new Pointíe.6 (ya visto anteriormente). en el momento de dibujar la figura.s t a r t . Así es como se hizo en dibujar-java usando el método mouseDragged: una vez que se está seguro de que el usuario está dibujando libremente. 1 1 Después.x.start.y). Dibujo libre El dibujo libre con el ratón se puede hacer utilizando la clase AWT Graphics.y. .int width = end.getY0 ) . Dibujar retes 1 Dibujar WalOS e 1 Dibujar redngolos 1 ~ S ~ ~ i ( F e T $ ~ ~ [ ü s ~ Dibuja libte ]< c ' : ] d~~~~ Figura 9. se unen los puntos usando rectas.y . ~ . 1 El resultado se muestra en la figura 9.drawLineídot[loop-index] . 10. dot[loop-index + l1. height.x .

Seleccionar colores "Mi trabajo con los gráficos ha sido un poco monótono". Es muy útil.Dibujar arcos Con el método drawArc de la clase Graphics se pueden dibujar arcos (st? especifica el ángulo en grados): drawArc (int x. de f c interactiva. modo d i r e c t o y modo XOR. le contesta. setPaintMode0. se haría como sigu usuario dibuja una figura. drawPolygon(Polygon p ) . dice el p r o g r p mador novato. con estos métodos: setXORMode (Color cl ) . int width. cuando mueve el ratón. En el modo directo. A continuación. lo que significa que se puede dibujar algo en la pantalla y después dibujarlo usando el modo X01R. se recupera cualquier cosa que estuviera originalmente I pantalla. .java. se redibu figura usando el modo XOR para borrarla. drawpolyline (int [] xPoints. "Bien". "porque todo es de color negro". las figuras que dibuja en dibujar. int[l y ~ o i n t s . B se almacena. cualquier cosa que se pinte sólo cubre lo que e s m debajo. A continuación se vuelve a di1 con su nuevo tamaño. T Dibujar polígonos Hay gran cantidad de formas de dibujar polígonos y rectas de múltiple? segmentos con AWT: drawPolygon(int[] xPoints. Por ejemplo. si se quiere permitir al usuario que estire. int arcAngle) . int height. int [ 1 yPoints. después. Establecer los modos de dibujo AWT también permite alternar entre dos modos de dibujo. lo que se dibuje será exclusivamente ORed con un color particular que ya está en la pantalla. porque cuan(jo se hace XOR A con B dos veces. int y.int n ~ o i n t s ) . int startAngle. "puede seleccionar el color fácilmente". pero en modo XOR. int n ~ o i n t s ) .

usando setForeground: Ahora. que se gestionan con la clase Color de AWT. como fillArc. hay libertad para fijar el nuevo color de dibujo. las operaciones de dibujo tendrán lugar en el color que se especifique. Los campos de esta clase se encuentran en la tabla 9. . como Color.blue. Color amarillo. también se pueden rellenar figuras usando el color que se especifique con los métodos de Graphics. Por ejemplo. Color gris.Ninguna lección sobre gráficos estaría completa sin hablar de los colores. etc. green. b l u e ) . Color rosa. Color verde.1 9. donde se está fijando el color de fondo: De hecho. Color blanco.20 y sus métodos en la 9.19. Además se puede usar un color predefinido. Además. Color naranja. Color rojo.21. para crear un nuevo color. sus constructores en la tabla 9. Color azul. Tabla 9. en este caso. verde y azul (en el rango O a 255) al constructor de la clase Color. Color gris claro. static Color black static Color blue static Color cyan static Color darkGray static Color gray static Color green static Color IightGray static Color magenta static Color orange static Color pink static Color red static Color white static Color yellow Color negro. Campos de la clase Color. Color gris oscuro. fillOval. Color magenta. como sigue: Color c = new coloríred. se pueden especificar los valores rojo. Color cyan.

. Rendering Hin ts hin ts) Color darker() static Color decode(String nm) Hace una versión del color con r brillo. int g. Convierte una cadena en un en1 y devuelve ese color. int b.20. float b. Crea y devuelve un contexto paira generar un modelo en color sóliido. verde y alfa dados. Color(ColorSpace cspace. Crea un color opaco con los valores dados para rojo. que consiste en el valor de alfa en los bits 24-31. int g. float g. rojo en los bits 16-23.Tabla 9.O. en el rango O a 255. int b) Color(int r. Crea un color con el valor RGBA combinado. float b) Crea un color en el espacio suministrado por ColorSpace. Crea un color opaco con el valor RGB combinado.0 a 1 . verde. Color brighter() PaintContext createContext(Co1orModel cm.21. Hace una versión del color rnás oscura. verde y azul. RectanglePD rZd. que consiste en el valor rojo en los bits 16-23. Crea un color opaco con los valores dados para rojo. Color(f1oat r. boolean hasalpha) Color(int r.O. float alpha) Color(f1oat r. Métodos de la clase Color. en el rango 0.0 a 1 . Constructores de la clase Color. el verde en 8-15 y el azul en los bits 0-7. en el rango O a 255. azul y alfa. AffineTransform xform. Crea un color opaco con los valores rojo. float a) Color(int rgb) Color (int rgba. rectangle r. float[] components. azul. azul yverde dados. en el rango 0. int a) Tabla 9. el verde en 8-15 y el azul en los bits 0-7. float g. Crea un color opaco con los valores rojo.

int v) float[] getColorComponents(ColorSpace cspace. floa t[] compArray) float[] getColorComponents(float[] cornpArray) ColorSpace getColorSpace() float[] getComponents(ColorSpace cspace. Obtiene el valor azul. static Color getColor(String nrn. Color v) Busca un color en las propiedades del sistema. Obtiene el valor rojo. float S. Obtiene el valor alfa. Obtiene un arrayde floatque contiene los componentes de color y alfa del objeto Color en el color space. Obtiene un arrayde float que contiene los componentes de color y alfa del objeto Color. float[] getCornponents(float[] compA rray) int getGreen() static Color getHSBColor(f1oat h. Obtiene un arrayde float que contiene los componentes de color (no alfa) del objeto Color en el color space. Obtiene el valor RGB que representa el color en el modelo de color por defecto. Crea un objeto Color basado en los valores HSB. Busca un color en las propiedades del sistema. Obtiene un arrayde float que contiene los componentes de color (no alfa) del objeto Color. Obtiene el valor verde. static Color getColor(String nm. Obtiene un arrayde floatque contiene los componentes de color del objeto Color en el color space. float[] compArray) Busca un color en las propiedades del sistema. Obtiene el color space del objeto Color. float b) int getRed() int getRGB() float[] getRGBColorCornponents (floa t[] comArray) .boolean equals(0bject obj) int getAlpha() int getBlue() static Color getColor(String nm) Determina si otrocolor es igual a éste.

Este es el diagrama de herencia de la clase AWT Canvas: java. Constructores de la clase Canvas.23. - Crea un nuevo canvas. proporciona un espacio e n blanco para dibujar7 usando el objeto Graphics que se le pasa al métodopaint.~omponent Ijava.awt. Obtiene una representación en cadena de este color. I .22 y sus métodos en la 9.Canvas Los constructores de esta clase se encuentran en la tabla 9.lang. float brightness) static float[] RGBtoHSB(int r. dado según el modelo RGB. int g. String toString() Usar Canvases El componente canvas se construye especialmente para soportar las opera-" ciones de gráficos. Convierte los componentes de un color dado por el modelo HSB al modelo RGB por defecto. a un conjunto de valores equivalente según el modelo HSB. int b.22. float[] hsvals) Devuelve el modo de transparencia para este color.Obtiene un array de float que contiene los componentes de color y alfa del objeto Color en el color space.util. dado un objeto config) GraphicsConfiguration.~vent~bject Ijava.0bject Ijava. Calcula el hashcodeparaeste color. Convierte los componentes de un color.awt. Canvas(GraphicsConfiguration Crea un nuevo canvas. Tabla 9. int getTransparency0 int hashCode() static int HSBTOrgb(f1oat hue. Como su nombre indica.

Tabla 9.*. Métodos de la clase Canvas. import java.Appletimp1ements MouseListener { graphicscanvas gc. 0). 1 void paint(Graphics g) Se le llama para volver a pintar el canvas. addigc). Button buttonl. public void h i t 0 I gc = new graphicsCanvas0.setLocation(loop~index. 1 Los canvases se usan normalmente para soportar una forma básica de animación. Aquí hay un applet que hace esto cuando se hace clic sobre ella: import java.23. 100). import java. ----- Crea el compañero del canvas.applet. gc.awt.setSize(100.event. } public void mousePressed(MouseEvent e) ( 1 public void mouseClicked(MouseEvent e) { for(int loop-index = 0. addMouseListener(this). ya que se puede utilizar el método setLocation d e la clase Component para mover un canvas (o cualquier otro componente).applet.*.awt. } 1 public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) ( } public void mouseExited(MouseEvent e ) { ) 1 class graphicscanvas extends java. loop-index < 150. public class canvas extends java. loop-index++) { gc.Canvas .awt.Applet.

50.drawOval(10.I public void paint (Graphics g) I g. el canvas. y el resto. Como vimos antes. Figura 9. Este ejemplo se encuentra en el CD como canvas. pregunta ESP. "Así funciona la red Internet".1 1. Para ver las imágenes que se cargan se pueden usar los métodos de interfaz ImageObserver.drawLine(l0. es necesario indicar a la interfaz ImageObserver que se carga una imagen en un applet y especificar la implementación por defecto de esta interfaz. 50. se mueve a la izquierda y luego hacia la derecha. g. se puede usar cualquier método Graphics en un canvas. 40. 1 } El resultado se muestra en la figura 9. En este punto. 50.1 applet. "¿No se puede arreglar?"." "Ha habido quejas de cómo su programa dibuja las imágenes que se descargan de la red Internet. 50. 90).11. Cuando se hace clic sobre . comoal método paint de un canvas se le pasa un objeto Graphics. sorprendido. que visualiza una figura pequeña.java. Observe que. gradualmente". 90). le responde. 40). Animación sencilla con un canvas. g.drawLine(50. primero sólo aparece parte de la imagen. Usar la interfaz lmageobserver El especialista en soporte de productos (ESP) aparece y dice tristemente. 10. crearemos nues- .

HEIGHT: Indica que la altura de la imagen base está disponible (y se puede leer del argumento height del método imageupdate). ALLBITS: Indica que una imagen estática que fue dibujada previamente ya está completa. que está siendo cargada de forma asíncrona. int y .applet. se sobrescribe el método imageUpdate para llamar a repainr y visualizar una imagen. FRAMEBZTS: Indica que otro marco completo de una imagen está disponible para dibujarse.awt. WIDTH: Indica que la anchura de la imagen base está disponible (y se puede leer del argumento width del método imageUpdate). SOMEBITS: Indica que hay disponibles más pixels para dibujar la imagen. int height) A este método se le llama cuando la información de una imagen. Este es un ejemplo. El método imageupdate devuelve verdadero si se necesitan actualizaciones. imageupdate: boolean imageUpdate(image img. int infoflags. int width. import java.*. int x.*. Estos son losf7ags que se pasan en infoflags en el método imageupdate: ABORT: Indica que una imagen que se estaba siguiendo fue abortada. public class iobserver extends Applet i . está disponible.tra propia implementación de esta interfaz. En este caso. devuelve false si se ha recibido la información que se quiere. pero sólo cuando está totalmente cargada: irnport java. La interfaz ImageOhserver sólo tiene un método. PROPERTIES: Indica que las propiedades de la imagen están disponibles. ERROR: Indica que una imagen que se estaba siguiendo ha producido un error.

12. w.java. h). int flags. Este ejemplo está en el CD como iobserver. int id) void addImage(1mage image. int w . int y. 10.drawImage(image. int w. Por ello. especialmente cuando se trata de descargas múltiples. int h) { if ((flags & ALLBITS) ! = 0 ) { repaint(x.1 2. int h) . int x. Usar la interfaz ImageObserver Usar la clase MediaTracker La clase MediaTracker proporciona una manera fácil (más fácil que utilizar los objetos ImageObserver) para monitorizar la descarga de imágenes. Figura 9. 1 1 El resultado se muestra en la figura 9. sólo pasaremos al método addlmage.jpgn). Para empezar. Los programadores han comentado a Sun que la interfaz ImageObserver es demasiado compleja. una imagen y un ID que se quiera utilizar para esa imagen (se puede usar el mismo ID que se utilice para enumerar las imágenes si se quieren controlar como si fueran un grupo): void addImage(1mage image.Image image. this). "image. 10. 1 return (flags & ALLBITS) == 0. y. 1 public void paint(Graphics g ) { g. 1 gublic boolean imsgeUpdate(1mage img. donde la imagen aparece una vez que ha sido totalmente cargada. int id. Sun creó la clase MediaTracker (ver el siguiente apartado). public void init ( { ) image = g e t ~ m a g e ( g e t D o c u m e n t B a c e ~ ) .

Indica que se completó la descarga del medio. Añade una imagen a escala. . Métodos de la clase MediaTracker.24.26.25. boolean checkAll(boolean load) Verificación para ver si todas las imágenes que se están siguiendo se han terminado de cargar. su constructor en la 9.26. a la lista de imágenes que están siendo controint w. Indica que algún dato se está cargando actualmente. I Tabla 9. este método vuelve cuando todas las imágenes rastreadas están cargadas. Constructor de la clase MediaTracker. devuelve False.25 y sus métodos en la tabla 9. como sigue: boolean checkIDíint id) boolean checkID(int id. Los campos de la clase MediaTracker se encuentran en la tabla 9.24. boolean load) Este método devuelve Verdadero si la imagen o grupo de imágenes involucradas han terminado de cargarse. int h) ladas. void addlmage(1mage image. static int ABORTED static int COMPLETE static int ERRORED static int LOADING Indica que la descarga se abortó. void addlmage(1mage image. en caso contrario. lndica que hubo un error en la descarga de algún medio desarrollado. Campos de la clase MediaTracker. int id) Añade una imagen a las imágenes que están siendo controladas. Tabla 9. Tabla 9. int id. Además se puede usar el método waitForAl1. / MediaTracker(Componenf comp) Crea un media fracker.Con el método checkld se puede verificar si una imagen o grupo de imágenes han terminado de cargarse.

se usa el método waitForAl1 para esperar a que una imagen esté totalmente cargada (observe las sentencias try/ . se han terminado de cargar. lnicia la carga de todas las imágenes. se han terminado de cargar. Verifica el estado de error de todas las imágenes con el identificador dado. lnicia la carga de todas las imágenes. int id. Obtiene una lista de todas las imágenes que han dado un error. boolean checklD(int id. int id) void removelrnage(1mage irnage. altura e ID dados. Obtiene el desplazamiento de bits OR del estado de todos los media tracker con el identificador dado. boolean load) Object[] getErrorsAny() Object[] getErrorslD(int id) boolean isErrorAny() boolean isErrorlD(int id) void removelrnage(lmage irnage) Elimina una imagen de este media tracker. int anchura. long ms) lnicia la carga de todas las imágenes del identificador dado. boolean load) Elimina la imagen dada con el ID especificado. En este caso. void removelrnage(1rnage image. Elimina la imagen que tiene la anchura.boolean checklD(int id) Verificación para ver si todas las imágenes que se están siguiendo y que tienen el identificador dado. Obtiene una lista de las imágenes con el ID dado que han dado un error. Verificación para ver si todas las imágenes que se están siguiendo y que están etiquetadas con el identificador dado. int altura) int statusAll(boolean load) int statuslD(int id. lnicia la carga de todas las imágenes del identificador dado. Verifica el estado de error de todas las imágenes. Veamos un ejemplo. Obtiene el desplazamiento de bits OR del estado de todos los media tracker. void waitForAll() boolean waitForAll(long rns) void waitForlD(int id) boolean waitForlD(int id.

13. . Usar el objeto MediaTracker. drawimage(image. image = getImage(getDocumentBase~). "image. import java. public class mediatracker extends Applet I Image image. public void i n i t 0 ( MediaTracker tracker = new MediaTracker(this).13. las veremos con más detalle más adelante): import java. } 1 El resultado se muestra en la figura 9. que son las que gestionan las excepciones.java. Figura 9.awt. this). waitForAll ( ) . Este ejemplo está en el CD como mediatracker. 10.*.catch. ( ) { 1 catch (InterruptedException ex) 1 public void paint(Graphics g ) { g .applet-*. try tracker .jpgW). 10.

w. No sé utilizar Java para eso".PixelGrabber Los constructores de esta clase se encuentran en la tabla 9.27. int x. y. Obtiene el estado de los pixels. Constructores de la clase PixelGrabbers. h) de pixels y situarlos en u n array de la imagen dada. Este es el diagrama de herencia de PixelGrabber: java. int h. Tabla 9. int x. PixelGrabber(1mage img.28. boolean forceRGB) PixelGrabber(1mage img. . Tabla 9. int y. int w. int w. int h. h) de pixels. dice el programador novato. PN dice: " i Explíqueme más cosas! " Para situar los pixels de una imagen en un array y acceder a los mismos. Crea un objeto PixelGrabberpara coger la sección (x. Obtiene la altura del buffer de pixel. "Por supuesto que sabe". int y. y. int[] pix) Crea u n objeto PixelGrabber para coger la sección (x. void abortGrabbing0 ColorModelgetColorModel() int getHeight() Object getPixels() int getSta tus() int get Width() Pide al objeto PixelGrabber aborte la imagen.Object )java. "hay algunas cosas que quiero hacer gráficamente y sólo lo puedo hacer si tengo acceso directo a los pixels de la imagen. Obtiene el buffer de pixel. 1ang. w.27 y sus métodos en la 9.Trabajar pixel por pixel: Las clases PixelGrabber "De acuerdo".image. le contesta.28.awt. Obtiene la anchura del buffer de pixels. Obtiene el modelo de color para las pixels en el array. se pueden usar los objetos PixelGrabber. Métodos de la clase PíxelGrabber.

El diagrama de herencia de esta clase es: java. intsrcw. int srcOff. int srcScan) recuperar los pixels. void startGrabbing() int status() Para crear una imagen de un array de pixels. int srcY. boolean grabPixels(1ong mS) void imageComplete(int status) voidsetColorModel(ColorModelmodel) void setDimensions(int width. ColorModel model. hasta que finalice el tiempo dado.que void setPixels(int srcX.que esta clase debe implementar para recuperar los pixels. int srcOff. intsrcW. Reemplazado porgetstatus(). void setProperties(Hashtab1eprops) Parte del AP IImageConsumer. lang. Parte del APl lmageConsumer. ColorModel model. Pide la imagen o el productor de imagen para empezar a entregar los pixels y espera a todos ellos.que esta clase debe implementar para recuperar los pixels. void setHints(int hints) Parte del API ImageConsumer.0bject ~java. Pide al objeto PixelGrabberqueempiece a sacar los pixels. int srcH.MemoryImageSource . esta clase debe implementar para int[] pixels. Obsoleto.boolean grabPixels() Solicita la imagen o el productor de imagen para empezar a entregar los pixels. int srcY. esta clase debe implementar para byte[] pixels. se puede usar la clase MemorylmageSource.que void setPixels(int srcX. Parte del APl lmageConsumer. int height) Parte del API Imageconsumer. int srcScan) recuperar los pixels.awt. int srcH.que esta clase debe implementar para recuperar los pixels. Parte del API ImageConsumer. que esta clase debe implementar para recuperar los pixels. Parte del AP IImageConsumer. que esta clase debe implementar para recuperar los pixels.image.

ColorModel cm. int scansize) . int[] Crea un objeto ImageProducerque usa un array de enteros en el mopix. Métodos de la clase MemorylrnageSource. Crea un objeto ImageProducerque usa un arrayde enteros y propiedades. Color. int scan. byte[] pix.Cambia a un nuevo arrayde bytes. int h. Tabla 9. int scan. byte[] pix. ColorModel cm. Hashtable props) usa unarraydeenterosen el modelo de color RGB por defecto y las propiedades. int ColorModel cm. int off. int off. int[] Crea un objeto lmageProducerque pix. boolean isConsumer(lmageConsumer Indica si un objeto ImageConsumer está en la lista de imágenes de conic) sumidores. Model newmodel. h. void addConsumer(lmageConsumer ic) Añade un objeto ImageConsumer a la lista de consumidores.29 y sus métodos en la tabla 9. int scan) MemorylmageSource(int w. int off. int off. Hashtable props) MemorylmageSource(int w. int off. int h. MemorylmageSource(int w. Constructores de la clase MernorylmageSource. int scan) delo de color RGB por defecto. Crea un objeto ImageProducerque usaun arrayde bytes y propiedades. int ColorModel cm. int offset. int h. int scan) MemorylmageSource(int w. int[] pix. void newPixels(byte[] newpix. void newPixels() Envía todo un nuevo buffer de pixels a cualquier objetoImageConsumer. int h. Crea un objeto ImageProducerque usa un array de enteros. int off.30. int scan. Hashtable props) Crea un objeto ImageProducerque usa un array de bytes. MemorylmageSource(int w. byte[] pix. h.Los constructores de l a clase MernoryImageSource se encuentran en l a tabla 9. MemorylmageSource(int w. Tabla 9.30.29.

en (ImageConsumer ic) orden de arribaaabajo yde izquierda a derecha.*. void newPixels(int x.awt. Model newmodel. import java.awt. . int scansize) void newPixels(int x. En este caso. Este es un ejemplo en el que se usan las clases PixelGrabber y Memorylmagesource.Color.*. Indica si esta imagen animada debería ser siempre actualizada enviando el buffer completo de pixels. se sitúan sus pixels en un array llamado pixels usando el método grabPixels del objeto PixelGrabber y luego se crea una nueva imagen. int w. se carga la imagen en image. voidsetFullBuferUpdates(boolean fullbuffers) void startProduction(1mageConsumer Añade un objeto ImageConsumer a la lista de consumidores y empieza ic) la entrega de datos de la imagen. se lee una imagen y se copia en un nuevo objeto imagen. import java. image2. usando el objeto MemoryImageSource y el método createlmage de la clase Applet: import java. int y. Esto se hace cargando la imagen que se ha utilizado en los ejemplos anteriores de este capítulo.applet.image. int h) Envía una región rectangular del buffer de pixels a los objetos ImageConsumer.Cambiaa un nuevo arrayde enteros. voidrequestTopDownLeftRightResend Solicita que los datos de la imagen sean entregados de una vez . int w.*. Primero. voidsetAnimated(boolean animated) Cambia la imagen en memoria a una animación o a un estado de imagen sencilla. int offset. void removeConsumer(1mageConsumer ic) Elimina un objeto ImageConsumer de la lista de consumidores. Envía una región rectangular del bufferde pixels a los objetos Imageboolean framenotify) Consumer. int h. int y. que es de 485 por 88 pixels.

public class copiar extends Applet I Image image. loop-index < 485 * 88.grabPixels0.jpg").applet. loop-index++) int p = pixelsCloop-indexl. O. l image2 = createImage(new MemoryImageSource(485. que veremos en el siguiente punito. public void init ( 1 ) image = getImage(getDocumentBase(). pixela. int blue = Oxff & p. pixels[loop-index] = (Oxff000000 1 red << 16 1 green 8 1blue). 1 public void paint(Graphics g) I g. En el siguiente código. como el brillo. PixelGrabber pg = new ~ixelGrabber(image. 485). Este ejemplo está en el CD como copiar . int green = Oxff & (p >> 8). trY { pg. 1 catch (InterruptedException e) { l for (int loop-index = 0. ahora la imagen se ha copiado en image2 y se ha visualizado. int red = Oxff & (p >> 16). import java. . "image.*. pixels. . 0 485.*. 0. rojo. haremos alguna cosa más con las imágenes. 88. 1 1 Esto es todo lo que hay que ver aquí. image2.java. O 485) ).drawImage(image2. verde y azul en la misma cantidad. Dar brillo a las imágenes Se puede dar brillo a las imágenes incrementando sus valores para el colo. this). . Ahora que tenemos acceso a los pixels de la imagen. sumaremos 20 a cada valor de color: import java. 88.awt. int pixels[l = new int[485 * 8 8 1 . 10. 10.

"image. 0 . 10.10. Ahora.14. loop-index < 485 * 88. loop-index++){ int p = pixels[loop-index]. int red = (Oxff & ( 9 >> 16)) + 20. grabpixels ( ) . image2. O . 1 public void paint(Graphics g) ( g. 485). int blue = (Oxff & p) + 20. se convierte una imagen en . 88. O 485) . if (green > 255) green = 255. if (blue > 255) blue = 255.import java. 88. . if (red > 255) red = 255. O .*. int pixels [ 1 = new int [485 * 881 .drawImage(image2. PixelGrabber pg = new PixelGrabber(image. verde y azul para cada pixel. ~ i x e l s .image. pixels. try pg .jpgV). int green = (Oxff & (9 > > 8)) + 20. 1 1 image2 = createImage (new MemoryImageSOUrCe (485. En este caso. 485.awt. Convertir imágenes a escala de grises Se pueden convertir imágenes a grises haciendo la media de los valores rojo. public class brillo extends Applet Image image. this). 1 1 El resultado se muestra en la figura 9. {) (: 1 catch (~nterruptedException e) for (int loop-index = 0. public void init0 ( { image = getImage(getDocumentBase~). hemos manipulado las imágenes en el código. pixels[loop-index] = (Oxff000000 1 red << 16 1 green << 8 blue).

int red = (Oxff P (p >> 16)).color.image. cuando7 tratemos la animación de gráficos) a grises. 1 7 image2 = createIrnage (new MemoryImageSource (248.awt. 1 O .applet. 248). > public void paint(Graphics g) g. pixeis.15.drawImage(image2. ver una imagen ena escala de grises en esta figura quizás no sea lo suficientemente convincente en un libro lleno de imágenes en blanco y negro. import java. pixels. 248)). public void init0 ( { image = getImage(getDocument~ase().grabPixels0. O . whirl. this)."whirll.*. loop-index++){ int p = pixels [loop-indexl. En su lugar. 0 . intente ejecutar el ejemplo del CD. 0.*. 1 1 El resultado se muestra en la figura 9. 10. loop-index < 248 * 248. Por supuesto. public class escaladegrises extends Applet Image image.*.awt. es~aladegrises~java. 248. 10. pixels[loop-index] = (Oxff000000 ( avg << 16 1 avg << 8 1 avg). 248. 1 catch (InterruptedException e) ( 1 for (int loop-index = 0. PixelGrabber pg = new PixelGrabber(image. 248. Así es el código: import java. try { pg.gif (imagen blanca y roja que se verá más adelante.gif"). int green = (Oxff & (p >> 8)). image2. int blue = (Oxff 6 p ) . int pixels[l = new intr248 * 2481. int avg = (int) ((red + green + blue) / 3 ) . import java. .

awt. echaremos un vistazo a este efecto aquí. Sin embargo. las clases PixelGrabbery MemorylmageSource sólo funcionan con arrays unidimensionales.applet. simularemos las dos dimensiones multiplicando y sumando los índices del array. Este realce es más conveniente cuando se trabaja en términos de un array de dos dimensiones. Usar el objeto MediaTracker. . -- Figura 9.image.*.*. import java.*.gifque vimos en el punto anterior: import java. Convertir una imagen a grises. import java. Realzar imágenes "Realzar" imágenes es un efecto potente en el que las imágenes aparecen elevadas de la superficie de visión. por lo que. realzamos la imagen whirl.awt. en este ejemplo.Figura 9.15.14. A continuación.

~ixelGrabber = new PixelGrabber pg (image. O.drawImage(image2. this). 0.grabPixels0. 248). y < 247. image2. "whirll. x++) { for (int y = 2. int pixels[l = new int[248 * 2481.gif"). public void h i t ( ) { image = getImage(get~ocumentBase~). pixels. 248. O. 248. 1 catch (1nterruptedException e) {) for (int x = 2. x < 247. 1 1 image2 = createImage (new MernoryImageSource (248. 0. try { pg. } .((pixelS[x * 248 + y ] int avg = (red + green + blue) / 3.public class realzar extends Applet { Image image. pixels 1 O public void paint(Graphics g) { g. y++){ int red = ((pixels[(x + 1) * 248 + y + 11 (pixels[x * 248 + y ] & OxFF)) + 128. 0. pixelsix * 248 + y] 8 = (Oxff000000 1 avg << 16 1 avg c < 1 avg). 248. int green = & OxFF) - (((pixels[(x + 1) * 248 + y + 11 & 0 ~ ~ ~ / 0x100) 0 0 ) int blue = (((pixels[(x + 1) * 248 + y + 11 & OxFF0000) / 0x10000) 8 0x100 .

Realzar una imagen.E1 resultado se muestra en la figura 9. Este ejemplo está en el CD como realzar. . Figura 9.java.16.16. la figura aparece resaltada. Como se puede ver.

que son aquellas en las que se piensa . Ventanas. ya que en la programación AWT se necesita una ventana antes de poder visualizarlos.r m AWT: En este capítulo encontrará el siguiente paso para la construcción de controles en programas AWT. en la que la clase Applet gestiona la ventana en sí misma y automáticamente la crea y la gestiona. usando las clases de AWT Window y Frame. Todo lo que hay que hacer con la interfaz de usuario en un entorno gráfico tiene lugar en una ventana. menús y cuadros de diálogo Ventanas Las ventanas. y todo usuario GUI está familiarizado con ellas. por supuesto. Para los programadores de AWT hay tres tipos de ventanas. Crearemos y visualizaremos ventanas AWT y veremos todo lo que se va procesando. El primer tipo es la ventana applet. se pueden crear las ventanas frame. Echaremos un vistazo a cómo se usa la clase Dialog para crear cuadros de diálogo y la clase FileDialog para crear los cuadros de diálogo de archivos. son la base de la programación GUI. También revisaremos los menús. Además. Primeros veremos brevemente todos estos elementos.

un objeto de tipo Window a menos que ya se tenga una ventana Frame. sin marco. son esos controles indispensables que esconden todas las opciones de un programa y que las presentan por categorías. o Hay otro tipo de ventana que se puede utilizar. Los menús permiten almacenar esas opciones de forma compacta. Además. Además se crean objetos de la clase Menu para crear menús individuales (como Archivo. porque soportan un marco alrededor y un< barra de título.normalmente como ventanas. así como los botones de maximizar. se necesita una ventana frame para usar l o s menús. no habría espacio para escribir el texto. Es u n a técnica GUI muy atractiva. Imagine si todas las opciones de un procesador de texto que se pueden presentar estuvieran disponibles como botones. la clase Frame se deriva de la clase Window. Esta clase sólo presenta una ventana en negro. sólo un rectángulo negro. Aquí crearemos una. se pueden soportar algunas opciones agradables en los menú% submenús que se abren cuando se selecciona un elemento del menú y casillas de activación que le permiten activar o desactivar elementos del menú (como Revisar ortografía automáticamente o Mostrar barra de herramientas). Edición. en los programas no se puede crear. En la programación AWT. 9PI Todo usuario GUI conoce los menús. Veremos todo esto en este capítulo. minimizar y cerrar. Cada uno es responsable de visualizar lo que quiera en estas ventanas.). sin barra de título. ---? . porque el espacio es siempre un grado en los entornos de ventanas. Paradójicamente. visibles todos a la vez. porque el constructor públicamente disponible de Window requiere que se le pase un objeto de tipo Frame o Window. usando la clase Frame. etc. Como se podría esperar. sin embargo. directamente. la clase Window. Con el método de ventana setMenuBar se puede crear un objeto MenuBar y añadir esa barra de menú a una ventana frame.

los cuadros de diálogo son familiares para casi todos los usuarios GUI. Este es el diagrama de herencia de las ventanas frame: java. soportados por las clases Dialog y FileDialog.0bject )java.util. Hay mucho más que ver.Window (java. Se usan cuando se quiere que el usuario introduzca información. como el nombre del archivo que se va a abrir. cada una será una ventana situada en un lugar diferente del documento.Component 1java. lang.estoy trabajando con mi procesador de textos de Java y quiero tener varias vistas del documento. ¿Qué opina?" Creo que debería pensar en permitir al usuario lanzar nuevas ventanas frame".awt. ésta presenta un cuadro de diálogo de archivos que el usuario puede utilizar para seleccionar un archivo. Crear ventanas Frame "De acuerdo".EventObject Ijava. veremos dos tipos de cuadro de diálogo. Es decir. Hemos visto rápidamente de qué trata este capítulo. Al igual que otros elementos visuales de este capítulo. También se verá esto en este capítulo. le dice. dice el programador novato". pero no quiere visualizar un control dedicado. los cuadros de diálogo son ventanas temporales que se pueden rellenar con controles para la entrada de datos del usuario.7 Cuadros de diálogo Los programas de ventanas utilizan. por lo que pasaremos a la siguiente sección. ya que se usa como base de la programación de aplicaciones en AWT.Frame . En este capítulo.awt. con frecuencia. Los métodos y los miembros de datos de esta clase son suficientes para la mayoría de los propósitos de selección de archivos. cuadros de diálogo para que el usuario introduzca datos. generalmente no se necesita derivar una clase de la clase FileDialog. una clave o un color que se selecciona entre muchos otros.awt. todas las veces en la ventana principal. como un cuadro de texto.awt. Ya se ha visto la clase Frame en este libro. Por otro lado. Se usa la clase Dialog como una clase base para los cuadros de diálogo que se crean y personalizan.Container Ijava. y lo único que se necesita hacer es instanciar un objeto de esta clase y usarlo.

como sigue: import java . Por lo tanto. * . que muestre y oculte lo que se necesite. class 1abelFrame extends Frame C A continuación. crearemos un constructor para la clase. instalaremos el Jlow layout manager usando el método setlayout. Primero. basada en la clase Frame. Vamos a utilizar el constructor de la clase Frame.awt. class 1abelFrame extends Frame ( labelFrame(String title) ( super(tit1e). dándole un tamaño. añadiéndole controles y gestionando los eventos. * . añadiremos al constructor un parámetro para el título y lo pasaremos a la clase Frame. y se visualizará una etiqueta con el texto "¡Hola desde Java! Esta es una ventana framel'. en las tablas 6. crearemos una nueva clase. ZabelFrame. Observe que esto se aplica tanto a las ventanasframe que se visualizan desde las applets como a las ventanasframe que se usan en las ventanas de aplicación. awt . En los siguientes puntos. awt .*. el layout manager por defecto para las ventanasframe es el gestor BorderLayout (a diferencia de las ventanasapplet.5. hay que instalarlo. crearemos una ventana frame. que da título a la ventana. Para empezar. respectivamente.Los constructores y métodos de esta clase se pueden ver en el capítulo 6. class 1abelFrame extends Frame . En este caso. Si se quiere utilizar un layout manager diferente. Aquí hay un punto importante. que usan el gestor FlowLayout). declaramos esta nueva clase extendiendo la clase Frame: import java. como sigue: import j ava.4 y 6.

setLayout (new ~1owLayout) ) . Ver el siguiente punto para más detalles. . ZabelFrarne. class 1abelFrame extends Frame { Label label. que se creó en el punto anterior: import java.Ahora estamos preparados para crear una etiqueta y añadírsela al esquema: import java. "después de dar un tamaño a la ventana." le contesta. * . El siguiente paso es visualizarla. ( label = new Label("iHo1a desde Java! Esta es una ventana frame. sólo hay que usar el método setVisiblel'. label~rame(Stringtitle) ( super(tit1e).awt. ¿cómo visualizamos una ventana de esa clase?" "No es difícil. setLayout(new FlowLayout ( ) ). labelFrame(String title) { super(tit1e)."). class 1abelFrame extends Frame I Label label. "Ahora. acid(labe1). Mostrar y ocultar ventanas "Hemos creado una clase de ventana frarne". Esta es la clase de ventana frarne.*. awt . dice el programador novato. 1 1 Esto completa la clase de ventanas frarne.

bl. labelFrame window.Applet.addActionListener(this).event. Así es como se añaden estos botones a la applet: import java. b2. b2. import java. 1 1 Lanzaremos esta ventana desde una applet. add (bl) . public void init ( ) C bl = new Button("Visua1izar la ventanam).applet. b2 = new B~tton(~0cultar ventana"). dándole el título "Ventana Java": public class frame extends Applet implements ActionListener Button bl.addActionListener(this). la add(b2) . Para hacer eso. public class frame extends Applet implements ActionListener { Button bl. add(b1). tendremos dos botones: Visualizar la ventana y ocultarla.*. crearemos un nuevo objeto de la clase labelFrame.label = new Label("¡Hola desde Java! Esta es una ventana frame. add (label) .awt.") . public void init ( ) { { bl = new Button("Visua1izar la ventana"). b2.awt. 1 1 1 Ahora. .*. import java.

200).eetVisible(false). add(b2). El nuevo objeto ventana ya está preparado. La applet ya está preparada. se puede usar el método setvisible. Se le pasa un valor True y para ocultarla. el valor False.b2 = new Button("Ocu1tar la ventana"). usando el método setSize.addActionListener(this). no aparecerá en la pantalla. window = new labelFrame("VentanaJava"). Antes de que se pueda visualizar una ventana. public void h i t 0 1 { bl = new Button("Visualizar la ventana"). como se muestra en la figura 10. 1 if(event.addActionListener(this).1. b2.getSource() == b2){ window. A continuación se indica el código para estos dos botones en la applet: public void actionPerformed(ActionEvent event) { if(event.getSource0 == bl) i window. b2. Cuando se hace clic sobre el botón Visualizar la . window. bl. b2. 1abelFrame window. de lo contrario. add(b2). addíbl). window = new labelFrame("Ventana Javan).setSize(300. hay que darle una medida. 1 Esto es todo lo que se necesita. b2 = new Button("Ocu1tar la ventana"). Así es cómo utilizamos setSize dándole las dimensiones 300 por 200 pixels: public class frame extends Applet implements ActionListener Button bl. Para visualizar la ventana.setVisible(true).addActionListener(this).

dice el programador novato. . label = new Label ( ' ¡Hola desde Java! Esto es una ventana frame. implementando los métodos de las interfaces listener o usando las clases adaptador. Cuando se hace clic sobre el botón Ocultar la ventana. labelFrame(String title){ super (title) ." add(labe1). Visualizar una ventana frame. ésta desaparece de la pantalla. Vemos un ejemplo en el que gestionamos los eventos de ratón en la ventana frame desarrollada en los dos puntos anteriores. Usted sonríe y le dice. dice PN. setLayout(new FlowLayoutO ) . con un luminoso aviso en el fondo de la misma (que no es visible cuando se usa una ventana frame en una aplicación).ventana. implementando los métodos en la interfaz MouseListener y luego. no pasa nada". "he puesto trescientos botones en"" una ventana frame. visualizando lo que el ratón hace con los mensajes en la etiqueta de esa ventana: class 1abelFrame extends Frame implements MouSeLi~tener Label label. la ventana frame se muestra. 7 Figura 10. "¿Ha gestionado los eventos de hacer clic sobre cada botón en su ventana?" "Uh-oh". Gestionar eventos de ventana "Hmm". pero cuando se hace clic sobre ellos. como se puede ver en la figura. Los eventos en las ventanas se pueden gestionar de la misma forma que S gestionan en cualquier sitio.1.

lo que quiere decir que la ventana recibirá los eventos de teclado.").getX0 + "".public void mousePreesed(MouaeEvent e) { if((e.setText("Se soltó e1 botón del ratón. Este programa se encuentra en el CD que acompaña a este libro. es decir. e. + public void mouseReleased(MouseEvent e) ( label.getY0).setText("BotÓn derecho del ratón pulsado en "+ e.setText("Ratón para introducir.getX0 + + e.getX() + "".setText("PulsÓ e1 ratón en 1 + e.BUTTON1-MASK) { 1abel. 1 1 El resultado se muestra en la figura 10.java. como frame.getY() )."). Métodos de la interfaz WindowListener. Además hay eventos específicos para ventanas. 1 public void mouseEntered(MouseE0ent e) I label. + 1 else{ label. 1 1 public void mouseClicked(MouseEvrnt e) ( label. visualizando mensajes.BUTTOIO1-MASK) == InputEvent.1. la ventana frame gestiona eventos MouseListener.setTextí"Botón izquierdo del ratón pulsado en "+ e.").2. Tabla 10.1. hay toda una interfaz WindowListener. 1 public void mouseExited(MouseEvent e) ( label. void windowActivated(WindowEvent e) Se le llama cuando la ventana es la ventana activa del usuario. Sus métodos se pueden encontrar en la tabla 10. e.getY0). Como se puede ver. .setText("Ratón para salir.getMoclifiers() h InputEvent.

A los métodos de la interfaz WindowListener y de la clase WindowAdapter se les pasa un objeto de la clase WindowEvent.3 y sus métodos en la 10. Gestionar eventos d e ratón en una ventana frame.2. Esta clase ya implementa todos los métodos de la interfaz WindowListener y sólo se sobrescriben los métodos que se quieran usar.2.void windowClosed(WindowEvent e) Se le llama cuando una ventana se cierra. void windowClosing(WindowEvente) void windowDeactivated(windowEvent e) Se le llama cuando una ventana no es más grande que la ventana activa del usuario. 9 Observe que la clase WindowAdapter se puede usar también para gestionar los eventos ventana. void windowDeiconified(WindowEvent e) Se le llama cuando una ventana se cambia de un estado minimizado a uno normal. void windowOpened(WindowEvent e) Figura 10. void windowlconified(WindowEvent e) Se le llama cuando una ventana se cambia desde un estado normal a uno minimizado. .4. Los campos de esta clase Se pueden ver en la tabla 10. Se le llama cuando el usuario cierra la ventana desde el menú del sistema de la ventana. Se le llama la primera vez que una ventana se hace visible. su constructor en la 10.

Primer número de ID dentro del rango usado para los eventos de ventana. "Oh. "está cerrando una ventana por usted. no hace nada. Campos de la clase WindowEvent. int id) Crea un objeto Windo wEvent. Constructor de la clase WindowEvent. le dice. Voy a enviar un correo a Sun Microsystems sobre esto. - Obtiene una cadena que identifique el evento. Evento "ventana cerrándose". Evento "ventana abierta". "otra vez Java está graciosillo. dice el programador novato. " dice PN. Evento "ventana desactivada".4. 1 Windo wEvent( Window source.2.3. "¿cómo funciona eso?" . Evento "ventana cerrada". static int WlNDOW-ACTIVATED static int WlNDOW-CLOSED static int WlNDOW-CLOSING static int WlNDOW-DEACTIVATED static int WlNDOW-DElCONFlED static int WlNDOW-FlRST Evento "ventana activada". Métodos de la clase WindowEvent.En el siguiente punto. Tabla 10. Cuando intento cerrar una ventana frame. Último número de ID dentrodel rango usado para los eventos de ventana. static int WINDOW-ICONFIED static int WlNDOW-LAST static int WlNDOW-OPENED Tabla 10. 1 Ocultar ventanas automáticamente al cerrarlas "Hey". veremos uno de los métodos Windowlnterface trabajando junto con el evento windowCLosing. Evento "ventana sin ¡conos". "En realidad". Tabla 10. eso es todo". 1 Windo w gel Windo w() String paramString0 Obtiene el originador del evento. Evento "ventana iconificada".

estamos usando una clase interna adaptador anónima para hacerlo (ver el capítulo 6 para más detalles). Los constructores de esta clase se encuentran en la tabla 10. addWindowListener windowAdapter ( ) {public void windowClosing (~indowEvent {setVisible(false). le dice.6. window(Framepropietario) Crea una nueva ventana invisible. Aquí. se puede gestionar el evento windowClosing. Cuando se cierra una ventana de esta formair todavía existe un objeto. En este caso. Window(Windowpropietario) Crea una ventana nueva invisible con la ventana dada como su dueño.5. add ( label). Esto será útil cuando vayamos a trabajar con cuadros de diálogo y se quieran recuperar los datos que el usuario metió. Debería usar la clase Window y personalizarla". Para crear una ventana en negro preparada para personalizarse. Tabla 10. lo que significa que todavía se puede acceder a sus métodos y miembros de datos. Usar la clase Window "Quiero personalizar la apariencia de mi ventana totalmente".)l1: 1 e) 1 Hay algo útil que hacer notar. "Voy a visualizar los trabajos de los grandes maestros de pintura y quiero hacer que el borde parezca un marco de un cuadro real".Para cerrar una ventana frame cuando el usuario hace clic sobre el botón' Cerrar en la esquina superior derecha de la barra de título. ) label = new Label("iHo1a desde Java! Esta es una ventana frame. addMouseListeneríthis). Constructores de la clase Window. "Hmm". setLayout(new FlowLayout~)."). labelFrame(String title) I super(tit1e). se puede' usar la clase Window. sólo se esconde la ventana cuando el usuario hace clic sobre el botón Cerrar: class 1abelFrame extends Frame ( Label label. . "suena muy bien.5 y sus métodos en la 10. dice elT programador novato.

Finaliza los métodos de entrada y contexto. Window getOwner() Toolkit gettoolkit() Obtiene el propietario de esta ventana. conectando la ventana al sistema operativo. Reemplazado por dispatchEvent(A WTEvent). Obtiene la cadena de aviso visualizada con esta ventana. Obsoleto. Métodos de la clase Window. Obtiene las herramientas del frame. Hace que esta ventana sea medida para encajar la medida preferida y los esquemas de sus componentes. Aplica las propiedades del recurso dado a la ventana. Window[]getOwnedWindows() Devuelve un array que contiene todas las ventanas a las que esta ventana pertenece realmente. ComponentgetFocusOwner() Obtiene el componente hijo de estaventana. que tiene el foco si y sólo si la ventana está activa. Esconde esta ventana. StringgetWarningString() void hide() boolean isShowing() void pack() boolean postEvent(Event e) protected void processEvent Procesa eventos en esta ventana. Carga el recurso con el nombre dado.Tabla 10. Libera todos los recursosde pantalla nativos usados por esta ventana. Verifica si esta ventana es visible. (A WTEvent e) . lnputContextgetlnputContext() Obtiene el contexto de entrada para esta ventana. Añade el Window listenerdado para obtener los eventos de ventana desde la misma. Locate getLocale() Obtiene el objetolocaleasociado a esta ventana si el locale está puesto. void addNotify0 voidaddWindowListener (WindowListener 1 ) voidapplyResourceBundle (ResourceBundle rb) voidapplyResourceBundle (String rbName) void dispose() protected void finalizeo Hace que laventana sea visible.6.

1 I void setCursor(Cursor cursor) Establece que la apariencia del cursor sea la del cursor especificado. labelWindow(AppFrame a £ )( super (a£) . como sigue: class labelwindow extends Window Label label.protected void processwindowEvent(WindowEvent e) voidremovewindowListener (WindowListener 1) Procesa los eventos d e ventana que ocurren en la misma. llamada 1abelWindow que visualiza una etiqueta con el texto "¡Hola desde Java!". ( Al igual que con las ventanas frame. por lo que instalaremos unflow layout y visualizaremos la etiqueta con su mensaje en la ventana: . usamos esta nueva ventana en una aplicación. void show() void toBack() void toFront() Hace que la ventana s e a visible. enviándolos a todos los objetos WindowListener registrados. Envía esta ventana a la parte d e atrás. I Veamos un ejemplo. En este caso. el gestor de esquemas por defecto ef' un border layout. Trae la ventana al frente. por lo que pasaremos el objeto principal de la ventana frame al constructor de la clase labelwindow y luego ese objeto se le pasa al constructor de la clase Window. Elimina el window listener dado. creamos una nueva clase de ventan. Para hacer las cosas más sencillas. Empecemos por declarar esta nueva clase: class labelwindow extends Window { Tenemos que pasar un objeto Frame u otro objeto Window al constructor" de la clase Window.

class labelwindow extends Window I Label label. instanciaremos un objeto de la clase y fijaremos su tamaño. al igual que en la applet: class labelwindow extends Window I Label label. add(labe1). la ventana aparecerá.height. Observe que se pueden determinar las dimensiones de la ventana con el método getSize. pondremos en funcionamiento esta clase en una aplicación. set~ayout(new FlowLayout~)). int height = getSize(). Además pondremos su ubicación en la pantalla usando setlocation. aparecerá en la posición (0. label = new Label("iHo1a desde Java! " ) . labe1 = new Label("lHo1a desde Java!"). En este caso. porque actualmente no hay forma de mover la ventana cuando aparece. y si sólo se muestra con el método servisible. que está en el extremo de la esquina superior izquierda. add(labe1). Cuando el usuario hace clic sobre el botón Esconder la ventana. 1 public void paint (Graphics g) { int width = qetSize0. labelwindow(AppFrame a £ ){ super(af). por lo que además sobrescribiremos el métodopaint de esta ventana para añadir un frame muy sencillo. esto es necesario antes de que la ventana se pueda visualizar.O) de la pantalla. } Las ventanas de la clase Window son sencillamente negras con espacios blancos. Esto completa la clase ZabelWindow. Ahora. Este es el código: . como un rectángulo. labelwindow(AppFrame af){ superíaf). ésta desaparecerá. setLayout(new FlowLayoutO ) . Cuando el usuario hace clic en el botón Visualizar la ventana de esta aplicación.width.

App1et. import java. bl = new Button("Visua1izar la ventana").event. 1 public void actionPerformed(ActionEvent event) if(event.setSize(300. window = new labellindow(this). 1 El resultado se muestra en la figura 10. 300). b2.eetVisible(falee).*.getSource0 == bl){ window. .3. 200). add (b2) . 1 if(event. window.awt. la ventana aparece con un borde mínimo y la etiqueta de control que visualiza un mensaje. class AppFrame extends Frame implements ActionListener ( Button bl. bl.applet. window.setVisible(true). b2.addActionListener(thic).java.getSource0 == b2) I window. labelwindow window.exit(0).))). add(b1) . b2 = new Button("Ocu1tar la ventana").awt. f.addActionListener(this).import java. Como se puede ver.*. AppFrame ( ) ( setLayout(new FlowLayoutO) . import java.addWindowListener(new WindowAdapterO { public void windowClosing(WindowEvent e) (System. public class window { public static void main(String [ l args) AppFrame f = new AppFrameO. Esta aplicación se puede encontrar en el CD como ventana.setLocation(300.

*. jsí?".applet. import java.*. dice el programador novato.3 Crear una ventana de la clase Window. Menu y Menultem. le dice.java.event.awt. se pueden añadir menús. "¿cómo se crean los menús?" Se sienta y le dice. */ <APPLET public class menu extends Applet implements ActionListener . "he estado esperando para preguntarle esto". Crear men ús "De acuerdo". Esta applet visualizará una ventana frame con un menú. Crearemos y usaremos menús en los siguientes puntos mientras desarrollamos una applet llamada menu. que encontrará en el CD. Después de que se ha añadido una barra de menú a una ventana frame. Aquí veremos los detalles de las tres. como el menú Archivo o el menú Edición. usando la clase Menultem.Applet. Se pueden añadir menús AWT a ventanas de la clase Frame usando tres clases AWT: MenuBar.. en el programa añadimos los elementos a los menús.Gsia~aa~a G~ana'l Ocultar la ventana !Hola desde Javal Figura 10.awt. "Ah. "Mejor tomemos un café". El programador novato pregunta. La primera que utilizaremos es la clase MenuBar. Finalmente. Esta es la applet: import java. a esa barra de menú usando la clase Menu. que añade una barra de menú a una ventana frame. import java.

add(menuitem3). menuitem2 = new MenuItem("Element0 2"). menuWindow. menubar = new MenuBarO. bl. . menuwindow = new frame("MenÚs").addActionListener(this). menuitem3 = new MenuItem("Element0 3"). add (bl). label = new Label(" {Holadesde Java! " ) . public void hit() I bl = new Button("Visua1izar el menú de la ventana"). menu. 200). menu = new Menu("Archiv0"). menuiteml. menuitern3.add(menuitem2) . add(labe1). setLayout(new GridLayoutíl. menuitem2.getSource( 1 1 1 ) == bl) ( menu~indow. MenuBar menubar. class frame extends Frame implements ActionListener ( Menu menu. menu.Button bl. menuitem3. frame menuwindow.setVisible(true).setSize(200. Label label: frame(String title) ( super(tit1e).addActionListener(this). 1)) . menuitem2. MenuItem menuiteml. menuiteml = new MenuItem("Elemento 1").addActionListener(this). 1 public void a c t i o n ~ e r f o r m e d ( ~ c t i o n ~ v e n t event) ( if(event .addActionListener(this).add(menuitem1). menu.

4. Crear un objeto MenuBar "Estoy preparado para crear un menú de sistema en mi ventana frame".d ? Javal Figura 10. se usa la clase MenuBar.addWindowListener(new WindowAdapterO {public void windowClosing(WindowEvent e) (setVisible(false). Siéntese y le explicaré cómo".getSource() == menuiteml) { label.getSource() == menuitem3) { label. 1 1 1 En la figura 10.getSource0 == menuitem2) { label. "¿Por dónde empiezo?" "Empiece creando un objeto MenuBar.7 y sus métodos en la 10. .setText("EligiÓ el elemento 2 " ) .setText("EligiÓ el elemento 3 " ) . 1 public void actionPerformed(ActionEvent event) if(event.set~ext("EligiÓel elemento 1 ") . Elemento l lHola d p . ) else if(event. Crear una ventana de la clase Window. Para crear una barra de menús en una ventana frame. dice el programador novato.>1). Desarrollaremos esta clase por medio de ejemplos a lo largo de los siguientes puntos. El menú de esta applet ocupa un lugar en la clase de la ventana Frame que hemos llamado frame. le contesta. ) else if(event. Este es el diagrama de herencia de la clase MenuBar: El constructor de esta clase se encuentra en la tabla 10.8.4 se muestra esta applet en funcionamiento.

construida en el punto "Crear menús" (observe que instalamos la barra de menú en la ventana frame con el método setMenuBar de la clase Frame: class frame extends Frame implements ~ctionListener { MenuBar menubar. frame(~tring title) . Obtiene el menú de ayuda de la barra de menú. Reemplazado por getMenuCount(). void remove(int indice) void remove(MenuComponent m) void removeNotify() void setHelpMenu (Menu m) Elimina el menú localizado en el índice dado de esta barra de menús. Constructor de la clase MenuBar.8. Elimina el compaiiero de la barra de menú. Crea el compañero de la barra de menú. Menultem getshortcut. Menu add(Menu m) void addNotify() int countMenus() void deleteShortCut (MenuShortCut S) Menu getHelpMenu0 Menu getMenu(int 1) int getMenuCount() Añade el menú dado a la barra de menú. Establece que el menú de ayuda del menú dado es el de esta barra de menú. Tabla 10. Obsoleto. Métodos de la clase MenuBar.Obtiene la instancia de Menultemasociadacon Menultem(MenuShorfcutS) el objeto MenuShortcut dado.java.7. Obtiene el menú dado. Elimina el componente dado de esta barra de menú. Borra el menú dado. A continuación encontrará cómo creamos una barra de menú en la ventana frame d e la applet menu.Tabla 10. Obtiene el número de menús de la barra de rnenús. Label label. MenuBar() Crea una nueva barra de menús. Enumeration shortcuts() Obtiene una enumeración de todas las formas abreviadas para usar el teclado de los menús.

le dice.10. ¿Cómo puedo añadir menús?" "Es fácil". setLayout(new G r i d L a y o u t í l . Constructores de la clase Menu. indicando si el menú puede partirse. se crean los menús individuales de la barra de menús. "me he dado cuenta de que después de crear una nueva barra de menús. Métodos de la clase Menu. Con esto. l a b e l = new Label("iHo1a desde J a v a ! " 1 .awt. Con la clase Menu. se visualiza una barra de menús en negro y es el momento de añadir algunos menús.9. Para más detalles.Menu Los constructores de la clase Menu se encuentran en la tabla 10. Menu() Crea un menú nuevo. dice el programador novato. Crea un menú nuevo con la etiqueta dada.10. ver el siguiente apartado. menubar 3 new MenuBar ( ) .awt.MenuItem 1java. Tabla 10. boolean tearOff) Crea un nuevo menú con la etiqueta dada. "sólo hay que usar la clase Menu". add ( l a b e l ) . 1 . 1)) .MenuComponent 1java. 1 Menultem add(Menu1tem m) Añade el elemento de menú dado. Crear objetos Menu "Bien". Este es el diagrama de herencia de esta clase: j a v a .awt. 1 Menu(String etiqueta.Object Ijava. está vacía.{ superítitle). Tabla 10.9 y sus métodos en la tabla 10. 1ang.

Inserta un elemento de menú con la etiqueta dada. . Obsoleto. en la posición actual. en la posición dada. con la etiqueta dada. Reemplazado por getl temcount.java y se añade a la barra de menú (observe que se nombra al menú simplemente pasando el nombre al constructor de la clase Menu): C ~ ~ S S frame extends Frame implements ActionListener { Menu menu.void add(Stringetiqueta) void addNotify() void addSeparator() Añade un elemento a este menú. Inserta un separador en la posición dada. Obtiene la cadena que representa el estado de este menú. Añade una línea o un guión de separación al menú. un elemento del menú. Inserta. Obtiene el elemento localizado en el índice dado. int indice) void insertSeparator(int indice) boolean isTearOff() String pararnString() void remove(int indice) void removeAll() void removeNotify() A continuación. se indica cómo se crea un menú Archivo en la applet menu. Elimina todos los elementos de este menú. int countltems() Menultem getltem(int indice) int getltemCount() void insert(Menu1tem menuitem. Label label. MenuBar menubar. int indice) void insert(String etiqueta. Indica si este menú es un menú partido. Elimina el compañero del menú. Crea el compañero del menú. Elimina el elemento del menú que se encuentra en la posición dada. Obtiene el numero de elementos.

lang. Tabla 10. Este es el diagrama de herencia de esta clase: java. label = new Label(".Hola desde Java!"). Crear objetos Menultem El programador novato regresa y dice.frame(String title) ( superítitle). setLayout(new GridLayout(1. 1)).12.MenuComponent 1 j a v a . menubar = new MenuBarO. "basta con usar la clase Menultem".awt. awt . le dice. add ( label) . 1 . ¿Cómo puedo añadir elementos a ese menú?" "No es tan difícil". he creado un nuevo menú. menu = new menuinArchivo"). Constructores de la clase Menultem. Cada elemento de menú que se añade a un menú AWT es realmente un objeto de la clase Menultem.0bject 1java.11 y sus métodos en la 10.MenuItem Los constructores de esta clase se encuentran en la tabla 10. "Hey.1 1. 1 Meenultem() Crea un nuevo elemento de menú.

void deleteShortcut() void disable() protected void disableEvents(1ong events ToDisable) void enable ( ) void enable(boo1ean b) protected void enableEvents(1ong events ToEnable) String getActionCommand() String getLabel() MenuShortcut getShortcut() boolean isEnabled() . Reemplazado por setEnabled(boo1ean). Obsoleto. void addNotify() 1 Crea el compañero del elemento de menú. void addActionListener(ActionListener 1) Añade el action listenenlado para recibir eventos de acción desde este elemento de menú. Métodos de la clase Menultem. Obtiene el objeto MenuShortcut asociado con este elemento de menú. Reemplazado por setEnabled(boo1ean). Deshabilita la entrega de eventos a este elemento de menú. Reemplazado por setEnabled(boo1ean).12. MenuShortcut S) 1 - Tabla 10.Menultem(Stringetiqueta) Crea un nuevo elemento con la etiqueta dada y sin posibilidad de activarlo de forma abreviada con el teclado. Obtiene el nombre del comando del evento de acción que ha sido producido por este elemento de menú. Verifica si este elemento de menú está habilitado. Habilita la entrega de eventos a este elemento de menú. Obsoleto. Crea un nuevo elemento con una forma abreviada para activarlo con el teclado. Borra cualquier objeto MenuShortcut asociado con este elemento de menú. Obtiene la etiqueta de este elemento de menú. Menuitem(String etiqueta. Obsoleto.

S) protected void processEvent (A WTEvent e) void removeActionListener (ActionListener 1 ) void setActionCommand(String comando) void setEnabled(boo1ean b) void setLabel(Stringetiqueta) void setShortcut(MenuShortcut Fija el objeto MenuShortcut asociado con este elemento. La etiquetade este elemento es la etiqueta dada. menuiteml = new MenuItem("E1emento 1"). menuitemi. MenuBar menubar. Fija el nombre del comando del evento de acción que está activado por el elemento del menú. basta con crear un nuevo objeto Menultem. Elimina el action listenerdado. menuited.ada(menuitem1) . menu = new Menu("Archivo"). menubar = new MenuBarO. MenuItem menuiteml.java: class frame extends Frame implements ActionListener { Menu menu. Label label: frame (String title) { super (title). menu. setLayout(new GridLayout(1. add(labe1). por lo que no obtiene más eventos de acción de este elemento. Fija si se puede elegir este elemento de menú. Para añadir un elemento de menú a un menú.String paramStrjng0 Obtiene la cadena de parámetros que representa el estado de este elemento de menú. label = new Label("iHo1a desde Java!"). Este es un ejemplo en el que se añaden elementos al menú Archivo de la applet menu. pasando al constructor Menultem el nombre del elemento nuevo y después usando el método add del objeto Menu para añadirlo a un menú. . 1)) . Procesa eventos en este elemento de menú.

dice PN. ya tengo todo el menB del sistema. Este es un ejemplo en el que se habilita la gestión de eventos de menú en la applet menu. menuitem2. Gestionar los eventos de menú El programador novato (PN) regresa y dice. . menu. menuitem3. Para aprender a soportar los eventos de menús.menuitem2 = new MenuItem("Element0 2 " ) . Cuando se hace clic sobre los elementos del menú no pasa nada".add(menuitem3). menu. pero hay un problema. menuitem3. ver el siguiente punto.add(menuitem2). En este caso. menuitem3 = new MenuItem("E1emento 3"). Los action listeners para los elementos de menú se utilizan igual que c o T los botones. MenuItem menuiteml. "Bien. .addActionListener(this). menuitem2. Primero.java. MenuBar menubar. "Eso es porque hay que añadir un action listener a cada uno de ~ l l o s "le dice riendo: "Oh". Ahora lo que ocurre es que cuando estos elementos son pulsados no hacen"i nada.addAction~istener(this). se añade unaction listener a cada uno de los elementos: class frame extends Frame implements ~ctionListener Menu menu. se indica qué elemento ha seleccionado el usuario: visualizando un mensaje en una etiqueta.

setText("EligiÓ el elemento 2 " ) . labe1 = new Label("¡Hola desde Java!"). menu = new Menu ( "Archivo" ) .11).getSource() == menuitem1)C label. 1 public void ectionPerformed(ActionEvent event) { if(event. } else if(event.setText("Eligió el elemento 3 " ) .addActionListener(thia). y usar el método getActionCommand de la clase ActionEvent para leer el comando d e acción. también se puede dar a cada elemento un comando de acción con el método setActionCommand.addActionListener(this).Label label. como se muestra en la figura 10. setLayout(new GridLayout(1. add (menuitem2 . menu.5. ) else if(event. menuitem3 = new MenuItem("E1emento 3 ") . menuiteml = new MenuItem("E1emento 1").addActionListener(this).setText("Eligió el elemento 1"). ) menu . menuitem2 = new MenuItem("E1emento 2").getSource0 == menuitem2){ label. frame(String title) { super (title) .getSource0 == menuitem3) ( label. el usuario puede ejecutar la applet menu-java y verá los elementos que seleccionó. menuitem2. menuitem3. 1)) . addWindowListener(new WindowAdapterO {public void windowClosing(WindowEvent e) {setVisible(false). menu. 1 Ahora. add (label). Aunque utilizamos el método getSource de la clase ActionEvent para determinar qué elemento d e menú fue pulsado.add(menuitem1).add(menuitem3) . como se hizo para los botones en el capítulo 6. menubar = new MenuBarO. . menuiteml.

import java.5. creamos una applet. lo elaboraremos más e incluiremos separadores d e menú. casillas de activación con elementos de menús y submenús.Applet.java. bl. import java. En los siguientes apartados.awt. * . elementos deshabilitados.event. public void h i t ( ) { bl = new Button("Visua1izar el menú de la ventana").O Eligin e l elemento 2 Figura 10. 1 public void action~erformed(~ctionEvent event) . menuWindow. 200) . add(b1) . Más opciones de menú En los puntos anteriores. m e n u ~ i n d o w= new f r a m e ( " ~ e n Ú s " ) .setSize (200. public class menu2 extends Applet implements ActionListener 1 Button bl. menu-java. Así e s la nueva applet: import java .applet.*.addActionListener(this). Crear y usar un menú del sistema. frame menuwindow. que examinaba la construcción básica de un menú de sistema. awt . todo en una nueva applet llamada menu2.

add(subiteml). menuitem2.add(menuitem2).add(menuitem3). submenu = new Menu("Sub menús"). menu. menuiteml = new MenuItem("E1emento 1"). menuitem2 = new Menu1temí"Elemento 2"). 1)). menu. setLayout(new GridLayout(1.addActionListener(this). frame(String title) { super(tit1e). . menu = new Menu("Archivo"). CheckboxMenuItem menuitem3.addActionListener(this). subiteml = new MenuItem("Subelemento 1"). Label label.addActionListeneríthis). menuitem3 = new CheckboxMenuItem("Elemento con casilla de activación" ) . menubar = new MenuBarO. submenu.getSource( ) == bl) { class frame extends Frame implements ActionListener { Menu menu.add(subitem3). subitem2 = new MenuItemínSubelemento 2 " ) . subitem2. MenuItem menuiteml.add(subitem2). submenu. subitem3 = new MenuItem("Sub elemento 3").addActionListener(this). label = new Label("iHo1a desde Java!"). menuitem2. menuitem2.addActionListener(this). submenu. subitem2. menuitem4. subitem3. MenuBar menubar.addActionListener(this) . menuiteml. menuitem2. menu. MenuItem subiteml. submenu.addActionListener(this). subiteml.{ if (event .addActionListener(this). menuitem3. add(label ) . subitem3.add(menuitem1).

.setText("EligiÓel elemento 3").)) ) . 1 public void actionPerformed(ActionEvent event) { if(event. else label.add(menuitem4).setText("E1 elemento 3 está seleccionado").addActionListener(this).setText("EligiÓel elemento 2"). menuitem4. menu.6. 1 else if(event.setText("Eligióel elemento 1").getStateO) label. ) else if(event.getSource0 == menuitem2) I label. 1 1 public void itemStateChanged (ItemEvent event) if(event.getSource() == menuitem3) I label. h i n g Applet Window Figura 10. addWindowListener(new WindowAdapterO {public void windowClosing(WindowEvent e) {setVisible(false). Elaborar un menú de sistema.getSource0 == menuiteml) I label.menuitem4 = new MenuItem("Saiir").getSource0 == menuitem3)I if(((CheckboxMenuItem)event.setText("E1elemento 3 no está seleccio-nado " ) .getItemSelectable~)) .

add(labe1).Esta applet se puede ver en la figura 10. ¡Hizo que explotara mi programa delante del gran jefe!" "Hmm". label = new Label("iHo1a desde Java!"). "ya ha estado ensuciando mi programa otra vez. setLayout(new GridLayout(1.addActionListener(this). "¿qué tal si se deshabilitan los elementos del menú cuando no son adecuados?" PN sonríe y dice. menuiteml. menu2. en los siguientes puntos. menu. menubar = new M e n u B a r O . líneas finas horizontales que aparecen en los menús (ver la figura 10.java. menuiteml = new MenuItem("Elemento 1 ") . como sigue: frame(String title) I superítitle). "¡Va a ver ese Johnson!" . cuando veamos cómo se gestionan varias partes de su código. menu = new Menu("Archivo").6).6. Deshabilitar elementos de menú "Este maldito Johnson". m- Añadir separadores de menú Los elementos de menú se pueden agrupar usando los separadores de menú. dice el programador novato.add(menuitem2). menuitem2 = new MenuItern("E1emento 2"). sólo hay que usar el método addseparator. menuitem2. seleccionando elementos de menú que no debería. menu.add(menuitem1).addActionListener(this) . Añadir un separador de menú es fácil. le dice. como la revisión ortográfica cuando el programa dibuja gráficos. 1 ) ) . Desarrollaremos varios nuevos aspectos de estaapplet.

getSource() == menuiteml) ( label. subitem3. 7 Ahora que el elemento está deshabilitado. MenuBar menubar. donde se puede ver el element$ deshabilitado. el 1 1 1 El resultado se muestra en la figura 10. Label label.Cuando se deshabilita un elemento de menú. menuitem2. menuiteml = new MenuItem("E1emento 1") . pasándole un valor de False. setLayout(new GridLayout(1. . subitem2. label = new Label(". el } else i£(event.~etEnabled(falce). el usuario no tiene forma de hacer clic sobre él hasta que no esté habilitado de nuevo. Para deshabilitar un elemento de menú. submenu. menu .add(menuitem2). MenuItem subiteml.addActionListener(this). como sigue: class frame extends Frame implements ActionListener { Menu menu.add(menuiteml) .set~ext("~ligió elemento 1"). CheckboxMenuItem menuitem3.getSource() == menuitem2) ( menuitem2. menuitem2 = new MenuItem("E1emento 2"). se usa el método setEnabled de ese elemento.set~ext("~ligió elemento 2"). rnenuiteml. 1)). Por ejemplo. menu = new Menu ( "Archivo " ) . label. add(labe1).7. public void action~erformed(ActionEventevent) ( if(event. menuitem2.Hola desde Java!"). frame(String title) I super (title) .java cuando el usuario haga clic sobre él. se visualiza en gris y no se" puede seleccionar ni hacer clic sobre él.addActionListener(this). menu. menubar = new MenuBarO. MenuItem menuiteml. se puede deshabilitar el segundo elemento de menú e n menu2. menuiteml.

l a n g . "Hmm". Añadir marcas de activación a menús El especialista en soporte de productos regresa descontento. y los resultados son bastante molestos". "supongo que puedo añadir una marca de activación a esa opción de menú para mostrar cuándo tiene efecto".Figura 10.awt. O b j ect Ijava. Constructores de la clase CheckboxMenultem. usamos la clase CheckboxMenuItem.MenuComponent Ijava.14.7. CheckboxMenultem(Stringetiqueta. Crea un elemento con casilla de activación. Se pueden crear elementos de menú que visualizan marcas de activación junto a ellos para indicar que esas opciones específicas tienen efecto.13 y sus métodos en la 10. boolean estado) . le dice.CheckboxMenuItem Los constructores de CheckboxMenuItem se encuentran en la tabla 10. CheckboxMenultem(Stringetiqueta) Crea un elemento con casilla de activación con la etiqueta dada. Tabla 10. dice.13. "Hay un problema en su nueva aplicación". Crea un elemento con casilla de activación con la etiqueta y el estado dados.awt. Para soportar este tipo de marcas. Además se puede mantener hundida esa marca cuando el usuario la selecciona. "porque el usuario no tiene forma de saber si la opción de menú "Traducción automática a alemán" está activada o no. Deshabilitar un elemento de menú. que tiene el siguiente diagrama de herencia: java .

. MenuItem subiteml. usando un objeto ItemListener: class frame extends Frame implments ActionListener. add(labe1).Tabla 10.14. menu = new Menu("Archivo"). submenu. CheckboxMenuItem menuitem3. Métodos de la clase CheckboxMenuItem. menubar = new MenuBarO. Procesa los eventos que ocurren en este elemento enviándolos aobjetos ItemListener. menuiteml = new MenuItem("Element0 1"). label = new Label("iHo1a desde Java!"). subitem3. menuitem4. setLayout(new Grid~ayout(1. no action listeners. subitem2. Procesa eventos en este elemento. ~temtistener{ Menu menu. Determina si el estado de este elemento es activado o no. MenuBar menubar. void additemListener(1temListener 1) void addNotify() Object[] getSelectedObjects() boolean getState() String paramString() protected void processEvent (A WTEvent e) protected void processEvent (ItemEvent e) void removeltemListener(itemListener 1) void setState(boo1ean b) Añade el item listener dado para recibir los eventosde este elemento.java. Observe que usamos item listeners. Label label. Obtiene una cadena que representa el estado de este elemento. Fija el elemento al estado dado. menuitem2. Crea el compañerode ese elemento.1)) . Elimina el item listener dado para que no reciba más eventos de este elemento. Obtienen unarrayde longitud 1 que contiene la etiqueta del elemento. Aquí vemos cómo se añade un elemento con casilla de activación en la applet menu2. con este tipo de elementos de menús. MenuItem menuiteml. frame(String title) I super(tit1e).

8 se puede ver un elemento d e este tipo funcionando.setText("E1 elemento 3 está seleccionado"). menuitem2 = new MenuItem("E1emento con casilla de activación"). En este caso.add(menuitem3). determinamos el estado del elemento y lo visualizamos en una etiqueta: public void itemStateChanged (ItemEvent event) I if(event. En la figura 10. hay que sobrescribir el método itemStateChanged. automáticamente. el se label.getItemSele~table~) ).addItemListener(this). menu.setTe~t(~E1 elemento 3 no está seleccionado").}~).8.addActionListener(this). menuitem3. Java hunde la marca d e activación o no. menuitem2. 1 Cuando el usuario selecciona este elemento una vez tras otra.menuitem2 = new MenuItem("E1emento 2"). Para gestionar los eventos de este elemento. R m . Usar un elemento con casilla de activación. menu. 1 Eligió el elemento 2 Figura 10.getStateO) label. addWindowListener(new WindowAdapterO {public void window~losing(WindowEvente) (setvisible(false).getSource(l == menuitem3)I if(((CheckboxMenuItem)event.add(menuitem2).

menubar = new MenuBarO. ) . se añaden los elementos de submenú que se ven en la figura 10. como se puede ver en la figura 10. Están unidos a un menú y cuando el usuario selecciona el elemento.add(menuitem1). setLayout(new ~ridLayout(1. Este es un ejemplo que muestra cómo funciona. menuitem2 = new MenuItem("Element0 2 " ) . Crear un submenú es fácil.add~ctionListener(this). rojo. menuiteml = new MenuItem("E1emento 1").9.9.Crear submenús Otro aspecto importante de trabajar con menús en la programación de AWT involucra a los submenús. quizás se quiera permitir que el usuario seleccione un color de dibujo con un elemento de menú. menu.9 a los elementos de los submenú. menuitem2. Figura 10. . menu = new Menu("Archiv0"). magenta y azul. menuiteml. el submenú se abre. 1) add(labe1) . Usar la técnica de los submenús es muy interesante cuando se necesita otro nivel de detalle. sólo hay que añadir elementos de menú a otro' elemento usando el método add. que un submenú se abra indicando los colores posibles. Usar submenús. por ejemplo. label = new Label("iHo1a desde Java!").add~ction~istener(this). verde. y cuando esté seleccionado. En este caso. El usuario puede seleccionar los elementos del submenú de la misma forma que lo hace en los menús normales. Así sería el código: frame (String title) { superititle).

add(menuitem3). 1 .setEnabled(false). subitem3.addActionListener(this).menuitem3 = new CheckboxMenuItem('Elemento con casilla de activación"). } A continuación se puede ver cómo se gestiona el hacer clic sobre el elemento del submenú con el método actionPerformed: public void actionPerformed(ActionEvent event) { if(event.getSource() == subitem2)C label. menuitern3.eetText("Eligió el sub elemento 2 " ) . subitem3 = new MenuItem("Sub elemento 3"). menu. submenu.add(subitem3). } else if(event. menubar. subiteml.getSource() == subitem3)C label. } else if(event.getSource0 == subitem1)C label.setText("E1igió el elemento 2"). label.add(subitem1). submenu.getSource0 == menuiteml){ label.setText("Eligió el sub elemento 1").add~ctionListener(this).addActionListener(this). submenu = new Menu("Sub menús"). menuitem4.add(subitem2). menuitem4 = new MenuItem("Sa1ir") .setText("EligiÓel elemento 1"). subitem2. ) else if(event. menuitd. set~enuBar(menubar).addActionListener(this) .addActionListener(this) . } else if(event. } else if(event. add(menu) . menuitd. submenu.add(menuitem4).getSource0 == menuitem4){ setVisible(fa1se). subiteml = new Men~Item(~Sub elemento 1"). subitem2 = new MenuItem("Sub elemento 2").addActionListener(this).addActionListener(this). menu.getSource0 == menuitem2){ menuItem2.set~ext("Eligió el sub elemento 3").

Veamos un ejemplo. le contesta. Constructores de la clase PopupMenu. creamos un nuevo menú emergente y le añadimos cuatro elementos (observe q u e además instalamos la interfaz MouseListener para gestionar los clics con el botón derecho): . "basta con usar la clase PopupMenu". la applet visualiza el elemento que fue seleccionado en la etiqueta de la ventana frame. int y) Muestra el menú emergente en la posición x. dice el programador novato. Los constructores de la clase PopupMenu se encuentran en la tabla 10.MenuItem 1java. Métodos de la clase PopupMenu. 7 Menús emergentes "Hey". "Claro". ¿Se puede hacer eso en Java?". int S. Cuando el usuario selecciona uno de los elementos del submenú. Aquí. Este es el diagrama de herencia de esta clase: j ava l a n g .16.9.15 Y sus métodos en la tabla 10.PopupMenu . 1 Po~u~MenuO . Crea un nuevo menú emergente.El submenú se muestra en la figura 10. y.15.MenuComponent 1java.1 6.awt. void addNotify() void show(Component origen.awt. Crea el compañero del menú emergente. PopupMenu(Stringetiqueta) Tabla 10. "he visto que se puede hacer clic con el botón derecho sobre algunas aplicaciones y se visualiza un menú emergente. Tabla 10.awt. Crea un nuevo menú emergente con el nombre dado.awt. 0 b j e c t Ijava.Menu 1java. Se utiliza la clase PopupMenu para crear menús emergentes que no nece-y sitan estar unidos a una barra de menú.

menuitem2 = new MenuItem("E1emento 2"). visualizamos el menú emergente en la posición en la que se hace clic con el ratón): public void mousePressed(MouseEvent e) I if(e.*.applet.add(menuitem1). label = new Label("iHo1a desde Java!").awt.addActionListener(this).awt. PopupMenu popup. menuitem4. popup. popup.addActionListener(this). menuiteml = new MenuItem("E1emento 1"). } Cuando el usuario hace clic con el botón derecho sobre la ventana de la applet. add(popup). popup.addSeparator0.event. menuiteml.add(menuitem3). popup.add(menuitem4). menuitem4. menuitem2. pasándole la palabra clave this que apunta a la applet y la posición en la que se visualizará el menú emergente (aquí.addActionListener(this). add(labe1). popup. menuitem3. addMouseListener(this). import java.addActionListener(this). menuitem3 = new MenuItemí"E1emento 3 " ) .import java. podemos utilizar el métodoshow de la clase PopupMenu para visualizar el menú.getModifiers0 ! = O){ . popup. public void init ( ) { popup = new PopupMen~(~t4enu~).*. menuitem3. MenuItem menuiteml.add(menuitem2). MouseListener { Label label.addSeparator0. popup. menuiteml = new MenuItem("E1emento 4 " ) . import java.Applet. public class menuemergente extends Applet implements ActionListener. menuitem2.addSeparator().

10. else if(event. le "bien.Cuando el usuario hace clic sobre un elemento de un submenú. Como se puede ver en ella.iido!".getSource() == menuitem4) label. por ejemplo.setText("EligiÓ el elemento 1 ") . Cuando el usuario selecciona un elemento del menú. PN dice. "jestuPc. dice el programador novato. Las ventanas que se crean con esta clase se parecen más a los cuadros de diálogo estándar que los que se crean con las ventanas frame.setText("EligiÓ el elemento 2 " ) .getSource() == menuitem3) label. la applet devuelve el elemento seleccionado. el usuario puede abrir el menú emergente simplemente pulsando el botón derecho sobre la applet. la clase Dialog.getSource() == menuiteml) label. las ventanas de diálogo no tienen un botón Minimizar ni Maximizar.setText("EligiÓ el elemento 4 " ) . else if(event. El resultado se muestra en la figura 10. que se puede utilizar para crear cuadros de diálogo. me arrepentiría". Este ejemplo está en el CD como menuemergente-java. "Hmm". siempre se puede utilizar un cuadro de diálogo para obtener la er del usuario si no se quiere usar otro cuadro de texto". "¿Cuántos cuadros de texto tiene en su programa9" la pregunta. dice el programador novato. "necesito que el usuario introduzca datos. pero el gran jefe dijo que si pongo más cuadros de texto en mi programa. Este es el diagrama de herencia para la clase Dialog: . AWT soporta una clase especial de ventana. "Unos cuatrocientos".setText("EligiÓ el elemento 3 " ) . 1 Cuadros de diálogo "Uh-oh".getSource0 == menuitem2) label. podemos visualizar dicho elemento con el método actionPerformed: public void actionPerformed(ActionEvent event) ( if(event. else if(event.

Crea un objeto Dialog. Tabla 10.10. sin título y con el frame propietario y modalidad dados. Constructores de la clase Dialog. inicialmente invisible y no moda1con el propietario y título dados. Dialog(Dialogpropietario. I Eligió el elemento 2 I Ihpplet staried. boolean modal) Crea un objeto Dialog inicialmente invisible. Usar menús emergentes. no modal con . String titulo) Crea un objeto Dialog. boolean modal) Dialog(Framepropietario. inicialmente no visible con el propietario. Crea un objeto Dialog inicialmente invisible. dialogtitulo.17 y sus métodos en la tabla 10. título y modalidad dados. no modal sin título y el frame propietario dado. 1 Figura 10. Dialog(Dia1ogpropietario.Los constructores de la clase Dialog s e encuentran en la tabla 10. Dialog(Frame propietario. Crea un objeto Dialog inicialmente invisible y no modal sin título y el cuadro de diálogo propietario.18.17. String titulo) Crea un objeto Dialog inicialmente invisible.

Obtiene el título del cuadro de diálogo. Métodos de la clase Dialog. Una es que se pueden crear cuadros de diálogo modales (es decir. Tabla 10. 1 boolean isModal() boolean isResizable() protected String paramString() void setModal(boo1ean b) void setResizable(boo1ean resizable) I Oculta el cuadro de diálogo. boolean moda/) Crea un objeto Dialog. dependiendo del constructor Dialog que utilice o s i se usa el método setModa1. 1 Indica si el cuadro de diálogo puede ser redimensionado por el usuario. inicialmente no visible con el propietario. Fija el título del cuadro de diálogo. Otra puntualización es que se puede usar el método setResizeable para crear un cuadro de diálogo que el usuario pueda redimensionar. Empezaremos creando una nueva clase cuadro de diálogo llamada okcanceldialog que . título y modalidad dados. void addNotify() 1 void dispose() 1 String getTittle() 1 void hide() Hace que este cuadro de diálogo sea visualizable conectándolo a un compañero nativo. Dialog(Frame propietario. Indica si este cuadro de diálogo puede ser redimensionado por el usuario.el título y el frame propietario dados. / void setTittle(String titulo) void show() I En estas tablas hay varias cosas que observar. String titulo. Veamos un ejemplo que pone a funcionar a l a clase Dialog.1 8. Elimina el cuadro de diálogo. Especifica si este cuadro de diálogo debería ser modal. I Indica si el cuadro de diálogo es modal. que el usuario debe quitar el cuadro de diálogo de l a pantalla antes de interactuar con el resto del programa) o cuadros de diálogo no modales. Hace que el cuadro de diálogo seavisible. Obtiene la cadena que representael estado de este cuadro de diálogo.

M o d a l ). este texto aparecerá en la ventana principal de la aplicación. add(cance1). String title. en ese miembro de datos situamos una cadena vacía. Si el usuario hace clic sobre Cancelar. cancel. okcanceldialog(Frame hostFrame. setSize(300. 100). title.visualiza un cuadro de texto y dos botones: Aceptar y Cancelar. 1 setvisible(fa1se). add(text). public void actionPerformed(ActionEvent event) I if(event. 1 1 Cuando el usuario hace clic sobre el botón Aceptar. y luego instalando los controles que se necesiten: class okcanceldialog extends Dialog implements ActionListener I Button ok. boolean dModal) ( super (hostFrame. text = new TextField(30). cancel = new Button("Cancelarn). data = new String(""). Este es el código: class okcanceldialog extends Dialog implements ActionListener I Button ok.getText0. si el usuario hace clic sobre el botón Cancelar.getSource0 == ok) data = text.adBActionListener(this). 1 else ( data = "". creando un nuevo cuadro de diálogo.addActionListener((ActionListener) this). TextField text. ok. cancel. cancel. Empezaremos por extender okcanceldialog de la clase Dialog. add(ok) . no aparecerá texto. escondemos el cuadro de diálogo. setLayout(new FlowLayout()). Cuando el usuario hace clic sobre cualquier otro botón. el texto que el usuario escribió se almacena en un miembro de datos público llamado data para que sea accesible para el resto del programa en el método actionPerformed. } { . de lo contrario. Si el usuario escribe en el cuadro de texto y hace clic sobre el botón Aceptar. TextField text. public String data. ok = new Button("Aceptarm).

").applet. menuiteml = new MenuItem("Cuadr0de diálogo. true). 1 . Menul.add(menuitem1).. m f. 1)) . MenuBar Menubarl. setMenuBar(Menubar1). Label label.awt. dialog = n e w okcanceldialog(this. public class dialog ( public static void main(String [ l args) { dialogframe f = new dialogframe("Diálogos"). Menubarl = new MenuBarO. {public void class dialogframe extends Frame implements ActionListener ( Menu Menul.addWindowListener(new WindowAdapterO windowClosing(WindowEvent e) (System. rnenuiteml. add(labe1). visualizando un cuadro de diálogo de esa clase cuando el usuario selecciona la opción cuadro de diálogo del menú Archivo: import java .Applet. setLayout(new GridLayout(1. dialogframe(String title) { super(tit1e) . MenuItem menuiteml.add~ction~istener(thi~) .Se puede utilizar la nueva clase okcanceldialog en una aplicación. import java.awt . okcanceldialog dialog..*. Menul = new Menu("Archiv0"). * . import java.event. label = new Label("¡Hola desde Java! " ) .}}).exit(O). mDiálogom.

11. Visualizar un cuadro de diálogo. Visualizar texto desde el cuadro de diálogo. el archivo cuadro de diálogo. del menú Archivo.data). como se muestra en la figura 10. Ardmro . que veremos a continuación.12.Este es el texto1 Figura 10. el cuadro de diálogo aparece. . Cuando esta aplicación se ejecuta y se hace clic sobre la opción Cuadro de diálogo.setVisible(true)..getSource0 == menuiteml)( dialog. 1 1 1 Observe que además se recuperan los datos del texto del cuadro de diálogo usando el miembro de datos público data y lo situamos en una etiqueta en la aplicación.. Figura 10.public void actionPerforrned(ActionEvent event) { if(event. label. Hay otro tipo de cuadro de diálogo.12.1 1. como se muestra en la figura 10.setText(dia1og. Cuando el usuario escribe texto en el cuadro de texto del cuadro de diálogo y hace clic sobre Aceptar. el cuadro de diálogo se cierra y el texto aparece en la etiqueta de la ventana principal de la aplicación.

1 . 1 FileDialog(Frarnepadre) FileDialog(Framepadre. static int LOAD Indica que el propósito del cuadro de diálogo de archivos es localizar un archivo del que se pueda leer. int modo) Crea un cuadro de diálogo paraabrir un archivo. String titulo) FileDialog(Framepadre.20 y sus métodos en la 10. Tabla 10. Crea un cuadro de diálogo con el título indicado para abrir un archivo. Indica que el propósito del cuadro de diálogo de archivos es localizar un archivo en el que a se ~ u e d escribir.1 9. Campos de la clase FileDialog. Crea un cuadro de diálogo con el título indicado para abrir o guardar un archivo. Constructores de la clase FileDialog.19. static int SA VE Tabla 10.20. sus constructores en la 10.21.Cuadros de diálogo de archivos Se puede usar la clase especial AWT FileDalog para crear y visualizar un cuadro de diálogo de archivos que permita al usuario visualizar directorios y seleccionar ficheros. Este es el diagrama de herencia para esta clase: Los campos de esta clase se encuentran en la tabla 10. String titulo.

Establece que el nombre de este cuadro de diálogo es el nombre indicado. awt . * import java. Establece que el archivo de este cuadro de diálogo es el archivo dado. basta con crear un objeto FileDialog. Métodos de la clase FileDialog.awt. Determina el nombre de este cuadro de diálogo. Cuando el usuario selecciona un archivo. se visualiza el nombre del mismo en la ventana principal de la aplicación. Obtiene la cadena que representa el estado de este cuadro de diálogo. Obtiene el directorio de este cuadro de diálogo. Indica si este cuadro de diálogo es para abrir un archivo o para guardarlo. void addNotify() String getDirectory() String getFile() FilenarneFiltergetFilenarneFilter() int getMode() protected String pararnString() void setDirectory(String dir) void setFile(String file) void setFilenameFilter(Filename Filter filter) voíd setMode(ínt rnode) Crea el compaiiero del cuadro de diálogo. Establece el modo del cuadro de diálogo.event.* public class filedialog { public static void main(String [ ] args) I . mostrarlo con el método setvisible. Este es un ejemplo en el que se permite al usuario visualizar los directorios por medio de un cuadro de diálogo. Establece que el directorio de este cuadro de diálogo es el directorio dado.Tabla 10. Obtiene el archivo seleccionado de este cuadro de diálogo.21. y luego leer el nombre del archivo que el usuario seleccionó con el método getFile: import java . Hacer esto es fácil.

1)) . En esta figura.13 se muestra el resultado en Windows (por lo tanto se usa un cuadro de diálogo de archivos de Windows). Menul . setLayout(new GridLayout(1. MenuBar Menubarl.)l).dialogframe f = new dialogframe("Diá1ogos"). label = new Label("iHo1a desde Java! " ) . Label label. hemos seleccionado un archivo y cerrado el cuadro de diálogo..getSource() == menuiteml) I dialog. En la figura 10. g dialog = new FileDialog(this. Ipublic void class dialogframe extends Frame implements ActionListener { Menu Menul. true).exit(O). MenuItem menuiteml. nDiálogo archivo .14. menuiteml = new MenuItem("Abrir archivo. FileDialog dialog.addWindowListener(new WindowAdapterO windowClosing(WindowEvent e) {System.add~ctionListener(this). setMenuBar(Menubar1).setVisible(true). Menul = new Menu("Archivo"). y la aplicación principal visualiza el archivo seleccionado.. . dialogframe(String title) { super(tit1e). Menubarl = new MenuBarO. add(label ) . 1 public void action~erformed(~ctionEvent event) I if(event."). f. add (menui teml ) . navegamos hasta un archivo. menuiteml. En la figura 10.

Figura 10.14. Eligió archivo8 lava i Figura 10.13. Usar un cuadro de diálogo de archivos. Leer el nombre de un archivo desde un cuadro de diálogo de archivos. .

no diseñada para proporcionar una U1 seria y básica para las necesidades de millones de programadores. tiene muchos bugs y consume gran cantidad de recursos del sistema. un debate sobre Swing. fue modelado con controles HTML y asignada . es parte de la distribución estándar de Java y está tan de moda que ha llegado a desplazar a AWT. está limitado en el rango.y cambios apariencia Este capítulo inicia una sección del libro que muchos programadores estaban esperando. para los estándares de hoy.que tiene aproximadamente cuatro veces el número de componentes de la interfaz de usuario de AWT. AWT tuvo un avance significativo durante su existencia. Demos antes un repaso a la historia de Java. aunque es. el AWT original se tardó en escribir sólo seis semanas. Como se mencionó anteriormente en este libro. Clases Foundation de Java AWT era una herramienta poderosa que impulsó la popularidad de Java. Sin embargo. El conjunto de componentes AWT no fue diseñado para soportar la popularidad con la que fue recibido y dentro de las necesidades de programación de hoy. una implementación limitada. Ahora Swing.

Accesibilidad: Ayuda a los usuarios con aquello que no es posible hacer.1. pero no es así.applet. éstas fueron muy populares. y losenumeremos aquí (observe que cada componente U1 empieza con J. los componentes U1 son probablemente los más interesantes. Swing introdujo tres avances significativos: utiliza pocos recursos del sistema.Applet que añade el soporte para los paneles base y otros paneles. Esto es lo que hay en JFC: Swing: El gran paquete UI. Dado que los programadores llegaban a utilizar gran cantidad de controles. Impresión: Originalmente disponible en Java 1. Cuando Netscape introdujo su librería de clases Znternet Foundation Classes para usar con Java. imagen y texto. Muchos programadores creen que JFC y Swing son lo mismo. JButton: Pulsador o comando de botón.una ventana del sistema operativo por componente. veremos Swing con más detalle. Sun decidió actuar y la unión de los esfuerzos de Sun y Netscape dio lugar al conjunto de componentes Swing como parte de las clases Foundation de Java (JFC). Java 2D: Soporte mejorado del color. . añade gran cantidad de componentes más sofisticados y permite construir la apariencia de los programas. Colores del escritorio: Primero se introdujo en Java 1. A continuación. Desde el punto de vista del programador.1. Cortar y pegar: Soporte de portapapeles. lo que hizo que en Sun Microsystems se pusieran nerviosos. los colaboradores empezaron a producir sus propios conjuntos de controles. Swing es un conjunto de paquetes construido en la parte más alta de AWT que proporciona un gran número de clases preconstruidas (aproximadamente 250 clases y 40 componentes UI). que es una de las razones por la que muchos programadores usan erróneamente los términos JFC y Swing intercambiándolos): JApplet: Versión extendida de java. JFC contiene Swing y otro gran número de elementos.

JInternalFrame. JEditorPane: Componente de texto que permite al usuario editar varios tipos de contenido. JFiEechooser: Permite al usuario elegir un archivo. JDesktopPane: Contenedor usado para crear una interfaz de documentos múltiples o un escritorio. JLabel: Área visualizable para una cadena de texto corta o una imagen (o ambos). JColorChooser: Panel de controles que permite al usuario seleccionar un color. permitiendo que los componentes se solapen unos con otros. de forma que visualmente se pueda saber su estado. JMenu: Un menú de lista desplegable que contiene Jmenultems. que se visualiza cuando el usuario lo selecciona en el componente JMenuBar.awt. que es una combinación de cuadro de texto y lista desplegable. JFrame: Una versión extendida de java. JComboBox: Cuadro de lista desplegable. JOptionPane: Facilita la posibilidad de que emerja un cuadro de diálogo estándar. JMenultem: Una implementación de una opción de menú.JCheckBox: Casilla d e activación que puede ser seleccionada o deseleccionada. JComponent: Clase base para los componentes Swing. JPanel: Un contenedor genérico peso ligero. JMenuBar: Una implementación de una barra de menú. JInternalFrame: Un objeto de peso ligero que proporciona muchas de las características de un frame peso pesado.Frame que añade soporte para los paneles base y otros paneles.JDesktopIcon: Representa una versión iconificada de un JInternalFrame. JDialog: Clase base para crear un cuadro de diálogo. JLayeredPane: Añade capas a un contenedor Swing. . JList: Componente que permite al usuario seleccionar uno o más objetos de una lista.

JToggleButton. JScrollPane: Contenedor que gestiona barras de desplazamiento verticales y horizontales y las cabeceras de filas y columnas. JScrollBar: Implementación de una barra de desplazamiento. marcando su estado visualmente. JTree: Visualiza un conjunto de datos jerárquicos. JPopupMenu. JTextPane: Componente de texto que se puede marcar con atributos. JRootPane: Componente fundamental de la jerarquía del contenedor. JTabbedPane: Permite al usuario cambiar entre un grupo de componentes haciendo clic sobre lengüetas. útil para visualizar controles usados normalmente.JPasswordField: Permite editar una línea simple de texto donde no muestra los caracteres originales. JRadioButtonMenuZtern: Botón de opción de un elemento de menú. JToolTip: Visualiza una utilidad para un componente. JToggleButton: Botón de dos estados. JTextArea: Área de múltiples líneas que visualiza texto plano. JToolBar.Separator: Separador de un menú específico emergente. JTextFieEd: Permite la edición de una línea de texto sencilla.Separator: Separador específico de barra de herramientas. ToggleButtonModel: Modelo de botón toggle. JSeparator: Separador de menú. JPopupMenu: Un menú emergente. JSplitPane: Divide dos componentes. . JProgressBar: Componente que visualiza un valor entero en un intervalo. JToolBar: Barra de herramientas. JRadioButton: Botón de opción que puede ser seleccionado o no. JTable: Presenta datos en un formato de tabla bidimensional. JSlider: Componente que permite al usuario seleccionar un valor deslizando un botón en un intervalo.

se les denomina componentes peso ligero. derivada de la clase AWT Container. En programas extensos. por lo que usan bastantes menos recursos del sistema. JTree. se pueden obtener resultados extraños porque los controles Java aparecerán por encima de ellos. todos los componentes Swing son componentes AWT y se pueden mezclar controles AWT con controles Swing en los programas. JViewport: Vista mediante la que se ve información. . JComponent añade una cantidad tremenda de soporte de programación a la clase de componentes AWT. Cada componente AWT obtiene su propia ventana de la plataforma (y por lo tanto es como si fuera un control estándar de esa plataforma). por lo que JComponent es una clase peso ligero. y esta clase es. y que JComponent se deriva de la clase Container de AWT. dado que los controles Swing se dibujan en su contenedor. a su vez. Una cosa que deberíamos notar en esta lista es que todo control y contenedor AWT. Componentes peso pesado contra peso ligero ¿Por qué no se añadieron a AWT todas estas mejoras y nuevos componentes? Esta pregunta hace que volvamos de nuevo a ver cuál es la diferencia básica en la filosofía de los componentes AWT y Swing. la razón es que la clase JPanel ya soporta todo lo que el componente Canvas soportaba. que tiene ventana peso pesado (llamada compañero). Como se verá en este capítulo. JWindow: Ventana que puede visualizarse en cualquier sitio del escritorio. Los controles Swing. por otro lado. Todos los componentes Swing se derivan de la clase JComponent. excepto JCanvas. Por lo tanto.EmptySelectionMode1: Modelo de elección de árbol que no permite seleccionar nada. por lo que Sun no consideró necesario añadir un componente JCanvas por separado. tiene un sustituto en Swing.JTree. Observe que dado que los componentes Swing se derivan de JCornponent. todas estas ventanas ralentizan el rendimiento y consumen gran cantidad de memoria. Por este motivo. A tales componentes se les ha denominado pesos pesados.DynamicUti1TreeNode: Permite separar vectoreslhashtables/ arrays/cadenas y crear nodos apropiados para los hijos. son sencillamente dibujados como imágenes en sus contenedores y no tienen una ventana de la plataforma propia.

algo que era imposible con AWT. Igual que construimos applets AWT usando la clase Applet y aplicaciones AWT usando la clase Frame. para visualizar todo en un entorno de ventanas. Todo requiere un esfuerzo adicional de programación para pasar de AWT a Swing. son necesarias algunas ventanas del sistema operativo. Facilidad de desplazamiento: Ahora se puede conectar el desplazamiento a varios componentes. no por Sun. Por ejemplo. de diferentes. Por esa razón. que se puede ver cada línea cuando se está dibujando y hacerla un flash. Swing soporta estas clases peso ligero: JFrarne. entre otras cosas. como veremos en este capítulo.Ahora todos los componentes Swing son pesos ligeros. JWindow y JApplet. El hecho de que Swing esté construido sobre AWT no significa nada para el programador. no se sobrescribe el método paint nunca más. Características Swing Además del gran array de componentes en Swing y el hecho de que sean peso ligero. Tooltips: Se puede usar el método JCornponent. Estas son algunas de ellas: Bordes: S e pueden dibujar bordes alrededor de los componentes. Apariencia: Se puede establecer la apariencia de las applets y aplicaciones como cualquiera de los tres estándares: Windows. Facilidad de operaciones sin ratón: Ahora es fácil conectar las teclas a los componentes. y los contenedores peso pesado Swing de hecho tienen una estructura compleja para ser usados. Motif (Unix) 0 Metal (la apariencia estándar de Swing). De hecho. lo que significa. para pintar componentes. Swing introduce muchas otras innovaciones. Swing con frecuencia tiene el sentimiento de que algo es añadido por una tercera parte. construiremos applets Swingen la clase JApplet y aplicaciones Swing usando la clase Jframe. utilizando el método setBorder.setToopTipText para dar a los componentes un tooltip. y tendremos acceso directo a las partes del programa en las que se dibujan los menús de cuadros de diálogo. . que aparece cuando se mueve el ratón alrededor de un componente. no sólo para dibujar controles de peso ligero. porque Swing necesita hacer eso para dibujar los bordes y todo lo demás. una de esas pequeñas ventanas con texto explicativo. Debugging de gráficos: Se puede usar el método setDebuggingGraphicsOptions para iniciar el debugging de gráficos. JDialog.

por otro laao. y esto no era una buena idea para un lenguaje que estaba orgulloso de ser multiplataforma. ya q ue los compc ier transparentes en su lugar. y este objeto es de la clase JRootPane. lo que hizo que los programas AWT tuvieran una apariencia dependiente de la plataforma. En AWT. Swing introduce la apariencia Metal. Adicionalmente. evitando así las fluctuaciones. JApplet y JFrame. Por ejemplo. porque permite seleccionar el estilo de la apariencia del programa. método update para dibujar el fondo del elemento. De todas esta innovaciones. se puede dar a los programas una apariencia de Windows o Motif. y la otra es la arquitectura de programación Modelo-Vista-Controlador. sólo se pueden . Utilizar paneles en la programación de gráficos Las clases que son la base de las applets y aplicaciones. los controles se construían en ventanas de la plataforma. En la programación AWT. ya que fuentes y controles diferentes se usan en diferentes plataformas. ei métod no vue Ive a ditmjar el 1Fondo de:I elemerlto. y los program. el esquema de los programas podría aparecer diferente en distintas plataformas. ya que hay que entender cómo lo hacen los paneles antes de fijarlos en cualquier sitio en Swing. Ea Swing. Una es que cuando se crean applets Swing y aplicaciones se trabaja con paneles. tienen un objeto hijo que hace todo el trabajo de gráficos. Primero revisaremos cómo Swing funciona con paneles. que es la nueva apariencia de Java. Veremos este proceso en este capítulo. y será igual en todas las plataformas. Entre AWT y Swing hay dos diferencias de programación esenciales. directamente.adores con frecuencia sabrescriben update para llamar al método paint directamente.Nuevos gestores de esquemas: Swing introduce los gestores BoxLayout y Overlayout. la apariencia es probablemente la más importante. update 1 ama a 1 3 > ! .

Si se tiene una barra de menú en el programa. el controlador es la parte del componente que gestiona la entrada. probablemente los elementos más interesantes en el layered pane son la barra de menús y el área de trabajo. porque se espera que los añada al content Pune del objeto JRootPane. pero en Swing es un poco más complejo. Esta arquitectura es el corazón de la programación de componentes U1 de Swing. soportado con el objeto JMenuBar. Desde el punto de vista del programador. Hay capas específicas que tienen acceso. se obtendrá un error a menos que primero se desactive la verificación de errores. se ha convertido en algo estándar. El glas pane es realmente un objeto Component de AWT que pasa por todo el resto y que intercepta los eventos de ratón cuando se hace que este panel sea visible (aunque generalmente es transparente) y añade un Mouse listener. que visualizan menús y cuadros de diálogo cuando se abren. que es de la clase JLayeredPane. que quiere decir que primero hay que obtener una referencia de dicho panel. como en Microsoft Visual C++. En este caso. esto significa que cuando se añaden componentes a un programa. Esta es la estructura de un JRootPane: el panel tiene otros dos. se visualiza sobre el content pane. Dividir grandes programas en vistas y documentos. como la forma en que aparece un botón o una lista. El content pane es realmente un objeto de la clase AWT Container (no hay clase JContentPane). Aunque realmente se pueden añadir componentes directamente a JFrame o JApplet. se les añade al área de trabajo. Arquitectura Modelo-Vista-Controlador Hay un último punto que tratar antes d e pasar a la programación Swing: la arquitectura Modelo-Vista-Controlador (MVC). es donde tiene lugar la mayoría de las acciones. un layered pane y un glass pane. una vista pro- . como el estado de un botón o los elementos de una lista. La vista es la representación en pantalla del componente.añadir componentes a las applets o ventanas frarne. En la práctica. y es donde las applets y las aplicaciones visualizan sus componentes. como los clics del ratón. Finalmente. y la comprensión del término es fundamental. El layered pane. Esto es lo que este término significa: el modelo de un componente está donde están almacenados sus datos.

en Swing es útil separar la vista del modelo.1. que es donde los datos del programa se almacenan. Formalmente hablando. "probablemente por la clase JComponent". constructores y métodos. Ahora que hemos dado una pasada rápida por Swing. estoy preparado para empezar a trabajar con Swing. y mucho más. añadir objetos PropertyChangeListener. se debería echar un vistazo a las tablas 11. . inspirado en el lenguaje Smalltalk.2 y 1 1. swing. que contienen los campos. que son notificados cuando se cambia el valor de la propiedad. le contesta. Es una clase peso ligero derivada de la clase AWT Container. es hora de pasar a la siguiente sección. de esta gran clase. porque javax es el paquete que contiene Swing. JComponent es realmente la clase javax. donde la apariencia de los componentes pueden cambiar con unas pocas líneas de código. Trabajar con Swing El programador novato aparece y dice. Pronto verá más sobre la arquitectura MVC. Campos de la clase JComponent. l . Swing. "De acuerdo. 11. La clase JComponent es la base de todos los componentes Swing. Para referencias. Este es el diagrama de herencia para JComponent: La clase JComponent añade bastantes cosas a la clase AWT Container. Como se puede imaginar. protected AccessibleContext accessibleContext protected EventLístenerList IistenerList Soporte de acceso. ¿Por dónde empiezo?" "Bien". Lista de los listeners de eventos actuales. va más adelante y basa sus componentes U1 en la arquitectura MVC. múltiples vistas pueden proporcionar múltiples ventanas en el documento.3. respectivamente. Tabla 11. JComponent.porciona una ventana en un documento. como la posibilidad de dibujar bordes predefinidos alrededor de componentes UI.

indicando que se debería llamar al comando cuando el componente que recibe es un progenitor del componente que tiene el foco. Constructor por defecto de JComponent. Métodos de la clase JComponent.KEY Comentario que se visualiza cuando el cursor está sobre el componente. Constante usada por registerKeyboardAction(). Notificación de que este componente tieneahora un componente padre. Añade un PropertyChangeListener a la lista de listener.2. Tabla 11. void addNotify() void addPropertyChangeListener (PropertyChangeListener listener) . Usado por registerKeyboardAction(). Constructor de la clase JComponent. protected ComponentUl ui static int UNDEFINED-CONDITION static int WHEN-ANCESTOR-OF FOCUSED-COMPONENT static int WHEN.3. voidaddAncestorListener(AncestorListener listener) Registra el listener para que reciba AncestorEvents. Constante usada para indicar que no se ha definido ninguna condición. lnterfaz de usuario. indicando que se debería llamar al comando cuando el componente tenga el foco.FOCUSED static int WHEN-IN-FOCUSEDWlNDOW Tabla 11.static String TTOL.TEXT. indicando que se debería llamar al comando cuando el componente tenga el foco.TIP. Constante usada por registerKeyboardAction().

byte newvalue) Reporta un cambio de propiedad de fronteras. int newvalue) void firePropertyChange(String property. void firePropertyChange(String property. double newvalue) de fronteras. Obtiene el rectángulo visible del componente. short newvalue) Reporta un cambio de propiedad de fronteras. in t y) JtoolTip create ToolTip() Añade un VetoableChangeListener a la lista de listener. char newvalue) de fronteras. Iong oldValue. float newvalue) void firePropertyChange(String property. newvalue) . Obtiene la instancia de JtoolTip que debería usarse para visualizar el tooltip.de fronteras. Object tar los cambios de propiedades.voidaddPorpertyChangeListener(String Añade un PropertyChangepropertyName. Name. void firePropertyChange(String property. char oldValue. Name. byte oldValue. void firePropertyChange(String property. Object newtar los cambios en las propiedaValue) des de fronteras.Reporta un cambio de propiedad Name. double oldValue. Object oldValue.Reporta un cambio de propiedad de fronteras. Determina si el componente contiene el punto dado. boolean new. Value) void firePropertyChange(String propertyName.Reporta un cambio de propiedad de fronteras. float oldValue. void firePropertyChange(String property.Reporta un cambio de propiedad Name. long newvalue) void firePropertyChange(String property. void firePropertyChange(StringpropertyName.Reporta un cambio de propiedad Name. short oldValue. protected void fireVetoableChange(String Proporciona soporte para reporpropertyName. listener) voidaddVetoableChangeListener (VetoableChangeListener listener) void compute VisibleRect(Rectang1e visible Rect) boolean contains(int x. Object oldValue. int oldvalue.Reporta un cambio de propiedad de fronteras.Proporciona soporte para reporName. Name. boolean oldValue. PropertyChangeListener Listenerpara una propiedad específica.

AccessibleContextgetAccessibleContext() Obtiene el AccessibleContext asociado con este JComponent. el método obtiene los intercalados. Si se ha establecido un borde para este componente. Obtiene el valor de la propiedad con la tecla especificada. Obtiene la alineación horizontal. Devuelve verdadero si este componente automáticamente desplaza su contenido cuando se arrastra. ActionListenergetActionForKeyStroke (KeyStroke a KeyStroke) Obtiene el objeto que ejecutará la acción registrada para una combinación de teclas dada. Obtiene un objeto lnsets para este componente. Obtiene la condición que determina si ocurre una acción para la tecla aceleradoraespecificada. Obtiene la altura actual de este componente. Obtiene el borde de este componente o nulo si no está el borde. Obtiene el contexto de gráficos de este componente. Almacena las fronteras de este componente en rv y devuelve rv. float getAlignmentX() float getAlignmentY() boolean getAutoscrolls() Border getBorder() Rectangle getBounds(Rectange rv) Object getClientProperty(0bject key) protected Graphics getcomponentGraphics(Graphics g) int getConditionForKeyStroke(KeyStroke a KeyStroke) int getDebugGraphicsOptions() Graphics getGraphics() int getHeight0 lnsets getlnsets() lnsets getlnsets(lnsets insets) . get-insets. De lo contrario llama a super. Obtiene el objeto gráfico usado para pintar este componente. Obtiene el estado del debugging de gráficos. Obtiene la alineación vertical.

este método lo devuelve. KeyStroke[] getRegisteredKeyStrokes() JRootPane getRootPane() Dimension getSize(Dimension rv) Point getToolTipLocation(Mouse Event event) String getToolTipText(MouseEvent event) Obtiene la cadena a utilizar por el tooltip en ese evento. Si el tamaño preferido se ha establecido a un valor no nulo. Rectangle getVisibleRect() int getWidth() int getX() .- -- Point getLocation(Point rv) Dimension getMaximumSize() Dimension getMinimumSize() Component getNextFocusableComponent() Dimension getPreferredSize() Almacena el origen x. Obtiene la coordenada x actual del origen de este componente. ComponentUI.y de este componente en rv y devuelve rv. Obtiene las teclas aceleradoras que inician acciones.plaf. Obtiene la posición del tooltip en el componente. ContainergetTopLevelAncestro() String getUIClasslD() Obtiene el primer antecesor del componente. Obtiene el tamaño máximo del componente. Obtiene el tamaño mínimo del componente. Obtiene la cadena tooltip que se ha establecido consetToolTípTexto. Obtiene el rectángulo visible del componente. Obtiene el progenitor de un componente. Obtiene la clave UlDefaults usada para encontrar el nombre de la clase swing. Obtiene el siguiente componente que debe tener el foco o null. Almacena la anchura y altura de este componente en rv y devuelve rv. Obtiene la anchura actual.

Devuelve verdadero si el componente titula a sus hijos. Especifica si este componente puede recibir el foco. boolean isDoubleBuffered() boolean isFocusCycleRoot() boolean isFocusTraversable() static boolean isLightweightComponent (Component c) boolean isManagingFocus() boolean ¡sopaque() boolean isOptimizedDra wingEnabled0 boolean isPaintingTile() boolean isRequestFocusEnabled() Preparar para crear un applet Swing "De acuerdo". Devuelve verdadero si este componente tiene el foco del teclado. "estoy preparado para empezar a crear applets usando Swing. Devuelve verdadero si el componente es la raíz de un árbol de componente con un ciclo de foco. Devuelveverdadero si el componente es opaco. Indica si el componente receptor debería usar un bufferpara pintar.int getY() void grabFocus() boolean hasFocus() Obtiene la coordenada y actual del origen de este componente. Devuelve verdadero si este componente es peso ligero. Esta clase tiene un . le responde. La clase JApplet es un contenedor peso pesado que es la base de las applets Swing y una extensión de la clase Applet AWT. dice el programador novato. Fija el foco en el componente. "coja una silla y veámoslo". Devuelveverdadero si el componente receptor puede obtener el foco. Devuelve verdadero si el componente está pintando un entramado. ¿Cómo lo hago?" "Con la clase JApplet". Devuelveverdadero si el componente gestiona el foco.

Campos d e la clase JApplet.*. se complican más las cosas (cuando se quiere dibujar en un applet o añadir controles en él).4. un objeto de la clase JRootPane.hijo. Para arrancar un applet Swing. porque normalmente se trabaja con el content pane en la applet en lugar de hacerlo en la applet en sí misma.swing. en este punto.*.6. su constructor en la 1 1.4. 1 protected JRootPane rootPane protected AccessibleContext accessiblecontext Accesibilidad a un contexto.awt. Panel raíz. Tabla 11. Indica si se producirán errores al intentar añadir componentes al root pane. protected boolean rootPanecheckingEnabled I . y es donde se continúa el dibujo y donde se añaden los componentes. * para usar JApplet): import java.5 y sus métodos en la 11. Este es el diagrama de herencia de JApplet: Los campos de esta clase se encuentran en la tabla 1 1. basta derivar una clase de la clase JApplet como sigue (observe que importamos javax.swing. import javax. public class applet extends JApplet I Desafortunadamente.

Fija la propiedad contentpane. Object constraints. Obtiene la propiedad glasspane. Constructor de la clase JApplet. Obtiene una representación en cadena de esta JApplet. JLayeredPane getLayeredPane() JRootPane getRootPane() protected boolean isRootPaneCheckingEnabled() protected String pararnString0 protected void processKeyEvent (KeyEvent e) void remove(Component cornp) void setContentPane(Container contentPane) void setGlassPane(Component glassPane) Obtiene el objeto IayeredPane para esta applet. Devuelve verdadero si la verificación delrootpaneestá habilitado.5. Elimina el componente especificado de este contenedor. . int indice) Añade hijo al content pane. Obtiene el objeto glasspanepara esta applet. Obtiene el objetocontentPanepara esta applet. AccessibleContext getAccessibleContexto ContainergetContentPane() Cornponent getGlassPane() Obtiene el contexto accesible asociado con esta JApplet.Tabla 11. Crea una instancia a un applet S wing. void setJMenuBar(JMenu5ar rnenuBar) Obtiene la barra de menú de esta applet. Obtiene el objeto rootPane para esta applet. Obtiene la barra de menú para esta applet. protected JRootPane createRootPane() Lo llaman los métodos del constructor para crear el rootpanepor defecto. protected void addlmpl(Component comp. Procesa eventos clave que ocurren en este componente enviándolos a los objetos KeyListener.

S y sus métodos en la 1 1. root) protected void setRootPaneCheckingEnabled(boo1ean enabled) void update(Graphics g) Si es verdadero. el root pane contiene glass pane. content pane y layered pane. su constructor en la 11 .void setLeyeredPane(JLayeredPane IayeredPane) void setLayout(LayoutManager manager) Obtiene la propiedad IayeredPane. Comprender los root panes La clase JRootPane es la clase que gestiona la apariencia de los objetos de JApplet y JFrame. Echaremos un vistazo a los root panes en el siguiente punto.awt.swing.7. En particular. Fija el esquema de este content pane. como es presionar la tecla Intro.Container Ijavax. lang. Tanto JApplet como JFrame tienen un objeto hijo.9.7.JComponent Ijavax. Botón que está activado cuando el panel tiene el foco y se produce una acción. y el content pane es parte de root pane.0bject Ijava.No vuelve a dibujar el fondo. Campos de la clase JRootPane.JRootPane Los campos de la clase JRootPane los encontrará en la tabla 11.swing. que veremos en la programación Swing. Este es el diagrama de herencia para JRootPane: java.awt. protected void setRootPane(JRootPane Fija la propiedad rootpane. Llama paint(g).Component 1java. Tabla 11. 1 protected Container contentpane protected JButton defaultButton El content pane. I . un objeto de la clase JRootPane. llamaa addy setlayout causará una excepción.

Llamado por los métodos constructores para crear el contentpane por defecto.9. Llamado por los métodos constructores para crear el glass pane por defecto. protected JLayeredPane createpane. Object constraints. estableciendo sus componentes glasspane. int indice) void addNotify() protected Container createcontentPane() protected Component createGlassPane() Sobrescrito por Swing.JRootPane.Llamado por los métodos construcLayout0 tores para crear el layout manager I por defecto. LayeredPane y contentPane. Tabla 11. protected JMenuBar menuBar Barra de menú. Constructor de la clase JRootPane.swing. Registra un nuevo root pane.protectedjavax. DefaultAction defaultReleaseAction protected Component glassPane Acción que se produce cuando se presiona el botón por defecto.swing. protected JLayeredPane IayeredPane El layered pane que gestiona la barra de menú y el content pane. Llamado por los métodos construcLayeredPaneO tores para crear el layered por defecto. por lo que pueden interceptar los movimientos de ratón. Tabla 11. protected void addlmpl(Component comp. JRootPane. Acción que se produce cuando el botón. JRootPanel() Crea un componente JRootPane. . por defecto.8. DefaultAction defaultPressAction protectedjavax. protected LayoutManager createRoot. Métodos de la clase JRootPane. se suelta. 1 Glass pane que cubre la barra de menú y el content pane.

Obtiene el contexto accesible. voidsetGlassPane(Componentglass) Fija un componente especificado para ser el glass pane para este root pane. Fija el layeredpane para elrootpane. Obtiene el layered pane usado por el root pane. Reemplazado por getJMenubar(). ContainergetContentPane() JButton getDefaultButton() Component getGlassPane() JMenuBar getJMenuBar() JLayeredPane getLayeredPane() JMenuBar getMenuBar() boolean ¡SFocusCycle Root() boolean is ValidateRoot() protected String paramString() void removeNotify() voidsetContentPane(Containercontent) Fija el content pane. Obtiene la barra de menú del layered pane. Elimina el registro desde SystemEventQueueUtils.Component findComponentAt(int x. . Obsoleto. Obsoleto. Obtiene el glass pane. Obtiene el content pane. Si un descendiente de esta JRootPane llama a revalidate. Reemplazado porsetJMenuBar. Forma la raíz de un ciclo de foco. int y) AccessibleContextgetAccessibleContexto Localiza el componente hijo visible que contiene la posición especificada. Obtiene una representación en cadena de root pane.la validación tendrá lugar de aquí hacia abajo. Obtiene el botón por defecto. void setJMenuBar(JMenuBar menu) voidsetLayeredPane(JLayeredPane layered) void setMenuBar(JMenuBar menu) Añade o cambia la barra de menú usada en el layered pane. void setDefaultButton(Jbutton defa ultButton) Fija el botón actual por defecto.

Lo veremos en el siguiente punto.10. su constructor en la 1 1. Comprender layered panes Los layered pane del root pane gestionan los componentes actuales que aparecen en lasapplets y aplicaciones. moveToFront. el layered pane. se puede usar los métodos JLayeredPane. generalmente se trabaja con el content pane del root pane. Poner un componente en una de estas capas hace que sea más fácil asegurarse de que los componentes se solapen adecuadamente. JLayeredPane: Por conveniencia. Como es típico que las operaciones de dibujo vayan en applets y aplicaciones. donde van los componentes. es parte de otro panel. PALETTE-LAYER: La capa de paleta se pone como defecto y e s útil para barras d e herramientas y paletas flotantes. El content pane en sí mismo. moveToBack y setposition.11 y sus métodos en la 11. JLayeredPane divide el rango en varias capas diferentes.Para construir applets y aplicaciones. . DRAG-LAYER: Cuando se arrastra un componente.12. También se puede utilizar el método setLayer usado para cambiar la capa actual del componente. sin embargo. se asegura de estar situado sobre otro componente en el contenedor. MODAL-LAYER: Capa usada para cuadros de diálogo modales. la parte más importante del layered pane es el content pane. incluyendo barras de menú y el content pane. LO veremos en el siguiente punto. POPUP-LAYER: Capa de menú emergente que se visualiza sobre la capa de diálogo. Los campos de la clase JLayeredPane se encuentran en la tabla 1 1. sin tener que preocuparse de especificar los miembros para cada espesor: DEFAULT-LAYER: La capa estándar y la de más al fondo. Para la reposición de un componente dentro de su capa. asignándolo a la capa de arrastre. Este es el diagrama de herencia para la clase de layered pane.

int indice) a este contenedor. Tabla 11 -12. Capa de paleta. Métodos de la clase JLayeredPane. Obtiene el atributo capa para el componente indicado. static lnteger DEFAULT-LA YER static Integer DRAG. Obtiene el hashtableque hace corresponder los componentes con las capas. Obtiene la propiedad de capa para un JComponent y no causa ningún efecto lateral como setLayer(). AccessibleContextgetAccessibleContext() Obtiene el contexto accesible.LAYER static String LA YER.1 1. protected void addlmpl(Component index.1 0. statis lnteger FRAMECONTENT-LAYER Capa frame content. Capa modal. Object constraints.Tabla 1 1. . Crea un nuevo objeto JLayeredPane. Campos de la clase JLayeredPane. Capa de arrastre.Añade el componente indicado comp. int getComponentCountlnLayer(int layer) Component[] getComponentlnLayer (int /ayer) protected Hashtable getcomponentTo Layero int getlndexOf(Component c) static int getLayer(JComponent c) Obtiene el número de hijos en la capa indicada. Obtiene un arrayde los componentes en la capa indicada. static lnteger POPUP-LAYER Capa por defecto. Tabla 11. Propiedad de frontera. Capa de menú emergente. Constructor de la clase JLayeredPane.PROPERTY static lnteger MODAL-LAYER static lnteger PAL ETTE-LA YER .

int lowestLayer() void moveTo Back(Component c) void paint(Graphics g) protected String paramString0 static void putLayer(JComponent c. int posición) void setPosition(Componentc. Obtiene el valor de la capa más baja desde el hijo actual. . boolean isOptimizedDrawingEnabled() Devuelve falso si los componentes en el panel pueden solaparse. Fija la propiedad de capa en un JComponent. Obtiene la posición relativa del componente dentro de su capa. Mueve el componentea la parte superior de los componentes en su capa actual. Pinta el layered pane usando un contexto gráfico. Fija el atributo de la capa para el componente indicado y además fija su posición dentro de esta capa.static JLayeredPane getLayeredPaneA bove(Component c) protected lnteger getObjectForLayer(int layer) int getPosition(Component c) int highestlayero Obtiene el primer JLayeredPane. Obtiene el valor de la capa más alta desde el hijo actual. Obtiene una representación en cadena de esteJLayeredPane. Obtiene el objeto lnteger con una capa indicada. int layer. Retira el componenteindexado de este panel. intposición) Mueve el componente a la posición dentro de su capa actual. Determina la propia ubicación int posición) en la que se inserta un nuevo hijo basado en la capa y la posición. int layer) void remove(int índice) void setLayer(Component c. protected int insertlndexForLayer(int layer. que contiene el componente indicado.

quizás estuviera esperando ver un método paint para gestionar las operaciones de pintura y los gráficos en applets y aplicaciones Swing. porque Swing. Otro punto importante es conocer qué content panes usa. Pintar en Swing frente a AWT Cuando hemos visto el contenido de AWT antes en este capítulo. pero de hecho. Se puede esperar que el content pane lo soporte su propia clase. en sí mismo. los controles y los gráficos se sitúan en un contentpane de un applet o aplicación. usando el método getContentPane de las clases JApplet y JFrame. hay un método paint. el método paint de la applet o ventana frame. comparado con la programación AWT. echemos un vistazo al siguiente punto. En lugar de usar el métodopaint para las operaciones de pintura. pero no debería sobrescribirlo a menos que realmente sepa lo que está haciendo. border layout. En lugar de sobrescribir. Éste tiene algunas ramificaciones al crear applets y aplicaciones. Para ver cómo funciona esto realmente en el código. así como para dibujar cualquier componente hijo en el componente. sino que es un objeto (una alternativa es crear una clase content pane personalizada y usar el método setContenrPane para instalarla en el . dice el programador novato. por defecto. utiliza ese método para dibujar los bordes alrededor del componente. le contesta. Crear un applet Swing "De acuerdo". ¿Cómo se hace esto?" "Siéntese y discutámoslo". Esto se debe hacer porque el content pane en un programa no es una clase en la que se puedan sobrescribir métodos. De hecho. Se puede tener acceso al contentpane en el layered pane de un applet o aplicación. esto marca una gran diferencia con la programación AWT. ahora hay que crear un componente para pintar en él. "estoy preparado para crear un applet Swing y añadir elementos al content pane. ahora se utiliza el métodopaintComponent.Comprender los content panes Generalmente. La importancia del content pane se debe a que es el lugar donde generalmente se añaden componentes a las applets y aplicaciones. así como donde se dibujan gráficos. s610. un contentpane es sólo un objeto Container (que es una clase peso ligero). entre otras tareas.

el método paintcomponent d e la super clase. Además se puede dibujar en ese panel sobrescribiendo su m é t o d i paintlomponent. lo primero que se debería hacer es llamar a super. ¿Cómo se visualiza el texto? No podemos visualizarlo en el contentpane por defecto de la applet. no una clase. En este caso. truir un compont presionan las t e d una visión compl-. se a para te ner Usar la clase JPanel La clase JPanel es la clase contenedora para cualquier propósito deSwing. Tanto en applets como en aplicaciones se usa por defecto el border layout. por lo que no podemos sobrescribir su método paintcomponent. e instalarlo con e l método setContentPane. Observe que se podría crear una nueva clase contentpane. se usa el método add del contentpane..programa). usaremos el método add. Este es el diagrama de herencia de JPanel: .paintComponent. Veamos un ejemplo.. en la que las applets usanflow layout y las ventanas frame. ya que es un objeto. como se hace en la programación AWT. representado por la clase JPanel. Visualizar controles en Swing frente a AWT Para añadir controles a un content pane. pero JPanel generalmente se utiliza para crear content panes de cualquier forma. la1 tal c omo JA is-lont~ el foco. o usar el border layout por defecto. no se puede añadir un panel. y es importante conocerla. a la applet para que cubra el content pane. visualizamos el texto "¡Hola desde Swing!" en un applet. Para añadir controles. observe que cuando se trabaja con paintlomponent. Por otro lado. Además. Para añadir controles a un content pane. sobrescribir su método paintlomponent. primero hay que fijar el layout manager como se quiera. a diferencia de la programación AWT. border layout.

JPanel(LayoutManager1ayout) JPanel(LayoutManagerlayout. JPanel usa por defecto unflow layout. Métodos de la clase JPanel. Obtiene una representación en cadena de JPanel. JPanel(boo1ean isDoubleBuffered) Construye un nuevo JPanelcon un flow layout y la estrategia de bufferespecificada. se le pasa un objeto AWT Graphics. . Construye un nuevo JPanelcon un doble buffer y un flow layout.Al contrario que los contenedores peso pesado de Swing.1 3. Se le llama cuando la apariencia ha cambiado. Tabla 11. protected String paramString() void updateUl() A continuación crearemos una clase JPanel que visualiza el texto "¡Hola desde Swing!" (observe que a este panel se le está dando un fondo blanco y que se sobrescribe el método paintcomponent. Constructores de la clase JPanel. Construye un nuevo JPanelcon el layout manager especificado.14.white).14. Construye un nuevo JPanelcon el layoutmanagery la estrategia de buffer especificados. AccessibleContext getAccessibleContexto String getUIClasslD() Obtiene el contexto accesible. Los constructores de la clase J P a n e l se encuentran en la tabla 11. boolean isDoubleBuffered) Tabla 11.13 y sus métodos en la tabla 1 1. Obtiene una cadena que especifica el nombre de la clase que devuelve este componente. que se puede usar para escribir el texto): class jpanel extends JPanel { jpanel( 1 I setBackground(Color.

0. 0 . 1 1 class jpanel extends JPanel I jpanel( setBackground(Color.white). g.awt. public void init0 { Container contentpane = getContentPane0. como se muestra en la figura 11.* . j = new jpanel ( ) .paintComponent(g).paintComponent(g).add(j).public void paintcomponent (Graphics g) c super.*. 1 1 Ahora se puede añadir un objeto de esta nueva clase al contentpane de un applet usando el método getContentPane de la clase JApplet. contentPane. g. Este ejemplo está en el CD que acompaña a este libro como . public class applet extends JApplet { jpanel j.dra~String(~iHola desde Swinglw.drawString("iAola desde Swingl". import javax. 1 1 Ahora se puede compilar y ejecutar esta applet.1. 60). 6 0 ) . 1 public void paintcomponent (Graphics g) C super. y después usar el método add del content pane para añadir el panel: import java.swing.

Frame Ijavax. "¿Usando la clase Frame?.awt. Un applet Swing. "la clase JFrame". .Figura 11 . cuando se crean aplicaciones en Swing se usa un objeto JFrame.16 y sus métodos en la tabla 11. Este es el diagrama de herencia para JFrame (observe que se deriva de la clase Frame y es un contenedor peso pesado): java. ¿Por dónde empiezo?" "Creando una ventana frame ".15. "estoy preparado para crear una aplicación usando Swing.Object 1java." pregunta NP. que tiene un root pane hijo.17.Container 1j ava . Observe que el layout por defecto en un JFrame es un border layout.swing.lang. Al igual que en las aplicaciones AWT generalmente usamos una ventana frame.awt. sus constructores en la 11.le dice. dice el programador novato.JFrame Los campos de la clase JFrame se encuentran en la tabla 11. awt . le contesta.Component Ijava. "No". l . Crear una aplicación Swing "De acuerdo".

1 1 JFrame() Crea un nuevo frame Crea un nuevoframe co8 título especificado I ( JFrame(Títu10) I Tabla 11. Campos de la clase JFrame. Constructores de la clase JFrame. Llamado por los métodos del constructor para crear el root pane por defecto. protected void framelnit() AccessibleContext getAccessibleContext() ContainergetContentPane() int getDefaultCloseOperation() I Component getGlassPane() .barra de menú y glass pane. Obtiene el contexto accesible asociado con este JFrame. Obtiene el objeto glassPane. Obtiene el objeto content pane de este frame. llama a add y setLayout produce una excepción. Tabla 11. 1 1 protected AccessibleContext accessibleContext Contexto accesible.1 6. protected JRootPane rootfane Root pane que gestiona el contentpane.Tabla 11. I protected boolean rootPaneCheckingEnabled Si es verdadero.17. Obtiene la operación tiene lugar cuando el i rio cierra el frame.15. Object constraints. Llamado por los constructores para inicializar la propiedad JFrame. int indice) protected JRootPane createRootPane() Añade hijos al contentpane. Métodos de la clase JFrame protected void addlmpl(Component como.

void setGlassPane(Componente glasspane) void setJMenuBar(JMenuBar menubar) void setLayeredPane(JLayeredPane layeredPane) void setLayout(LayoutManager manager) protected void setRootPane(JRootPane root) protected void setRootPaneCheckingEnabled Determina si llama a addy (boolean enabled) setLayout causa una excepción. Establece la barra de menú para este frame. void setDe faultCloseOpera tion(in t operación) Fija la operación que tendrá lugar. protected void porcessKeyEvent(KeyEvent e) Procesa los eventos de tecla que ocurren en este componente. protectedboolean isrootPaneCheckingEnabled() Indica si llama a addy setLayout causa una excepción. se debería fijar el layout del content pane en su lugar. por defecto. Por defecto. . void setContentPane(Container contentpane) Obtiene la propiedad contentPane.Procesa eventos de ventaEvent e) na que ocurren en este componente. cuando el usuariocierre este frame. Fija la propiedad layeredPane. protected String paramString() Obtiene una representación en cadena de este JFrame. void update(Graphics g) Llama a paint. Obtiene el root pane. Fija la propiedad glassPane. Fija la propiedad rootPane. protected voidprocess WindowEvent(Window. void remove(Component comp) Elimina el componente de este contenedor.JMenuBar getJMenuBar() JRootPane getRootPane() Obtiene la barra de menú.

60). Este es el código: class jpanel extends JPanel { public void paintcomponent (Graphics g) i super. pero haremos que el panel sea blanco fijando su color de fondo.add(j). 0. Container contentpane j = new jpanel(). g. instalaremos el panel en un objeto JFrame.*. creamos un objeto de esta nueva clase y lo añadimos al content pane de JFrame en una aplicación. class jpanel extends JPanel I jpanel( ) I . 1 1 A continuación. P get~ontentPane0. El color de fondo por defecto de JFrame es gris. como sigue: import javax.*.paintC-onent(g). y visualizaremos el texto "¡Hola desde Swing!" en el panel. public app ( ) I super("Ap1icación Swing").dra~String(~~Hola desdel". public class app extends JFrame y I jpanel j.swing. crearemos1 un objeto JPanel (como en el punto anterior).*.awt. contentPane. import java. 1 public static void main(String argsil) I final JFrame f = new app ( ) .event.awt. En este caso. import java.Ahora. pondremos a funcionar la clase JFrame.

además. por otro lado. no pasa nada. Este ejemplo se encuentra en el CD como app. "Tomemos un café". "se puede solucionar de varias formas".Estos son los valores posibles que se le pueden pasar a este método: . Visualizar una aplicación Swing en una ventana frame. por defecto. > 1 Ahora.2. dice PN. 0. 60). hay un problema con esta aplicación. Cerrar ventanas JFrame "Hey". Cuando se cierra una ventana AWT. no hace nada". Para remediar esta situación.paintComponent(g). "otra vez Java está graciosillo. Las ventanas JFrame de Swing. g. El resultado se muestra en la figura 11. Cuando se cierra esta ventana de aplicación haciendo clic en el botón Cerrar. Sin embargo.public void paintcomponent (Graphics g ) super. hemos usado el método setBounds para fijar la posición y tamaño de la ventana JFrame. pero la aplicación no finaliza. le contesta. veamos el siguiente punto. Figura 11. dice el programador novato. desaparece de la pantalla (que es más de lo que una ventana de aplicación AWT haría).drawString("iHola desde Swing!". pero se pueden gestionar los eventos de ventana y finalizar la aplicación si se quiere.java. Cuando intento cerrar una ventana JFrame de Swing. "Bien".2. permiten establecer una operación de cierre por defecto con el método setDefaultCloseOperation.

nos liberamos de la ventana y finalizamos la aplicación con una clase interna adaptadora: import javax. 1 1 class jpanel extends JPanel ( .*.addWindowLiitener(new WindorAdapterO < public void w i n d o r ~ l o c i e d ( ~ i n d ~e) ( at Syntam. public class app extends JFrame ( jpanel j. 1 public static void main(String argsil) { final JFrame f = new a p p 0 .DO-NOTHING-ON-CLOSE: rra la ventana. todavía tendrá que gestionarse.exit (O) . add ( j ) .*. Observe que estas posibilidades sólo tratan con la ventana en sí misma.event. No pasa nada cuando se cie- HIDE-ON-CLOSE: Esconde la ventana cuando se cierra. 1 1).awt. si se quiere finalizar la aplicación cuando la ventana de aplicación se cierra. contentpane . A continuación. DISPOSE-ON-CLOSE: Se libera de la ventana cuando se cierra. El defecto. aunque el objeto todavía está disponible en memoria.*. j = new jpanelo .awt. public app() { super("Ap1icación Swing"). import java. Container contentpane = getContentPane0. No se puede volver a visualizar la ventana. import java. f.swing.

public void paintcomponent (Graphics g) { super. g. Este es el diagrama de herencia de la clase BorderFactory: Los métodos de la clase BorderFactory se recogen en la tabla 11. 1 1 Seleccionar los bordes del componente "Bien". Además se pueden usar las clases EmptyBorder.19. EtchedBorder. He aquí el diagrama de herencia de la clase Insets: . este método devuelve un objeto de la clase Insets. dice el programador novato. "¿Cómo funciona?" pregunta PN. que indican la distancia que se debe permitir en cada borde para considerarlo en el cálculo. Los insets de un borde se pueden obtener con el método getBorderInsets de la interfaz Border. Usar Insets Una parte importante de trabajar con bordes es conocer los insets. "puede usar diferentes tipos de bordes para los componentes en Swing. Para crear un borde d e un componente. 60). Es bastante fácil".paintComponent(g). CompoundBorder y AbstractBorder para crear los propios bordes. le contesta. La clase BorderFactory crea objetos que implementa la interfaz Border. SoftBevelBorder. los métodos de la interfaz están en la tabla 11. "el gran jefe quiere que nuestros programas sean más decorativos. interesado. visualmente más atractivos. que crea bordes de estas clases: BevelBorder. 0. ¿Alguna idea?" "Bien".drawStringíU ¡Hola desde Swing!'.18. s e puede usar la clase BorderFactory. TitledBorder y MatteBorder. LineBorder.

int fondo. static Border createBevelBorder(int tipo. - Crea un borde compuesto. Border borde-interior) static Border createEmptyBorder() Crea un borde compuesto. int de. Devuelve una Iínea de borde con el color y grosor indicados.18. int izquierda. static CompoundBorder create CompoundBorder0 static CompoundBorder createcompoundBorder(Border border. static Border createLoweredBevelBorder() Devuelve un borde con un borde grabado más bajo. Devuelve un borde vacío.usando un color sólido. static Border createBevelBorder(int tipo) Crea un borde biselado del tipo indicado. indicando los objetos para los bordes interior y exterior.Tabla 11. Color highlight. Color shadow) iluminación y sombreado indicados. recha. Devuelve un borde vacío que no ocupa espacio. indicado. Color color) . static Border createEtchedBorder() static Border createEtchedBorder(Co1or Crea un borde como si fuera grabado usando los colores de ilumiiluminación. int grosor) Devuelve una Iínea de borde con el color indicado. con los colores especifiColor shadowouter. Crea un borde como si fuera grabado usando el color de fondo actual del componente para la iluminación y el sombreado. static MatteBorder createMatteBorder(int Devuelve un borde enmarañado superior. Color shadowlnner) cados para las áreas internas y externas de iluminación y sombreado. Colorsombra) nación y sombreado. Métodos de la clase BorderFactory. Color highlightinner. Crea un borde biselado del tipo. static Border createLineBorder(Co1or color) static Border createLineBorder(Co1or color. Crea un borde biselado del tipo Color highlightouter. static Border createBevelBorder(inttipo.

Tabla 11. String titulo.19. Añade un título a un borde existente. int derecha. posición y fuente. . Métodos de la interfaz Border. int fondo. int x. boolean isBorderOpaque() void paintBorder(Component c. int izquierda. String titulo. 1 Crea un nuevo título.static MatteBorder createMatteBorder (int superior.20. static Border createRaisedBevelBorder() Devuelve un borde con un borde biselado alzado. Graphics Pinta el borde del componente g. int y. indicando el texto del título.cando el texto del título con su cion-del-titulo. indicando el texto del título con su posición. colorColor-deltitulo) static TitledBorder createTitledBorder (String titulo) Añade un título a un borde. Añade un título a un borde. Font Fuente-del-titulo) static TitledBorder createTitledBorder (Border borde. int Justifica. Determina si el borde es opaco. I Los campos de la clase Insets se encuentran en la tabla 11.21 y sus métodos en la 11. indi(Border borde. /con tilelcon) Devuelve un border enmarañado hecho con múltiples azulejos de un icono indicado.22. static TitledBorder createTitledBorder Añade un título a un borde. String titulo) static TitledBorder createTitledBorder (Border borde. indicando el texto y usando las propiedades por defecto. 1 lnsets getBorderlnsets(Componenf c) Obtiene los insets del borde. intPosicion-del-titulo. static TitledBorder create TitledBorder (Border borde) static TitledBorder createTitledBorder (Border borde. int Justificacion-deltitulo. fuente y color. indicando el texto del título con su posición. int Justificacion-del-titulo. su constructor en la tabla 11. Font Fuente-deltitulo. int Posicion-del-titulo. int anchura. int altura) especificado. String titulo. intPosicion-del-titulo) Devuelve un borde con un título vacío.

Tabla 11.*. java.22.20. Obtiene una representación en cadena de este objeto Insets.uti1. *. int bottom int left int right int top Inset del fondo. 1 Object done() String toString() Crea una copia de este objeto.awt. lnset de la derecha. Para hacer eso. Campos de la clase Insets. Tabla 11. int fondo. awt . int derecha) Crea e inicializa un nuevo objeto Insets. lnset de la izquierda. public class borde extends JApplet I . * . I I 1 I Insets(int superior. lnset de la parte superior. Verifica si dos objetos son iguales. Constructor de la clase Border. sólo usamos el método setBorder del panel (que tienen la mayoría de los componentes en Swing) y creamos un nuevo borde biselado alzado con el método createRaisedBevelBorder de la clase BorderFactory: import import import import javax.event. java . En este caso. se añade un borde a JPanel usado en el ejemplo de la applet hace algunos apartados.21.*. Métodos de la clase Border.swing. java. Tabla 11. int izquierda. 1 boolean equals(0bject obj) 1 -7 Veamos un ejemplo.

3. usaremos el método getBorder para obtener el borde actual.left. y el miembro de datos left de ese objeto para determinar dónde se empieza a pintar el mensaje para que no se solape con el borde: class jpanel extends JPanel ( public void paintcomponent (Graphics g) I g. . Para ello.set~order(BorderFactory.jpanel j.drawString("yBola desde üwingln. tomaremos los insets de este borde para dibujar en su interior el mensaje "iH01a desde Swing!" sin solaparse con el borde.add(j). getBorder(). 1 1 Después de añadir un nuevo borde al panel. Este ejemplo está en el CD como borde-java. Como se puede ver.getBorderInsete(this). } 60)j 1 El resultado se muestra en la figura 11. public void init0 ( Container contentpane = getContentPane0. Añadir un borde a un objeto JPanei. ola desde Swing! Figura 11. j = new jpanel0. contentPane.createRaised8evelBorder~)). el método getBorderInsets del objeto que soporta la interfaz Border. el texto aparece en el interior del borde biselado que encierra el panel.3. j.

Constructor de la clase UIManager. com. Sin embargo.java.24. Tabla 11.Establecer la apariencia El gran jefe (Gj) regresa y dice.23. windows. Por defecto.sun. Añade u n PropertyChangeListener.23 y sus métodos en la 11. la que Sun ha diseñado independiente de la plataforma. com. "Es correcto".pasándole uno de estos argumentos como una cadena: javax. "Entiendo que no se puede establecer la apariencia de un programa Swing para relacionar varias plataformas de programación". static void addAuxiliaryLookAndFee1 static void addpropertyChangeListener (PropertyChangeListener listener) static Object get(0bject key) Añade un objeto LookAndFeel a la lista de apariencias.MetalLookAndFeel: Apariencia de Metal.swing.pla~motifMotifLookAndFeel: Apariencia de Motif. .swing.java. la apariencia de los programas de Swing es la de Java Metal.24.swing. se puede cambiar usando la clase UIManager. le responde.plaf. Tabla 11. se puede usar el método setLookAndFee1de la clase UIManager.plajmetal. UIManager() Construye u n nuevo objeto UIManager. le dice. Para cambiar la apariencia cuando se está poniendo a punto un programa.sun.WindowsLookAndFeel: Apariencia de Windows. Obtiene un objeto de la tabla por defecto. Métodos de la clase UIManager. "¿Tiene algo en color caoba?" "Lo siento". BB pregunta.Este es el diagrama de herencia de esta clase: El constructor de esta clase se encuentra en la tabla 11.

Obtiene un borde de la tabla por defecto. Obtiene la apariencia por defecto actual. .Obtiene el nombre de la clase LookAndFeel que soporta la ClassName(} apariencia independiente de la plataforma por defecto. static int getlnt(0bject key) static LookAndFeel getLookAndFeel(} static UlDefaults getLookAndFeelDefaults() Obtiene los valores por defecto de esta apariencia. Obtiene un arrayde objetos que gestiona la información sobre la implementación LookAndFeelinstalada.LookAndFeellnfo[] getlnstalledLookAndFeels() Obtiene el defecto para esta apariencia. static String getString(0bject key) static String getSystemLookAndFeelClassName() Obtiene una cadena desde la lista de defectos. Obtiene una fuente de la lista por defecto. static String getCrossPlatformLookAndFeel. Obtiene un color para dibujar de la tabla por defecto. static UlDefaults getDefaults() static Dimension getdimension(0bject key} static Font getFont(0bject key) static /con getlcon(0bject key) static insets getlnse ts(0bject key) static UIManager. Obtiene un objetolnsetsde la lista por defecto. Obtiene un entero de la lista por defecto. Obtiene el nombre de la clase LookAndFeelque implementa los sistemas nativos.static LookAndFeel[] getAuxilizaryLookAndFeelsO static Border getBorder(0bject key) static Color getColor(0bject key) Obtiene la lista de apariencias. Obtiene un icono de la lista por defecto. Obtiene una dimensión de la lista por defecto.

swing.*.event.*. import java. Almacena un objeto en los defectos. . static boolean removeAuxiliaryLookAndFeel Elimina un objeto LookAnd(LookAndFeel laf) Feel de la lista de apariencias. Después de cambiar la apariencia del content pane. Crea una nueva apariencia y la añade al array actual. etiquetadas como Metal. Fija la apariencia por defecto actual con un nombre de una clase.awt. Instala la apariencia especificada. Este es el código (veremos cómo se usan todos estos controles en los siguientes capítulos): import java.awt. Motify Windows. por lo que se puede ver cómo aparecen con distintas apariencias. Object valor) Obtiene la apariencia del objeto que dibuja ei componente objetivo. LookAndFeellnfo info) static Object put(0bject key. como sigue: Este es un ejemplo en el que se añaden muchos controles Swing con los que ya hemos trabajado en un applet. la applet cambia a la apariencia correspondiente. import javax.static ComponentUl getUI(JComponent target) static void installLookAndFeel(Stringnombre. Reemplaza elarrayactual de los objetos LookAndFeellnfo instalados. y cuando se hace clic sobre uno de los botones de opción.LookAndFeellnfo[] infos) static void setLookAndFeel(LookAndFeel newLookAndFee1) static void setLookAndFeel(String className) Elimina un objeto PropertyChangeListener. static void remove PropertyChangeListener (PropertyChangeListener listener) static void setlnstalledLookAndFeels (UIManager. se puede hacer efectiva con el método updateComponentTreeUI de la clase SwingUtilities.*. String nombre-de-clase) static void installLookAndFeel(UIManager. Fija la apariencia por defecto actual con un objetoLookAndFeel. Hay tres botones de opción en estaapplet.

MetalLookAndFeel.sun.MotifLookAnd~eel. group.swing.add(b1).WindowsLookAndFeel.plaf.CENTER). } class jpanel extends JPanel implements ActionListener { public jpanel ( ) { add(new JButton("JBotón") . "JLista Elemento 2"". BorderLayout. add(new JLabel("JEtiquetan) .metal. public class plaf extends JApplet { JRadioButton bl = new JRadioButton("Metalm) b2 = new JRadioButton("Motif").sun.HORIZ0NTAL)) .swing.import javax. ) add(new JTextField("JCuadro-de-texto")). add(new JScrollBar(SwingConstants. ButtonGroup group = new ButtonGroupO.~wing.JListaElemento 3"))). ) add(new JList(new String [ l { "JLista Elemento l " . b3 = new JRadioButton("Windows").add(new jpanelo.motif.plaf.java. group.add(b3).plaf. import com. add(new JCheckBox("JCasilla~deeactivaciÓn") ). add(new JRadioButton("JBotÓn~de~opciÓn")). public void actionPerformed(ActionEvent e) { . group. importcom.java. public void init0 I Container contentpane = getContentPane0.add(b2).wind~ws. contentPane.

Apariencia Motif. .java. la de Windows.16.JRadioButton src = (JRadioButton)e.plaf.5. Figura 11. 1 catch(Exception ex) {) La figura 11.4.Wind~~sL~~kAndFeel").java. la d e M o t i f y la 1 1. la figura 1 1 -15. Apariencia Java Metal.swing. "com.sun. Este ejemplo está en el CD como plaf.Cambiar entre estas apariencias es tan fácil como hacer clic sobre un botón d e opción.4 muestra la applet con la apariencia Metal. JLlSla EIen _ Justa Efen r Metal 6 M - Appletslaried I Figura 11.wind~w~.getSourceO.

pero se puede hacer en Swing". PN pregunta. Obtiene una cadena corta que identifica esta apariencia.setLookAndFeel para crear los defectos de la apariencia. abstract String getlD() abstract String getName() .6.25 y sus métodos en la 11. Establecer los componentes para la apariencia Dice el programador novato: "¿No sería maravilloso si todos los componentes usaran las mismas fuentes y bordes?" "Bien".P de texto I Figura 11. Apariencia Windows. "¿Usted sabe?" Se puede establecer la apariencia de los componentes individuales en Swing usando la clase LookAndFeel. Tabla 11.25. Este es el diagrama de herencia de esta clase: El constructor de la clase LookAndFeel se encuentra en la tabla 11. Constructor de la clase LookAndFeel. Obtiene una cadena que identifica esta apariencia. "no estoy seguro de eso. Lo llama UIManager. le contesta.26. abstract String getDescription() Obtiene una descripción on line de esta implementación de la apariencia.

la plataforma subSi AndFeel() yacente soporta y10 permite esta apariencia.fondo y de primer plano de un compofaultFGName) nente con losvalores de los defectos actuales. String defaultBorderName) del componente. static void installColorAndFont (JCom-ponent c. String defaultFontName) abstract boolean isNativeLookAndFeel() Instala las propiedades de primer plano.LazyValue que crea un lmagelcon para el nombre gifFile indicado. String de.KeyBinding[] Construye la lista de encuadernamakeKeyBinding(Object[] keyBinciones clave. Desinstala un borde por defecto del componente si el borde es una instancia de UIResource.setLookAndFee1llama a este método antes de la primera Ilamada a getDefaults(). static void instaIlBorder(JComponent Instala un objeto Borderpor defecto c. static void installColors(JComponent Instala las propiedades del color de c.void initialize() UIManger. fondo y fuente de los componentes con valores por defecto. reemplazando a ésta. dinglist) String toString() void uninitialize() Obtiene una cadena que identifica las propiedades de este objeto. ésta es una implementación de la apariencia nativa de la plataforma. static void uninstallBorder(JComponent c) Veamos un ejemplo en el que se da la apariencia de una etiqueta Swing a un cuadro de texto. Observe que todavía no se han visto funcionar estos .setLookAndFee1 llama a este método justo antes de que se instale una nueva apariencia por defecto. usando los métodos installBorder e installColorsAndFont de la clase LookAndFeel. static JTextComponent. String gifFile) Crea un UIDefaults. static Object makelcon(Class baseClass. UIManager. Si es verdadero. String defaultBgName. String defaultBgName. abstract boolean i s ~ u ~ ~ o r t e d ~ o o kes verdadero.

Este es el código: import java."): contentPane. contentPane. Crearemos una etiqueta Swing y una clase extendida desde la clase del cuadro de texto para que parezca una etiqueta.") ) .controles formalmente. public class plafcomponente extends JApplet { public void init ( ) { Container contentpane = getContentPane0. En la figura 11.updateUI().swing. JNewLabel jnewlabel = new JNewLabel( "Esta es una etiqueta falsa. 1 public void updateUI0 I super. este ejemplo es sólo para indicar qué se puede hacer con estas apariencias. Como se puede ver en la figura. 3 1 class JNewLabel extends JTextField { public JNewLabel(String S ) I super(s). import javax.add(jnewlabe1). el cuadro de texto que aparece debajo de la etiqueta tiene la apariencia de una .awt.7 se muestra el resultado.*.*.add(new JLabel("Esta es una etiqueta real.

etiqueta. .7. Esto le indica la potencia de la gestión de apariencias en Swing. Este ejemplo está en el CD como plafcomponente. Figura 11. Establecer la apariencia de un cuadro de texto como si fuera una etiqueta.java.

Sería razonable pensar que las etiquetas soportan varias líneas de texto en Swing. todos estos controles le deberían resultar familiares de la programación AWT. cuadros de texto. y aquí resaltaremos lo que es diferente. Todos ellos son controles esenciales que ocupan gran parte de los fundamentos de Swing. A excepción de los botones toggle. Etiquetas y cuadros de texto Las etiquetas son controles básicos Swing que sólo visualizan una línea de texto. pero sólo soportan una.m Swing: Cuadros de texto. es importante recordar esto cuando se empiece a programar con ellos). revisaremos las etiquetas. botones toggle. botones y casillas de activación Este capítulo se inicia con un debate sobre los controles Swing. Por otro lado. botones. soportan algo que no tienen . Gran parte de la funcionalidad de estos controles Swing tiene su correspondencia en la de AWT. (Hay que tener en cuenta que todos los controles Swing aparecen de diferentes formas según las diversas apariencias. en concreto. casillas de activación y botones de opción en Swing.

Ahora. y con ellos se pueden usar imágenes. cualquier botón se construye con la clase AbstractButton. En Swing. Lo veremos a continuación. iniciaremos este tema con los cuadros de texto. es la clase base para las clases de estos controles en Swing. Los botones toggle son como las casillas de activación y botones de opción que parecen botones estándar. viendo cómo funcionan en este capítulo y más adelante. pero los gestiona de diferente forma que Swing.las etiquetas AWT: imágenes. de hecho. Botones toggle Swing introduce los botones toggle. La gestión del texto en los componentes Swing es uno de los apartados que veremos más tarde en este libro. Además. Botones En Swing. permanecen pulsados hasta que volvemos a hacer clic. los botones Swing tienen más capacidad que sus correspondientes en AWT. veremos que cuando se utilizan las imágenes con las casillas de activación y los botones de opción. hay algunos asuntos que considerar. De hecho. usar mnemónicos (combinación de teclas). y más cosas. Veremos cómo utilizar la claselmagelcon para añadir imágenes a las etiquetas. Como se podía esperar. Casillas de activación y botones de opción AWT tiene casillas de activación y botones de opción. se pueden agrupar botones toggle y usar imágenes en ellos. son casillas de activación en AWT). la clase JToggleButton. Al igual que ocurre con las casillas de activación y botones de opción. a un botón se le pueden asignar múltiples imágenes para gestionar el caso en que el ratón se mueva sobre el botón. y en este capítulo veremos esta clase. . que son botones que. cuando se hace clic sobre ellos. y además se pueden instanciar objetos de esta clase directamente. los botones de opción tienen su propia clase (los botones de opción. diseñar un botón como botón por defecto de una ventana y fijar los márgenes y alineación del texto de un botón. incluyendo la capacidad de visualizar imágenes.

/con icono. ..JComponent Ijavax." "Un momento". JLabel(Stringtext0. "Estoy creando una nueva applet Swing y quiero poner etiquetas a sus controles. Usar etiquetas El programador novato (PN) aparece y dice. "Debería estar usando un objeto JLabel". Tabla 12.awt.Component 1java.2. PN dice. JLabel(lconimagen.swing. "Ah".1. Construye un objeto JLabel con el texto.1 y sus métodos en la tabla 12.Container Ijavax. La clase de las etiquetas peso pesado en Swing es JLabel.. Este es el diagrama de herencia de esta clase: java. intalineación-horizontal) Construye un objeto JLabel con la imagen y la alineación horizontal especificadas. le contesta. intalineación-horizontal) Construye un objeto JLabel con el texto y alineación horizontal indicados.JLabel Los constructores de la clase JLabel se encuentran en la tabla 12. Pasemos a la siguiente sección.awt.Object Ijava. 1ang. Constructores de la clase JLabel. por ello estoy empezando con un objeto Label y. JLabel(1con imagen) Construye un objeto JLabel con la imagen indicada.swing. JLabel(String texto) JLabel(String texto. int alinea -ción-horizontal) Construye un objeto JLabel con el texto indicado. imagen y alineación horizontal indicados.Con esto finalizamos la visión rápida de lo que contiene este capítulo. Construye un objeto JLabel sin imagen.

Obtiene la imagen gráfica (glyph o icono) que visualiza la etiqueta. Obtiene el valor de la propiedad disabledlcon si se ha establecido. Obtiene la posición horizontal del texto de la etiqueta. Métodos de la clase JLabel. relativo a su imagen. int getDisplayedMnemonic() int getHorizontalAlignment() Obtiene el código de la tecla que indica un mnemónico. Obtiene el componente del objeto thispara el que es esta etiqueta. protected int checkHorizontalKey(int key. String mensaje) Verifica un valor para las propiedades de alineación horizontal. Obtiene la alineación de los contenidos de la etiqueta a lo largo del eje x. protected int checkVerticalKey(int mensaje) Verifica un valor para la propiedad alineacióno la posición de texto verticales. Obtiene la apariencia que tiene este componente. int getlcon TextGap() Obtiene la cantidad de espacio entre el texto y el icono visualizados en la etiqueta.Tabla 12. int getHorizontalTextPosition() Component getLabelFor() String getText() LabelUl getUI() String getUIClasslD() .2. Obtiene una cadena que indica el nombre de la apariencia de la clase de este componente. Obtiene la cadena de texto que visualiza la etiqueta. Obtiene el contexto accesible.

Especifica el mnemónico visualizado como un carácter. Si el icono y las propiedades del texto están establecidas. Fija la alineación de los contenidos de la etiqueta a lo largo del eje x. Fija el icono que se va a visualizar si este objetoJLabelestá deshabilitado. Fija la alineación de los contenidos de esta etiqueta a lo largo del eje y. int ge tVerticalTextPosition() protected String paramString() void setDisabledlcon(lconicono~deshabilitado) void setDisplayedMnemonic(char aChar) void setDisplayedMnemonic(int key) void setHorizontalAlignment(intalineación) void setHorizontalTextPosifion(intposición-deltexto) void setlcon(lcon icono) void setlcon TextGap(int icon TextGap) void setLabelFor(Component c) void setText(String texto) void setUI(LabelU1 ui) void setVerticalAlignment(intalineación) . Define el icono que visualizará este componente. Obtiene una representación en cadena de este objeto JLabel. relativo a su imagen. Fija el componente que este objeto está etiquetando. esta propiedad define el espacio entre ellas. Obtiene la posición vertical del texto de l a etiqueta. Define la línea de texto que este componente visualizará. Fija la posición horizontal del texto relativo a su imagen. Fija la apariencia del objeto de este componente. Especifica el código de tecla que indica un mnemónico.int getVerticalAlignment() Obtiene la alineación de los contenidos de esta etiqueta a lo largo del eje y.

Lo llama la clase UlFactory cuando la apariencia ha cambiado.void setVerticalTextPosition(intposición~ del-texto) void updateUl() Fija la posición vertical del texto relativo a la imagen.awt. * .Hola desde Swing ! " ) .swing . este ejemplo se encuentra en el CD que acompaña a este libro como etiqueta-java.1.*. El resultado de este código se muestra en la figura 12. JLabel jlabel = new JLabel í " . import javax. Figura 12. m . public class etiqueta extends JApplet { public etiqueta0 ( Container contentpane = getContentPane0. Una etiqueta Swing.1. A continuación tenemos un ejemplo básico que muestra cómo se crea una etiqueta Swing con el texto "iHola desde Swing!": import java.

dice NP.4. Graphics g. "ya eché un vistazo a la interfaz Icon. Métodos de la interfaz Icon. Dibuja el icono en la posición indicada. 1 int getlconHeight() 1 int getlcon Width() void paintlcon(Component c.5. Imagelcon() Imagelcon(byte[] imageData) Imagelcon(byte[] ImageData.3). int y) Obtiene la altura del icono. Construye un icono imagen desde un array de bytes. La clase Irnagelcon permite crear un icono desde un fichero de imagen para utilizarlo en un control Swing. Constructores de la clase Irnagelcon. ¿Tengo que pintar las imágenes en los iconos yo mismo cuando utilizo Swing?" "Por supuesto que no". String descripción) Construye un icono imagen. como se ve en el siguiente punto. Veremos todas las posibilidades en un par de secciones. Afortunadamente. Construye un icono imagen desde un arrayde bytes que se leyó de un . Tabla 12. se puede fijar la alineación del texto en una etiqueta. le dice. Tabla 12. dice el programador novato. "Se puede utilizar la clase ImageIcon para hacer las cosas más fáciles". Por ejemplo. Este es el diagrama de herencia de esta clase: Los constructores de la clase ImageIcon se encuentran en la tabla 12.3.Hay muchas cosas que se pueden hacer con las etiquetas Swing. en Swing hay una forma fácil de crear iconos desde las imágenes: se puede usar la clase Irnagelcon. así como utilizar imágenes. int x. se necesita un objeto que implemente la interfaz Icon (encontrará sus métodos en la tabla 12.4 y sus métodos en la 12. Para visualizar una imagen en una etiqueta. "Cuénteme todo sobre esto". Obtiene la anchura del icono. 1 Usar iconos imagen "Heyl'.

Construye un icono imagen desde el fichero dado. Imagelcon(Stringnombre_defichero) Imagelcon(Stringnombre_de_fichero. Obtiene la imagen del icono. String descripción) Construye un icono imagen desde un objeto imagen. Imagelcon(URL posición) Imagelcon(URL posición. String descripción) Construye un icono imagen desde la URL indicada. Obtiene la anchura del icono. void setlmage(1mage imagen) void setlmageObserver(lmage0bserver observer) Fija la imagen visualizada por este icono.fichero imagen que contiene un formato de imagen soportado. Construye un icono imagen desde Stringdescripción) el fichero dado. String getDescription() int getlconHeight() int getlcon Width() lmage getlmageo int getlmageLoadStatus() Obtiene la descripción de la imagen. Construye un icono imagen desde la imagen dada. Espera a que se cargue la imagen. Imagelcon(lmage imagen) Imagelcon(lmage imagen. Graphics g. int y) voidsetDescription(Stringdescripción) Fija la descripción de la imagen. Pinta el icono. Obtiene la altura del icono. int x. Obtiene el estado de la operación de carga de imagen.5. Tabla 12. Construye un icono imagen desde la URL indicada. Obtiene el image observer de la imagen. Fija el imageobserverparala imagen. . Métodos de la clase Imagelcon. lmageobservergetlmageObserver() protected void loadlmage(lmage imagen) void paintlcon(Component c.

Para especificar las alineaciones se pueden utilizar constantes como estas: BOTTOM. porque muchos componentes Swing pueden visualizar iconos. y se puede especificar la alineación de las imágenes y del texto con métodos como estos: setVerticalTextAlignment: Fija la alineación vertical del texto relativo a la imagen. El texto estará centrado debajo de la imagen.swing. SOUTH-WEST. usamos la clase ImageIcon. e s etiqueta-jpg): import java. NORTH-EAST. la competencia dentro del campo de GUI e s muy fuerte". Se pueden utilizar varios constructores JLabel para añadir imágenes a las etiquetas. LEADING. "De acuerdo".*. . TRAILING. "Bien". RIGHT. S O U T H . Usar imágenes en etiquetas El gran jefe (GJ) aparece y dice: "Necesitamos que las cosas sean un poco más atractivas en nuestros programas. setVerticalAlignment: Fija la alineación vertical de los contenidos d e la etiqueta. NORTH-WEST.La clase ImageZcon es extremadamente útil en Swing. CENTER. "su nuevo código era para ayer". LEFT. le contesta. en este caso. setHorizontalAlignment: Fija la alineación horizontal de los contenidos d e la etiqueta. TOP. A continuación tenemos un ejemplo en el que se añade una etiqueta con una imagen y texto a un applet. dice Gj. VERTICAL y WEST. porque ahora.awt.*. "podemos añadir iconos de imágenes a cada etiqueta". En el siguiente apartado veremos esta clase funcionando. import javax. pasando al constructor de esa clase el nombre del fichero que gestiona la imagen que queremos usar (que. SOUTH-EAST. setHorizontalTextAlignment: Fija la alineación horizontal del texto relativo a la imagen. Para crear la imagen. HORIZONTAL. EAST. NORTH.

El resultado se muestra en la figura 12. le sonríe. Como es muy sencillo. Figura 12.2. los cuadros de texto en Swing funcionan como en AWT. new~mage~con(~etiqueta. JLabel-CENTER). y este ejemplo se encuentra en el CD como etiquetaimagen-java.2. "creo que acertaré el nombre de la clase de Swing para los cuadros de texto: JTextField. ¿es correcto?" "Exactamente". dice el programador novato. Observe lo fácil que es añadir imágenes a las etiquetas en Swing. Este es el diagrama de herencia de la clase JTextField: . con algún valor añadido. Por compatibilidad. JLabel jlabel = newJZabel("Etiquetan.public class etiquetaimagen extends JApplet public void init0 { Container contentpane = getContentPane0. es muy común.jpg~). Una etiqueta Swing con una imagen. Usar cuadros de texto "No me lo diga".

Constructores de la clase JTextField. veremos más cosas sobre los componentes de texto Swing. Notifica a los listenersque tiene este tipo de evento. void addActionListener(ActionListener1 Añade el action listener para ) obtener eventos de acción desde este cuadro de texto. por defecto. 1 JTextFieldO JTextField(Document doc. String texto. Construye un nuevo objeto JTextField que usa el modelo de almacenamiento y las columnas dados. Tabla 12. introduciremos la clase JTextField para que podamos obtener entradas del usuario antes de ese momento. Tabla 12. Obtiene la lista de comandos para el editor. . int getColumns() protected int getcolumn Width() Obtiene el número de columnas.6 y sus métodos en la 12.Más adelante en este libro. protected Document createDefaultModelo portected void fireAction Performedo AccessibleContext getAccessible Contexto Construye la implementación. int columnas) Construye un nuevo cuadro de texto inicializado con el texto y columnas indicados. del modelo.7.7. pero por ahora. Obtiene el contexto accesible. Los constructores de la clase JTextField se encuentran en la tabla 12. I JTextField(String texto. int columnas) Construye un nuevo cuadro de texto.6. Obtiene la anchura de la columna. Construye un nuevo cuadro de texto vacío con el texto indicado. Métodos de la clase JTextField.

int getHorizontalAlignment() BoundedRangeModelgetHorizontalVisibility() Dimension getPreferredSize() Obtiene la alineación horizontal del texto. Obtiene la visibilidad del cuadro de texto. . Procesa eventos de acción que ocurren en este cuadro de texto enviándolos a cualquier objeto ActionListenerregistrado. Elimina el action listener indicado. Este es un ejemplo rápido que sólo visualiza un cuadro de texto con el texto "¡Holadesde Swing!": import java.swing. Fija el offset de desplazamiento. void setActionCommand(Stringcomando) void setColumns(int columnas) void setFont(Font f) void setHorizontalAlignment(intalineación) void setScrollOffset(int scrollOffset) Fija la cadena del comando usada para eventos de acción. Obtiene eloffsetdedesplazamiento. Fija la fuente actual. Fija la alineación horizontaldel texto.*: import javax. Obtiene la clase ID para un UI. Obtiene las dimensiones preferidas necesarias para este cuadro de texto.awt. Fija el numero de columnas.*. Obtiene una representación en cadena de este cuadro de texto. Vuelve a validar las llamadas que vienen desde el cuadro de texto y que serán gestionadas para validar el nuevo cuadro de texto. int getScrollOffset() String ge tUIClasslD() boolean isValidateRoot() protected String paramString() void positionActionEvent() void removeActionListener(Action Listener 1) void scrollRectToVisible(Rectangle r) Desplaza el campo a la izquierda o derecha.

3. Por ejemplo. se muestra en la figura 12.Hola desde Figura 12.dice el programador novato.public class cuadrodetexto extends JApplet { JTextField text = new JTextField(20). Abstract Button: base de los botones Swing "Pero no quiero usar la clase AbstractButton ". public void i n i t 0 { Container contentpane = getContentPane0. ¿Por qué tengo que saber nada sobre . contentPane. Esto es sólo el comienzo en la utilización de los componentes de texto en Swing. Un cuadro de texto Swing. en los siguientes apartados conectaremos un cuadro de texto a un botón. /.java en el CD. } 1 El resultado de este código.add(text1. pero nos permite empezar y nos proporciona una forma fácil de visualizar la salida de nuestros programas.setLayout(new FlowLayoutO).setText("iHola desde Swing! " ) . text.3. contentPane. cuadrodetexto. "Quiero utilizar la clase JButton.

su constructor en la 12. "Ah". Tabla 12. La clase AbstractButton es la base de las clases de botones en Java. únicamente como referencia. lndica un cambio para tener el borde iluminado cuando se tiene o no el foco. todos los botones se derivan de AbstractButton ". El cambio de evento del botón. proporciona muchos métodos que no podemos ignorar.AbstractButton?" "En Swing. static String BORDER-PAINTED-CHANGED-PROPERTY protected ChangeEvent changeEvent protected ChangeListener changeListener static String CONTENT-A REA-FILLEDCHANGED-PROPERTY static String DISABLED-ICON-CHANGED-PROPERTY static String DISABLED-SELECTED/CON-CHANGED-PROPERTY static String FOCUS-PAINTED-CHANGED-PROPERTY static String HORIZONTAL-ALIGNMENTCHANGED-PROPERTY . Los modelos de listeners del botón.8.9 y sus métodos en la 12. "y hay un número tremendo de métodos en esa clase que debería conocer.10.8. protected ActionListener actionlistener Action listener. lndica un cambio del icono mostrado cuando el botón se ha deshabilitado. lndica un cambio al borde. le dice. Indica un cambiode habilitado a deshabilitado o volver a habilitado. dice PN. lndica un cambio del icono mostrado cuando el botón se ha deshabilitado y seleccionado. Realmente. será bueno para usted". Campos de la clase JAbstractButton. lndica un cambio en la alineación horizontal del botón. y al igual que JComponent. Este es el diagrama de herencia de AbstractButton: Los campos de esta clase se encuentran en la tabla 12.

lndica un cambio en la propriedad "rolloverenab1ed"deI botón. lndica un cambio en el nemónico del botón. lndica un cambio en el icono cuando el cursor está sobre el botón. lndica un cambio en el modelo del botón. static String VERTICAL-ALIGNMENTCHANGED-PROPERTY static String VERTICAL. lndica un cambio en los márgenes del botón.PROPERTY static String ROL LOVER-SEL ECTED/CON-CHANGED-PROPERTY El itemListenerde este botón. lndica un cambio en la posición vertical del texto del botón.POSITION-CHANGED-PROPERTY lndica un cambio en la posición horizontal del texto del botón. protected ItemListener itemListener static String MARGIN-CHANGED-PROPERTY static String MNEMONIC-CHANGEDPROPERTY protected ButtonModel modelo static String MODEL-CHANGED-PROPERTY static String PRESSED-ICON-CHANGED-PROPERTY static String ROLLOVER-ENABLEDCHANGED-PROPERTY static String ROL LOVER-ICON-CHANGED. . lndica un cambio en el icono cuando se ha seleccionado el botón. static String /CONCHANGED. lndica un cambio en el icono cuando el botón se ha presionado.TEXT. Modelo de datos que determina el estado del botón.POSITIONCHANGED-PROPERTY lndica un cambio en la alineación vertical del botón. static String SEL ECTED-ICON-CHANGED-PROPERTY static String TEXT-CHANG ED.PROPERTY lndica un cambio en el icono que representa el botón.PROPERTY lndica un cambio en el texto del botón. lndica un cambio en el icono cuando el botón esta seleccionado y el cursor sobre el botón.static String HORIZONTAL-TEXT.

String excepción) protected int checkVerticalKey(int key. Lanza un evento de estado cambiado. void addChangeListener(ChangeListener 1 Añade un change listener ) void addltemListener(itemListener 1 ) protected int checkHorizontalKey(int properkey. Crea un action listener. protected ItemListener createlternListener() Crea un itern listener. - Tabla 12. Obtiene el comando deacción para este botón.9. Sobrescribeeste método para devolver otro ChangeListener. Verifica que keyes un valor legal para las propiedades de alineación vertical. Hacer clic sobre el botón en un tiempo determinado de forma programada. Métodos de la clase AbstractButton. void addActionListener(ActionListener 1) Añade un action listener. String excepción) protected ActionListener createActionListener() protected ChangeListener createlmplernentationChangeListener() void doClick() void doClick(int pressTime) Añade un itern listener a una casilla de activación. Hacer clic en el botón de forma programada. protected void fireActionPerformed(Action Event event) protected void fireltemStateChanged(item Event event) protected void fireStateChanged0 String getActionCornmand() . Lanza un evento de acción. Verifica que keyes un valor legal para la alineación horizontal. Constructor de la clase AbstractButton.10. Lanza un evento de elemento cambiado. - Construye un nuevo objeto AbstractButton.Tabla 12.

Obtiene el iconoseleccionado deshabilitado. Obtiene el icono seleccionado para el botón. Obsoleto. Obtiene el UI actual del botón.Obtiene el icono deshabilitado. Obtiene la posición vertical del texto relativa al icono. int getHorizontalAlignment() int getHorizontalTextPosition() /con getlcon() String ge tLabel() lnsets getMargin() int getMnemonic0 Obtiene la alineación horizontal del icono y del texto. . Obtiene el mnemónico del t e c l a do del modelo actual. Obtiene el icono por defecto. Obtiene el modelo que representa este botón. Obtiene un array de longitud 1 que contiene la etiqueta o nulo si el botón no está seleccionado. Obtiene el icono presionado para el botón Obtiene el icono del botón. Obtiene la alineación vertical del texto y del icono. Obtiene el margen entre el borde del botón y la etiqueta. ButtonModel getModel() lcon getPressedlcon() lcon ge trolloverlcon() /con getrolloverSelectedlcon() lcon ge tSelec tedlcon() String getText() ButtonUl getUI() int get VerticalAlignment() int getVerticalTextPosition() Obtiene el texto del botón. Reemplazado por getText(). Obtiene el icono seleccionado del botón. Obtiene la posición horizontal del texto relativo al icono.

Determinasi se debería pintar el foco. Elimina un action listener. void setHorizontalAlignment(intalineación) Fija la alineación horizontal del icono y del texto. Habilita (o deshabilita) el botón.protected void init(String texto. Fija el icono seleccionado deshabilitado para el botón. void removeActionListener(ActionListenerl) void removeltemListener(ltemListener 1) void setActionCommand(String actionCommand) void setBorderPainted(boo1ean b) void setContentAreaFilled(boolean b) void setDisabledlcon(lcon disabledlcon) void setDisabledSelectedlcon(icon disabledSelectedlcon) void setEnabled(boo1ean b) void setFocusPainted(boo1eanb) ~oidremoveChangeListener(ChangeListenerI) Elimina un change listener. Fija si se debería pintar el foco. Determina si se debería pintar el borde. Obtiene el estado del botón. Fija si se debería pintar el borde. Especifica si el botón debería pintar el content area. Establece el comando de acción. Obtiene una representación en cadena de este objeto AbstractButton. . void setHorizontalTextPosition(int textPosition) Fija la posición horizontal del texto relativa al icono. /con icono) boolean isBorderPainted() boolean is Con tentArea Filled() boolean isFocusPainted() boolean isRolloverEnabled() boolean is Selectedo protected String paramString0 Para uso interno. Verifica si se debería rellenar el área de contenido del botón. Verifica si los efectos derollover están activados. Elimina un item listener. Fija el icono deshabilitado para el botón.

"¡bastantes cosas! Mejor tome asiento". void setMode(ButtonMode1nuevo-modelo) Fija el modelo que representa este botón. Especificael valor mnemón ico. le contesta. void setSelected(boo1ean b) void setSelectedlcon(1con selectedlcon) void setText(String texto) void setUI(ButtonU1 u¡) void setVerticalAlignment(intalineación) void setVerticalTextPosition(intposición~ deltexto) void updateUI() Fija el icono seleccionado para el botón. Fija el mnemónicodel teclado. Fija el texto del botón.-- void setlcon(icon defaulticon) void setLabel(Stringetiqueta) void setMargin(1nsets m) void setMnemonic(char mnemonic) void setMnemonic(int mnemonic) Fija el icono por defecto del botón. Usar botones El programador novato llega y dice: "Estoy preparado para empezar a trabajar con botones Swing. Fija el espacio para los márgenes. Fija si se deberían habilitar los efectos de rollover. Fija el icono rollover para el botón. Selectedlcon) Fija el estado del botón. Obtiene un nuevo objeto UI desde la clase por defecto UIFactory. Reemplazado por setText(text0). Obsoleto.Fija el icono seleccionado rolloverpara el botón. Fija la alineación vertical del icono y del texto. ¿Qué hacen?" "Hmm". void setPressedlcon(lcon pressedlcon) void setRolloverEna bled(boo1ean b) void setRolloverlcon(lcon rolloverlcon) Fija el icono presionado. Fija el UI del botón. void setRolloverSelectedlcon(lcon rollover. . Fija la posición vertical del texto relativa al icono.

Constructores de la clase JButton. usardoclickpara hacer clic en el botón desde el código. usar setMargin para fijar los insets del mismo botón.1 1. como usar setEnabled para habilitar o deshabilitar el botón. Observe que esta clase se basa en la clase AbstractButton. añadir imágenes al botón y añadir mnemónicos (combinación de teclas) para el botón. Tabla 12. Los constructores de la clase JButton se encuentran en la tabla 12. String getUIClassld() . Construyeun botón con texto e ico I Tabla 12. Obtiene una cadena que indica el nombre de la apariencia. Por supuesto.1 1 y sus métodos en la 12. /con icono) Construye un botón.12.La clase JButton soporta los botones Swing. lo que quiere decir que hereda toda su funcionalidad (ver el punto anterior para más detalles). 1 1 JButton() JButton(1con icono) JButton(String texto) JBotton(String texto. -. AccessibleContextgetAccessibleCon texto Obtiene el contexto accesible. Métodos de la clase JButton. Algunas de estas cosas incluyen el uso de setToolTipText para añadir un tooltip al botón. usar addActionListener para registrar un action listener con el botón y añadir comandos de acción a objetos JButton con setActionCommand. Construye un botón con un ¡con Construye un botón con el te dado.12. Este es el diagrama de herencia de esta clase: Los botones Swing permiten hacer más cosas que los botones AWT. se pueden hacer cosas estándar de AWT con JButton.

import java. Especifica si este botón es capaz de ser el botón por defecto del rootpane.*. como se puede ver en el siguiente código: import java.*.boolean isDefaultButton() boolean isDefaultCapable() protected String paramString() void setDefaultCapable(boolean defa ultcapable) void updateUl() Indica si este botón es el botón por defecto en el root pane.java).addllctionListener(new ActionListenerO r public void actionPerfomed(ActionEvent event) text. Obtiene una representación en cadena de este objeto JButton. JTextField text = new JTextField(20). (en el CD botón. es muy sencillo.event.awt. ? { . Llamado por la clase UlFactory cuando cambia la apariencia.swing. Indica si este botón es capaz de ser el botón por defecto del root pane. Aquí se visualiza el mensaje "¡Hola desde Swing! " cuando el usuario hace clic sobre un botón.awt.*. button. Veamos un ejemplo en el que está funcionando la clase JButton. import javax.setText(~iHola desde Swing!"). public class boton extends JApplet { JButton button = new JButton("Haga clic aquí m). Este ejemplo. public void init0 { Container contentpane = getContentPane0.

"pero jse pueden visualizar en botones?" "No hay ningún problema". m setHorizontalTextA1ignment:Fija la alineación horizontal del texto relativo a la imagen. cuando el usuario hace clic sobre el botón. Figura 12. Como se puede ver. Además se puede establecer la alineación del texto y de la imagen usando los métodos AbstractButton siguientes: setVerticalTextAlignment: Fija la alineación vertical del texto relativo la imagen. Visualizar imágenes en botones "Sé que se pueden visualizar imágenes en etiquetas Swing". setVerticalAlignment: Fija la alineación vertical de los contenidos del botón. "basta con tener un objeto Icon". la applet visualiza su mensaje en el cuadro de texto. . le dice. setHorizontalAlignment: Fija la alineación horizontal de los contenidos del botón. Es fácil visualizar imágenes en botones usando la clase Imagelcon.El resultado de este código se muestra en la figura 12. ya que varios constructores JButton permiten añadir iconos a los botones. veremos todas las posibilidades en los siguientes apartados.4. Usar un botón Swing. dice el programador novato. Hay mucho más que hacer con los objetos JButton.4.

Este ejemplo está en el CD como botonimagen.Veamos un ejemplo en el que se añade una imagen desde el archivo boton'jpg al ejemplo del botón del apartado anterior: import java. public void k i t ( ) Container contentpane = getContentPane0.*. import javax.*.awt. button. new ImageI~on(~boton.jpg~) ). el botón visualiza una gran imagen.5. . JTextField text = new JTextField(20).*. Usar un botón Swing con una imagen. } } { El resultado se muestra en la figura 12. public class botonimagen extends JApplet { JButton button = new JB~tton(~Botón". haciendo que el programa sea visualmente más interesante.swing.setText(" ¡Hola desde Swing!").add~ctionListener(new ActionListenerO public void actionPerformed(ActionEvent event) text.java.awt. import java.event. Como se puede ver ahora. Figura 12. 1 }).5.

* .swing. ¿por qué no hemos animado las cosas?" "Porque". ~ setRolloverSelectedIcon. Icono rollover.Usar imágenes rollover y deshabilitadas El gran jefe está aturullado y dice.*. le dice. En el siguiente ejemplo veremos todas estas posibilidades funcionandg (en el CD es el archivo botoniconos. Hasta ahora. "¿No deberíamos hacer nosotros lo mismo?". Icono seleccionado deshabilitado. "iTenemos que alegrar nuestros progrfl mas!" "De acuerdo". "No sea ridículo". I usamos un método con el nombre correspondiente: setlcon. public class botoniconos extends JApplet . Icono deshabilitado.setSelectedIcon. "nuestros competidores han invertido años de trabajo y dinero para hacer que sus programas sean el doble de útiles que los nuestros". El GJ dice. import javax. awt .Aquí tenemos el código (observe que para habilitar 10s eventos rollover.java). "puedo añadir imágenes rollover con los botones para que se visualice una imagen cuando el ratón se mueva sobre ellos. le pregunta. llamamos a setRolloverEnabled con un valor verdadero): ~ import j ava . Estas son la? posibilidades (iconos rollover que aparecen cuando se mueve el ratón sobre el botón): Icono normal. Icono seleccionado rollover. setPressedIcon. setDisabledSelectedlcon. Icono seleccionado. Para los botones se puede establecer un número de iconos. Para instalar todos estos iconos. Icono presionado. dice el gran jefe. setRolloverIcon. setDisabledlcon Y .

Icon rollover = new ImageIcon(nrollover. la imagen rollover está visible. Botones por defecto y mnemónicos Si echa un vistazo a los cuadros de diálogo de su sistema operativo. Icon normal = new ImageI~on(~normal. Usar imágenes rollover y otras en un botón. Icon selected = new ImageIcon("seleccionado.jpg").6. generalmente. Icon disabledselected = new ~mage~con(~deseleccionado.jpg"). hay un botón marcado como botón por defecto y ese . Applet Stalted Figura 12.jpg~).jpg").I public void i n i t 0 ( Container contentpane = getContentPane0. verá que.6. Cuando el ratón se mueve sobre el botón. Icon pressed = new ImageIcon("pulsado. Icon rolloverSelected = new ~mageIcon(~reseleccionado. JButton jbutton = new JButtonO. El resultado se muestra en la figura 12.jpgn).jpgm). Icon disabled = new ImageI~on(~deshabi1itado~jpg~).

JButton button2 = new JButton("Haga clic aquí"). JTextField text = new JTextField(20).*. como es pulsar la tecla Intro. y cuando tiene el foco.swing. se puede dar a cada botón un mnemónico.awt. Si el botón no tiene nombre. * . Así se haría en el código (observe que damos el foco al root pane al final del código para que se puedan interceptar los eventos de tecla y así se active el botón por defecto cuando el usuario pulse la tecla Intro): import j ava . En este caso. la tecla Alt en Windows) y el mnemónico del botón lo activa. public void action~erformed(ActionEventevent) .event. como se puede ver en los menús. al pulsar ese carácter el botón se activa. Con Swing se puede poner un botón por defecto usando el método setDefaultButton. pulsando la meta tecla (por ejemplo. awt . import javax. Veamos esto en el código. public void h i t ( ) { Container contentpane = getContentPane( ) . import java. Este botón tendrá el literal "Haga clic aquí". Además de hacer botones por defecto.class WIDTH= 300 HEIGHT = 200 > </APPLET> */ public class botonpordefecto extends JApplet { JButton buttonl = new JButton("Haga clic aquí").*. Se subraya una letra (no sensible a mayúsculas y minúsculas) en el texto del botón. que es la combinación de teclas cortas. se añaden dos botones a un applet y se hace que el segundo sea el botón por defecto. y haremos que la letra H sea el mnemónico.botón automáticamente es pulsado si el usuario ejecuta alguna acción con el' teclado. /* 1 <APPLET CODE = botonpordefecto.

{ text. el segundo botón aparece con un borde resaltado. y la letra H de su etiqueta está subrayada. "pero son realmente la clase base de las casillas de activación y de los botones de opción". "Ahora están los botones toggle ". 1 1). y presentan un botón de dos estados (realmente tres estados si se cuenta el estado deshabilitado) que . Los botones toggle son nuevos en Swing. visualizando el mensaje que se muestra en la figura 12.setText(" ¡Hola desde Swing!"). Usar botones toggle El programador novato regresa con una pregunta: "¿Añade Swing nuevos tipos de botones a Java?" "Bien". 1 1). Usar un botón por defecto con un mnemónico.7. Como se puede ver.7. dice PN. "sí y no". le dice.setText(" ¡Hola desde Swing!").le contesta.add~ctionLi~tener(newActionListener() ( public void actionPerformed(ActionEvent event) { text. indicando que es el mnemónico del botón. Cuando el usuario pulsa la tecla Intro. se hace clic sobre el botón por defecto automáticamente. button2. indicando que es el botón por defecto.7. 1 1 El resultado se muestra en la figura 12. " iCuénteme más! ". Figura 12. "Sabía que diría eso".dice PN.

AccessibleContextgetAccessibleContexto Obtiene el contexto accesible. Constructores de la clase JToggleButton. 7 Construye un botón toggle. Tabla 12. Construye un botón toggle con el texto.pueden aparecer como seleccionados o no.13. Métodos de la clase JToggleButton. Tabla 12. dibujamos algunos botones toggle. la mayoría con iconos y algunos con texto. /con icono. la clase de los botones toggle: - Los constructores de esta clase se encuentran en la tabla 12. boolean selected) JToggleButton(String texto) JToggleButton(String texto. Obtiene una representación en cadena de este botón toggle. Así es el código: . Obtiene una cadena que gestiona el nombre y la apariencia. Construye un botón toggle no seleccionado con el texto indicado. boolean selected) Construye un botón toggle con la imagen y estado indicados. JToggleButton(lcon icono. Este es el diagrama de JToggleButton. Llamado por la clase UlFactory para indicar que la apariencia hacambiado. Construye un botón toggle con el texto y estado indicados. Construye un botón toggle no seleccionado con la imagen indicada. imagen y estado indicados. En él. String getUIClasslD() protected String paramString0 void updateUl() Usaremos JToggleButton en un ejemplo.14.14. boolean selected) JToggleButton(String texto.13 y sus métodos en la 12.

import java. Figura 12.Haga clic awí!").swing. El resultado de este código se puede ver en la figura 12. Usar botones toggle.*.import java. . new ImageIcon("togg1e.awt.event. JToggleButton togglel = new JToggleButton(icon). true) . icon).awt. JToggleButtontoggle5 = new JToggleButton("~Haga clic aquí!". true).8. JToggleButton toggle3 = new JToggleB~tton(~.icon. JToggleButton toggle2 = new JToggleButton(icon. JToggleButton togglel = new JToggleButton("iHaga clic agui!". import javax.*.*.jpg"). public class toggle extends JApplet { public toggle0 I Container contentpane Icon icon = = getContentPane0.8.

import javax. ImageIcon("toggle. como un grupo.jpg")) El resultado se muestra en la figura 12. public class grupotoggle extends JApplet { public grupotoggle ( ) ( Container contentpane = getContentPane0. de hecho. JToggleButton[] buttons = new JToggleButton(new new JToggleButton(new new JToggleButton(new new JToggleButton(new new JToggleButton(new 1. Los botones toggle están actuando. "Los botones toggle son nuevos en Swing.jpg")) . de . Crear grupos de botones toggle El programador novato dice. Los botones toggle se pueden agrupar como cualquier otra clase de botones.*. Este ejemplo está en el CD como toggle.jpg") ) . import java.awt.Como se puede observar en ella.jpg")) . "se pueden agrupar".awt. ButtonGroup group = new ButtonGroupO. new JToggleButton[] { ImageIcon("togg1e.event. ImageIcon("togg1e. ImageIcon("toggle.jpg")) . cuando se hace clic sobre uno. ImageIcon("togg1e. con la clase ButtonGroup: import java. le responde. por lo tanto. ¿hacen algo más que presentar al usuario un estado seleccionado o no seleccionado?" "Claro". *.java.*.9. se fija el estado de un botón toggle pasando a su constructor un valor Verdadero si se quiere que aparezca seleccionado inicialmente.swing.

ellos cualquiera de los otros botones que estuviera seleccionado se deselecciona automáticamente.. Necesito . Necesito algo para que el usuario pueda seleccionar desde muchas opciones. . Usar casillas de activación El programador novato dice. Este es el diagrama de herencia de la clase JCheckBox: Los constructores de esta clase se encuentran en la tabla 12. dice PN. "Necesito algo para que el usuario pueda seleccionar una opción.15 y sus métodos en la 12. Necesito algo para que el usuario seleccione múltiples opciones de muchas opciones. de hecho. Figura 12. como visualizar imágenes. La clase JCheckBox tiene algunas ventajas sobre la clase AWT CheckBox.java. le responde. "Lo que necesita son casillas de activación".16. Este ejemplo está en el CD como grupotoggle. Usar botones toggle en un grupo.. "Cierto"." "Casillas de activación".9.

Obtiene una cadena que indica el nombre de la clase de apariencia. Construye una casilla de activación con texto e indica si está seleccionado inicialmente. AccessibleContextgetAccessibleContexto Obtiene el contexto accesible. boolean seleccionado) JCheckBox(String texto) JCheckBox(String texto. JCheckBoxO JcheckBox(lcon icono) JCheckBox(1con icono. Métodos de la clase JCheckBox.*. Construye una casilla de activación con el texto e iconos indicados. import javax.event.awt. se visualizan cuatro casillas de activación y se indica la que el usuario ha marcado (observe que. se usa ItemListener con los objetos JCheckBox.16. . booleanseleccionado) Construye una casilla de activación. Llamado por la clase Ulfactorypara indicar que laapariencia ha cambiado.awt. Tabla 12. String getUIClasslD() protected String paramString() void updateUl() Veamos un ejemplo.*. import java.Tabla 12. Construye una casilla de activación con un icono. Construye una casilla de activación con un iconoe indica si está seleccionado inicialmente. Construye una casilla de activación con texto y un icono e indica si está seleccionado inicialmente. Aquí. Constructores de la clase JCheckBox. como en AWT. Obtiene una representación en cadena de esta casilla de activación. lcon icono) JCheckBox(String texto.1 5. Construye una casilla de activación con texto.swing. boolean seleccionado) JCheckBox(String texto. no Actionlistener): import java. lcon icono.*.

Como se ve. public void init0 ( Container contentpane = getContentPane0. 4").").10.getItemSelectable0 == check3) { text.java. Veremos más cosas sobre el uso de las .setText(~Seleccionóla casilla de activación } else if (e. la applet devuelve la casilla de activación que se ha seleccionado.")."). JTextField teXt.public class casilladeactivacionextendsJApplet implements 1temListener I JCheckBox checkl. contentPane.getItemSelectable0 == checkl) { te~t. check4.setText('Se1eccionó la casilla de activación } else if (e. checkl check2 check3 check4 = new JCheckBox("Casi1la = new JCheckBox('Casi1la = new JCheckBox("Casi1la = new JCheckBox("Casi1la de de de de activación activación activación activación 1"). 1 1 El resultado se puede ver en la figura 12. 3"). 4. 2.setText("Se1eccionó la casilla de activación } else if (e.getItemSelectable() == check2) t text.setLayout(new FlowLayoutO ) . public void itemStateChanged(1temEvent e) { if (e. 3. text = new JTextField(20).setText("SeleccionÓ la casilla de activación 1 l.").getItemSelectable() == check0 { text. 2"). check2. Este ejemplo está en el CD como casilladeactivacion. check3.

Los constructores de la clase JRadioButton se encuentran en la tabla 12. Usar casillas de activación. le contesta. . "necesito botones de opción en mi código Swing.10.17 y sus métodos en la tabla 12. Figura 12. los botones de opción tienen su propia clase en Swing. como es el siguiente de los botones de opción. en los siguientes apartados. Este es el diagrama de herencia de la clase JRadioButton: A diferencia de la programación AWT. "¡Qué bien!" dice PN.casillas de activación en Swing. Usar botones de opción "De acuerdo". iTi Casilla de xthmiún 1 it? Casila de acttweión2 3 PCasile asilla de activ. en Swing existe JRadioButton".18. dice el programador novato. la clase JRadioButton. ¿Se hace usando la clase JCheckBox?" "No". "Aunque se puede usar la clase CheckBox para hacer botones de opción en la programación AWT.

Construye un botón de opción sin texto. JRadioButton(Stringtexto.swing. Construye un botón de opción con el texto y estado de selección indicado. boolean seleccionado) Construye un botón de opción con la imagen indicada pero sin texto. Obtiene una representación en cadena de este botón de opción. Obtiene el nombre de la clase de apariencias. JRadioButton(Stringtexto. Tabla 12. Constructores de la clase JRadioButton.*. Veamos un ejemplo. Construye un botón de opción que tiene el texto.awt. import javax. Este es el código: import java.18. AccessibleContextgetAccessibleContexto String getUICalsslD() protected String paramString() void updateUI() Obtiene el contexto accesible.*. Aquí sólo se visualizan cuatro botones de opción y se agrupan para que sólo se pueda seleccionar uno de ellos al mismo tiempo. Llamado por la clase UlFactorypara indicar que la apariencia ha cambiado. Construye un botón de opción con la imagen y estado de selección indicados. imagen y estado de booleanseleccionado) selección indicados. JRadioButton(1con icono) JRadioButton(1con icono.17. . Construye un botón de opción con el texto indicado. /con icono) Construye un botón de opción que tiene el texto y la imagen seleccionados. boolean seleccionado) JRadioButton(String texto) JRadioButton(String texto. /con icono.Tabla 12. Métodos de la clase JRadioButton.

").setLayout(new FlowLayoutO ) . radiol.getItemSelectable() == radiol) { text.*. group = new ButtonGroupO. public class grupobotonesopcion extends JApplet implements ItemListener ( JRadioButton radiol. radio3.set~ext(~Seleccion6 botón de opción l. contentPane.set~ext(~Seleccionó botón de opción 2. de = new JRadio~utton(~BotÓn opción 4"). el > else if (e.awt.event. de text = new j~extFieid(20). de = new JRadioB~tton(~Botón opción 3").get~temSelectable() == radio2) { text. public void init ( ) I Container contentpane = getContentPane0. JTextField text. = new JRadio~utton(~BotÓn opción 2"). radiol radio2 radio3 radio4 = new JRadioButton("Botón de opción 1"). el . ButtonGroup group. radio2.import java. public void itemStatechanged(1temEvent e ) I if (e.").

getItemSelectable0 == radiol) { text. Usar imágenes en casillas de activación y botones de opción "Uh-oh".else if (e.11. por lo tanto se debe añadir al control una imagen seleccionada.awt. Cuando se hace clic sobre uno. no hay indicación visual en el control (como la marca de activación) para mostrar si están seleccionados.swing. Sonríe y le responde. Ioíón da opción Figura 12. "de nuevo Java está graciosillo. " ) . Este ejemplo está en el CD con el nombre grupobotonesopcion. ) 1 } El resultado de este código se muestra en la figura 12. .setText("Seleccionó el botón de opción 3. la apariencia de la casilla de activación no cambiará cuando se haga clic sobre ella". Usar botones de opción. Este es un ejemplo que muestra cómo funciona.*. observemos un punto importante: si utiliza imágenes en casillas de activación o botones de opción. Aquí. como parte de un grupo. cualquiera que hubiera seleccionado se deselecciona. import javax. Ahora que ya sabe añadir casillas de activación y botones de opción. ) else if (e. Añadí una imagen a una casilla de activación y ahora no funciona".getItemSelectable() == radio3) { text. añadimos una imagen seleccionada a una casilla de activación: import java. Todos los botones de opción de la figura actúan juntos. "Eso es porque además hay que añadir una imagen seleccionada a la casilla de activación.11.java. De lo contrario.setText("Seleccionó el botón de opción 4 ."). dice el programador novato.*.

text.event. contentPane.setText("Seleccionó la casilla de activación l. public void init { () Container contentpane = getContentPane0. public void itemStateChanged(1temEvent e) { if (e.*. aparece la imagen seleccionada ("selected).awt. Cuando el usuario hace cliC sobre la casilla de activación. pero a veces se quiere trabajar con estos controles . new text = new JTextField(20). como se muestra en la figura. 1 } 1 El resultado se muestra en la figura 12. - checkl = new JCheckBox("Casil1a de activación ImageIcon("normal.import java.setLayout(new FlowLayoutO ) .getItemSelectable() == checkl) { text. java. Obtener y fijar el estado de las casillas de activación y de los botones de opción Es bastante fácil responder a los eventos de las casillas de activación y dc los botones de opción."). JTextField.jpg")) . l".12. - public cla~sima~encasillaactivacionextendsJAppletimplements ItemListener { JCheckBox checkl. Este ejemplo está en el CD como imagencasillaactivacion.

En ese momento. import javax.*. import java. Por ejemplo. Para determinar si una casilla de activación o botón de opción está seleccionado se puede usar el método isSelected y el método setState para fijar el estado de una casilla de activación o radio de opción. Usar imágenes en casillas de activación. es necesario determinar qué casillas de activación están seleccionadas.*.*. public class casilladeactivacionseleccionada extends JApplet irnplements ItemListener I JCheckBox checks[l.awt.awt.12. Empecemos creando un array de cuatro casillas de activación y visualizarlos: import java.fuera de los métodos de gestión de eventos.swing. . Este es un ejemplo en el que visualizamos cuatro casillas de activación y listamos las que están marcadas cuando el usuario hace clic sobre ellas. el usuario puede seleccionar un número de opciones usando casillas de activación en un cuadro de diálogo que no tienen efecto hasta que se salga del cuadro de diálogo. Figura 12.event.

checks[loop-index] = new ~CheckBox("Casil1a de activación + loop-index). cuando el usuario selecciona las casillas de activación. for(int loop-index = 0.add(checks[loop~indexl). loop-index <= checks.setLayout(new FlowLayoutO ) .add~te~istener(this).setText(outString).13. 1 text = new JTextFieldílO).java. public void init 0 I Container contentpane = getContentPane0. checks[loop~index]. 1 El resultado se muestra en la figura 12. . Como se puede ver. isselected ( ) ) I outstring += " casilla de activación " + loop-index.length loop-idex++){ - 1.length . contentPane. content~ane. la applet indica las que están seleccionadas. usando el método isSelected para ver si están seleccionadas y listar aquellas que lo están: public void itemStateChanged(1temEvent e) t String outstring = new String("Actua1menteseleccionada: ").1. loop-index <= checks. for(int loop-index = 0. recorremos un bucle con todas las casillas de activación. Este ejemplo está en el CD con el nombre casilladeactivacionseleccionada. 1 1 text. Ahora. checks = new JCheckBox[lI. loop-index++){ if(checks[loop-index] . cuando el usuario hace clic sobre una casilla de activación.~~extField text.

Determinar si las casillas de activación están seleccionadas.-x iasliia de actk asiRa de actk ~ ~ :tualmente seleccionada casilla de activación 2 casilla deactivac~ón 3 Figura 12.13. .

Un viewport es una ventana dentro de una vista. barras de desplazamiento y cuadros de lista. deslizadores y listas En este capítulo trataremos algunos temas importantes de la Swing: Viewport. que visualizará una sección de nuestros datos. Utilizando Viewports. es un control muy importante en la Swing. Examinaremos el uso de la clase JViewport para desplazar imágenes.m Swing: viewports. deslizadores. por lo que necesitamos comprender cómo funciona con desplazamiento antes de trabajar con vistas y muchos otros controles de la Swing. pero no procesa el desplazamiento por sí mismo. de forma similar a aquella en que realizamos nosotros mismos el desplazamiento. Podremos desplazar manualmente los Viewports. . El de lista. Hagamos una breve descripción de los temas de este capítulo antes de profundizar en el código. podemos desplazarnos por los datos visualizados. desplazamiento. en concreto. Viewports La clase JViewport es el corazón del desplazamiento en la Swing. Los controles de este capítulo tienen todos una cosa en común: el desplazamiento. paneles de desplazamiento.

Paneles de desplazamiento Una forma común de implementar el desplazamiento en la Swing es utilizar paneles de desplazamiento. debido a que permiten presentar una lista de elementos senci- . De hecho. Listas Las listas. son unos controles muy populares. soportadas por la clase JList en la Swing. Cuando el cuadro de desplazamiento (también llamado burbuja o marcador) se mueva. Barras de desplazamiento Cada usuario de una U1 conoce las barras de desplazamiento. como el control JList. y también puede hacer clic sobre la pista de la barra de desplazamiento para cambiar su valor en su incremento unitario. Utilizaremos la clase JScrollBar en este capítulo desplazando texto en un applet. el valor de la barra de desplazamiento cambiará. implementan la interfaz Scrollable para trabajar con paneles de desplazamiento. por supuesto. por supuesto. Varios controles de la Swing. y la Swing las soporta al igual que hacía el AWT. como las áreas de texto. Los deslizadores son similares a los controles que vemos en los dispositivos de audio que permiten deslizar un mando a lo largo de una pista. soportado por la clase JSlider. Puede hacer lo mismo. los deslizadores son como barras de desplazamiento. De hecho. excepto porque explícitamente utilizamos deslizadores para permitir al usuario seleccionar un valor dentro de un rango continuo. con barras de desplazamiento. puesto que permiten desplazar componentes. éstos se utilizan habitualmente con controles JList para crear listas desplazables. Puede hacer clic sobre los botones de flecha en los extremos de la barra de desplazamiento para cambiar el valor de la barra de desplazamiento en el incremento de bloque. Deslizadores Otro control desplazable es el control deslizador de la Swing. pero los deslizadores se introducen aquí debido a que los usuarios actualmente esperan que las barras de desplazamiento se utilicen para desplazar otros controles.

swing. Verá cómo funciona todo esto en este capítulo. Hasta aquí el resumen de este capítulo. . puede realizar selecciones múltiples de diversas formas en los cuadros de lista de la Swing. De hecho.1. También examinaremos cómo implementar un nuevo modelo para listas. sin mostrar ninguna barra de desplazamiento al usuario. awt . Para presentar al usuario una única parte del documento. así como para renderizadores de celdas. con el fin de manejar la visualización real de cada elemento en la lista de una forma personalizada. "existe. que tiene un documento enorme. Mostraremos cómo desplazar largas listas y veremos diversos temas de la Swing. Es el momento de pasar al primer punto. Manejo de viewports "Mmh". dice el programador novato. Container j -javax. "Como es natural". ocultando una larga lista de elementos al hacer que el cuadro de lista sea desplazable.3. vendrá mucho más. Los viewports están soportados por la clase JViewPort.lla de manejar.JComponent -javax.lang. Aquí tenemos el diagrama de herencia para esta clase: java.awt. Por ejemplo.Object -java. puede utilizar un viewport". Imagine.1. Tabla 13. Campos de la clase JViewPort. Como puede ver. contestamos. protected boolean backingstore Devuelve true cuando el viewport mantiene una imagen fuera de pantalla de sus contenidos.swing.ava .JViewPort Encontrará los campos para la clase JViewPort en la tabla 13. por ejemplo. "quiero mover una imagen bajo control de programa. su constructor en la tabla 13. Los viewports representan ventanas o portales en una vista. puede configurar un viewport en ese documento y mover el viewport a través del documento a medida que lo ve. puede tener múltiples viewports para permitir que el usuario recorra los datos del modelo de su programa a voluntad.Component . manejar eventos de clics de ratón dobles y triples e incluso aún más. que es la base del desplazamiento en la Swing.2 y sus métodos en la tabla 13. que no se puede visualizar en la pantalla en un momento dado. También puede visualizar imágenes. ¿Existe alguna forma de hacerlo?".

Tabla 13. Tabla 13. Di. que puede ser nulo. protected boolean computeBlit(int dx.2.ración Blit. Point blitfrom. Calcula los parámetros de unaopeint dy. int index) Añade un ChangeListener Asigna el hijo ligero del viewport. Object constraints. El indicador scrollUnderway indica si una operación de desplazamiento está en marcha. El constructor de la clase JViewPort. Notifica a los receptores de un cambio de estado.ViewListener createViewListener() protected JViewport. . Métodos de la clase JViewPort. Notifica a los receptores de un cambio en una propiedad. JViewport() Construye un objeto JViewport. Devuelve el tamaño de la parte visible de la pista.ViewListener createViewListener() protected void fireStateChanged0 AccessibleContext getAccessibleContexto Dimension getExtentSize() Sobrescribe this para instalar un distinto gestor de distribución (o nulo) en el constructor. Point blitTo. protected boolean isViewSizeSet protected Point IastPaintPosition protected boolean scrollunderway Devuelve true cuando se han asignado las dimensiones del viewport. void addChangeListener(ChangeListener 1) protected void addlmpl(Component child. La última viewPosition pintada.3.protected lmage backingstorelmage La imagen utilizada para un fondo. Devuelve el contexto accesible. mension blitsize. Rectangle blitPaint) protected LayoutManager createLayoutManagerO protected JViewport. Construye un receptor para la vista.

Devuelve el tamaño preferido si se ha asignado tamaño. Devuelve una representación de cadena de este objeto JViewport.0). Pinta de nuevo la lista. int h) void reshape(int x. int w. int y. void repaint(longtm. JViewport sobrescribe éste método para devolver falso. int h) void scrollRectToVisible(Rectangle contentRect) Asigna los límites de este viewport. Devuelve lascoordenadas de la vista que aparece en la esquina superior izquierda del viewport (0.O si no existe vista). Sobrescrito para desplazar la vista de tal forma que el rectángulo que contiene la vista pase a ser visible. devuelve el tamaño actual de la vista.0. .0. Devuelve el hijo del viewporto nulo. en cualquier otro caso.lnsets getlnsetso Obtiene las dimensiones del lnset (borde) como (0. int w. Devuelve un rectángulo cuyo origen es getViewPosition() y su tamaño es getExtentSize0. El objeto JViewport no soporta bordes. int y. Devuelve un objeto lnsets conteniendo los valores del lnsets del objeto JViewport. Elimina el componente hijo ligero del vie wport. Pinta la imagen. Insets getlnsets(lnsets insets) Component getView() Point getViewPosition() Rectangle getViewRect() Dimension getViewSize() boolean isBackingStoreEnabled() boolean isOptimizedDrawingEnabledo void paint(Graphics g) protected String paramString() void remove(Component child) void removeChangeListener(Change. Devuelve true si el viewport mantiene una imagen fuera de pantalla. int x.Elimina un receptor de cambios de Listener 1 ) la lista.

void setViewSize(Dimension newSize) Dimension toViewCoordinates (Dimension size) Point toViewCoordinates(Point p) Vamos a examinar un ejemplo de Viewport que permite al usuario desplazar el viewport con botones y no con barras de desplazamiento. así como un panel conteniendo botones con los textos desplazar izquierda. El usuario puede desplazar la imagen en el viewport haciendo clic con el ratón sobre los botones. el viewport mantendrá una imagenfuerade pantalla. añadimos un viewport con la imagen a un programa. . Asigna el hijo ligero del viewport(su vista). Convierte un punto en coordenadas de puntos a coordenadas de vista. utilizamos el método setView de la clase JViewPort. Asigna las coordenadas de vista que aparecen en la esquina superior izquierda del viewport así como el tamaño de la vista. desplazar arriba.void setBackingStoreEnabled(boolean x) void setBorder(Border border) void setExtentSize(Dimension newExtent) void setView(Component view) void setViewPosition(Point p) Si el valor x es true. un nuevo panel. estará desplazando realmente el panel. Convierte un tamaño en coordenadas de puntos a coordenadas de vista.swing. Cuando el usuario desplace el viewport. * . Aquí. Comencemos creando un nuevo viewport y después. Añadiremos unaetiqueta con una imagen al panel y después añadiremos éste al viewport. import javax. Aquí tenemos el mecanismo para crear el viewport Y añadirlo al programa (observe que para añadir realmente el panel al viewport. Asigna un borde. Asigna las coordenadas de vista que aparecen en la esquina superior izquierda del viewport. Asigna el tamaño de la parte visible de lavista utilizandolas coordenadas de vista. que asigna el objeto vista del viewport): import j ava . desplazar abajo y desplazar derecha. awt .*.

button2 = new JButton("Desp1azar arriba"). button3 = new JButton("Desplazar abajo") . Llamaremos a éste panel buttonpanel. .import java. También necesitamos otro panel que no forme parte del viewport. Observe ahora que pasamos el viewport al constructor de esta clase para poder desplazar el viewport. JViewport jviewport = new JViewportO. public class viewport extends JApplet { public viewport ( ) I container contentpane = getContentPane0. en el que visualizaremos los botones que puede utilizar para el desplazamiento. JPanel jpanel = new JPanelO. JButton JButton JButton JButton buttonl = new JButton("Desp1azar a la izquierda"). public buttonpanel(JViewport vport) add (buttonl) .awt. add(button2).*.event. add(button4). Aquí tenemos la forma de almacenar el viewport pasado al constructor y añadimos los botones necesarios para el desplazamiento: class buttonpanel extends JPanel implements ActionListener I JViewport jviewport. add(button3). button4 = new JButtoníMDesplazar a la derecha") .

java del CD que acompaña a este libro. else if(e.getSource() == button3) p0sition. Para hacerlo.getSource() == buttonl) p0sition. Cuando el usuario hace clic sobre un botón. jpanel .y -= 10.getsource() a = button2) p0sition. utilizamos el método getViewPosition de la clase JViewPort para obtener la posición actual de la vista. .jpg") ) ) . Este applet es un éxito y se encuentra en el archivo viewport. JPanel jpanel = new JPanelO. Después. los botones de desplazamiento aparecen al pie del applet.getSource() == buttonl) p0sition. else if(e. El resultado se muestra en la figura 13. cambiamos esa posición (de acuerdo con el botón sobre el que se haya hecho clic) en 10 puntos y utilizamos el método setViewPosition para asignar la nueva posición del viewport: public void actionPerformed(ActionEvent e) I Point position = jviewport.getViewPosition0.x += 10.x -= 10. else if(e. Ahora instalamos un objeto buttonpanel al pie del applet. if(e.1. la imagen se mueve de forma correspondiente.add(new JLabel (new ImageIcon("viewport. Como vemos. JViewport jviewport = new JViewportO.y += 10. como sigue: public class viewport extends JApplet I public viewporto I Container contentpane = getContentPane0.Todo lo que tenemos que hacer es implementar el desplazamiento cuando el usuario haga clic sobre un botón.

Creación de paneles de desplazamiento El programador novato aparece y dice: "Oye.". La clase JScrollPane es la implementación ligera en la Swing de un panel de desplazamiento y podemos utilizarlo para desplazar otros controles. Esto es un error. pero lo puedes poner en un panel de desplazamiento". "¿De verdad? ¿Es ésa la forma en que se espera que funcione?". El PN pregunta. Figura 13. JScrollPane y JScrollBar implementan todas esta interfaz). Aquí tenemos el diagrama de herencia para JScrollPane: . utilizaremos componentes como paneles de desplazamiento.. siempre que visualicemos una lista. He creado un nuevo control de lista de la Swing.. que examinaremos a continuación.Normalmente. insertado 40. Gracias a la nueva interfaz Scrollable de la Swing.1. voy a crear un informe y. "Espera". le decimos. Desplazamiento de un viewport. no utilizaremos siempre la clase JViewPort para manejar nuestro desplazamiento.000 elementos en el mismo y aparecen únicamente dos visibles a la vez y no existen barras de desplazamiento. las operaciones de desplazamiento se coordinan de una forma mucho más próxima al control que se desplaza (las clases JViewPort. en su lugar. "El control JList no implementa desplazamiento por sí mismo. De hecho. Java ha fallado de nuevo. el mecanismo habitual es visualizarla dentro de un panel de desplazamiento para permitir al usuario desplazar los elementos de la lista.

protected Component IowerLeft protected Component IowerRight protected JViewport rowHeader protected Component upperLeft protected Component upperRight El componente a visualizar en la esquina inferior izquierda. JScrollPane(Component view) Construye un objeto JScrollPane que visualice los contenidos del componente indicado.4. El componente a visualizar en la esquina superior derecha. Construye un objeto JScrollPane vacío. El hijo panel de desplazamiento del viewport. int hsbPolicy) . int vsbPolicy. protected JScrollBar verticalScrollBar El hijo barra de desplazamientovertical del panel de desplazamiento. El componente a visualizar en la esquina superior izquierda.5. protected JScrollBar horizontalScroll. Campos de la clase JScrollPane. Bar protected int horizontalScrollBarPolicy La política de visualización para la barra de desplazamiento horizontal. Tabla 13. El componente a visualizar en la esquina inferior derecha.El hijo barra de desplazamiento horizontal del panel de desplazamiento. protected JViewport columnHeader El hijo cabecera de columna. Construye un objeto JScrollPane que visualice el componente vista en un viewport cuya posición de JScrollPane(Component view.6.5 y sus métodos en la tabla 13. Tabla 13. Constructores de la clase JScrollPane.Encontrará los campos para l a clase JScrollPane en l a tabla 13. protected int verticalScrollBarPolicy protected JViewport viewport La política de visualización para la barra de desplazamiento vertical.4. sus constructores en la tabla 13. El componente hijo cabecera de fila.

int hsbPolicy) Construye un objeto JScrollPanevacío con políticas de barras de desplazamiento indicadas. protected JViewport createViewport() Obtiene un nuevo objeto JScrollPane predeterminado. Obtiene el valor de la política de barras desplazamiento horizontal. JScrollBar createVerticalScrollBar() Crea la barra de desplazamiento vertical. Obtiene el objeto apariencia que renderiza éste componente. Obtiene el componenteen laesquina indicada. Obtiene la barra de desplazamiento vertical. Obtiene el valor de la política para las barras desplazamiento verticales. Obtiene la clave utilizada para buscar la clase ScrollPaneUl que proporciona la apariencia para JScrollPane. Obtiene la cabecera de columna. Obtiene la barra de desplazamiento horizontal.6. JScrollBar getVerticalScrollBar() int getVerticalScrollBarPolicy() . Obtiene la cabeza de fila. Tabla 13.vista se pueda controlar con un par de barras de desplazamiento. AccessibleContext getAccessibleContexto JViewport getColumnHeader() Component getCorner(String key) JScrollBar getHorizontalScrollBar() int getHorizontalScrollBarPolicy() JViewport getRowHeader() ScrollPaneUl getUI() String getUIClasslD() Obtiene el contexto accesible asociado con este objeto JComponent. Métodos de la clase JScrollPane JScrollBar createHorizontalScroIIBar() Crea la barra de desplazamiento horizontal. JScrollPane(int vsbPolicy.

y si es necesario. Rectangle getViewportBorderBounds() Obtiene los límites del borde del vie wport. void setColumnHeaderView(Component view) void setCorner(String key. y después añade el viewport para cabecera de fila al panel de desplazamiento. este método la elimina. Si existe una cabecera de columna vieja. Añade un hijo que aparecerá en una de las esquinas de los paneles desplazamiento (si existe espacio). Construye un viewport de cabecera de columna. asigna su vista y después añade el viewportde cabecera de columna al panel de desplazamiento. . Component corner) void setHorizontalScrollBar(JScrollBar horizontalScrollBar) void setHorizontalScrollBarPolicy (int policy) void setLayout(LayoutManagerlayout) Asigna el gestor de distribuciónpara este objeto JScrollPane.JViewport getViewport() Border getViewportBorder() Obtiene el objeto JViewPort actual. Obtiene el valor de la propiedad viewportBorder. boolean ¡sopaque() boolean isValidateRoot() protected String paramString() void setColumnHeader(JViewport columnHeader) Devuelve true si este componente pinta todos los puntos en su rango. Añade la barra de desplazamiento que controla la posición de la barra de vista horizontal del viewport al panel de desplazamiento. void setRowHeader(JViewport rowHeader) void setRowHeaderView(Component view) Asigna la nueva cabecera de fila. si es necesario. Obtiene una representación de cadena de este objeto JScrollPane. Determina cuándo aparece la barra de desplazamiento horizontal en el panel de desplazamiento. Comprueba la raíz. Construye un viewport para cabecera de fila.

void setUI(ScrollPaneUI u¡) void setVerticalScrollBar(JScrollBar verticalScrollBar) void setVerticalScrollBarPolicy(int policy) Asigna el objeto que proporciona la apariencia. Se llama cuando cambia la apariencia predeterminada. Comenzaremos creando un objeto JPanel relleno con campos de texto: import java. void setViewportBorder(Border viewportBorder) void setViewportView(Component view) void updateUl() Añade un borde alrededor del viewport.setLayout(new GridLayout(l1. Vamos a examinar un ejemplo en el que añadiremos una distribución de rejilla a los campos de texto de un panel y desplazaremos el panel en un panel de desplazamiento.swing. Añade la barra de desplazamiento que controla la posición de vista vertical del viewport. 16)): for(int outer = O. void setViewport(JViewport viewport) Fuerza la posición devista del nuevo viewporta la posición del cuadrante +x. import javax.*. si es necesario. asigna su vista. public class scrollpane extends JApplet ( public void init0 ( Container contentpane = getContentPane0. outer <= 10. Determina cuándo aparece la barra de desplazamientovertical en el panel de desplazamiento.*. jpanel. m a n e 1 jpanel = new JPanelO. +y. outer++) í . Construye un viewporty.awt.

*. jpanel. outer <= 10. 1 1 + Ahora.add(new JTextFieldínCuadro de texto " + outer ".*.ALWAYS. HORIZONTALSCROLLBAR. inner++) { jpanel. foríint outer = O.for(int inner = O. import javax. VERTICAL. VERTICALSCROLLBAR. outer++) { for(int inner = O. } + 1 JScrollPane jscrollpane = new ~~croll~ane(jpane1. public class scrollpane extends JApplet I public void init ( ( ) Container contentpane = getContentPane0. añadiremos este nuevo panel a un panel de desplazamiento.HORIZONTAL~SCROLLBAR~ .swing.NEVER. En este caso. JPanel jpanel = new JPanelO. inner++) { jpanel.setLayout(new GridLayout(l1.VERTICAL~SCROLLBAR~ALWAYS. ' + inner) ) . S~~~~~P~~~C~~~~~~~~. Cuando creemos un objeto panel de desplazamiento. inner <= 15.awt. inner <= 15. HORIZONTAL-SCROLLBAR-AS-NEEDED. ScrollPaneConstants. 16)) . VERTICAL-SCROLLBAR-AS-NEEDED. pasaremos el objeto a desplazar y podemos especificar cuándo y dónde deseamos las barras de desplazamiento con estas constantes: HORIZONTAL-SCROLLBARALWAYS. + inner)).add(new JTextField("Cuadr0 de texto " + outer ". VERTICAL-SCROLLBAR-NEVER. siempre permitiremos que el panel de desplazamiento muestre las barras de desplazamiento: import java.SCROLLBAR.

2.java del CD. Uso de un panel de desplazamiento. "Se puede hacer en Java e incluso se puede seleccionar el tipo de borde también". se pueden especificar etiquetas o incluso imágenes para utilizar como cabeceras de filas y columnas". el conjunto completo de la rejilla de campos de texto aparece en el panel de desplazamiento y el usuario puede desplazar esa rejilla con las barras de desplazamiento. .El resultado de la adición de un panel de desplazamiento al panel de contenidos del applet se muestra en la figura 13. También podemos personalizar el borde utilizado en un panel de desplazamiento con el método setViewPortBorder. Creación de paneles de desplazamiento con cabeceras y bordes El zar de la corrección programática aparece y dice: " ~ J a v no tiene panea les de desplazamiento? Bueno. Figura 13. no tienen una apariencia muy profesional. dice el ZCP. "Sin problema". Podemos personalizar un panel de desplazamiento añadiendo imágenes de cabecera o texto con los métodos setColumnHeaderView y setRowHeaderView. "Vaya". Como muestra la figura.2. con controles profesionales. contestamos. Este ejemplo se encuentra en el archivo scrollpane.

utilizaremos etiquetas como cabeceras de filas y columnas y añadiremos un borde simple: import java .HORIZONTAL~SCROLLBAR~ALWAYS). m . for(int outer = O. * . crearemos esta personalización para que trabaje con el ejemplo de panel de desplazamiento que desarrollamos en el tema anterior.VERTICAL~SCROLLBAR~ALWAYS. 16)).Como ejemplo.add(new JTextField("Cuadro de texto " + outer + ". JLabel jlabell = new JLabel("Etiqueta horizontal"). inner++) { jpanel. outer <= 10. 1 La figura 13.*. } 1 1 JScrollPane jscrollpane = new JScroll~ane(jpane1.setLayout(new GridLayout(l1. outer++) { foríint inner = O . " + inner ) ) . JLabel jlabel2 = new JLabel("Etiqueta verticalm). jpanel. import javax. public class scrollpane extends JApplet { public void init() I Container contentpane = getContentPane0. awt .3 muestra el resultado de éste código. En este caso. ScrollPaneConstants. inner <= 15. JPanel j panel = new JPanel ( ) .swing. ScrollPaneConstants.

O Figura 13.i tiqueta 1101170ntal Cuadro de . Aquí tenemos un ejemplo que muestra cómo funciona: import java. j ~ ~ " ) ) ~ JScrollPane jscrollpane = new JScrollPane(jlabe1). 0 tl /Cuadro de texto 4 .awt. o d texto O.--texto c i p i i ~ u a d. l de !cuadro de texto 3. l 1 de cuadro de texto 2.H --l l ~ u a d r o texto 1 .r e -.*. l I [ ~ u a d r o texto 4 .4. Adición de cabeceras a un panel de desplazamiento. import javax. JLabel jlabel = new JLabel(new ~ m a g e ~ c o n ( ~ s c r o l l p a n e . todo lo que tenemos que hacer es mostrar la imagen en una etiqueta (o en un componente similar) y añadir esa etiqueta al panel de desplazamiento. 1 . public class scrollpaneimage extends JApplet { public scrollpaneimage0 { Container contentpane = getContentPane0. 0 1 Cuadro de texto 2. para manipular imágenes que no puedan . El resultado se muestra en la figura 13.swing.*. /Cuadro de texto l . 1 j Cuadro de texto 3 .. Ahora el usuario puede desplazar una imagen tan grande como desee.-. Desplazamiento de imágenes Los paneles de desplazamiento proporcionan un mecanismo ideal para desplazar imágenes. O pr~.3.

JComponent javax. Creación de deslizadores El programador novato vuelve y dice.Object . el usuario desplaza un selector con el ratón. Los deslizadores presentan controles al usuario similares a aquellos que vemos en un equipo de audio.4. como las listas. Podemos utilizar barras de desplazamiento para permitir al usuario seleccionar un valor dentro de un rango continuo.7.swing.lang. "He visto un nuevo control en varios programas.java en el CD. Aquí tenemos el diagrama de herencia para la clase JSlider: java. están dirigidos claramente a permitir al usuario seleccionar un valor dentro de un rango. Por esa razón.awt.Container javax.7 visualizarse al mismo tiempo.swing.8 y sus métodos en la tabla 13. Sonríe y le dice. "Dentro de mucho tiempo". Component j -java. awt . Este ejemplo está en el archivo scrollpaneimage.ava . Desplazamiento de una imagen. . sus constructores en la tabla 13. deslizadores. pero los usuarios están más familiarizados con las barras de desplazamiento para otros controles. Para utilizar los deslizadores. Swing añade la clase JSlider para dar soporte a los controles deslizamiento. Figura 13. ¿Cuándo piensas que lo tendremos en Java?".9.JSlider Puede encontrar los campos de la clase JSlider en la tabla 13.

que maneja el valor numérico máximo. Campos de la clase JSlider. Construye un deslizador horizontal utilizando los valores mínimo. La orientación del deslizador. Constructores de la clase JSlider. protected ChangeListener changelis. la caja se resuelve a la marca siguiente más cercana a donde el usuario ha situado el cuadro. El modelo de datos. valor mínimo y valor para la posición actual del deslizador. int value) .8.Tabla 13. int max. Construye un deslizador horizontal utilizando los valores mínimo y máximo indicados con un valor inicial de 50. El número de valores entre las marcas de incremento menores. JSlider(BoundedRangeModel brm) Construye un deslizador horizontal utilizando el modelo de límites de rango indicado. máximo e inicial indicados. Si vale true. Construye un deslizador utilizando la orientación indicada con el rango O a 100 y un valor inicial de 50. protected ChangeEvent changeEvent El evento de cambio.El receptor de cambio. JSlider(int orientation) JSlider(int min. protected boolean snapToTicks Tabla 13. tener protected int majorTickSpacing protected int minorTickSpacing protected int orientation protected BoundedRangeModel sliderModel El número de valores entre las marcas de incremento mayores.7. int max) JSlider(int min. Construye un deslizador horizontal con el rango O a 100 y un valor inicial de 50.

void addChangeListener(ChangeListener 1 ) protected ChangeListener create ChangeListenerO Hashtable createStandardLabels(int increment) Hashtable createStandardLabels(int increment. Construye una tablahash que dibujará etiquetas de texto comenzando en el punto indicado. Obtiene el contexto accesible. Obtiene el diccionario para dibujar las etiquetas.JSlider(int orientation. Obtiene el valor mínimo soportado por el deslizador. Construye una tabla hashque dibujará etiquetas de texto comenzando en el mínimo del deslizador. Métodos de la clase JSlider. Devuelve true. Sobrescribe este método para devolver su propia implementación del receptor de cambios.9. si el rango devalores mostrado para el deslizador está invertido. int min. AccessibleContext getAccessibleContexto int getExtent() boolean getlnvertedo Dictionary getLabelTable0 int getMajorTickSpacing() int getMaximum() int getMinimum() . Obtiene el espaciamiento de marcas mayores. int start) protected void fireStateChanged0 Añade un receptor de cambio al deslizador. Envía un evento de cambio a cada receptor. int value) Construye un deslizadorcon la orientación indicaday los valores máximo. int max. Obtiene la extensión. Tabla 13. mínimo e inicial indicados. que se encuentra en el rango de valores cubierto por el cuadro. Obtiene el valor máximo soportado por el deslizador. cuyo origen es el deslizador.

Devuelve el objeto IU. que implementa la apariencia para este componente. void setMajorTickSpacing(int n) Asigna el espaciamiento de marcas mayores. máximo y valor. Pasa un valor JSlider para invertir el rango de valor. Devuelve la orientación vertical u horizontal del deslizador. . int getOrientation() boolean getPaintLabels() boolean getPaintTicks() boolean getPaintTrack0 boolean getSnapToTicks() String getUIClasslD() int getValue() boolean getValuelsAdjusting() protected String paramString() Obtiene el nombre de la apariencia que representa este componente. void removeChangeListener(Change. Devuelve true si se arrastra el cuadro del deslizador. Obtiene el modelo de datos que maneja las tres propiedades fundamentales de los deslizadores: mínimo. Indica si se debe pintar la pista.Elimina un receptor de cambios del Listener 1 ) deslizador. Indica si se tienen que pintar las etiquetas. void setExtent(int extent) void setlnverted(boolean b) Asigna el tamaño de rango cubierto por el cuadro. Devuelve true si el cuadro se resuelve a la siguiente marca más cercana a donde el usuario hubiera posicionado el cuadro.int getMinorTickSpacing() BoundedRangeModel getModel() Obtiene el espaciamiento de marcas menores. Obtiene el valor del deslizador. void setLabelTable(Dictionary labels) Utilizado para especificar qué etiqueta se dibujará en un valor dado. Devuelve unacadena para representar este objeto JSlider. Indica si deben pintarse las marcas.

Asigna la propiedad valuelsAdjusting del modelo. Determina si se pintan etiquetas en el deslizador. que implementa la aparienciapara este componente. Asigna la propiedad mínimo del modelo. Llamada internamente para reemplazar la interfaz de usuario de la etiqueta con las últimas versiones de la clase U IFactory. Determina si se pintan marcas en el deslizador. Asigna el espaciamiento de marcas menores. Asigna valor actual del deslizador. Determina si se pinta la pista del deslizador. Asigna el modelo que procesa las tres propiedades fundamentales de los deslizadores: mínimo. el cuadro resolverá a la siguienteposiciónmás cercana de las marcas donde se hubiera posicionado el cuadro. Si especificamos true. Asigna la orientación de la barra desplazamiento bien a VERTICAL o HORIZONTAL.void setMaximum(int maximum) void setMinimum(int minimum) void setMinorTickSpacing(int n) void setModel(BoundedRangeModel newModel) Asigna la propiedad máximo del modelo. Notificación procedente de la clase UlFactory para indicar que la apariencia ha cambiado. Asigna el objeto IU. máximo y valor. void setOrientation(int orientation) void setPaintLabels(boolean b) void setPaintTicks(boolean b) void setPaintTrack(boo1ean b) void setSnapToTicks(boolean b) void setUl(SliderUI ui) void setValue(int n) void setValuelsAdjusting(boolean b) protected void updateLabelUls() void updateUl() .

statechanged. 1 0 0 .setLayout(new FlowLayout()). contentPane.*. JButton jbutton = new JButton("Fijadala extensión de texto a 60").event. crearemos justamente un deslizador que puede devolver valores desde O hasta 100 e informar del valor actual en una barra de estado del applet.awt.*. 0 ) . javax. javax.event.swing. Utilizaremos receptores de cambios con deslizadores y no receptores de ajuste.swing.HORIZONTAL. añadimos este deslizador al panel de contenidos del applet.*.*. JSlider jslider = new JSlider(SwingConstants.10.Vamos a hacer funcionar la clase JSlider en un ejemplo. public void init0 Ahora. public class slider extends JApplet implements ActionListener. Añadimos un receptor de cambio al deslizador en este applet y después añadimos el deslizador como sigue: public void h i t 0 ( Container contentpane = getContentPane0. 0. un valor máximo de 100 y un valor inicial de O: import import import import java. El interfaz ChangeListener tiene únicamente un método. que se muestra en la tabla 13. Aquí vemos cómo crear un deslizador horizontal con la constante SwingConstants.VERTICAL) con un valor mínimo de O. ChangeListener 1. como hicimos con las barras de desplazamiento. la otra posibilidad es SwingConstants. en el método init. java. En este caso.awt.HOR1ZONTAL (como podrá suponer. .

El método de la interfaz ChangeListener. lo que puede hacer como sigue 7 .getMinimum()+ " . lo que implica que su huella aparecerá rellena desde el origen hasta el selector del deslizador. Figura 13.En el método statelhanged. puede rellenar sus deslizadores. valor: " + jsliderl.getSource().10. void stateChanged(ChangeEvent e ) Invocado cuando el destino del receptor ha cambiado s u estado. Tabla 13. showStatusí"Des1izador mínimo: " + jsliderl. Como vemos. utilizamos los métodos g e t ~ i n i m u m r getMaximum y getValue de JSlider para visualizar la configuración del deslizador en la barra de estado: public void stateChanged(ChangeEvent e) i JSlider jsliderl = (JSlider) e.java del CD. el usuario mover el selector del deslizador y aparece el nuevo valor.5. Para hacerlo.getValue() ) . Uso de un deslizador.getMaximum( ) + ' . debe asignar la propiedad cliente isFilled del JSlider a true. máximo: '' + jsliderl .5. 1 El resultado se muestra en la figura 13. Este ejemplo se encuentra en el archivo slider. Relleno de un deslizador Si está utilizando la apariencia de metal predeterminada de Swing.

contentpane. Figura 13. "Bien".6. utilizando los métodos setMajorTickSpacing y setMinorTickSpacing. Como puede ver. dicen que no pueden conseguir lo que quieren utilizando un único deslizador largo". Para pintar las marcas en un control de deslizamiento. pasamos un valor de true al método setPaintTicks y después indicamos el desplazamiento mayor y menor que queremos para las marcas. como aquí (observe que estamos añadiendo este código al ejemplo del deslizador existente): public void i n i t 0 i . "los usuarios se quejan de los deslizadores en mi programa. El resultado aparece en la figura 13. el deslizador de la figura está relleno. Pintar las marcas de un deslizador "Ah".6.(observe que estamos añadiendo este código al ejemplo del deslizador a partir del tema anterior): public void init í ) ( Container contentpane = getContentPane0. Relleno de un deslizador.setLayout(new FlowLayoutO ) . "puede arreglarlo añadiendo marcas". decimos. dice el programador novato.

7. Como se muestran la figura.setLayout(new FlowLayout~)). 7 Figura 13. El resultado aparece en la figura 13.Container contentpane = getContentPane0. el deslizador ahora muestra las marcas. contentPane. consulte el siguiente tema para conocer los detalles. Aquí vemos cómo hacerlo añadiendo una línea de código al ejemplo del deslizador existente: public void init() ( Container contentpane = getContentPane0. Pintar etiquetas en un deslizador Puede utilizar el método setPaintLabels de la clase JSlider para visualizar el valor numérico de las marcas mayores en el deslizador.7. .setLayout(new FlowLayoutO . contentPane. También puede pintar los valores numéricos para las marcas mayores. Pintar marcas en un deslizador.

el valor de deslizador jamás podrá exceder al valor máximo . Pintar las etiquetas del deslizador.setLayout(new FlowLayoutO ) .TRUE). Como vemos.8. máximo 100.El resultado se muestra en la figura 13. 0. jslider. se etiquetan las marcas mayores. jslider .8. Ajuste de la extensión del deslizador Puede ajustar la extensión del deslizador. jslider. contentPane.addChangeListener(this).setPaintTicks (true). 1 Declizador mínimo 0. Como ejemplo. que limita el valor máximo de éste. añadimos un botón al ejemplo deslizador que hemos desarrollado en los últimos temas para permitir que el usuario ajuste la extensión del deslizador a 60: public class ChangeListener slider extends JApplet implements ~ctionLi~tener. JButton jbutton = new ~ ~ u t t o n ( " F i j a d a extensión de texto a 60").setMajorTickSpacing (20). la public void h i t 0 { Container contentpane = getContentPane0. valor 60 i Figura 13. I JSlider jslider = new JSlider(SwingConstants. . Si ajusta la extensión del deslizador y su valor máximo es máximo. jslider. 0 ) .putClientProperty("Jslider.extensión.isFilled".setPaintLabels(true). jslider. ~oolean. 100.HORIZONTAL.

Observt: aue incluso aunque el deslizador esté ajustado a su valor máximo. extensión: " + jsliderl. eso significa qi valor no puede superar 40.getExtent0 ) . valor: " + jsliderl.9. se ajusta la extensió deslizador a 60 y debido a que su valor máximo es 100. máximo: " + j sliderl . dice el programador novato. su valor únicamente es 40. La figura 13. Ajuste de la extensión del deslizador. showStatus("Deslizador mínimo: " + jsliderl. "quiero permitir al usuario recorrer los datos en mi programa.getSource0.getMinimum0 + " . 1 public void actionPerformed(ActionEvent e) Cuando el usuario hace clic sobre el botón. Quiero que -7 . Figura 13.getMaximum ( ) + " . Creación de barras de desplazamiento "Bien".getValue0 + " .9 muestra el resultado. Quiero dejarle ajustar los valores.public void stateChanged(ChangeEvent e ) I JSlider jsliderl = (JSlider) e.

. JScrollBar(int orientation) Construye una barra de desplazamiento con la orientación indicada y los siguientes valores iniciales. y valores máximo y mínimo indicados. JScrollBar(int orientation.".. dice el PN. Tabla 13. protected int blocklncrement El incremento de bloque. int max) Tabla 13. . Tabla 13. Constructores de la clase JScrollBar. Campos de la clase JScrollBar. El incremento unitario.13. protected BoundedRangeModelmodel El modelo que representa los valores actual. int value.13.1 2. Métodos de la clase JScrollBar. Quiero. respondemos. protected int orientation protected int unitlncrement La orientación de la barra de desplazamiento. valor. "Barras de desplazamiento". Construye una barra de desplazamiento con la orientación. int extent. máximo y extensión de la barra de desplazamiento." "Correcto".11. int min. extensión. Construye una barra de desplazamiento vertical.1 1. sus constructores en la tabla 13. "Lo que quiere son barras de desplazamiento. void addAdjustmentListener(AdjustmentListener 1 ) Añade un receptor de ajuste.pueda navegar por los elementos en una lista larga.12 y sus métodos en la tabla 13. El componente ligero de la Swing para barras de desplazamiento es l a clase JScrollBar y su diagrama de herencia es como sigue: Puede encontrar los campos de l a clase JScrollBar en la tabla 13. mínimo.

ScrollBar. int type. Obtiene la cantidad que debe carnbiar el valor de la barra de despla- int getBlocklncrement(int direction) int getMaximum() Dimension getMaximumSize() int getMinimum() Dimension getMinimumSize() BoundedRangeModel getModel() int getOrientation() ScrollBarUl getUI() String getUIClasslD() int getUnitlncrement() int getUnitlncrement(int direction) .protected void fireAdjustmentValueChanged(int id. Obtiene el nombre de la clase LookAndFeel para este componente. valor y extensión. dado un bloque de petición de cambio. Obtiene el delegado que implementa la apariencia de este componente.awt. Obtiene el contexto accesible. El valor máximo de la barra de desplazamiento es igual al valor máximo menos la extensión. Obtiene la cantidad en que debe cambiarse el valor de la barra de desplazamiento.ScrollBar. Obtiene el modelo de datos que procesa las cuatro propiedades fundamentales de la barra de desplazamiento: mínimo. Obtiene la orientación del componente (horizontal o vertical). Utilizado para compatibilidad con versiones anterioresúnicamente con java. Obtiene el tamaño mínimo de la barra de desplazamiento. Utilizado para compatibilidad con versiones previas únicamente para java.awt. máximo. Obtiene el mínimo valor soportado por la barra de desplazamiento. int value) AccessibleContext getAccessibleContexto int getBlocklncrement() Dispara un evento de ajuste. Obtiene el tamaño máximo de la barra de desplazamiento.

zamiento, dada una unidad de solicitud de cambio. int getValue() boolean getValuelsAdjusting() Obtiene el valor de la barra de desplazamiento. Devuelve true, si se ha arrastrado el cuadro de la barra de desplazamiento. Obtiene la extensión de la barra de desplazamiento. Obtiene una cadena que representa la barra de desplazamiento Elimina un receptor de AdjustmentEvent. Asigna la propiedad blocklncrement. Habilita el componente para que la posición del cuadro pueda cambiar. Asigna la propiedad máximo del modelo. Asigna la propiedad mínimo del modelo. Asigna el modelo que procesa las cuatro propiedades fundamentales de la barra de desplazamiento: mínimo, máximo, valor y extensión. Asigna la orientación de la barra de desplazamiento a losvaloresVERTICAL u HORIZONTAL. Asigna la propiedad unitlncrement. Asigna el valor de la barra de desplazamiento. Asigna la propiedad valuelsAdjusting del modelo.

int getVisibleAmount() protected String paramString() void removeAdjustmentListener (AdjustmentListener 1 ) void setBlocklncrement(int blockIncrement) void setEnabled(boo1ean x) void setMaximum(int maximum) void setMinimum(int minimum) void setModel(BoundedRangeModel newModel)

void setOrientation(int orientation)

void setUnitlncrement(int unitlncrement) Sets the unitlncrement property. void setValue(int value) void setValuelsAdjusting(boolean b)

void setValues(int newvalue, int new- Asigna las cuatro propiedades Bounded RangeModel. Extent, int newMin, int newMax)

void setVisibleAmount(int extent) void updateUI()

Asigna la propiedad extensión del modelo. Sobrescribe JCornponent.updateU1.

Aquí tenemos un ejemplo en el que utilizamos una barra de desplazamien-Y to para desplazar texto en un applet. Para hacerlo, crearemos un nuevo panel que muestre una etiqueta con e 7 texto "¡Hola desde Swing!" en la posición vertical dada por el miembro público de datos denominado y. Aquí tenemos la apariencia de la clase del panel:
class jpanel extends JPanel

I
JLabel jlabel = new JLabel ( " i Hola desde la Swing! " ) int y = 0; jpanel ( )
{
;

jlabel = new JLabel("iHo1a desde la Swing!"); add(jlabel);

1
public void paintComponent(Graphics g )
(

super.paintComponent(g);

jlabel.setLocation(0, y);

1
public void setScrolledPosition(int newposition)
(

y = newposition;

1

1

Ahora podemos añadir un objeto de esta nueva clase panel a un applet, as1 como una barra de desplazamiento vertical en una distribución de borde, como sigue:
import java.awt.*; import javax.swing.*; import java.awt.event.*;

-7

public class scrollbar extends JApplet
(

private JScrollBar vsb = new JScroilBar(JScrollBar.VER~~c~~, O, o, 0, 180); private jpanel j = new jpanelo; public void init ( )
{

Container contentpane = getContentPane();

vsb.addAdjustmentListener(new AdjustmentListenerO
{

public void adjustmentValueChanged( AdjustmentEvent e) JScrollBar sb = (JScrollBar)e.getSource(); j.setScrolledPosition(e.getValue()); j repaint ( ); 1

{

.

1);

1 1

El resultado se muestra en la figura 13.10. Como muestra la figura, el usuario puede utilizar la barra de desplazamiento para mover el texto arriba y abajo en el panel. Este ejemplo se encuentra en el archivo scrollbar.java del CD.

Figura 13.10. Creación y uso de una barra de desplazamiento.

Creación de listas
El gran jefe aparece envuelto en una nube de humo de cigarro y dice, "Ahora tenemos 14.389 productos para que el usuario seleccione. ¿Cómo vamos a visualizarlos todos en un programa?". "Sin problema", respondemos, "utilizamos un control de lista". El gran jefe sonríe y dice, "Aquí tiene los nombres de los productos para introducirlos". La clase JList de la Swing es un control de lista de poco peso. Aquí tenemos el diagrama de herencia para la clase JList:
j ava . lang . Obj ect -java.awt.Component -java.awt.Container -javax.swing.JComponent -javax.swing. JList

Podemos hacer más con los controles JList de lo que podíamos con los controles List del AWT; por ejemplo, podemos visualizar imágenes en listas Swing. De hecho, examinaremos lo que podemos hacer con las listas Swing desde este punto hasta el final del capítulo. Puede encontrar los constructores de la clase JList en la tabla 13.14 y sus métodos en la tabla 13.15.
Tabla 13.14. Constructores de la clase JList.

Construye un objeto JList. JList(ListModel dataMode1) Construyeun objeto JList, quevisualizará los elementos en el modelo de datos indicado. Construye un objeto JList quevisualice los elementos en la matriz indicada. Construye un objeto JList quevisualice los elementos en el vector indicado.

I

JList(Object[] IistData)

JList(Vector IistData)

Tabla 13.15. Métodos de la clase JList.

void addListSelectionListener(ListSelectionListener listener)

Añade un receptor de selección.

void addSelectionlnterval(int anchor, Hace que la selección sea la unión int lead) del intervalo indicadocon laselección actual. void clearSelection() Borra la selección.

protected ListSelectionModel create- Obtiene una instancia de DefaultSelectionModel() ListSelectionModel. void ensurelndexlsVisible(int index) Desplaza el viewportpara asegurar que un elemento sea visible.

protected void fireSelectionValue- Notificaalos receptoresde selección Changed(int firstlndex, int lastlndex, de la lista JList que el modelo de seboolean isAdjusting) lección ha cambiado. AccessibleContext getAccessibleContexto int getAnchorSelectionlndex() Obtiene el contexto accesible. Obtiene el argumento del primer índice a partir de la llamada addSelectionlnterval o setSelectionlnterval más reciente.

Rectangle getCellBounds(int indexl , Obtiene los límites del rango de eleint index2) mentos indicado. ListCellRenderer getCellRenderer0 int getFirstVisiblelndex() Obtiene el objeto que renderiza la lista de elementos. Devuelve el índice de la celda en la esquinasuperior izquierda del objeto JList. Obtiene el valor de altura fija de la celda. Obtiene el valor de anchura fija de la celda. Devuelve el índice de la celda en la esquina inferior derecha del objeto JList. Obtiene el argumento del segundo índice a partir de la llamada addSelectionlnterval o setselectionlnterval más reciente.

int getFixedCellHeight() int getFixedCellWidth() int getLastVisiblelndex()

int getLeadSelectionlndex()

int getMaxSelectionlndex() int getMinSelectionlndex()

Obtiene el índice máximo de la celda seleccionada. Obtiene el índice mínimo de la celda seleccionada. Obtiene el modelo de datos que contiene la lista de elementos de datos.

Dimension getPreferredScrollable ViewportSize() Object getPrototypeCellValue()

Calcula el tamaño delviewportnecesario para visualizar visibleRowCount filas. Obtiene el ancho de celda de la celda prototipo (una celda utilizada para el cálculo de anchos de celdas).

int getScrollableBlocklncrement(Rec- Obtiene la cantidad de incremento tangle visibleRect, int orientation, int de bloque. direction) boolean getScrollableTracksViewportHeight0 boolean getScroIlableTracksViewportWidth() int getScrollableUnitlncrement(Rectangle visibleRect, int orientation, int direction) int getSelectedlndex() Obtiene la altura de la pista del viewpori. Obtiene el ancho de la pista del viewpori. Devuelve el tamaño del tipo de letra de la lista Devuelve el índice del primer seleccionado. Devuelve una matriz con todos los índices seleccionados en orden creciente. Object getSelectedValue() Devuelve el primer valor seleccionado o nulo, si no hay selección. Devuelve una matriz de valores para las celdas seleccionadas. Color getSelectionBackground() Color getSelectionForeground() Obtiene el color de fondo de las celdas seleccionadas. Obtiene el color de primer plano.

int getSelectionMode()

Obtiene si están permitidas o no las listas simples o múltiples. Obtiene el valor del modelo de selección actual. Obtiene la apariencia que renderiza este componente. Obtiene el nombre de la clase UlFactory que genera la apariencia para este componente. Obtiene el valor de la propiedad valuelsAdjusting del modelo de datos. Devuelve el número preferido de filas visibles. Obtiene el origen del elemento indicado en coordenadas de JList. Devuelve nulo si el índice no es válido. Devuelve true si el índice seleccionado es el indicado. Devuelve true si no hay nada seleccionado. E s un método conveniente que únicamente delega en el modelo de selección. Convierte en un punto en coordenadas JList al índice de la celda en esa localización. Obtiene una representación de cadena de este objeto JList. Elimina al receptor de la lista que recibe notificación cada vez que ocurra un cambio en la selección. Establece la selección para que sea la diferencia como conjunto del intervalo indicado y la selección actual.

'

ListSelectionModel getselectionModelo ListUl getUI() String getUIClasslD()

boolean getValuelsAdjusting()

int getVisibleRowCount() Point indexToLocation(int index)

boolean isSelectedlndex(int index) boolean isSelectionEmpty()

int locationTolndex(Point location)

protected String paramString() void removeListSelectionListener (ListSelectionListener listener) void removeSelectionlnterval (int index0, int indexl)

void setCellRenderer (ListCellRenderer cellRenderer) void setFixedCellHeight(int height) void setFixedCellWidth(int width) void setListData(Object[] IistData)

Asigna el delegado que se utiliza para pintar cada celda de la lista. Define la altura de todas las celdas de la lista. Define la anchura de todas las celdas de la lista. Construye un modelo de lista a partir de una matriz de objetos y después aplica el setModel al modelo. Construye un modelo de lista a partir de un vector y después aplica setModel. Asigna al modelo que representa los contenidos de la lista y limpia la selección. Utilizado para calcular fixedcellWidth y fixedCellHeight. Selecciona una única celda.

void setListData(Vector IistData)

void setModel(ListModel model)

void setPrototypeCellValue (Object prototypeCellValue) void setSelectedlndex(int index) void setSelectedValue(0bject anobject, boolean shouldScroll) void setSelectionBackground (Color selectionBackground) void setSelectionForeground (Color selection Foreground) void setSelectionlnterval(int anchor, int lead) void setSelectionMode (int selectionMode) void setSelectionModel (ListSelectionModel selectionModel)

void setSelectedlndices(int[]indices) Selecciona un conjunto de celdas. Selecciona el objeto indicado de la lista. Asigna el color de fondo para las celdas seleccionadas. Asigna al color de primer plano para las celdas seleccionadas. Selecciona el intervalo indicado Determina si están permitidas Ii selecciones simples o múltiples Asigna al modelo de selección p la lista a la implementación no rbula del modelo de selección ListSellectionModel. Asigna el objeto que renderiza la apariencia de este componente.

void setUI(ListUI ui)

void setValuelsAdjusting(boolean b) void setVisibleRowCount (int visibleRowCount) void updateUl()

Asigna la propiedad isAdjusting del modelo d e datos a true. Asigna el número preferido d e filas en la lista que puede visualizarse sin una barra d e desplazamiento. Asigna la propiedad IU con el objeto ListUI a partir d e la clase UIFactory predeterminada.

Observe que puede obtener el índice del elemento seleccionado actualmente con el método getSelectedIndex d e la clase JList, selecciones múltiples con getSelectedIndices, el elemento seleccionado actualmente con getSelectedValue y los elementos seleccionados en el momento con getSelectedValues.

rnant iene rea lmente s u model o, por It3 que si deseamc n~ elemtrnto que no está se l e c ~ i oado, podlemos uti lizar el rr rr . s t se ~ ~ 1 para voten t del m01
1

1

L .

--

Haremos funcionar la clase JList en éste y los temas siguientes. Para comenzar, crearemos un ejemplo sencillo JList que únicamente visualice 12 elementos e informe sobre cuál de ellos se ha hecho clic. Comenzaremos creando un control de lista que contendrá esos elementos:
import java.awt.*; import javax.swing.*; import javax.swing.event.*;

public class list extends JApplet implements ~istSelectionListener
{

JList jlist; public void init()

Container contentpane = getContentPane0; String[l items = new String[l2]; for(int loop-index = 0; loop-index <= 11; loop-index++) items[loop-indexl = "Elemento " + loop-index;
1
{

jlist = new JList(items);

Después, añadimos este control de lista a un panel de desplazamiento para permitir el desplazamiento, lo configuraremos para que visualice cinco filas y añadiremos un receptor de selección para él:
public void init ( )
{

Container contentpane = getContentPane0; String[l items = new String[l2]; for(int loop-index = 0; loop-index <= 11; loop-index++) items[loop-index] = "Elemento " + loop-index;
{

1
jlist = new JList(items1; JScrollPane jscrollpane = new ~~croll~ane(jlist); jlist.setVisibleRowCount(5); jlist.add~ist~election~istener(thi~);

Ahora, en el método valuechanged, podemos utilizar el método getSelectedIndex para obtener el elemento sobre el que ha hecho clic el usuario y visualizar el número del elemento en la barra de estado:
public void valueChanged(ListSelectionEvent e)
(

String outstring = '~eleccionóel elemento: outstring += jlist.getSelectedIndex~); showStatus(outString); 1

";

Eso es todo lo que hace falta. Ahora, cuando el usuario hace clic sobre un elemento de la lista, el applet visualiza sobre qué elemento se ha hecho clic, como se muestra en la figura 13.11. Este ejemplo se encuentra en el archivo list-java del CD.

Observe, sin embargo, que existe más de una forma de seleccionar elementos en una lista; puede realizar selecciones múltiples también sobre listas. Examine el siguiente tema para conocer los detalles.

Iseleccionó el elemento 5

1

Figura 13.11. Gestión de selecciones en un control de lista.

Gestión de selecciones múltiples
Aparece el especialista de soporte a productos y comenta: "A los usuarios no les agrada el nuevo programa. Quieren reordenar doce productos a la vez, pero el control de lista del programa únicamente les permite ordenar uno". "iAH sí?", preguntamos. "Por tanto el gran jefe va a ser muy infeliz", dice el ESP. "Bien", decimos, "configuraremos un control de lista de selección múltiple".

Modos de selección de lista
Por defecto, existen tres modos de selección para los objetos JList y podemos asignar el deseado con el método setSelectionMode. Aquí tenemos los constantes que podemos pasar a este método y lo que significan: SINGLE-SELECTION. Selección simple.

SINGLEINTERVAL-SELECTION. Selección en un intervalo. El usuario puede seleccionar un único intervalo con elementos. MULTIPLE-INTERVAL-SELECTION. tiple.
Intervalos de selección múl-

Crearemos un control de lista de selección con intervalo múltiple y mostraremos cómo determinar qué elementos están seleccionados cuando el usuario

realiza una selección. Para comenzar, vamos a crear un control de lista como en el tema anterior, convirtiéndolo en un control de lista de selección de intervalo múltiple. Aquí tenemos el código:
import java.awt.*; import javax.swing.*; import javax.swing.event.*;

public classlistmultiple extends JApplet implements ListSelectionListener
{

JList jlist; public void init()
{

Container contentpane = getContentPane0; String[] items = new String[l2]; for(int loop-index = 0; loop-index <= 11; loop-index++) items[loop-index] = "Elemento " + loop-index;
{

1

jlist = new JList(items); JScrollPane jscrollpane = new JScrollPane(j1ist); jlist.setVisibleRowCount(5); jlist.set~election~ode(~ist~electionModel.M~~~~PLE~~~~~~~~~_SE ; jlist.add~istSelectionListener(this);

Ahora, cuando el usuario realiza una selección, podemos determinar qué elementos fueron seleccionados en el método valuechanged, utilizando el método getSelectedIndices, que devuelve una matriz con los índices seleccionados. El resultado final es que podemos informar de estos índices en la barra de estado del applet, como sigue:
public void value~han~ed(~istSelectionEvent e) i int[] indexes = j l i s t . g e t ~ e l e c t e d I n d i c e s 0 ; String outstring = "Su selección:";

for(int loop-index = 0; loop-index < indexec.length; loop-index++) { outstring += " elemento " + indexec[loop-index]; 1 showstatusioutStrins);

1

El resultado se muestra en la figura 13.12. El usuario puede hacer clic sobre un elemento para seleccionarlo y después utilizar la tecla Control para seleccionar otros elementos, o la tecla Mayús para seleccionar un intervalo de elementos. Siempre y cuando se realice una selección, el applet informa de la selección en su barra de estado, como se muestra en la figura 13.12. Este ejemplo es un éxito y aparece en el archivo 1istmultiple.java del CD.

u selección. elemento 1 elemento 3 elemento 4

Figura 13.12. Gestión de selecciones múltiples en un control de lista.

Visualización de imágenes en listas
"Tenemos que mejorar las cosas", dice el gran jefe, "la competencia está siendo demasiado dura". "Bien", preguntamos, "¿qué tal si añadimos más funcionalidades?". "Eso cuesta dinero", ruge el gran jefe. "Ajá", decimos, "supongo que podríamos visualizar imágenes en los controles de lista". "Perfecto", dice el gran jefe, "hagámoslo". Hacer que un control de lista de la Swing visualice imágenes no es tan fácil como añadir imágenes a una etiqueta de la Swing. En particular, tenemos que crear nuestro propio modelo y nuestra propia clase de volcado para el control de lista y lo haremos aquí. El resultado que buscamos se muestra en la figura 13.13. Este ejemplo se encuentra en el archivo1istimages.java del CD. Para gestionar imágenes en un control de lista, crearemos un nuevo modelo de control de lista, newModel, y un nuevo control de lista para volcar celdas, newRenderer. Para instalar el nuevo modelo, que contendrá la cadena de cada elemento de lista y el icono de imagen para cada uno de ellos,

podemos pasar un objeto de la clase newModel al constructor JList. Para instalar el nuevo volcador, podemos utilizar el método setCellRenderer. Aquí tenemos el código:
import java.awt . * ; import javax.swing.*; import java.awt.event.*;

public class listimages extends JApplet
{

public void i n i t 0

I
Container contentpane = getContentPane0; newModel newrnodel = new newModel0; newRenderer newrenderer = new newRenderer0; JList jlist = new JList(newrnode1); jlist.setCellRenderer(newrenderer); jlist.setVisibleRowCount(6);

Applet staried

1

Figura 13.13. Adición de imágenes a un control de lista.

Esto instala el nuevo modelo y renderizodor; lo único queda realmente e 4 crear las clases correspondientes y lo haremos en los dos temas siguientes.

Creación de un modelo de lista personalizado
La creación de un nuevo modelo para una lista no es difícil; todo lo que tenemos que hacer es almacenar nuestros datos utilizando el método addElement. En este caso, crearemos el nuevo modelo para el ejemplo de lista del tema anterior, que visualizará imágenes y texto en un control de lista. En este caso, solamente haremos que cada elemento del modelo sea una matriz de dos elementos; el primer elemento de la matriz contendrá el texto para el elemento de lista y el segundo elemento de la matriz contendrá el icono de imagen para el elemento de lista. Aquí tenemos el código:
class newModel extends DefaultListModel

I
public newModel ( )
(

foríint loop-index = 0; loop-index <= 12; loop-index++) addElement(new Object[l {"Elemento ' + loop-index, ; new ImageIcon("item.jpg")}) 1 1

{

1

Esto es todo. Ahora hemos creado un nuevo modelo para un control de lista. Para dibujar realmente el icono de la imagen, sin embargo, tenemos que procesar nosotros mismos el volcador de la celda. Lo haremos en el tema siguiente.

Creación de un renderizador personalizado para celdas de lista
Cada elemento de lista es realmente de clase JLabel, por lo que podemos utilizar los métodos de JLabel, como setText y setIcon, para visualizar imágenes en las celdas de la lista. Aquí, lo haremos mediante la creación de un nuevo renderizador de celda que dibujará los elementos en la lista que ya hemos desarrollado en los dos temas anteriores. Para crear un renderizador de celdas, tenemos que implementar la interfaz ListCellRenderer, que tiene únicamente un método: getListCellRendererComponent. Este objeto recibe el objeto a volcar (que en este caso es la matriz bidimensional que contiene el texto e icono del elemento) y devuelve un renderizador de celda. Aquí tenemos el resultado del

código (observe que también indicamos si está seleccionado un e l e m e n t q asignando su fondo):
class newRenderer extends JLabel implements ListCellRenderer
{

public newRenderer0
{

setopaque (true) ;
)

public Component getListCellRendererComponent( JList jlist, Object obj, int index, boolean isselected, boolean f ocus)
{

newModel model

=

(newModel)jlist.getModel();

setTexti (String)((ObjectLl)obj) [O11 ; setIconi (Icon)( (Object []) obj) [l]) ;

return this;
} }

Eso es todo. Ahora el control de lista visualizará imágenes, como s q muestra en la figura 13.13. Este ejemplo se encuentra en el archivo 1istimages.java del CD.

Procesamiento de doble clic en listas
Dice el programador novato: "Quiero permitir que el usuario lance d elemento desde un control de lista al hacer doble clic sobre él, pero el método valuechanged de la interfaz ListSelectionListener se llama para clics senci- 1 110s y no puedo decir si la lista ha recibido un clic doble". "Bien", decimos, 1 I "Puede utilizar los clics del ratón para interceptar los clics dobles". El progra- I l mador novato dice, "¿De verdad? ¡Dígame más!" Si interceptamos los eventos de ratón, podemos determinar el número del clics de ratón y, accediendo al modelo de la lista, podemos determinar cuál 1 fue el elemento sobre el que se hizo clic.

/

Vamos a verlo en el código. Aquí, únicamente añadimos una lista con varios elementos a un applet y después añadimos un receptor de ratón a la lista:
import java.awt.*; import javax.swing.*; import java.awt.event.*;

public class listdouble extends JApplet implements MouseListener
{

public void init (
(

) =

Container contentpane

getContentPane0;

String[] items = {"Elemento l " , "Elemento 2 " , "Elemento 3 " , "Elemento 4 " , "Elemento 5 " , "Elemento 6 " , "Elemento 7 " , "Elemento E " , "Elemento 9 " , "Elemento l o " , "Elemento 11", "Elemento 12 " } ; JList list = new JLiStiitemS);

Ahora, en el método mouseClicked, determinamos dónde se hizo doble clic con el ratón; entonces utilizamos el método locationToTndex de la lista para determinar el elemento de la lista sobre el que se hizo clic. Finalmente, podemos determinar cuántas veces se hizo clic sobre el elemento con el método getClickCount de MouseEvent y, por tanto. informar del número de veces que se hizo clic sobre un elemento, como a continuación:
public void mouseClicked(MouseEvent e )
(

JList jlist = (JList)e.getSourceO; int index = jlist.locationToIndex(e.get~oint0) ;

String outstring

=

new String( "Número de clics para el elemento'

public public public public
1

void void void void

mouseEntered(MouseEvent e) { } mouseExited(MouseEvent e) { 1 mousePressed(MouseEvent e) { 1 mouseReleased(MouseEvent e ) I )

El resultado se muestra en la figura 13.14. Como vemos, el applet informa? del número de clics que se realizan sobre un elemento de lista cada vez. De esta forma, podemos manejar clics dobles e incluso triples. Este ejemplo se encuentra en el archivo 1istdouble.java del CD.

l ~ u m e r o clicc para el elemento Elemento 4 2 de

1

Figura 13.14. Gestión de doble clic en un control de lista.

barras d e progreso. veremos algunos controles importantes de la Swing: cuadros combinados. Cuadros combinados Los cuadros combinados son uno de los controles más importantes en la programación de la IU. separadores y selectores. Los cuadros combinados también son controles muy compactos. pero el AWT no tiene un cuadro combinado.m Swing: barras. Son muy útiles. separadores y selectores En este capítulo. especialmente los cuadros combinados. debido a que muestran únicamente un elemento y un botón que el . ya que permiten al usuario tanto seleccionar un elemento de la lista como introducir su propio valor en el campo de texto. Los cuadros combinados con combinaciones de campos de texto y listas desplazables. Todos estos temas. unas pequeñas ventanas que muestran un texto de explicación cuando dejamos el ratón sobre un control. son importantes en Java y los introduciremos antes de profundizar en el código. También examinaremos la adición de herramientas de ayuda. La Swing rectifica esto. herramientas. cuadros.

Examinaremos todas sus posibilidades en este capítulo. y han pasado a ser muy populares por esa razón. originalmente introducidas como mecanismo para mostrar el progreso de un programa de instalación. Los selectores de archivos permiten al usuario seleccionar un archivo para abrir o guardar algo. ya que tienen únicamente una función: mostrar el progreso de una tarea. como descargas de archivos desde la red Internet. se utilizan ahora para todo tipo de operaciones de consumo de tiempo. De hecho. de forma similar a como lo hace el mercurio en un termómetro. Podemos utilizar inmediatamente en los programas el selector de color. Ambos selectores representan cuadros de diálogo estándar y Sun únicamente nos ahorra tiempo al crearlos. la Swing soporta cuadros de diálogo. Al contrario que la AWT. ya que el valor predeterminado para los cuadros combinados sería hacerlos no editables. para mostrar visualmente cómo progresa una operación. la Swing tiene como valor predeterminado del cuadro combinado que muestre únicamente una lista desplegable. Las barras de progreso. las barras de progreso siguen siendo controles sencillos. Selectores Como en la AWT. lo que los convierte en listas desplegables. Las barras de progreso muestran una barra coloreada dentro de ellas que crece (o se reduce). Barras de progreso Las barras de progresos son controles relativamente nuevos. Trabajaremos con ambos selectores en este capítulo. seleccionar los colores y etiquetas que use en ellas y manejar sus eventos. pero para utilizar los archi- . Los selectores de color permiten al usuario seleccionar un color entre muchos.usuario puede utilizar para desplegar la lista de otros elementos. proporcionando al usuario un mecanismo incluso aún más compacto para visualizar los elementos de una lista que el que proporciona un cuadro de lista. Los cuadros combinados pueden funcionar como listas desplegables. muy similar a cualquier cuadro de diálogo de archivos estándar. Y aún más. Puede orientar las barras de progreso tanto horizontal como verticalmente. que se han hecho populares como mecanismo para proporcionar al usuario la indicación del progreso de una operación larga. la Swing también soporta adicionalmente varios cuadros de diálogo que no tenemos que crear o personalizar nosotros mismos: selectores de archivos y selectores de color.

dice el PN. dice el programador novato. podrá utilizar separadores en componentes JApplet y JFrame como cualquier otro control. Los cuadros combinados se pueden utilizar en la Swing de dos formas: como cuadros combinados normales y como listas desplegables. Es el momento de pasar al primer punto que comienza con los cuadros combinados. Herramientas de ayuda Las herramientas de ayuda son esas ventanas pequeñas que aparecen y muestran un texto de explicación (como por ejemplo Descargar ahora o Abrir nueva carpeta) cuando se detiene el ratón sobre un control. Las listas desplegables permiten al usuario seleccionar en una lista que aparece cuando . vendrá mucho más. Creación de cuadros combinados "Mmh". Por otro lado. "quiero permitir al usuario seleccionar una palabra para realizar un análisis sintáctico a partir de una lista de palabras. ¿qué tal si utiliza un cuadro combinado?" "Bien". Este es el resumen de lo que aparece en este capítulo.vos que devuelve el selector de archivos. "Suena razonable. por ejemplo) pueden ser contraproducentes y dar una apariencia de dificultad a su programa. "¿puede añadir uno a mi código?". como veremos más adelante. Lo único que tiene que hacer el usuario es dejar el ratón sobre su programa para ver qué es lo que hacen los distintos controles. Aunque se utilizan mayoritariamente en los menús para dividir elementos de menú en agrupaciones lógicas. Separadores Los separadores son barras horizontales o verticales que le permiten organizar sus controles en grupos. Las herramientas de ayuda pueden ser muy útiles debido a que los usuarios de la IU tienen una gran resistencia a leer los manuales. Como puede ver. tendremos que esperar unos pocos capítulos (hasta que comencemos a trabajar con archivos). pero ahora los usuarios dicen que quieren introducir sus propias palabras también". tenga en cuenta que muchas herramientas de ayuda (conectadas con muchos elementos de texlo en un control de texto.

. únicamente se puede seleccionar un elemento a la vez en un cuadro combinado.3 sus métodos. Observe que para añadir o eliminar elementos.4. puede utilizar el método getModel del JComboBox. que e s responsable del campo de texto. Indica s el cuadro combinado e s editai ble. Campos de la clase JComboBox. por otra parte. El modelo de datos. El editor. El gestor de selección de teclas. Indica si la lista desplegable está habilitada como componente de poco peso. Puede encontrar los métodos de este objeto en la tabla 14. la tabla 14.2 muestra sus constructores y la tabla 14. protected String actioncommand protected ComboBoxModel dataModel protected ComboBoxEditor editor protected boolean isEditable protected JComboBox. Los datos actuales del cuadro combinado se almacenan en su modelo.1. Observe que al contrario de los cuadros de lista. Los cuadros combinados están soportados por la clase JComboBox en la Swing y aquí tenemos el diagrama de herencia para esta clase: La tabla 14.hace clic sobre la flecha que apunta hacia abajo. los usuarios pueden seleccionar un elemento de la lista desplegable o introducir su propio texto en el campo de texto. Los cuadros combinados normales. que es un objeto de la clase DefaultComboBoxModel predeterminado. Tabla 14. puede utilizar los métodos del modelo.Key SelectionManager keyselectionManager protected boolean IightWeight PopupEnabled El comando de acción.1 muestra los campos de la clase JComboBox. como se muestra en la tabla. Para obtener el objeto del modelo. son combinaciones de campos de texto y listas desplegables.

Añade un receptor de acciones.2. Añade un receptor de elementos. protected ListCellRenderer renderer protected Object selectedltem Reminder El renderizador de celdas. Constructores de la clase JComboBox. JComboBox(Vector items) Tabla 14. Tabla 14. void actionPerformed (ActionEvent e) void addActionListener (ActionListener 1 ) void addltem(0bject anobject) void addltemListener(ltemListener alistener) void configureEditor(ComboBox Editor anEditor. Construye un objeto JComboBox. Construye un objeto JComboBox que contiene los elementos en el vector indicado. Métodos de la clase JComboBox. Un recuerdo del elementoseleccionado. Añade el elemento a la lista de elementos. JComboBox(ComboBoxModel aModel) JComboBox(Object[] items) Construye un objeto JComboBox que toma elementos de un modelo de cuadro combinado ya existente.protected int maximumRowCount Contiene la cuenta de filas. .3. Construye un objeto JComboBox que contiene los elementos en la matriz indicada. Object anltem) void contentschanged (ListDataEvent e) Público como implementación de un efecto lateral. Inicializa el editor. Público como implementación de un efecto lateral.

Notifica a todos los receptores que han registrado interés en la notificación de este tipo de evento. Obtiene el editor utilizado para editarel elemento seleccionado del campo de texto JComboBox. Obtiene el comando de acción. Obtiene la lista de elementos en el índice indicado. Obtiene el elemento seleccionado actual. Obtiene el modelo de datos.KeySelectionManager Obtiene el gestor de selección de teclas getKeySelectionManager() de la lista. ComboBoxModel getModel() ListCellRenderer getRenderer() int getSelectedlndex() Object getSelectedltem() . Obtiene el índice del elemento actualmente seleccionado.Key SelectionManager createDefault KeySelectionManager() protected void fireActionEvent() Obtiene en instancia del gestor de selección de teclas predeterminado. int getMaximumRowCount() Obtiene el máximo número de elementos que puede visualizar a la vez un cuadro combinado. Obtiene el renderizador. Notifica a todos los receptores que han registrado interés para la notificación en este tipo de evento. Obtiene una matriz que contiene los elementos seleccionados. String getUIClasslD() Obtiene el nombre de laclase apariencia que renderiza éste componente. protected void fireltemstate Changed(1temEvent e) AccessibleContext getAccessible Contexto String getActionCommand() ComboBoxEditor getEditor() Object getltemAt(int index) int getltemCount() JComboBox. Obtiene los elementos de la lista.protected JComboBox. Obtiene el objeto apariencia que renderiza este componente. Obtiene el contexto accesible.

void rernoveltemListener (ItemListener aListener) . Invocado cuando los elementos se añaden al modelo de datos interno. Determina la visibilidad del cuadro emergente. void rernoveltemAt(int anlndex) Elimina elemento en el index. Devuelve cierto si el componente puede recibir el foco. Elimina al receptor de elementos. int index) protected void installAncestor Listener() void intervalAdded (ListDataEvent e) void intervalRemoved (ListDataEvent e) boolean isEditable() boolean isFocusTraversable() boolean isLightWeightPopupEnabled() Provoca que el cuadro combinadocierre su ventana emergente. lnvocadocuando los valores se han eliminado de un modelo de datos. buscando la tecla Tab. Devuelve falso si se utilizan diálogos emergentes de más peso. boolean isPopupVisible() protected String paramString() void processKeyEvent(KeyEvent e) Procesa a eventos de teclas. void removeActionListener (ActionListener 1 ) void removeAll ltems() Elimina un receptor de acción. Inserta elementos en la lista de elementos en un índice dado.void hidePopup() void insertltemAt(0bject anobject. void rernoveltem(0bject anobject) Elimina un elemento de la lista de elementos. Instala un receptor padre. Obtiene una representación de cadena para este objeto JComboBox. Elimina todos los elementos de la lista de elementos. Devuelve cierto si los cuadros emergentes de poco peso se utilizan. Devuelvecierto si el objeto JComboBox es editable. Este método funciona únicamente si el objeto JComboBox utiliza el modelo de datos predeterminado.

void insertElementAt(0bject anOb. Aquí tenemos el código: import java. basta crear un cuadro combinado y cinco elementos (es decir. ject. int index) void removeElementAt(int index) Elimina un elemento en un índice específico. Tabla 14.protected void selectedltemchanboolean selectWithKeyChar(char keyChar) void setActionCommand(String acommand) void setEditable(boolean aFlag) Llamado cuando cambia el elemento seleccionado. import javax. Veamos un ejemplo que muestra cómo funciona. Asigna el elemento seleccionado. Obtiene el valor en el índice indicado. Asigna el comando de acción que debería incluirse en el evento enviado a los receptores de acción. Selecciona el elemento de la lista que corresponde al carácter de teclado indicado.awt. 1 void setSeIectedItem(0bject anObject) Para añadir elementos a un cuadro combinado.*. cinco objetos String).class . pasándole un objeto que a su vez pasará a su modelo interno.Añade un elemento al final del modelo.*. /* <APPLET CODE = combobox. Devuelve el elemento seleccionado. 1 I I I int getlndexOf(0bject anobject) Obtiene la posición del índice del objeto indicado en la lista.swing. puede utilizar el convei niente método addItem. Asigna el indicador de edición. En este caso. 1 1 Object getElementAt(int index) 1 Object getSelectedltem() 1 int getSize() void addElement(0bject anobject) Añade un elemento al final del modelo. Métodos de la clase DefaultCornboBoxModel. Obtiene la longitud de la lista.4.

donde puede ver el cuadro combinado con su lista desplegable abierta. Creación de un cuadro combinado. mostrando los cinco elementos. pub1 ic void init ( ) I Container contentpane = getContentPane0. Cuando el usuario selecciona un elemento de esa lista y suelta el botón del ratón. por defecto.WIDTH = 200 HEIGHT = 200 > < /APPLET> */ public class combobox extends JApplet ( private JComboBox j c o m b o b o x = n e w JComboBox ( ) .1. el campo de texto en el cuadro combinado no es editable. El resultado se muestra en la figura 14. Este ejemplo se encuentra en el archivo combobox. Observe que. el elemento queda como nuevo elemento seleccionado en el cuadro combinado y también aparece en el campo de texto. Figura .java del CD que acompaña a este libro. Por tanto. mostraremos cómo cambiarlo en unas pocas páginas. jcómo recuperar elementos de un cuadro combinado? Debido a que únicamente se puede seleccionar al mismo tiempo un elemento de un .

"Quiero cambiar el color de dibujo en mi nuevo programa tan pronto como el usuario seleccione un nuevo color de un cuadro combinado. ¿cómo puedo hacerlo?".awt. dice el PN. basta con añadir un receptor de elementos al cuadro combinado del ejemplo desarrollado en el tema previo: import java.*. como sigue: String outstring = (String)jcombobox. "basta con hacer que el código responda a eventos de selección". Observe que también puede responder a los eventos del cuadro combinado.getSelectedItemO int index = (String) jcombobox. respondemos. Para manejar eventos de selección. puede obtener ese elemento con el método get~elected~temT que devuelve el mismo elemento (observe que el elemento es un objeto).class WIDTH = 300 HEIGHT = 2 0 0 > < /APPLET> */ public class comboboxevents extends JApplet implements ItemListener . import java. Manejo de los eventos de selección del cuadro combinado El programador novato vuelve y dice.*. Puede utilizar dos tipos de receptores con cuadros combinados: receptores de acción para manejar eventos de edición en el cuadro de texto y receptores de elementos para manejar selecciones d e listas. También puede utilizar los métodos insertElementAt y removeElementAt del modelo para editar la lista. utilice el método getElementAt del modelo.awt.swing. import javax.cuadro combinado. Lo examinaremos en el siguiente tema. Examinaremos las selecciones de listas en este tema y los eventos de edición en el siguiente. ¿puede arreglarlo?". "Aquí tiene mi código. También puede utilizar getSelectedIndex para determinar el índice del elemento seleccionado en curso en el cuadro en la lista del cuadro combinado.event.*.getSelectedIndex0 Para obtener un elemento en un índice específico. "Es fácil". <APPLET CODE = comboboxevents. "Ajá".

addItem("Elemento 5 " ) .getStateChange() == ItemEvent-SELECTED) Indicaremos si un elemento estaba seleccionado o deseleccionado en la barra de estado del applet como sigue: public void itemStateChanged(1temEvent e) I if(e. public void init0 I Container contentpane = getContentPane0.addItem("Elemento 4").addItem("Elemento 1")..{ JComboBox jcombobox = new JComboBoxO. jcombobox. Ahora añadimos el método itemStateChanged a este applet que necesita la interfaz ItemListener: public void itemStateChanged(1temEvent e) I . String outstring = " " . jcombobox. jcombobox.getStateChange0 == 1temEvent.getItemo. jcombobox. else outstring += "Deseleccionado: + (String)e.getItemO..addItem("Elemento 3" ) . .SELECTED) outstring += "Seleccionado: " + (String)e. 1 Este método recibe un objeto de la clase ItemEvent y puede determinar si el elemento correspondiente en la lista del cuadro combinado estaba seleccionando. addItem ( "Elemento 2 " ) . jcombobox. utilizando el método getStateChange como sigue: public void itemStateChanged(1temEvent e) I if(e.

"Ah". Como puede ver en el pie del applet de la figura. "Eso es debido a que lo tiene como editable". import java. Figura 14. Este programa es un éxito y se encuentra en el archivo comboboxevents.2. Creación de cuadros combinados editables "Maldición". utilice el método setEditable. el código informa cada vez que el usuario deselecciona un elemento y selecciona otro. import javax.swing.*. Sonreímos y contestamos.awt. Trabajo con eventos de selección del cuadro combinado. utilice un receptor de acciones. "¿Cómo puedo hacerlo?". * . dice el PN. parece que no puedo introducir ningún texto en él". awt . /* <APPLET CODE = comboboxedit. Para manejar eventos de edición. Aquí tenemos un ejemplo donde hacemos el cuadro combinado editable y le añadimos un receptor de acción: import j ava .class WIDTH = 2 0 0 HEIGHT = 2 0 0 > < /APPLET> */ public class comboboxedit extends JApplet implements ActionListener { .*.El resultado de este código se muestra en la figura 14. "no puedo hacer que el campo de texto de mi cuadro combinado funcione.2.event.java del CD. Para convertir el campo de texto en un cuadro combinado editable. dice el programador novato.

mostramos el texto del elemento antes de que se haya editado y el texto después de que haya sido editado y el usuario pulse Intro. . como muestra la figura. Observe que no estamos añadiendo un receptor de acción al cuadro combinado directamente sino.getItemo . El editor es responsable de las acciones de edición en el campo de texto del cuadro combinado.5 muestra los métodos de ComboBoxEditor. al editor del cuadro combinado. En este ejemplo. más bien. Para obtener el texto del elemento antes de su edición. puede utilizar el método getSelectedItem y para obtener el elemento después de su edición.private JComboBox jcombobox = new JComboBox().java del CD.3 muestra el resultado. Este ejemplo se encuentra en el archivo comboboxedit. el texto viejo y nuevo del cuadro combinado aparecen en la barra de estado del applet. public void h i t 0 ( Container contentpane = getContentPane0. puede utilizar el método getItem. Obtenemos este objeto con el método getEditor. Cuando el usuario edita un elemento en el campo de texto y pulsa Intro.getSelectedItemO + se cambió a " + (String)jcombobox.getEditor0 . como sigue: public void actionPerformed(ActionEvent e) { String outString = (String)jcombobox. que es un objeto que implementa la interfaz ComboBoxEditor. La figura 14. y la tabla 4.

Elimina al receptor d e acciones. Devuelve el elemento editado. Aquí vemos cómo instalarlo en el cuadro combinado: .Tabla 14. para un cuadro combinado. Edición del campo d e texto d e un cuadro combinado. "jexiste alguna posibilidad de mostrar imágenes en un cuadro combinado?" "Claro".3. cuando añade imágenes a los cuadros combinados. Métodos de la interfaz ComboBoxEditor void addActionListener(ActionListener 1) Añade un receptor de acciones.5. Solicita al editor el inicio d e la edición y selecciona todo. decimos. Aquí tenemos un ejemplo en el que creamos un nuevo modelo. Asigna el elemento que debería ser editado. y el renderizador de celdas. por lo que el proceso es prácticamente igual que añadir imágenes a las listas. Puede añadir imágenes a cuadros combinados al igual que puede hacerlo con cuadros de lista. newMode1. "basta con sentarse y examinarlo". dice el programador novato. Adición de imágenes a cuadros combinados "Veamos". Component getEditorComponent() Object getltem() void removeActionListener(ActionListener 1) void selectAll() void setltem(0bject anobject) Devuelve el componente del editor. newRenderer. realmente añade imágenes a la parte de lista del cuadro combinado. o 1 se cambió a Elemento 15 1 Figura 14. De hecho.

J C d o B o x jlist = new JComboBox(newmode1). Este ejemplo se encuentra en el archivo comboimages. Figura 14. import java.*.class WIDTH = 400 HEIGHT = 2 0 0 > < /APPLET> */ public class cornboimages extends JApplet I public void init ( ( Container contentpane = getContentPane0. nemenderer newrenderer = new newRenderer0.4. Ahora.java del CD. jlíst.awt. /* <APPLET CODE = comboimages. Adición de imágenes a cuadros combinados.swing. import javax. nemodel ne-del = new newModel ( ).setLayoutínew FlowLayoutO) .4 muestra el resultado.import java. contentPane. m .*.event.*. lo único que resta es crear el nuevo modelo y el nuevo renderizador y lo haremos en los dos temas siguientes.setRenderer(ne=enderer). Este nuevo modelo y renderizador almacenará y visualizará las imágenes en un cuadro combinado y la figura 14.awt.

Cada elemento se compone de una cadena de texto y un icono de imagen' como sigue: class newModel extends DefaultComboBoxModel I public newModel0 I for(int loop-index = 0. Este nuevo modelo.Creación de un modelo de cuadro combinado Crearemos un nuevo modelo de cuadro combinado en este tema p a r a utilizarlo con el cuadro combinado del tema anterior (el que visualiza imágenes). sobrescribimos el método getListCellRendererComponent utilizando los métodos setText y setIcon de la clase JLabel para instalar el texto e imágenes en el cuadro combinado: class newRenderer extends JLabel implements ListCellRenderer { public newRenderer0 public Component getListCellRendererComponent( JList jlist.jpg " ) 1 ) . que es la clase de cada elemento en un cuadro combinado. boolean isselected. loop-index <= 12. crearemos un renderizador que visualice imágenes en un" cuadro combinado (este renderizador se utiliza en el código de los dos temas anteriores). Object obj. e implementar la interfaz ListCellRenderer. Para implementar esa interfaz. int index. boolean focus) . 1 > } Creación de un renderizador personalizado para el cuadro combinado En este tema. loop-index++) ( addElement(new Object[l {"Elemento " + loop-index. basta extender la clase JLabel. Para crear el renderizador de celdas para un cuadro combinado. new ImageIcon ( "combo. que extiende la clase DefaultComboBoxModel. utilizará el método addElement para almacenar los elementos de datos en el modelo.

"iClaro! ". dice el programador novato.4. donde puede ver las imágenes visualizadas en un cuadro combinado. "a menos que le dé algún tipo de indicación visual d e lo que sucede. o puede utilizar los métodos setMinimum y setMaximum.getModel(). Creación de barras de progreso "Bien". "es cierto que lleva tres horas el que mi programa ordene sus datos internos. "¿Qué es una barra de progreso?" Un control de barra de progreso dibuja una barra coloreada y actualizada dentro de sí mismo para visualizar el progreso de alguna operación. setTexti (String) ((Objectrl)obj)[O]) : setIcon( (Iconi ((Object[l )obj) [l]) . ¿Qué tal si añadimos una barra de progreso a su programa?". Puede actualizar repetidamente la barra de progreso llamando a su método setValue para indicar el estado progresivo de la operación. Puede configurar los valores mínimo y máximo de la barra de progreso cuando llama al constructor JProgressBar. pero ¿existe alguna razón para que los usuarios lo comprendan?" "Por supuesto". Aquí tenemos el diagrama de herencia para la clase JProgressBar: . return this. decimos. 1 \ 1 El resultado se muestra en la figura 14.dice el PN.newModel model = (newModel)jlist.

Tabla 14. JProgressBar(BoundedRangeModel newModel) JProgressBar(int orient) Construye una barra de progreso horizontal (orientación predeterminada). Constructores de la clase JProgressBar. Cadena opcional que puede mostrarse en la barra de progreso.8. Devuelve cierto si debe existir un borde alrededor de la barra de progreso. protected ChangeListener change. que es la predeterminada. Construye una barra de progreso horizontal. Construye una barra de progreso horizontal.El receptor de cambio. protected String progressstring Tabla 14.VERTICAL o JProgressBar. protected ChangeEvent changeEvent El evento de cambio. que puede ser o bien JProgressBar. JProgressBar(int min. La orientación en que se visualiza la barra de progreso. Campos de la clase JProgressBar. int max) .7. Listener protected BoundedRangeModel model protected int orientation protected boolean paintBorder protected boolean paintstring El modelo de datos que contiene los valores de datos para la barra de progreso.Puede encontrar los campos de la clase JProgressBar mostrados en la tabla 14.7 y sus métodos se muestran en la tabla 14. sus constructores se muestran en la tabla 14.6. Construye una barra de progreso con la orientación indicada.HORIZONTAL. Devuelve cierto si debe existir una etiqueta de cadena en la barra de progreso.6 (observe que también hereda dos constantes de la clase SwingConstants que utilizamos para la orientación: HORIZONTAL y VERTICAL).

String getU IClasslD() int getValue() boolean isBorderPainted() boolean isStringPainted() Obtiene el nombre de laclase apariencia que renderiza este componente.HORIZONTAL. Obtiene el modelo de datos.Obtiene el contexto accesible asociado con este objeto JComponent. Devuelve JProgressBar. Métodos de la clase JProgressBar. protected void fireStateChanged0 Notifica a todos los receptores que registraron interés para la notificación de este tipo de evento.VERTICAL o JProgressBar.8. Obtiene el valor mínimo del modelo. Devuelve cierto si la barra de progreso tiene un borde y falso en otro caso. - void addChangeListener(ChangeListener 1 ) protected ChangeListener create ChangeListenerO Añade un receptor de cambios. Obtiene el porcentaje completado para la barra de progreso. . Contexto int getMaximum() int getMinimum() BoundedRangeModel getModel() int getOrientation0 double getPercentComplete() String getString0 Obtiene el valor máximo del modelo. Construye una barra de zando la orientación y los valores mínimo y máximo indicados. Obtiene el valor actual del modelo. Tabla 14. AccessibleContext getAccessible. Devuelve cierto si la cadena se va a dibujar en la barra de progreso. Obtiene el valor en curso de la cadena de progreso.orient. Crea un receptor de cambios. Obtiene el objeto apariencia que renderiza este componente. int min.

y más. También puede seleccionar el color de dibujo para l a barra actual. 1 void setValue(int n) void updateUI() Existen diversas formas de visualizar las barras de progreso. E l uso básico de todas las barras de progreso. Aquí tenemos unos pocos ejemplos que muestran algunas de las formas en que podemos mostrar las barras de progreso: . Asigna el valor mínimo del modelo a n.Elimina un receptor de cambios del bogeListener l) tón. Asigna el objeto apariencia que renderiza este componente. Por ejemplo. visualizar la etiqueta dentro de l a barra de progreso que indique el valor en curso. void setBorderPainted(booleanb) Asigna si la barra de progreso debería pintar su borde. void removeChangeListener(Chan. Asigna si la barra de progreso renderiza una cadena. Asigna la orientación de la barra de progreso a neworientation. asignamos un valor mínimo y máximo a l a barra de progreso (los valores predeterminados son O y 100) y actualizamos su pantalla con el método setValue según convenga. Asigna el valor máximo del modelo a n. es el mismo sin importar l a apariencia que tengan. Obtiene una representación de cadena del objeto JProgressBar. puede hacerlas horizontales o verticales cuando llama al constructor de la clase o utilizar el método setorientation. 1 void setMaximum(int n) 1 void setMinimum(int n) void setOrientation(int neworientation) void setString(String S) void setStringPainted(boolean b) void setUI(ProgressBarUI ui) void setModel(BoundedF4angeMo. Llamada por la clase UlFactory para indicar que la apariencia ha cambiado. no obstante.Asigna al modelo de datos utilizado por del newModel) el objeto JProgressBar. Asigna el valor de la cadena de progreso.protected void paintBorder(Graphics g) protected String paramString() Pinta el borde de la barra de progreso (siempre que la propiedad BorderPainted sea cierto). Asigna el valor actual del modelo a n.

setForegroundíColor.red).~etOrientation(JProgreseBa). jprogressbar3.add(jprogressbar5). jprogressbar4.createRaisedBevelBorder~)).class WIDTH = 500 HEIGHT = 200 > </APPLET> */ public class progressbar extends JApplet I JProgressBar jprogressbarl.awt. jprogressbar5.setValue(80). jprogressbar4.setBorder(BorderFactory.add(jprogressbar3).setOrientation(JProgreasBar.~etStringPainted(true).~etString("~Hola desde Swingl").*.import java.VeRTICAL).setValue(50).~etStringPainted(true). contentPane. jprogressbar4 = new JProgressBarO.add(jprogressbar2). jprogressbar3.setOrientation(JProgressBar. jprogressbar4. contentPane. jprogressbar2. jprogressbar3.setValue(90). jprogressbar2 = new JProgressBar(). public void init O I Container contentpane = getContentPane0.~etMinimum(lOO). jprogressbar5.*: /* <APPLET CODE = progressbar. jprogressbar3. jprogressbar5. .blue).~etstringPainted(true).setValue(50). jprogressbar2. jprogressbar2. jprogressbar3. import javax. jprogressbarl.add(jprogressbar1).swing. contentPane. jprogressbar4. contentPane. jprogressbar2. j~rogressbar5. jprogressbar4.~etBorderPainted(false): contentPane. jprogressbar5. jprogressbar5 = new JProgressBarO. jprogressbar3 = new JProgressBar().~etMaximum(200).add(jprogressbar4). jprogressbar2.setValue(180).VeRTICAL).setForegroundíColor. jprogressbar6. jprogressbar3.red). jprogressbarl = new JProgressBarO. jprogressbar4.setForeground(Color.

import javax. "eso se debe a que tiene que llamar al método setValue para actualizarlas". he puesto barras de progreso en m í programa. donde puede ver varias barras de progreso visualizadas de formas distintas. que puede añadir una etiqueta a la barra de progreso para indicar su configuración actual y puede personalizar el borde). respondemos. ¿qué está mal?" "Bien". dice el PN. es cuenta del programador actualizarla con el método setvalue. . Después de la creación y visualización de una barra de color de progreso.awt. import java.awt.5. "Vaya.*.El resultado de este código se muestra en la figura 14.*.5. Normalmente lo haremos dividiendo la tarea que consuma tiempo en partes y actualizaremos la barra de progreso a medida que se complete cada parte. Para ver cómo actualizar una barra de progreso. Actualización de barras de progreso El programador novato dice. Aquí tenemos un ejemplo (progressbarupdate.java en el CD) que incrementa una barra de progreso cada vez que se pulsa un botón: import java. las barras de progreso estáticas. como las que muestra la figura 14.swing. "Ajá". Visualización de barras de progreso.5. en concreto. Por otro lado. pero no hacen nada. Figura 14. Este ejemplo se encuentra el en archivo progressbar. Aquí tenemos muchas posibilidades (observe.event.*. no tienen mucha utilidad ya que no hacen nada. examine el tema siguiente.java del CD.

su código actualizará la barra de progreso automáticamente. jbutton. m .class WIDTH = 400 HEIGHT = 200 > c/APPLET> */ public class progressbarupdate extends JApplet ( JProgressBar jprogressbar = new JProgressBarO.6. por supuesto. 1 >). JButton jbutton = new JButtoní"1ncrementar la barra de progreso") . Figura 14. Actualización de una barra de progreso.6. Observe que puede actualizar la barra de progreso solamente haciendo clic sobre el botón. debido a que las barras de progreso se utilizan para indicar al usuario el progreso de las operaciones que consumen tiempo. Normalmente.cAPPLET CODE = progressbarupdate. public void init ( ) I Container contentpane = getContentPane0.setValue(jprogressbar.getValue() + 10). El resultado se muestran en la figura 14.addActionListener(new ActionListenerO ~ u b l i cvoid actionPerformed(ActionEvent e) { { jprogressbar.

Manejo de los eventos de barras de progreso Los eventos de barras de progreso ocurren cada vez que el valor de la barra de progreso cambia. jbutton. javax. jprogressbar.*. <APPLET CODE = progressbarevents.*. JButton jbutton = new JButton("1ncrementar la barra de progreso").awt. javax.setValue(jprogressbar.swing.java en el CD) que permite al usuario actualizar la barra de progreso con un botón.addChange~istener(new ChangeListenerO { public void statechanged(ChangeEvent e) i showStat~s(~Mínimo de la barra de progreso: jprogressbar getMinimum() + . Captura los eventos a medida que suceden.*.class WIDTH = 400 HEIGHT = 200 > < /APPLET> */ public class progressbarevents extends JApplet I JProgressBar jprogressbar = new JProgressBar(). 1 1). java.event.getValue0 + 10). public void init í ) I Container contentpane = getContentPane0. como se muestra a continuación: import import import import /* java.addActionListener(new ActionListenerO public void actionPerformed(ActionEvent e) { { jprogressbar. Aquí tenemos un ejemplo (progressbarevents. junto con sus valores mínimo y máximo.event.swing.*. y podemos trabajar con receptores de cambios para capturar esos eventos. Informamos del nuevo valor de la barra de progreso cada vez que cambia. " + .awt.

Figura 14.7.java del CD. Manejo de eventos de barras de progreso.máximo: + jprogressbar. Las ayudas de herramientas están soportadas por la clase JToolTip de la Swing y aquí tenemos el diagrama de herencia de clase: . dice el especialista de soporte de productos. "podría reducir todo a una serie de animaciones". cada vez que el usuario actualiza la barra de progreso. decimos. Como vemos. "no parece que nadie lea nunca los manuales. Creación de ayudas de herramientas "Bien". Por ejemplo. Visualizan algún texto que explica el propósito del control. su nuevo valor aparece en la barra de estado del applet.getValue()). "Añadiremos ayudas de herramientas a los controles del programa". Este ejemplo es un éxito y puede encontrarlo en el archivo progressbarevents. dice el ESP pensativo. contestamos rápidamente. ¿Existe alguna forma de hacer que nuestros programas sean autoexplicativos?" "Bien". + 1 1)3 1 1 El resultado de éste código se muestra la figura 14.getMaxi-() valor: " + jprogreesbar. "Mm". Las ayudas de herramientas son ventanas pequeñas que aparecen cuando el usuario deja parado el ratón sobre un componente. la ayuda de herramientas del botón Cortar podría leer "Corta el texto seleccionado". "Es una broma".7.

9. Obtiene el objeto apariencia que renderiza este componente. Tabla 14.La tabla 14. protected String paramString0 void setComponent(JComponent c) void setTipText(String tipText) void updateUl() Muchos componentes ya tienen un método setToolTipText que puede utilizar para añadir una ayuda de herramientas. Obtiene una representación de cadena de este objeto JToolTip. Construye una ayuda de herramientas. Métodos de la clase JToolTip. Asigna el componente que describe esta ayuda de herramientas. Asigna al texto mostrado cuando aparece la ayuda de herramientas. Obtiene el texto que se muestra en la ayuda de herramientas. String getUIClasslD() Obtiene el nombre de la clase apariencia que renderiza este componente. Llamada por la clase UlFactory cuando cambia la apariencia. Obtiene el elemento al que se aplica la ayuda de herramientas.10 muestra sus métodos.10.9 muestra el constructor de la clase JToolTip y l a tabla 14. Aquí tenemos un ejemplo en el que añadimos una ayuda de herramientas a un botón: . AccessibleContext getAccessibleContexto JComponent getComponent() String getTipText0 Obtiene el contexto accesible. Tabla 14. El constructor de la clase JToolTip.

1 1 Es tan sencillo como añadir una ayuda de herramientas a la mayoría de los componentes. L - . JTextField text = new JTextField(20). donde puede ver la ayuda de herramientas con su texto explicativo. public void actionPerformed(ActionEvent event) text .event. ) { 1). i 80es un botón ---- Figura 14. awt . button.java del CD. import javax. public class tooltip extends JApplet { JButton button = new JButton("Haz clic aquí").awt.*.setToolTipText("Esto es un botón. El resultado se muestra en la figura 14.import java . Uso de ayudas de herramientas. Este ejemplo se encuentra en el archivo tooltip.8. * . setText ( " i Hola desde Swing ! " ) . public void init ( ) t Container contentpane = getContentPane0.*. import java.swing.8. .").

12 muestra sus métodos. 1 AccessibleContext getAccessibleContexto int getOrientation() Obtiene el contexto accesible. "El gran jefe me ha dicho que hay demasiados campos de texto en mi programa y debería dividirlos en grupos".dice el PN. "como añadir campos de texto a los paneles y dar a los paneles varios colores de fondo. Tabla 14.Creación de separadores El programador novato dice. Puede incluso utilizar separadores. Métodos de la clase JSeparator. Los separadores son líneas verticales u horizontales y normalmente aparecen en los menús para separar elementos de menú en grupos lógicos.11. 1 JSeparatorO JSeparator(int orientation) Crea u n nuevo separador horizontal.illas". Quedan soportados por la clase JSeparator en la Swing. pero también pueden utilizarse para separar componentes en una distribución. Obtiene la orientación de este separador. Para empezar. respondemos.11 muestra los constructores de la clase JSeparator y la tabla'i 14.12. ¿Cuántos campos de texto existen en su programa?" "Cerca de 2. "Ojo". y aquí tenemos el diagrama de herencia de clase: La tabla 14. . Tabla 14. Crea un nuevo separador con la orientación horizontal o vertical indicada.4 13 ". "Puede hacerlo de diversas formas senc. Constructores de la clase JSeparator. decimos.

String getUIClasslD() Obtiene el nombre de la clase apariencia que renderiza este componente.swing.VERTICAL)i Dimension dimension = jseparator.class WIDTH = 400 HEIGHT = 2 0 0 > < /APPLET> */ public class separator extends JApplet { JSeparator jseparator = new ~~eparator(~Separator. tenemos que hacer algo más que añadirlo a la distribución. que tiene los campos: width y height. import javax. situamos un separador entre los campos de texto en una distribución de flujo. Aquí. Indica si este componente puede recibir el foco. Asigna el objeto apariencia que renderiza este componente. /* <APPLET CODE = separator. Asigna la orientación del separador.awt. La forma normal de hacerlo es utilizar el método getPreferredSize del separador para obtener el ancho actual del separador y después pasarlo con el nuevo tamaño que queramos en el método setPreferredSize. Aquí tenemos la forma de crear un nuevo separador y obtener sus dimensiones: import java. Llamada por la clase UlFactory cuando cambia la apariencia.*. Obtiene una representación de cadena de este objeto JSeparator. también debemos proporcionar un tamaño preferente utilizando el método setPreferredSize. Para hacer visible el separador.*.Obtiene el objeto apariencia que renderiza este componente. Los métodos setPreferredSize y setPreferredSize trabajan con objetos de la clase Dimension de la AWT. .get~referredSiZe~). boolean isFocusTraversable() protected String paramString0 void setOrientation(int orientation) void setUI(SeparatorU1 u¡) void updateUl() Vamos a examinar un ejemplo.

m . contentPane. dándole una altura de cien puntos: public class separator extends JApplet { JSeparator jseparator = new JSeparator(JSeparator. public void init0 { Container contentpane = getContentPane0.add(new JTextField("iHo1a desde Swingl")).9.getPreferredSize0. podríamos querer cambiar el tamaño del separador para que se ajuste. A pesar de todo. sde Swingl Figura 14. Creación d e un separador. el separador aparece entre los dos campos de texto.VERT1CAL). contentPane.9. Como muestra la figura. consulte el siguiente tema para ver los detalles. El resultado de este código (separator. tenemos un problema. Podemos hacerlo procesando los eventos de cambio de tamaño. ¿qué sucede si cambia el tamañol del applet? En ese caso.add(new STextField("iH0la desde Swingl")). como hacemos aquí.java en el CD) se muestra en la' figura 14. contentPane.add(jseparator). Dimension dimension = jseparator.Ahora podemos poner el separador entre los campos de texto.

*.*. Métodos de la interfaz ComponentListener.awt. void componentResized(Component.Cambio de tamaño automático de separadores Para cambiar el tamaño de un separador. Aquí tenemos un ejemplo en el que creamos un separador entre los campos de texto. cuando cambia el tamaño de su applet.*.swing.VERTICAL). incluyendo applet y ventanas. import javax. Los métodos de esta interfaz se muestran en la tabla 14.13. .class WIDTH = 400 HEIGHT = 2 0 0 > </APPLET> */ publicclass separatorevents extendsJApplet implements ComponentListener { JSeparator jseparator = new ~~eparator(JSeparator. Aquí tenemos el código: observe el código de cambio de tamaño en los métodos componentshown (para visualizar por primera vez el separador) y componentResized: import java. puede cambiar el tamaño del separador asignando el que desee. Tabla 14.awt. que va desde la parte superior de la ventana del área de cliente del applet hasta la parte inferior y mantiene esa extensión incluso cuando cambia de tamaño el applet.13. que maneja los eventos de cambio de tamaño para componentes. Event e) void componentShown(ComponentEvent e) Llamado cuando se hace visible el componente. import java. void componentHidden(ComponentEvent e) void componentMoved(ComponentEvent e) Llamado cuando se hace invisible el componente. /* <APPLET CODE = separatorevents. podemos capturar los eventos de cambio de tamaño del componente utilizando la interfaz ComponentListener.Llamado cuando el tamaño del componente cambia. Llamado cuando la posición del componente cambia. Por ejemplo.event.

10. public void init0 I Container contentpane = getContentPane0.set~referredSize(new Dimension(dimension. Figura 14. ). getSize0-height)).java del CD.add(new JTextField("iHo1a desde Swing! " ) contentPane. contentPane.revalidate0. 1 public void componentMoved(ComponentEvent e) ( 1 public void componentHidden(ComponentEvent e) 0 1 El resultado de este código se muestra en la figura 14. public void componentResized(ComponentEvent e) { jseparator.10. Como puede ver7 el separador se extiende desde la parte superior del área de cliente del applet hasta la parte inferior y cambiará de tamaño automáticamente junto con el applet.setPreferredSize(new ~imension(dimension. ).width.getPreferredSize0.add(jseparator).width.Dimension dimension = jseparator. Este ejemplo se encuentra en el archivo separatorevents.add(new JTextField("iHo1adesde Swing! " ) public void componentShown(ComponentEvent e) { jseparator. jseparator. Creación de un separador que cambia de tamaño automáticamente. contentPane. .

Creación de un selector de color "Ahora tenemos un problema real".15 muestra sus constructores y la tabla 14. "¡Buena idea!". ma .14.0bject I Puede encontrar los campos de la clase JColorChooser en la tabla 14. "Escriba el código y yo lo miro". que es un cuadro de diálogo ya creado que presenta al usuario diversas formas de seleccionar colores. Constructores de la clase JColorChooser Construye un panel selector de color. Campos de la clase JColorChooser. Podemos permitir al usuario seleccionar un color con la clase JColorChooser de la Swing. dice el PN. Tabla 14.El contexto accesible. Tabla 14. El nombredela propiedaddel modelo de selección. blecontext static String CHOOSER-PANELSPROPERTY static String PREVIEW-PANELPROPERTY static String SELECTION-MODELPROPERTY El nombre de la propiedad de lamatriz del panel de selector. "Quiero permitir a los usuarios la selección de un color de dibujo para mi nuevo programa. El nombre la propiedad del panel de vista previa.pero no puedo pedirles que introduzcan los nuevos valores de color".14. "¿Por qué no utiliza un selector de color?". preguntamos. Aquí tenemos el diagrama de herencia de la clase JColorChooser: java. dice el programador novato.15. protected AccessibleContext accessi. lang. la tabla 14.16 muestra sus métodos. SuperDuperArtisticPro.

Obtiene el panel de vista previa que muestra un color seleccionado. String title. ActionListener cancellistener) AccessibleContext getAccessibleContexto Aiíade un panel selector de color. boolean modal. Construye y devuelve un nuevo diálogo con el colory indicado por el selector de color con los botones Aceptar. JColorChooser(ColorSelectionModel Construye un panel selector de color model) con el modelo de selección de color indicado. ChooserPanel(AbstractColorChooser Panel panel) . ActionListener oklistener. Cancelar y Reiniciar.Elimina el panel de color indicado.JColorChooser(Color initialcolor) Construye un panel selector de color con el color inicial indicado. AbstractColorChooserPanel[] getChooserPanels() Color getColor() JComponent getPreviewPanel() ColorSelectionModel getselectionModel() String getUIClasslD() Obtiene el nombre de la clase apariencia que renderiza este componente. Obtiene los paneles de color indicados. Tabla 14. Obtiene el contexto accesible. Obtiene una representación de cadena de este objeto JColorChooser. void addChooserPanel(AbstractCoIorChooserPanel panel) static JDialog createDialog(Component c. JColorChooser chooserpane. Obtiene el modelo de datos que maneja selecciones de color. Obtiene el objeto apariencia que renderiza este componente. protected String paramString0 AbstractColorChooserPanel remove.16. Obtiene el valor actual del color a partir del selector de color. Métodos de la clase JColorChooser.

Especifica los paneles de color utilizados para seleccionar un valor de ChooserPanel[] panels) color. static Color showDialog(Component. int g. Asigna al color actual del sector de color al color RGB indicado. Asigna al color actual del selector de color el color indicado. void setColor(Color color) void setColor(int c) void setColor(int r.*.Muestra el cuadro de diálogo de secomponent. lo único que tenemos que hacer es mostrarlo con el método showDialog y después pasar a este método un objeto padre.*. Es sencillo utilizar un sector de color.class WIDTH = 2 0 0 HEIGHT = 2 0 0 > . Color initial. Asigna al objeto apariencia que renderiza este componente. import java.swing.*.awt. Este método devuelve el color seleccionado por el usuario como un objeto Color (o el color predeterminado si el usuario no realizó selección alguna). un título y un color predeterminado. Asigna el modelo que contiene el color seleccionado. Una vez que el usuario seleccione un color. Asigna el panel de vista previa actual. Color) void updateUl() Llamada por la clase UlManager cuando la apariencia ha cambiado. import javax. CODE = colorchooser. int b) void setPreviewPanel(JComponent preview) void setSelectionModel(ColorSelectionMode1 newModel) void setUI(ColorChooserUI ui) Asigna al color actual de selector de color el color indicado.lección de color modal. Aquí tenemos el código: import java.event.void setChooserPanels(AbstractColor. String title. el código cambia el fondo del panel a ese color.awt. Vamos a examinar un ejemplo en el que situamos un botón en un panel y permitimos al usuario visualizar el selector de color cuando haga clic sobre el botón.

m .this. JButton jbutton. Color. como se muestra en la figura 14.add(jbutton1.java en el CD) es un éxito. Cuando el usuario selecciona un color en el selector.public class colorchooser extends JApplet implements ActionListener { JPanel jpanel = new JPanelO. es sencillo utilizar un selector de color.white)..addActionListener(this).showDialog(colorchooser. éste apareceen .1 1. jbutton.. el nuevo color aparece en el panel del applet. Como puede ver.11. Este ejemplo (colorchooser. public void actionPerformed(ActionEvent e) { Color color = JColorChooser. public void init ( ) { jbutton = new JButton("Haga clic aquí para cambiar los colores.12."). Uso de un selector de color.1 figura 14. jpanel.". "Seleccione un nuevo color. Figura 14.

. dice el programador novato. decimos.19 sus métodos.12. la tabla 14. Los selectores de archivos son cuadros de diálogo que permiten al usuario especificar el nombre y vía de acceso de un archivo. Los selectores de archivos quedan soportados por la clase JFileChooser. "Bien". "Ah". ¿existe alguna forma rápida de hacerlo?" "Claro".17 muestra los campos de la clase JFileChooser. "necesito obtener el nombre de un archivo de usuario.Figura 14. Aquí tenemos el diagrama d e herencia para esta clase: La tabla 14. "quiero permitir que el usuario explore el disco para obtener el archivo correcto si fuera necesario". dice el PN. Cambio del color de un panel a un color seleccionado. "entonces desea un selector de archivos". Creación de selectores de archivos "Ajá". permitiéndole explorar el espacio de disco si es necesario. "un campo de texto". decimos.18 sus constructores y la tabla 14.

lndica un cambio en el título del cuadro de diálogo. Valor de tipo indicando que el selector de activos soporta una operación archivo específicada por el desarrollador. Campos de la clase JFileChooser. static int APPROVE-OPTION static String APPROVE-SELECTION static int CANCEL-OPTION static String CANCEL-SELECTION static String CHOOSABLE-FILE-FlLTERCHANGED-PROPERTY static int CUSTOM-DIALOG static String DIALOG-TITLE-CHANGEDPROPERTY static String DIALOG-TYPE-CHANGEDPROPERTY . lndica un cambio en el mnemónico para el botón de Aceptar. protected AccessibleContext accessibleContext static String ACCESSORY-CHANGEDPROPERTY static String APPROVE-BUTTON-MNEMONIC-CHANGED-PROPERTY static String APPROVE-BUTTON-TEXTCHANGED-PROPERTY static String APPROVE-BUTTON-TOOL -TIP-TEXT-CHANGED-PROPERTY El contexto accesible. Instrucción para probar la selección actual. lndica un cambio en la lista de títulos de archivo predeterminados entre los que puede seleccionar el usuario. lndica que un componente accesorio diferente está en uso. El valor de retorno si selecciona el botón Cancelar.Tabla 14. lndica un cambio en el texto de la ayuda de herramientas para el botón AceptarfSílAprobar.17. Instrucción para cancelar la selección actual. lndica un cambio en el texto del botón AceptarfSíIAprobar. El valor de retorno si se se-' lecciona el botón Aceptar/Si/ Aprobar. lndica un cambio en el tipo de archivos mostrados (únicamente archivos. sólo directorios o tanto archivos como directorios).

lndica que el selector de archivos soporta una operación de apertura de archivos. múltiple y así sucesivamente). Instrucción para visualizar únicamente archivos. lndica que se utiliza un objeto distinto para recuperar información de los archivos. static String FILE-VIEW-CHANGEDPROPERTY static int FILES-AND-DIRECTORIES static int FILES-ONLY static String MULTI-SELECTION-ENABLED-CHANGED-PROPERTY static int OPEN-DIALOG static int SAVE-DIALOG static String SELECTED-FILE-CHANGED-PROPERTY . lndica un cambio en la propiedad "Mostrar archivos ocultos". lndica un cambio de directorio. El usuario cambia el tipo de archivos a mostrar. lndica un cambio en la selección única de archivos del usuario. Permite selección múltiple de archivos. Instrucciónpara visualizar tanto archivos como directorios.static int DIRECTORIES-ONLY static String DIRECTORY-CHANGEDPROPERTY static int ERROR-OPTION static String FILE-FILTER-CHANGEDPROPERTY static String FILE-HIDING-CHANGEDPROPERTY static String FILE-SELECTION-MODECHANGED-PROPERTY static String FILE-SYSTEM-VIEW-CHANGED-PROPERTY Instrucción para visualizar únicamente directorios. lndica un cambio en laclase de selección (simple. lndica que se está utilizando un objeto diferente para encontrar los archivos disponibles en el sistema. lndica que el selector de archivos soporta la operación para guardar archivos. El valor de retorno si ocurre un error.

Constructores de la clase JFileChooser. . Métodos de la clase JFileChooser. Construye un objeto JFileChooser utilizando la vista del sistema archivos dada. void addChoosableFileFilter(FileFilterfilter) Añade un filtro a la lista de filtros de archivo seleccionables.19. Construye un objeto JFileChooser utilizando un archivo dado como vía de acceso. Construye un objeto JFileChooser utilizando el directorio actual dado y la vista del sistema archivos. Tabla 14. Construye un objeto JFileChooser utilizando el directorio actual en curso como vía de acceso y la vista del sistema archivos. FileSystemView fsv) Tabla 14. Construye un objeto JFileChooser utilizando la vía de acceso dada. Añade un receptor de acciones. boolean accept(File f) void addActionListener(ActionListener 1 ) Devuelve cierto si el archivo deber mostrarse. FileSystemView fsv) JFileChooser(FileSystemView fsv) JFileChooser(StringcurrentDirectory Path) JFileChooser(String currentDirectoryPath. JFileChooser() JFileChooser(File currentDirectory) Construye un objeto JFileChooser.GED-PROPERTY Indica un cambio en la selección múltiple de archivos del usuario. JFileChooser(File currentDirectory.18.

Obtiene el filtro archivos AcceptAll. Asigna el padre del directorio actual. Obtiene la lista de filtros de archivo seleccionados por el usuario. void cancelSelection() void changeToParentDirectory() void ensureFilelsVisible(File f) protected void fireActionPerformed(String command) FileFilter getAcceptAllFileFilter() AccessibleContext getAccessibleContext() JComponent getAccessory() int getApproveButtonMnemonic() 1 String getApproveButtonText() String getApproveButtonToolTipText() FileFilter[] getChoosableFileFilters() 1 File getCurrentDirectory() String getDescription(File f) 1 . Devuelve el directorio actual. Obtiene el contexto accesible asociadocon este objeto JFileChooser. Llamada por la IU cuando el usuario hace clic sobre el botón Cancelar. Obtiene el componente accesorio. Notifica a todos los receptores que han registrado interés por la notificación de este tipo de evento. Obtiene el mnemónico del botón Aprobar. Obtiene el texto usado en el botón aprobar en FileChooserUI.void approveSelection() Llamado por la IU cuando el usuario hace clic sobre los botones Guardar o Abrir. Asegura que el campo indicado es visible. Obtiene la descripción de archivo. Obtiene el texto de la ayuda de herramientas utilizada en el botón Aprobar.

int getDialogType() FileFilter getFileFilter() int getFileSelectionMode() FileSystemView getFileSystemView() FileView getFileView() lcon getlcon(File f) String getName(File f) File getSelectedFile() File[] getSelectedFiles() String getTypeDescription(File f ) FileChooserUl getUI() String getUIClasslD() boolean isDirectorySelectionEnabled() boolean isFileHidingEnabled() . Obtiene la vista del archivo actual. Un método conveniente que determina si los directorios se pueden seleccionar. Devuelve cierto si los activos ocultos no se muestran en el selector de archivos. Obtiene elarchivo seleccionado. Obtiene el nombre de archivo. Obtiene el tipo de este cuadro de diálogo. Obtiene una lista de los activos seleccionados si el selector de archivos permite la selección múltiple. Obtiene el icono para este archivo o tipo de archivo. dependiendo del sistema. Obtiene el filtro de archivo seleccionado en curso. Obtiene el tipo de archivo. Obtiene una cadena que especifica el nombre de la clase de apariencia que renderiza este componente. Obtiene la vista del sistema archivos. Obtiene el modo de selección de archivos actual. Obtiene el objeto IU que implementa la apariencia de este componente.String getDialogTitle() Obtiene la cadena que va en la barra de título del selector de archivos.

Asigna el texto utilizado en el botón Aprobar. Explorar de nuevo la lista de archivos a partir del directorio actual. Obtiene una representación de cadena de este objeto JFileChooser. 1 void setCurrentDirectory(Filedir) . boolean removeChoosableFileFilter(FileIisFilter f) void rescanCurrentDirectory() Elimina un filtro a partir de la lista de filtros de archivos seleccionables. Asigna el directorio actual. Reinicia el filtro de archivo seleccionado de la lista a su estado inicial. ButtonText) void setApproveButtonToolTipText(String toolTipText) Asigna al texto de la ayuda de herramientas utilizada en el botón Aprobar. Devuelve cierto si el archivo (directorio) se puede visitar. Asigna un componente accesorio. Asigna el mnemónicodel botón Aprobar utilizando un carácter.boolean isFileSelectionEnabled() Un método conveniente que determina si los archivos son seleccionables basado en el modo de selección de archivo actual. boolean isMultiSelectionEnabled() boolean isTraversable(File f) protected String paramString0 void removeActionListener(ActionListener1 Elimina un receptor de accio) nes del botón. void resetChoosableFileFiIters() void setAccessory(JComponent newAccessory) void setApproveButtonMnemonic(char mnemonic) void setApproveButtonMnemonic(int mnemonic) void setApproveButtonText(String approve. Devuelve cierto si se pueden seleccionar múltiples archivos. Asigna mnemónico del botón Aprobar utilizando un código de teclado numérico.

Asigna el selector de archivos que permite al usuario seleccionar únicamente archivos. int showDialog(Component parent.void setDialogTitle(String dialogTitle) Asigna la cadena que va en la barra de título de la ventana del selector de archivos. como el icono que representará el archivo o la descripción del tipo de un archivo. Asigna el filtro de archivos actual. . Asigna el tipo de este cuadro de diálogo. Configura el selector de archivos para que pueda realizar selección múltiple. únicamente directorios o ambos. Asigna la lista de archivos seleccionados si el selector de archivos está configuradopara permitir selección múltiple. void setMultiSelectionEnabled(boolean b) void setSelectedFile(File selectedFile) void setSelectedFiles(File[] selectedFiles) protected void setup(FileSystemView view) Realiza la configuración e ¡nicialización del constructor. Asigna la ocultación de archivos. Asigna el archivo seleccionado. String approveButtonText) Visualiza un cuadro de diálogo de selector de archivos personalizado con un botón Aprobar personalizado. void setDialogType(int dialogType) void setFileFilter(FileFilter filter) void setFileHidingEnabled(boolean b) void setFileSelectionMode(int mode) void setFileSystemView(FileSystemView fsv) Asigna la vista del sistema archivos que utiliza un objeto JFileChooser. void setFileView(FileView fileview) Asigna la vista de archivos utilizada para obtener información de la IU.

*. . Estos métodos devuelven los siguientes valores: APPROVE-OPTZON. Debido a que normalmente no abrimos archivos desde los applet (por razones de seguridad). Aquí tenemos el código (observe que comprobamos el valor de retorno de showOpenDialog para ver si el usuario ha hecho clic sobre el botón Abrir antes de visualizar el nombre de archivo en el campo): import import import import java. En este caso. Se devuelve si el usuario hace clic sobre Cancelar. java. haremos que este ejemplo sea una aplicación.awt.swing. Visualiza un cuadrodediálogo d e selector de archivos "Guardar archivo".event. Se devuelve si el usuario hace clic sobre un botón de aprobación. ERROR-OPTION. Vamos a examinar un ejemplo que hace funcionar todo esto.io. Guardar o Abrir. CANCEL-OPTION.*. Permitimos que el usuario seleccione un archivo y después visualizaremos el nombre del archivo y su vía de acceso en un campo de texto. int showSaveDialog(Component parent) void updateUl() Puede utilizar el método showOpenDialog de la clase JFileChooser con el fin de mostrar un selector de activos para buscar archivos que necesite abrir. getName y otros de la clase File para devolver información sobre el archivo. java. y puede utilizar el método showSaveDialog para mostrar un selector de archivos con el fin de especificar el nombre de archivo y vía de acceso que desea utilizar para guardar un archivo.int showOpenDialog(Component parent) Visualiza un cuadro de diálogo d e selección de archivos "Abrir archivo".awt. javax. visualizaremos un selector de apertura de archivos cuando el usuario hace clic sobre un botón. Se devuelve si existe un error. Llamada por la clase U IFactory cuando cambia la apariencia.*.File. Puede obtener el archivo seleccionado como un objeto File con el método getSelectedFile del selector de archivos (examinaremos la clase File en este libro más tarde) y puede utilizar los métodos getPath.

swing. El usuario puede explorar y seleccionar un archivo.13 muestra el selector de archivos que visualiza esta aplicación. public void windowClosing(WindowEvent e) { System. 200).filechooser. Container contentpane = getContentPane0.*. JButton jbutton = new JButton("M0strar selector de archivos"). } 1).import javax.set~ext("Hiz0 clic sobre Cancelar").getSelectedFile0. JTextField jtextfield = new JTextField(30). Cuando lo hace. public void actionPerformed(ActionEvent e) { int result = chooser.ehowOpenDialog(null). 400. if(resu1t == J'FileChooser. f.exit(0). 200.APPROVE~OPTION) { jtextfield. } 1 La figura 14.setBounds(200. haciendo clic sobre el botón Abrir en el selector de archivos o simplemente haciendo doble clic sobre el archivo en el selector de . } else if(resu1t == JFileChooser-CANCEL-OPTION) { jtextfield. public filechooser ( ) { super ( ) . File fileobj = chooser. ya sea resaltando un archivo.setText("Su selección " + fileobj. public class filechooser extends JFrame implements ActionListener { JTileChooser chooeer = nem JFileChooserO.get~ath()). 1 1 public static void main(String argsil) { JFrame f = new filechooser ( ) .

Java. Creación de filtros para selectores de archivo Existen muchas formas de personalizar los electores de archivo y una de ellas es crearfiltros de archivos. Este ejemplo se encuentra en el archivo filechooser. Figura 14. Para añadir un filtro de archivos a un selector. 1113 anirnator Figura 14.GIF y otro para archivos . Creación de un selector de archivos.13.14. . Vamos a examinar un ejemplo en el que añadimos dos nuevos filtros de archivo a un selector. Puede utilizar filtros para asignar los tipos de archivos (basándose en su extensión) que mostrará un selector de archivos. como se muestra en la figura 14. Los filtros de archivos derivan de la clase FileFilter. se cierra el selector de archivos y aparecen el nombre y vía de acceso del archivo seleccionado en el campo de texto de la aplicación. utilice el método addChoosableFileFilter de JFileChooser.java del CD. Determinación del archivo seleccionado. Eso es todo.archivos. un filtro para archivos .14.

event. como se realiza a continuación: import import import import /* java .awt.*.swing.*.APPROVE-OPTION) { jtextfield. JButton jbutton = new JButton("M0strarel selector de archivos").awt. JTextField jtextfield = new JTextField(20). iAPPLET CODE = filechooserfilter. java.getPath0 1 . javax. } 1 public static void main(String aíl) t JFrame jframe = new filechoocerfilter0. por lo que podemos utilizar el método addChoosableFileFilter para añadirlos a un selector de archivos. . java.Estos dos filtros están soportados por las clases filterl y filter2.getSelectedFileO.setText("Su selección es " + jfilechooser. Container contentpane = getContentPane0. * . public filechooserfilter0 I super ( ) . if(resu1t == JFileChooser.showOpenDialog(null). io.*. public void action~erformed(ActionEvent e) I int result = jfilechooser.class WIDTH = 200 HEIGHT = 200 > </APPLET> */ public class filechooserfilterextends JFrame implements ~ction~istener ( JFileChooser jfilechooser = new JFileChooserO.

el método accept recibe un objeto File (veremos la clase File más tarde en este libro).lastIndexOf('. abstract boolean accept(Fi1e f) abstract String getDescription() Devuelve cierto si s e acepta el archivo por este filtro.Java)" en este filtro) y directorios.lastIndexOf('.gif (descritos como "Archivos GIF (*.getPath~). Devuelve ladescripción de este filtro. Devuelve verdadero si el archivo se debe visualizar (es decir.20. normalmente. si su extensión es una de las que acepta el filtro o. El método getDescription devuelve una cadena que visualizará el selector de archivos para indicar al usuario los tipos de archivos para los que vale el filtro. Estas clases derivan de la clase abstracta FileFilter y encontraremos los métodos de esta claseen la tabla 14. si el archivo corresponde a un directorio) y false en otro caso.exit (O) .') + l). 1 } Tabla 14. No es difícil implementar los métodos de la clase FileFilter.substring( fileobj.getPath0 . La clase filterl aceptará archivos . } 1).Java (descritos como "Archivos Java (*.20. y la clase filter2 filtra archivos .filechooser.gif) " en este filtro) y directorios.swing.getPath() .addWindowListener(new WindowAdapterO public void windowClosing(WindowEvent e) { { System. Métodos de la clase FileFilter. if(fileobj.jframe.toLowerCaseO. if(extension ! = "") . Aquí tenemos el código de estas clases: class filterl extends javax. Ahora hemos creado las clases filterl y filter2.') > 0 ) extension = fileobj.FileFi1te1 I public boolean accept(Fi1e fileobj) I String extension = "".

else return fileobj. puede facilitar al usuario la búsqueda de archivos de un tipo particular.getPath0 . if(fileobj.15. Uso de los filtros en un selector de filtros.15.java en acción.gif) .substring( fileobj.FileFi1ter { public boolean accept(Fi1e fileobj) { String extension = "". 1 public String getDescription0 I return "Archivos Gif (*.java en el CD.java) . donde puede ver el filtro . El resultado de este código se muestra en la figura 14. 1 public String getDescription0 { return "Archivos Java (*.toLowerCaseO. Este ejemplo es un éxito y puede encontrar el archivo filechooserfilter. ~ lava fi1e7 AI Figura 14.swing.lastIndexOf('.return extension.') + l). " 1 1 Y eso es todo.filechooser. 1 .isDirectory().isDirectory0. return extension.equals("gif"). " 1 1 class filter2 extends javax. El uso de filtros como este.equals("java").') > 0 ) extension = fileobj. .lastIndexOf('. else return fileobj.getPath0 .getPath().

La distribución de cuadro nos permite crear filas de columnas d e componentes. paneles d e lengüetas y paneles d e separación. También examinaremos la distribución en este capítulo. Los paneles de capas. separadores y distribuciones En este capítulo. examinaremos algunos de los contenedores d e poco peso de la Swing: paneles de capas. y podemos hacer clic sobre las lengüetas para abrir cada carpeta. La Swing proporciona varios continentes de poco peso. o fijando el orden en el eje Z (que apunta hacia el exterior de la pantalla) de los componentes. una técnica usada habitualmente para soportar dos vistas del mismo modelo. nos permiten especificar la capa en los componentes que añadimos. facilitando la configuración del orden Z. Primero vimos la distribución del AWT en el capítulo 7. introducidos en el capítulo 1 1. Finalmente los paneles de separación no permiten visualizar dos componentes colindantes y ajustar la cantidad visible de cada uno.m Swing: paneles de capas. . La Swing soporta todas estas distribuciones y dos más: distribución de cuadro y distribución de superposición. para permitir a los programadores manejar componentes de forma sencilla. de lengüetas. Los paneles de lengüetas nos permiten ordenar los componentes como si los añadiéramos a una colección de archivos de carpeta de lengüetas. incluyendo JPanel (que ya se ha visto). Examinaremos estas dos nuevas distribuciones en este capítulo.

Paneles de separación Otra técnica popular de programación de las IU hoy día es permitir al usuario dividir una vista en un modelo de datos. Los procesadores de texto a veces permiten a los usuarios dividir sus presentaciones en dos paneles de tal forma que puedan pasar de forma independiente entre dos áreas de un documento. opciones generales. Paneles de lengüetas Los cuadros de diálogo que permiten a los usuarios seleccionar entre muchas opciones han cambiado a medida que los programas se han hecho más complejos y ofrecían más opciones. Como es de esperar. contenedores de poco peso. debido a que puede ver las capas que utiliza la Swing para visualizar los cuadros de diálogo. archivos y otras. Se implementan personalizadamente de esta forma. áreas rígidas y pegadas. Uno de los aspectos más populares del panel de capas es que es la raíz del panel de contención. nos permite dibujar componentes superpuestos. como implica el nombre. que nos permite distribuir componentes utilizando estructuras visuales. La Swing soporta los paneles de separación para permitir a los programas presentar dos . arrastrar componentes. creando de esta forma una nueva vista con los datos. Paneles de capas Los paneles de capas. Los paneles de capas se dividen en varias capas verticales que pueden trabajar conjuntamente con la Swing. todas las capacidades de la Swing están disponibles aquí. Veremos todo en este capítulo.La distribución superpuesta. información de usuario. Esta es una de las áreas en las que la implementación de la Swing sobre AWT no es transparente para el programador. organizando la configuración del programa en lengüetas para la pantalla. La Swing soporta ahora paneles de lengüetas para permitirle crear cuadros de diálogo y programas de esta clase. son paneles importantes para los contenedores de alto peso de la Swing como JApplet y JFrame. como la visualización de imágenes de lengüetas. La Swing también define la clase Box. menús emergentes y otros. cruces.

vendrá mucho más. Sonreímos y decimos. debido a que permite distribuir los componentes en filas y columnas horizontales y verticales. dice el programador novato. el orden Z representa el emplazamiento relativo de los componentes a lo largo del eje Z. Es decir. "Es perfectamente posible. De las dos. Cuando los componentes se superponen. De hecho. El gestor de distribución de superposición nos permite superponer componentes de una forma bien definida y. su orden Z pasa a ser muy importante. El componente de poco peso que se haya añadido primero aparecerá por encima de aquellos que se añadan posteriormente. llamados cuadros. y la Swing soporta estas distribuciones así como dos más: distribución de cuadro y distribución superpuesta. Distribución En el capítulo 7 examinamos la distribución del AWT. la distribución de cuadro es la más popular. comenzando con una descripción de los componentes de desplazamiento de la Swing. tiene su utilidad. De hecho. El PN dice. permitiendo especificar el espacio de distribución de componentes.componentes conjuntamente. " i Vaya! " Cuando añadimos componentes de poco peso a un panel contenedor. aunque no es tan común como los otros sectores de distribución. los componentes se dibujarán sencillamente sobre el panel y nada nos impide hacer que los componentes se superpongan. Es suficiente para el resumen de lo que aparece en este capítulo. siempre y cuando no utilicemos un gestor de distribución (excepto para el gestor de distribución de superposición) que impediría la superposición. como examinaremos. Como puede ver. que sale fuera de la pantalla. Estos componentes pueden representar vistas del mismo u otro modelo de datos. Examinaremos estas dos nuevas distribuciones en este capítulo. "Deposité algunos componentes en la misma zona de mi programa por error y aparecían unos encima de otros". la Swing también soporta una clase Box que va más allá. Es el momento de pasar a la sección inicial. Puede . Comprensión de los componentes de la Swing y orden Z "Java ha fallado de nuevo". en la Swing no está fuera de lo común superponer componentes".

setOpaque(true). l labels [ll. mostrando de esta forma que la primera etiqueta añadida aparecerá por encima del resto. /* CAPPLET CODE = 1ayered. . labels[0]. normalmente aparecerán por encima de los componentes de la Swing.setOpaque(true). contentPane.awt.add(labels[21 1 . labels[2] = new ~~abel("Etiqueta 2"). labels = new JLabelI61.*. Aquí tenemos el código (observe que hemos añadido un borde a las etiquetas para hacer visible la superposición): import java. contentPane.set~order(BorderFactory. que tienen su propio sistema operativo de ventanas. labels[ll. contentPane.swing.add(labeIs[ll). labels[O] = new JLabel("Etiqueta O " ) .también añadir componentes pesados de la AWT a su programa y esos componentes.createEtchedBorder~. setopaque (true) . labels[2].class WIDTH = 350 HEIGHT = 280 > </APPLET> */ public class layered extends JApplet { JLabel labels [ 1 . labels[Ol. public void h i t ( ) { Container contentpane = getContentPane0.add(labels[Ol). import javax. labels[4] = new J~abel("Etiqueta 4"). labels[3] = new ~Label("Etiqueta 3"). Aquí tenemos un ejemplo en el cual eliminamos el gestor de distribución de borde predeterminado de un panel de contenidos y añadimos una serie de etiquetas superpuestas. labels[2].set~order(~order~actory. contentPane.setLayout(null) .createEtchedB0de~ .setBorder(BorderFa~tory. labels[l] = new ~ L a b e("Etiqueta 1 " ) .*.createEtchedBorderO).

Transparencia en los componentes de la Swing "Acabo d e ver el programa más extraño". El resultado se muestra en la figura 15. 100. 40 * loop-index. loop-index < 6. labels[4]. loop-index++) { labels[loop-indexl .add(labelsi51) .setopaque(true). contentPane.set~order(B0rderFa~t0ry. Figura 15.~reateEtched~order() ).createEtchedBorder(~~. labels[5]. Este ejemplo se encuentra en el archivo 1ayered. "No .labelsr41 .setBorder(BorderFactory.1. La siguiente etiqueta añadida aparece por encima de las posteriores y así sucesivamente.setBounds(40 * loop-index. "Realmente podía ver todos los controles como si fueran transparentes".1. Como ve. add (labels141 ) . labels [ S ] . 60). consulte el siguiente tema para obtener más detalles. la primera etiqueta añadida aparece por encima de las otras. Debe también observar que hemos utilizado el método setopaque para cada etiqueta con el fin de asegurar que las etiquetas que quedan por debajo no se muestren de ninguna forma.setOpaque(true) . for(int loop-index = 0.java del CD. contentpane. dice el programador novato. definiendo de esta forma un orden Z distinto para cada etiqueta. labels [S] = new JLabel("Etiqueta 5 " ) . Controles superpuestos.

de tal forma que los controles por debajo se pueden ver.createEtchedBorderO contentPane. labels = new JLabelr61. labels[0]. contentPane.*. / <APPLET CODE = 1ayered. labels[2] = new ~~abel("Etiqueta ) . labels[l] = new JLabel("Etiqueta 1"). labels[l]. Puede asignar la transparencia de los componentes de la Swing con el método setopaque.class WIDTH = 350 HEIGHT = 280 > </APPLET> */ public clasc layered extends JApplet I JLabel labels[l .add(labels[ll ) .setBorder(~order~actory. En el tema anterior. "¡Dígame más!" Dice el PN.setOpaque(false). l h l s [ O ] . muchos programas de la Swing lo hacen d i forma intencionada". A continuación mostramos cómo hacer que las etiquetas del ejemplo del tema anterior sean transparentes (de hecho. decimos. las llamadas a setopaque son realmente innecesarias aquí debido a que la configuración predeterminada para etiquetas es hacerlas transparentes): import java. n o pinta su fondo cuando lo dibujamos o repintamos.setLayout(nu1li .awt.swing. labels [O] = new JLabel("Etiqueta 0'' ) . Esta es una técnica ampliamente utilizada que nos permite hacer que su apariencia sea como si dibujáramos componentes que fueran irregulares y no rectangulares. . "De hecho. Cuando hacemos un control transparente.es extraño".add(labels[01): ). contentPane. import javax. podemos hacerlos transparentes. Debido a que los controles de poco peso simplemente se dibujan dentro sus contenedores. aetOpaque (false) .*.create~tchedBorderO 1.setBorder(BorderFactory. 2" labela[Z]. escribimos un ejemplo en el que mostramos etiquetafl opacas superpuestas de la Swing. public void hit() ( Container contentpane = getContentPane0.setOpaque(false). pero también explícitamente podemos hacerlas transparentes. labele[l].

add(labe1~~31).2. labels[3]. labels[3].add(label~[41).~reate~hd0d. .setBounds(40* loop-index. labels [4] = new JLabel ( "Etiqueta 4" ) . labels[4].~reateEt~hedB0rde~O~. loop-index++) { labels[loop~index].~reate~tchedBorderO).set~~rder(B0rderFa~t~ry. labels[5]. Figura 15. 100.setOpa~e(falSe). contentPane.labels[3] = new JLabelíMEtiqueta 3 " ) . Esto involucra a un panel de capas que podemos utilizar en la mayoría de los programas. Consulte el siguiente tema para obtener más detalles. 1 1 1 El resultado se muestra en la figura 15. contentPane. 60). m B . 40 * loop-index. for(int loop-index = 0. donde puede ver las etiquetas transparentes superpuestas. contentPane. labels 151 eetOpaque(false) .eetOpaqueífalse).2.setB0rder(BorderFa~t0ry.setBorder(BorderFa~tory. Observe que existe una forma explícita de manejar controles superpuestos sin configurar nuestro propio gestor de distribución. Transparencia de controles. loop-index i6. labels[4].add(labels[51). labels[5] = new JLabel("Etiqueta 5 " ) .

O b j e c t I JLayeredPane divide su rango de profundidad en varias capas distintas. pero cuando los componentes se arrastran. lang.Uso de paneles de capas "Tengo algún problema". JLayeredPane: java. pregunta el PN. asignado a la capa de arrastre. La capa de paleta está situada por encima de la capa por defecto y se utiliza para las barras de herramientas y paletas flotantes. MODAL-LAYER. dice el programador novato. sin tener que preocuparnos de la especificación de números para asignar profundidades específicas: DEFAULT-LAYER. La capa utilizada por los cuadros de diálogo modales. Aquí tenemos el diagrama de herencia para la clase del panel de capas. Cuando arrastramos un componente. PALETTE-LAYER. Al situar un componente en una de estas capas es más sencillo asegurarnos de esta forma de que el componente se superpone de forma adecuada. POPUP-LAYER. donde se sitúan la mayoría de los componentes. Debería poner lo que desea arrastrar en la capa de arrastre". pasan por encima de unos componentes y por debajo de otros". "Quiero permitir al usuario arrastrar componentes en un contenedor de la Swing. incluyendo barras de menú y el panel de contenido. El panel de capas dentro del panel raíz contiene los componentes reales que aparecen en los applet y aplicaciones. "¿Cómo es eso?". Responde: "eso se debe a que tiene que tener en cuenta que los componentes de la Swing se presentan en capas. nos aseguramos de que queda posicionado sobre todos los demás componentes en el contenido. . La capa emergente se visualiza sobre la capa de diálogo. La capa estándar más baja. DRAG-LAYER.

su constructor en la tabla 11. los métodos como setLayer necesitan enteros. labels[O] = new JLabel("Capa de contenido").setOpaque(true).10. reemplazamos el panel de contenido de un applet con un nuevo panel de capas y añadimos una etiqueta a cada etapa estándar. labels[Ol . Una curiosidad de la Swing es que las constantes como JLayeredPane. El método setLayer también se puede utilizar para cambiar la capa actual del componente.*. no enteros.Puede utilizar los métodos moveToFront. Examinamos en el capítulo 11 JLayeredPane y podemos encontrar los campos de la clase JLayeredPane en la tabla 11.11 y s u s m é t o d o s e n l a t a b l a 11.*. En este caso. import javax. /* <APPLET CODE = 1ayeredpane. . como a continuación: Aquí añadimos etiquetas a todas las capas descritas en la lista anterior: import java. moveToBack y setposition de JLayeredPane para reposicionar un componente dentro de su capa.12. por lo que debemos usar el método intValue de la clase Integer para convertir estas constantes a valores útiles.swing. en realidad. utilizamos el método setLayer y para especificar la capa que utilizamos. No obstante. Para asignar la capa actual en el panel de capas. como JLayeredPane.awt.class WIDTH = 350 HEIGHT = 280 > < /APPLET> */ public class layeredpane extends JApplet ( JLayeredPane jlayeredpane = new JLayeredPaneO. objetos Integer. public void init ( ) labels = new JLabelt61. Aquí tenemos un ejemplo que muestra cómo añadir componentes a un panel d e capas.PALETTE-LAYERson. utilizamos las constantes definidas en la clase JLayeredPane. PALETTE-LAYER.

Este ejemplo se encuentra en el archivo 1ayeredpane. labels[2].setBorder(BorderFactory.setBorder(BorderFactory.add(labels[2]) . 40 * loop-index.java del CD. 5 l( labels [ S I .intValue0 ) . labels [3].~etLayer(labels[51.setopaque( true).setOpaque(true) . 6 0 ) . labels[3]. labels [ll . labels[3] = new JLabel("Capamodal"). labels 141 . setopaque labels[4].createEtchedBorder() . JLayeredPane.setopaque( labels[l].createEtchedBorder()). JLayeredPane.setBorder(BorderFactory. jlayeredpane.add(labels[4]) . jlayeredpane. 1 1 El resultado de este código se muestra en la figura 15.createEtchedBorder()) .set~order(~orderFactory. true).PALETTE-LAYER. (true). labels[2]. JLayeredPane.add(labels[l]). labels[2] = new JLabel("Capade paleta"). jlayeredpane. loop-index < 6. ) labels[4] = new JLabel("Capaemergente"). .~reateEtchedBorder~~ ).intValue0 ) .~etLayer(labels[2]. donde puede ver qué capas están por encima de otras.intValue0 ) . labels 1 1 = new ~ ~ a b e"Capa de arrastre"). jlayeredpane.set~order(BorderFactory. setBounds(40 * loop-index. jlayeredpane. Ahora ya hemos trabajado con todas lag capas estándar en un panel de capas (también podemos definir nuestras propias capas de forma numérica).add(labels[5]) .setOpaque(true).createEtchedBorder()).DEFAULT-LAYER. JLayeredPane.setLayer(labels[l].DRAG-LAYER. jlayeredpane. loop-index++) { labels[loop-index] . 100.~etLayer(labelc[4l.labels[l] = new JLabel("Capa predeterminada").intValue0 ) . for(int loop-index = 0.3. jlayeredpane.POPUP-LAYER. labels[5]. jlayeredpane.

3. lo que tiene sentido debido a que queremos que los componentes que el usuario arrastre pasen por encima de otros componentes. parece que se abren las distintas "carpetas" mostrando un nuevo panel completo de componentes. dice el PN. podemos añadir el componente que queramos arrastrar a la capa de arrastre. Applet started 1 Figura 15. asegurando que el gestor de distribución se haya asignado a nulo y después utilizar el método setLocation del componente para situarlo como respuesta a las acciones de ratón del usuario. Creación de paneles de lengüetas "Vaya". "Mi programa tiene tantas configuraciones ahora que el cuadro de diálogo de configuración es mayor que la pantalla". decimos. Para implementar el arrastre utilizando la capa de arrastre. puede observar que la capa de arrastre aparece por encima. lang Ob ject .3. Los paneles de lengüetas proporcionan una forma cómoda de distribuir muchos componentes en un espacio pequeño. Los paneles de lengüetas quedan soportados en la Swing con la clase JTabbedPane y aquí tenemos el diagrama de herencia para esta clase: j ava . Presenta al usuario una vista basada en las lengüetas de las carpetas de archivo y cuando el usuario hace clic sobre las diversas lengüetas. dice el programador novato. "Ah". "¿Cuánto mayor? ". "Como cuatro veces". preguntamos. Adición de componentes a un panel de capas. I . "parece que es el momento de distribuir estas opciones utilizando un panel de lengüetas".Como se muestra en la figura 15.

1 Tabla 15.2 sus constructores y la tabla 15. Component add(Component component) Component add(Component component. Object constraints. Métodos de la clase JTabbedPane. int index) Añade un componente. El modelo de selección predeterminado. Tabla 15. Tabla 15.1 muestra los campos para la clase JTabbedPane. Añade un componente al índice de lengüetas indicado. Añade un componente al panel de lengüetas.La tabla 15. la tabla 15. o RIGHT. .1. JTabbedPane(int tabplacement) Construye un JTabbedPane vacío con la disposición de lengüetas indicada por TOP. Campos de la clase JTabbedPane 1 protected ChangeEvent changeEvent protected ChangeListener changelistener protected SingleSelectionModel model protected int tabplacement El ChangeEvent. Constructores de la clase JTabbedPane. int index) void add(Component component. Construye un JTabbedPane vacío.3 sus métodos. Object constraints) void add(Component component. Dónde situamos las lengüetas. El ChangeListener añadido al modelo.2. BOTTOM. LEFT. Añade un componente en la posición de lengüeta indicada por el índice.3.

lcon icon. Obtiene el color de fondo de lengüetas en index. Obtiene los límites de lengüetas en index. Envía un ChangeEvent a cada receptor. void addTab(String title. String tip) Añade una lengüeta de ayuda representada por un título y10 icono. Obtiene el AccessibleContext asociado con este JComponent. nent component) pudiendo ser cualquiera de los dos nulos.Cornponent add(String title. protected ChangeListener createchangeListener() protected void fireStateChanged0 AccessibleContext getAccessibleContext() Color getBackgroundAt(int index) Rectangle getBoundsAt(int index) Component getComponentAt(int index) lcon getDisabledlconAt(int index) Color getForegroundAt(int index) lcon getlconAt(int index) . Component component) Añade una lengüeta representada por un título y un icono. Obtiene el componente en index. Obtiene el color de primer plano de la lengüeta en index. Component component) Añade un componente con un título de lengüetas indicado. Component component. lcon icon. cualquiera de los cuales puede ser nulo. Compo. Obtiene el icono de lengüetas en index. void addChangeListener(ChangeListener 1 Añade un ChangeListener a ) este panel de lengüetas. void addTab(String title. Obtiene el icono de la lengüeta deshabilitada en index. Sobreescribe éste método para devolver una subclase de ModelListener u otra implementación de ChangeListener. void addTab(String title.Añade la lengüeta representada por un título y10 icono.

int indexOfComponent(Component compo. Obtiene el texto de la ayuda de herramientas para el componente determinado por la posición del evento de ratón.Obtiene el índice del componente lengüeta indicado.SingleSelectionModel getModel() Component getSelectedComponent() Obtiene el modelo asociado con este panel de lengüetas. Obtiene el índice seleccionado actual para este panel de lengüetas. Obtiene el número de lengüetasdeeste panel de lengüetas. int getSelectedlndex() int getTabCount() int getTabPlacement0 int getTabRunCount() String getTitleAt(int index) String getToolTipText(MouseEvent event) String getUIClasslD() Obtiene el nombre de la clase IUque implementa la apariencia de este componente. Obtiene el número de lengüetas en ejecución actualmente en uso para visualizar lengüetas. Obtiene el componente seleccionado en curso para este panel de lengüetas. Obtiene el índice de la primera lengüeta con un título dado y devuelve -1 si no existen lengüetas con este título. int indexOfTab(String title) . Obtiene el título de la lengüeta en index. Obtiene el objeto IU que implementa la apariencia de este componente. nent) int indexOfTab(lcon icon) Obtiene el índice de la primera de las lengüetas con un icono dado. Obtiene la situación de las lengüetas para este panel de lengüetas.

Elimina la lengüeta que corresponde al componente indicado. Component component) void setDisabledlconAt(int index. Color back. Obtiene una representación de cadena de este JTabbedPane. Elimina todas las lengüetas del panel de lengüetas. lcon disabledlcon) Asigna el componente en index a Component.void insertTab(Stringtitle. lcon icon) Asigna el color de primer plano. Component component. void setModel(SingleSe1ectionModelmodel) Asigna al modelo a utilizar con este panel de lengüetas. ground) void setComponentAt(int index. Asigna el icono.Asigna el color de fondo. Asigna el índice seleccionado para este panel de lengüetas. void remove(Component component) void removeAll() void removeChangeListener(ChangeListe) ner 1 void removeTabAt(int index) void setBackgroundAt(int index. void setSelectedlndex(int index) . boolean enabled) Asigna si la lengüeta en index está habilitada. int index) boolean isEnabledAt(int index) protected String paramString() Inserta un componente representado por un título e icono. Asigna el icono inhabilitado en index a Icono. Elimina un ChangeListener de este panel de lengüetas. void setEnabledAt(intindex. void setSelectedComponent(Component c) Asigna el componente seleccionado por este panel de lengüetas. lcon icon. que puede ser nulo. Elimina la lengüeta en index. String tip. void setForegroundAt(int index. Color foreground) void setlconAt(int index. Obtiene si la lengüetaen index está actualmente habilitada.

void setTitleAt(int index.add(new JLabel("Este es el panel 1")). JPanel jpanell = new J'PanelO. Llamado por U IManager cuando cambia la apariencia. String title) void setUI(TabbedPaneU1 ui) void updateUI() Un ejemplo lo dejará más claro. /* <APPLET CODE = tabbedpane.add(new JLabel("Este es el panel 3")). Ahora.void setTabPlacement (int tabplacement) Asigna la posición d e las lengüetas para este panel d e lengüetas. JPanel jpanel3 = new ¡Panel(). por lo que crearemos un nuevo panel y utilizamos el método . crearemos un panel de lengüetas con tres lengüetas y damos a c