Problemas más comunes con los Componentes (y sus Soluciones)
Problema:¿Cómo aumentar o disminuir el número de componentes de un contenedor?
- Para añadir un componente a un contenedor, se utiliza una de las tres formas del método add() de la clase Container. Puedes ver Reglas Generales para el Uso de Componentes para más información. Para eliminar un componente de un contenedor, se utilizan los métodos remove() o removeAll() de la clase Container.
O simplemente se añade el componente a otro contenedor, y esto elimina automáticamente el componente de su contenedor anterior.
Problema: ¡Mi componente no se representa!
- ¿Has añadido el componente a un contenedor utilizando el método add() correcto para el controlador de disposición del contenedor? BorderLayout (el controlador de disposición por defecto para las ventanas), falla silenciosamente su se añade un componente llamando a la versión de un argumento de add(). Puedes ver la lección Distribuir los Componentes dentro de un Contenedor para ver ejemplos de utilización del método add().
- Si no estás utilizando el controlador de disposición por defecto, ¿has creado satisfactoriamente un ejemplar del controlador de disposición correcto y has llamado al método setLayout() del contenedor?
- Si se ha añadido correctamente el componente pero el contenedor ya podría estar visible, ¿has llamado al método validate() del contenedor después de añadir el componente?
- Si el componente es un componente personalizado (una subclase Canvas, por ejemplo), ¿implementa los métodos minimumSize() y preferredSize() para devolver el tamaño correcto del componente?
- Si no utilizas un controlador de disposición del AWT, o no utilizas ninguno, ¿tiene el componente un tamaño y unas coordenadas razonables? En particular, si se utiliza posicionamiento absoluto (sin controlador de disposición), se debe seleccionar explícitamente el tamaño de sus componentes, o no se mostrarán. Puedes ver Hacerlo sin Controlador de Disposición.
Problema: Mi componente personalizado no se actualiza cuando debería.
- Asegurate de que se llama al método repaint() del componente cada vez que la apariencia del componente deba cambiar. Para los componentes estandard, esto no es un problema, ya que el código especifico de la plataforma tiene cuidado de todo el dibujo de los componentes.
Sin embargo para los componentes personalizados, tiene que llamar explícitamente al método repaint() del componente siempre que deba cambiar su apariencia. Lamar al método repaint() del contenedor del componente no es suficiente. Puedes ver Cómo Utilizar la Clase Canvas para más información.
Problema: Mi componente no obtiene el evento XYZ.
- Comprueba si el componente obtiene algún evento. Si no lo hace, asegurate de que te estás refiriendo al componente correcto -- que ha ejemplarizado la clase correcta, por ejemplo.
- Asegurate de que el componente pueda capturar la clase de eventos que se quiere capturar. Por ejemplo, muchos componentes estandard no capturan eventos del ratón, por eso el AWT no puede generar objetos Event para ellos. ¿Se puede utiliza otro tipo de evento como ACTION_EVENT (manejado por el método action()), en su lugar? Si no es así, te podrías ver forzado a implementar una subclase de Canvas (o de Panel o Applet) para que la clase pueda ver todos los eventos que ocurran.
Problema: Mi aplicación no puede obtener un evento WINDOW_DESTROY, por eso no puede cerrar mi ventana (o salir de la aplicación)!
- En una subclase de Frame , implementa el método handleEvent() para que reaccione al evento WINDOW_DESTROY. No se puede capturar eventos WINDOW_DESTROY en una subclase de Panel, por ejemplo, ya que el Frame es superior en el árbol de herencia. Para salir, utilice System.exit(). Para destruir la ventana, se puede llamar a dispose() o puede hide() el Frame y, dejar de utilizarlo asegurándose de que todas las referencias se ponen a null.
Problema: Todos estos ejemplos son applets. ¿Cómo puedo aplicarlo a las aplicaciones?
- Excepto donde se ha avisado, en cualquier lugar de esta ruta donde vea una subclase de la clase Applet, se puede sustituirla por una subclase de la clase Panel, o si la clase no es utilizada como contenedor , una subclase de la clase Canvas. En general, es sencillo convertir un applet en una aplicación, siempre que el applet no utilice ninguna de las habilidades especiales de los applets (como utilizar métodos definidos en la clase Applet).
Para convertir un applet en una aplicación, se necesita añadir un método main() que cree un ejemplar de una subclase de Frame, cree un ejemplar de una subclase de Applet (o Panel, o Canvas), añade el ejemplar al Frame, y luego llame a los método init() y start() del ejemplar. La subclase Frame debería tener una implementación de handleEvent() que maneje eventos WINDOW_DESTROY de la forma apropiada.
Problema: Siempre que ejecuto una aplicación Java con un GUI, obtengo este mensaje:
Warning:
Cannot allocate colormap entry for default background
- Este mensaje sólo ocurre en sistemas Motif. Ocurre cuando la librería Motif es inicialziada y encuentra que no hay sitio en el colormap por defecto para asignar sus colores del GUI. La solución es ejecutar aplicaiones más pequeñas en su escritorio. El sistema de ejecución de Java se adapta a sí mismo a los colores de la paleta por defecto, pero la
librería Motif es menos generosa.
Si no has visto aquí tu problema puedes ver Problemas más comunes con la Disposición y, para los componentes personalizados, Problemas más comunes con los Gráficos.
También podrías arrojar luz sobre un problema leyendo Detalles de la Arquitectura de Componentes.
Ozito