+ All Categories
Home > Documents > Untitled

Untitled

Date post: 13-Aug-2015
Category:
Upload: api-202444860
View: 186 times
Download: 0 times
Share this document with a friend
Popular Tags:
96
Capitulo 5. SWING 5.1. Introducción 5.2. Contenedores de Alto Nivel 5.2.1. JWindow 5.2.2. JFrame 5.2.3. JDialog 5.3. Contenedores Intermedios 5.3.1. JPanel 5.3.2. JScrollPane 5.3.3. JSplitPane 5.4. Widgets 5.4.1. JLabel 5.4.2. JTextField 5.4.3. JTextArea 5.4.4. JButton 5.4.5. JCheckBox 5.4.6. RadioButton y ButtonGroup 5.4.7. JComboBox 5.4.8. JList 5.4.9. JTable 5.4.10. JTree 5.5. Layout 5.5.1. El layout null 5.5.2. FrowLayout 5.5.3. BoxLayout 5.5.4. GridLayout 5.5.5. BorderLayout 5.5.6. GridBagLayout 5.5.7. CardLayout 5.5.8. SpringLayout 5.6. Bean y Clases serializables 5.7. Look and Fiel 5.8. Archivos de Properties 5.9. Tablas y Modelos 5.10. Barras de Menú y Menús Contextuales 5.11. Drag-and-drop 5.12. DefaultTableCellRenderer y DefaultCellEditor 5.13. Ejemplos 5.14. Evaluacion Ing. Elkin Doney Suárez Gómez MBA
Transcript
Page 1: Untitled

Capitulo 5. SWING 5.1. Introducción 5.2. Contenedores de Alto Nivel 5.2.1. JWindow 5.2.2. JFrame 5.2.3. JDialog 5.3. Contenedores Intermedios 5.3.1. JPanel 5.3.2. JScrollPane 5.3.3. JSplitPane 5.4. Widgets 5.4.1. JLabel 5.4.2. JTextField 5.4.3. JTextArea 5.4.4. JButton 5.4.5. JCheckBox 5.4.6. RadioButton y ButtonGroup 5.4.7. JComboBox 5.4.8. JList 5.4.9. JTable 5.4.10. JTree 5.5. Layout 5.5.1. El layout null 5.5.2. FrowLayout 5.5.3. BoxLayout 5.5.4. GridLayout 5.5.5. BorderLayout 5.5.6. GridBagLayout 5.5.7. CardLayout 5.5.8. SpringLayout 5.6. Bean y Clases serializables 5.7. Look and Fiel 5.8. Archivos de Properties 5.9. Tablas y Modelos 5.10. Barras de Menú y Menús Contextuales 5.11. Drag-and-drop 5.12. DefaultTableCellRenderer y DefaultCellEditor 5.13. Ejemplos 5.14. Evaluacion

Ing. Elkin Doney Suárez Gómez MBA

Page 2: Untitled

Capitulo 5. SWING

5. 1. Introducción La mayor parte de las aplicaciones que se utilizan hoy en dia incluyen interfaces de

usuario mas sofisticadas que las de las apliaciones que se ejecutan modo consola.

Java incluye, como parte de su biblioteca de clases estándar, un conjunto de

componentes para crear interfaces graficas de usuario. Los componentes que se

utilizan en Java para crear interfaces graficas de usuario se agrupan en dos paquetes

AWT y SWING.

Los componentes AWT dependen de las facilidades graficas ofrecidas por cada

sistema operativo. Los programas escritos con AWT tendrá un “look and fiel” distinto

en Windows y en UNIX. SWING es 100% Java y por tanto completamente

independiente de la plataforma, los componentes graficos se pintan en tiempo de

ejecución por lo que las aplicaciones SWING suelen ser algo mas lentas que las AWT.

Cuando se creo SWING se hizo con el objetivo de evitar tener que usar los

componentes gráficos nativos de cada sistema operativo, y crear una interfaz que

fuera la misma en cualquier sistema operativo. Además el tener que usar los

componentes nativos generaba problemas ya que no se sabe como se comporta la

aplicación según el sistema operativo en el que fuese lanzado, al estar SWING

enteramente desarrollado en Java aumenta su portabilidad asegurando un

comportamiento idéntico en diferentes plataformas.

Page 3: Untitled

5.2. Contenedores de Alto Nivel

Un componente es un objeto que tiene una representación gráfica y que puede ser

mostrado por pantalla y que puede ser utilizado por el usuario

Los contenedores son componentes que pueden incluir a otros componentes. Utilizan

como base la clase java.awt.Component que está definida como abstracta.

Métodos de Información de la clase Component.

o String getName(). Obtiene el nombre del componente.

o void setName(String nombre). cambia el nombre del componente.

o Container getParent(). Devuelve el contenedor que sostiene a este

componente.

Métodos de apariencia y posición de la clase Component

o void setVisible(boolean b). Muestra u oculta el componente según el

valor del argumento sea true o false.

o Color getForeground(). Devuelve el color de frente.

o void setForeGround(Color color). Cambia el color frontal.

o Color getBackground(). Devuelve el color de fondo

o void setBackground(Color color). Cambia el color de fondo

o Point getLocation(). Devuelve la posición del componente en forma de

objeto Point.

o void setLocation(int x, int y). Coloca el componente en la posición x, y.

o void setLocation(Point p). Coloca el componente en la posición marcada

por las coordenadas del punto p.

o Dimension getSize(). Devuelve el tamaño del componente en un objeto

de tipo java.awt.Dimension.

o void setSize(Dimension d) o void setSize(int ancho, int alto). Cambia las

dimensiones del objeto en base a un objeto Dimension o indicando la

anchura y la altura con dos enteros.

o void setBounds(int x, int y, int ancho, int alto). Determina la posición de

la ventana (en la coordenada x, y) así como su tamaño con los

parámetros ancho y alto

o void setPreferredSize(Dimension d). Cambia el tamaño preferido del

componente. Este tamaño es el que el componente realmente quiere

tener.

Page 4: Untitled

o Cursor getCursor(). Obtiene el cursor del componente en forma de

objeto java.awt.Cursor

o void setCursor(Cursor cursor). Cambia el cursor del componente por el

o especificado en el parámetro.

o void setFont(Font fuente). Permite especificar el tipo de letra de la

fuente del texto.

Los objetos java.awt.Point tienen como propiedades públicas las coordenadas x e y.

Se construyen indicando el valor de esas coordenadas y disponen de varios métodos

que permiten modificar el punto. Los objetos java.awt.Dimension tienen como

propiedades la propiedad width (anchura) y height (altura). Los objetos java.awt.Color

representan colores y algunos constructores son:

Color(int rojo, int verde, int azul). Construye un objeto color indicando los

niveles de rojo, verde y azul.

Color(int rgb). Crea un color usando un único entero que indica los niveles de

rojo, verde y azul. Se suele emplear con 6 dígitos en hexadecimal. Ejemplo:

0xFFCC33.

Color(int rojo, int verde, int azul, int alfa). Construye un objeto color indicando

los niveles de rojo, verde y azul, y un valor de 0 a 255 indicando el valor alfa

(alfa indica la transparencia).

Además existen constantes de colores ya fabricados: Color.RED, Color.YELLOW,

Color.GREEN, Color.BLUE, Color.PINK, Color.GRAY, Color.CYAN,

Color.DARK_GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.PINK y

Color.WHITE.

Finalmente java.awt.Cursor es una clase que representa cursores y que se crea

indicando un número que se puede reemplazar por una serie de constantes estáticas

de la propia clase Cursor, que representan cursores. Las constantes son:

Cursor.HAND_CURSOR, Cursor.WAIT_CURSOR, Cursor.CROSSHAIR_CURSOR,

Cursor.TEXT_CURSOR, Cursor.DEFAULT_CURSOR y otros.

Métodos de dibujo de la clase Component

o void paint(Graphics p). Pinta el componente y sus subcomponentes.

Delega sus funciones en los tres métodos siguientes

Page 5: Untitled

o void paintComponents(Graphics p). Llama a los métodos de pintura de

todos los componentes de la ventana.

o void update(Graphics g). Llama a paint.

Activar y Desactivar componentes de la clase Component

o void setEnabled(boolean activar). Si el argumento es true se habilita el

componente, si no, se deshabilita.

Para que un componente sea al que van dirigidas las pulsaciones de las teclas o,

dicho de otra forma, el que recibe la interacción del usuario, debe poseer el enfoque

(focus). En muchos casos, el enfoque salta de un control al siguiente pulsando la tecla

tabulador. Varios métodos se encargan de controlar ese salto:

void requestFocus(). Pide el foco para el componente. Será posible, si este es

visible, activado y enfocable focusable. El contenedor del foco también poseerá

el foco.

boolean requestFocusInWindow(). Pide el foco para el componente si la

ventana contenedora poseía el foco. Devuelve true si el foco se puede dar sin

problemas. Aunque sólo el evento FOCUS_GAINED es el encargado de indicar

que el foco ha sido pasado. Actualmente, debido a que el método anterior es

dependiente de la plataforma, se recomienda este método siempre que sea

posible.

void transferFocus(). Hace que el siguiente componente en la lista de

tabulaciones, obtenga el foco.

void transferFocusBackward(). El foco pasa al anterior componente en la lista

de tabulaciones.

Estos métodos de la clase Container permiten obtener información sobre componentes

de un contenedor:

Component[] getComponents(). Devuelve un array de componentes con todos

los componentes correspondientes al contenedor actual

void list(PrintWriter out). Escribe en el objeto PrintWriter indicado, la lista de

componentes.

Page 6: Untitled

Component getComponentAt(int x, int y). Indica qué componente se encuentra

en esas coordenadas (calculadas dentro del sistema de coordenadas del

contenedor).

5.2.1. JWindow Este objeto deriva de la clase java.awt.Window que a su vez deriva de

java.awt.Container. Se trata de un objeto que representa un marco de ventana simple,

sin borde, ni ningún elemento. Sin embargo son contenedores a los que se les puede

añadir información. Estos componentes suelen estar dentro de una ventana de tipo

JFrame.

Constructores:

o JWindow(). Crea un marco de ventana típico e independiente.

o JWindow(Frame padre). Crea un marco de ventana dentro de la

ventana tipo Frame indicada.

o JWindow(Window padre). Crea un marco de ventana dentro de la

ventana indicada.

o JWindow(GraphicsConfiguration gc). Crea una nueva ventana usando la

configuración gráfica indicada

o JWindow(Window padre,GraphicsConfiguration gc). Crea una ventana

dentro de la padre con la configuración de gráficos indicada

5.2.2. JFrame

Objeto que representa una ventana típica con bordes, botones: cerrar, restaurar y

minimizar. Toda aplicación debe tener un único JFrame principal.

La manera más adecuada de crear un JFrame es:

Page 7: Untitled

Todos las clases que vayamos a crear deben extender de un componente SWING, es

este caso “MiFrame” hereda de un JFrame. Los objetos JFrame derivan de la clase

Frame que, a su vez deriva, también de la clase Window. Los objetos JFrame son

ventanas completas. Eclipse genera la siguiente estructura de código.

import javax.swing.JFrame;

public class MiFrame extends JFrame {

public static void main(String[] args) {

// TODO Auto-generated method stub

}

}

Constructores

o JFrame(). Crea una ventana con la configuración normal.

o JFrame(GraphicsConfiguration gc). Crea una nueva ventana usando la

configuración gráfica indicada

o JFrame(String titulo). Crea una ventana con el título indicado.

o JFrame(String titulo, GraphicsConfiguration gc). Crea una ventana con

el título y la configuración gráfica indicada.

Métodos

o void setDefaultCloseOperation(int modo) Indica el modo de cerrar la

ventana, en sustitución del entero se puede utilizar los siguientes

valores:

Page 8: Untitled

JFrame.EXIT_ON_CLOSE. Al cerrar la ventana, se acaba el

programa.

JFrame.DO_NOTHING_ON_CLOSE. No se hace nada al cerrar

la ventana

JFrame.HIDE_ON_CLOSE. Esconde la ventana al cerrarla.

JFrame.DISPOSE_ON_CLOSE. Esconde la ventana y se

deshace de ella. El programa acaba cuando todas las ventanas

han sido cerradas con esta opción.

void setResizable(boolean b). Con true la ventana es cambiable

de tamaño, en false la ventana tiene tamaño fijo.

void setTitle(String t). Cambia el título de la ventana

void pack() Ajusta la ventana a tamaño suficiente para ajustar

sus contenidos

void setState(int estado) Coloca la ventana en uno de estos dos

estados:

Frame.NORMAL

Frame.ICONOFIED.

setExtendedState(int estado). Idéntica a la anterior pero añade

tres estados:

JFrame.MAXIMIZED_HOR. Maximizada horizontal

JFrame.MAXIMIZED_VER. Maximizada vertical

JFrame.MAXIMIZED_BOTH. Maximizada completa

int getState() Indica el estado de la ventana.

int getExtendedState() Indica el estado de la ventana.

o setVisible(boolean b). True para mostrar ventana, false la ventana se

oculta.

o void toBack(). Coloca la ventana al fondo, el resto de ventanas

aparecen por delante

o void toFront(). Envía la ventana al frente (además le dará el foco).

Se le implemento a la clase “MiFrame” el constructor por defecto MiFrame, y la palabra

super llama al constructor del padre “JFrame” el cual crea una ventana con

configuración normal. El método inicializar permite el uso se ciertos métodos del

JFrame vistos anteriormente y el método showCentered permite centrar la ventana en

la pantalla del PC.

Page 9: Untitled

import java.awt.Dimension;

import java.awt.Frame;

import java.awt.Toolkit;

import javax.swing.JFrame;

public class MiFrame extends JFrame {

public MiFrame() {

super();

inicializar();

}

public void inicializar(){

Dimension screenSize = null;

try {

this.setTitle("Mi primer frame");

this.setExtendedState(Frame.MAXIMIZED_BOTH);

this.setResizable(true);

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.getExtendedState();

this.getState();

screenSize = Toolkit.getDefaultToolkit().getScreenSize();

if (screenSize.width < 1024){

setSize(800, 600);

}

else{

setSize(1024, 768);

}

} catch (java.lang.Throwable ivjExc){}

}

public void showCentered(int xOffset, int yOffset) {

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

Dimension frameSize = getSize();

if (frameSize.height > screenSize.height){

frameSize.height = screenSize.height;

}

if (frameSize.width > screenSize.width){

frameSize.width = screenSize.width;

}

int nXPos = (screenSize.width - frameSize.width) / 2 + xOffset;

int nYPos = (screenSize.height - frameSize.height) / 2 + yOffset;

setLocation(nXPos, nYPos);

setVisible(true);

}

public static void main(String[] args) {

new MiFrame().showCentered(0, 0);

}

}

Page 10: Untitled

5.2.3. JDialog Clase que genera un cuadro de diálogo. JDialog deriva de la clase AWT Dialog que es

subclase de Window. Representa un cuadro de diálogo que es una ventana

especializada para realizar operaciones complejas.

La forma más adecuada de crear un JDialog se muestra a continuación:

La clase “MiDialog” hereda de un JDialog, el IDE Eclipse genera la siguiente estructura

de código.

Page 11: Untitled

public class MiDialog extends JDialog {

public static void main(String[] args) {

// TODO Auto-generated method stub

}

}

Constructores

o JDialog(). Crea una ventana con la configuración normal.

o JDialog(Frame propietaria). Crea un nuevo cuadro de diálogo, indicando

como padre la ventana seleccionada

o JDialog(Frame propietaria, boolean modal). Crea un nuevo cuadro de

diálogo, indicando como padre la ventana seleccionada. Poniendo a

true el segundo parámetro, el cuadro de diálogo pasa a ser modal. Una

ventana modal obliga al usuario a contestar al cuadro antes de que

pueda continuar trabajando.

o JDialog(Frame propietaria, String título). Crea un cuadro de diálogo

perteneciente a la ventana indicada y poniendo el título deseado.

o JDialog(Frame propietaria, String título, boolean modal). Crea un cuadro

de diálogo perteneciente a la ventana indicada, poniendo el título

deseado e indicando si se desea el cuadro en forma modal.

o JDialog(Frame propietaria, String título, boolean modal,

GraphicsConfiguration gc). Lo mismo, pero además indicando una

posible configuración gráfica.

Es recomendable definir varios constructores para la clase “MiDialog”, ya que este

puede tener como padre una clase que herede de un JFrame o un JDialog o ninguna

ventana como padre.

import java.awt.Dialog;

import java.awt.Dimension;

import java.awt.Frame;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.JDialog;

public class MiDialog extends JDialog {

public MiDialog(Frame frame) {

super(frame,true);

inicializar();

}

public MiDialog(Dialog dialog) {

super(dialog,true);

Page 12: Untitled

inicializar();

}

public MiDialog() {

this((Frame) null);

}

private void inicializar(){

this.setSize(new Dimension(450, 270));

this.setResizable(false);

this.setTitle("Mi primer dialog");

this.setLocationRelativeTo(null);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e){

dispose();

}

});

}

public static void main(String[] args) {

new MiDialog().setVisible(true);

}

}

5.3. Contenedores Intermedios La mayoría de los componentes Swing están implementados como subclases de la

clase JComponent, que desciende de la clase Container y esta desciende de

Component. Algunas de las funcionalidades de la clase JComponent son:

Bordes. Usando el método setBorder, podemos especificar el borde que

muestra un componente alrededor de sus lados. Podemos especificar que un

componente tenga un espacio extra alrededor de sus lados usando un ejemplar

de EmptyBorder.

Doble buffer. El doble buffer puede mejorar la apariencia de un componente

que cambie frecuentemente. Ahora no tenemos que escribir nosotros el código

del doble buffer -- Swing nos los proporciona. Por defecto, los componentes

Page 13: Untitled

Swing usan el doble Buffer. Llamando al método setDoubleBuffered(false)

sobre un componente se desactiva el doble buffer.

Tool tips. Especificando un String con el método setToolTipText, podemos

proporcionarle ayuda al usuario de un componente. Cuando el cursor se para

sobre el componente, el String especificado se muestra en una pequeña

ventana que aparece cerca del componente.

Navegación con Teclado. Usando el método registerKeyboardAction, podemos

permitir que el usuario use el teclado en vez del ratón para moverse por el GUI.

void paintComponent(Graphics p). Pinta sólo este componente. Este es el

método recomendado en Swing para dibujar en un componente.

void paintChildren(Graphics p). Pinta los componentes hijo de este

componente.

void paintBorder(Graphics p). Pinta el borde del componente protected

Graphics.

getComponentGraphics(Graphics g). Obtiene el objeto gráfico utilizado para

dibujar el componente. El argumento es el objeto gráfico original. El otro es el

tratado por el componente.

void setNextFocusableComponent(Component c). Hace que el componente c

sea el siguiente en la lista de tabulaciones.

Component getNextFocusableComponent(). Obtiene el siguiente componente

de la lista de tabulaciones.

Los contenedores intermedios son aquellos que se colocan en el contenedor de alto

nivel y que su vez pueden contener otros componentes o Widgets. A continuación se

presentan los contenedores intermedios.

5.3.1. JPanel

Un JPanel permite agrupar a otros componentes, para el siguiente ejemplo se utilizo el

layout “BorderLayout” de la clase “MiDialog”. Este layout es el que usa por defecto el

JDialog.

import java.awt.BorderLayout;

import java.awt.Dialog;

import java.awt.Dimension;

import java.awt.Frame;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.JDialog;

Page 14: Untitled

import javax.swing.JPanel;

public class MiDialog extends JDialog {

private JPanel ejemploPanel;

public MiDialog(Frame frame) {

super(frame,true);

inicializar();

}

public MiDialog(Dialog dialog) {

super(dialog,true);

inicializar();

}

public MiDialog() {

this((Frame) null);

}

private void inicializar(){

this.setSize(new Dimension(450, 270));

this.setResizable(false);

this.setTitle("Mi primer dialog");

this.setLocationRelativeTo(null);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e){

dispose();

}

});

getContentPane().add(getEjemploPanel(), BorderLayout.CENTER);

}

protected JPanel getEjemploPanel() {

if (ejemploPanel == null) {

ejemploPanel = new JPanel();

}

return ejemploPanel;

}

public static void main(String[] args) {

new MiDialog().setVisible(true);

}

}

Cuando se diseñan ventanas, se usa el editor de diseño de WindowBuilder Pro, este

editor se puede configurar de tal manera que genera un método ya sea protegido o

privado para el componente que se desea agregar en el contenedor de alto nivel:

JFrame o JDialog. En el ejemplo anterior se crea una variable de tipo JPanel llamada

“ejemploPanel” esta variable es privada. Se mantiene el concepto de que todas las

variables de clase deben ser privadas. Esta variable la coloca el editor en el código

una vez estemos agregando componentes e inmediatamente crea el siguiente método:

protected JPanel getEjemploPanel() {

if (ejemploPanel == null) {

ejemploPanel = new JPanel();

}

Page 15: Untitled

return ejemploPanel;

}

La estructura de este método permite que el componente solo se cree una sola vez, es

recomendable acceder al componente por la llamada del método. getEjemploPanel()

ya sea dentro de la clase o fuera de la clase.

Dentro de este método podemos agregar propiedades adicionales para el

componente, por ejemplo color, tamaño, border etc.

En el constructor de la clase el editor genero la siguiente línea de código:

getContentPane().add(getEjemploPanel(), BorderLayout.CENTER);

Esa línea de código permite agregar el componente “EjemploPanel” en el centro del

contenedor de alto nivel en este caso la clase “MiDialog”.

Ahora si la idea es tener un contenedor intermedio en la parte norte, centro y sur del

dialogo. La estructura de diseño y código es:

import java.awt.BorderLayout;

import java.awt.Dialog;

import java.awt.Dimension;

import java.awt.Frame;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.JDialog;

import javax.swing.JPanel;

public class MiDialog extends JDialog {

private JPanel surPanel;

private JPanel nortePanel;

private JPanel centroPanel;

public MiDialog(Frame frame) {

super(frame,true);

inicializar();

}

public MiDialog(Dialog dialog) {

super(dialog,true);

inicializar();

}

public MiDialog() {

this((Frame) null);

}

private void inicializar(){

this.setSize(new Dimension(450, 270));

Page 16: Untitled

this.setResizable(false);

this.setTitle("Mi primer dialog");

this.setLocationRelativeTo(null);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e){

dispose();

}

});

getContentPane().add(getCentroPanel(), BorderLayout.CENTER);

getContentPane().add(getNortePanel(), BorderLayout.NORTH);

getContentPane().add(getSurPanel(), BorderLayout.SOUTH);

}

protected JPanel getCentroPanel() {

if (centroPanel == null) {

centroPanel = new JPanel();

}

return centroPanel;

}

protected JPanel getNortePanel() {

if (nortePanel == null) {

nortePanel = new JPanel();

nortePanel.setPreferredSize(new Dimension(0, 40));

}

return nortePanel;

}

protected JPanel getSurPanel() {

if (surPanel == null) {

surPanel = new JPanel();

surPanel.setPreferredSize(new Dimension(0, 40));

}

return surPanel;

}

public static void main(String[] args) {

new MiDialog().setVisible(true);

}

}

Page 17: Untitled

5.3.2. JScrollPane

Proporciona una vista desplazable de un componente ligero. Cuando el estado de la

pantalla real está limitado, se utiliza un ScrollPane para mostrar un componente que

es grande o cuyo tamaño puede cambiar dinámicamente. Ejemplo: JTable, JTree y

JTextArea.

Todo componente JPanel utiliza el layout “FrowLayout”, como layout por defecto. Para

agregar un JScrollPane en la región central del panel “centroPanel” se debe modificar

la propiedad layout del panel por “BorderLayout”.

La estructura de diseño y código se muestra a continuación:

private JScrollPane centroScrollPane;

protected JPanel getCentroPanel() {

if (centroPanel == null) {

centroPanel = new JPanel();

centroPanel.setLayout(new BorderLayout());

centroPanel.add(getCentroScrollPane(), BorderLayout.CENTER);

}

return centroPanel;

}

protected JScrollPane getCentroScrollPane() {

if (centroScrollPane == null) {

centroScrollPane = new JScrollPane();

}

return centroScrollPane;

}

Lo nuevo que el editor de diseño genera para la clase “MiDialog” es:

Una variable privada llamada “centroScrollPane” de tipo JScrollPane

centroPanel.setLayout(new BorderLayout()); Para el panel que va a contener el JScrollPane.

Page 18: Untitled

centroPanel.add(getCentroScrollPane(), BorderLayout.CENTER); agregar el

JScrollPanel al panel.

El método protegido para el componente JScrollPane.

5.3.3. JSplitPane

Contiene dos componentes de peso ligero, separados por un divisor. Arrastrando el

divisor, el usuario puede especificar qué cantidad de área pertenece a cada

componente. Un SplitPane se utiliza cuando dos componentes contienen información

relacionada y queremos que el usuario pueda cambiar el tamaño de los componentes

en relación a uno o a otro.

5.4. Widgets Son una representación visible de un componente que puede ser manipulada por el

usuario. Botones, campos de texto y barras de desplazamiento.

5.4.1. JLabel

La clase JLabel se utiliza para crear etiquetas de texto.

El siguiente ejemplo agregar una JLabel al panel del norte de la clase “MiDialog”.

private JLabel ejemploLabel;

protected JPanel getNortePanel() {

if (nortePanel == null) {

nortePanel = new JPanel();

nortePanel.setPreferredSize(new Dimension(0, 40));

nortePanel.add(getEjemploLabel());

}

return nortePanel;

}

protected JLabel getEjemploLabel() {

if (ejemploLabel == null) {

ejemploLabel = new JLabel();

ejemploLabel.setText("Ejemplo de una JLabel");

}

return ejemploLabel;

}

Page 19: Untitled

5.4.2. JTextField

Los objetos de esta clase se utilizan para el usuario pueda introducir datos a la

aplicación.

El siguiente ejemplo agrega una JLabel y un JTextField al panel sur del de la clase

“MiDialog”. Se modifica la propiedad layout del panel y se coloca null para agregar los

objetos más fácil.

private JTextField ejemploTextField;

private JLabel buscarLabel;

protected JPanel getSurPanel() {

if (surPanel == null) {

surPanel = new JPanel();

surPanel.setLayout(null);

surPanel.setPreferredSize(new Dimension(0, 40));

surPanel.add(getBuscarLabel());

surPanel.add(getEjemploTextField());

}

return surPanel;

}

protected JLabel getBuscarLabel() {

if (buscarLabel == null) {

buscarLabel = new JLabel();

buscarLabel.setText("Buscar");

buscarLabel.setBounds(294, 10, 50, 16);

}

return buscarLabel;

}

protected JTextField getEjemploTextField() {

if (ejemploTextField == null) {

ejemploTextField = new JTextField();

ejemploTextField.setBounds(350, 8, 87, 20);

Page 20: Untitled

}

return ejemploTextField;

}

5.4.3. JTextArea

Los objetos de esta clase se utilizan para introducir datos de tipo texto de gran

tamaño.

5.4.4. JButton

Un objeto de esta clase representa un botón. El siguiente ejemplo agrega un botón en

el panel sur de la clase “MiDialog”. Se agrega el evento addActionListener al botón.

Esta interfaz implementa el método actionPerformed que permite detectar los clics que

se hacen con el mouse sobre el botón.

private JButton ejemploButton;

protected JPanel getSurPanel() {

if (surPanel == null) {

surPanel = new JPanel();

surPanel.setLayout(null);

surPanel.setPreferredSize(new Dimension(0, 40));

surPanel.add(getBuscarLabel());

surPanel.add(getEjemploTextField());

surPanel.add(getEjemploButton());

}

return surPanel;

}

protected JButton getEjemploButton() {

if (ejemploButton == null) {

ejemploButton = new JButton();

ejemploButton.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

dispose();//metodo que cierra el dialogo

Page 21: Untitled

}

});

ejemploButton.setText("Cerrar");

ejemploButton.setBounds(10, 10, 80, 23);

}

return ejemploButton;

}

5.4.5. JCheckBox

Nos permite seleccionar varias opciones marcando el cuadrito que aparece a su

izquierda. El cuadrito pulsado equivale a un "sí" y sin pulsar a un "no" o, lo que es lo

mismo, a "true" o "false".

El siguiente ejemplo crea un JCheckBox en el panel sur de la clase “MiDialog”. Se

agrega el evento addActionListener al checkbox. Esta interfaz implementa el método

actionPerformed que permite detectar los clics que se hace con el mouse sobre el

JCheckbox. Este JCheckBox permite ocultar o mostrar la label y la caja de texto que

se muestra en la parte derecha del panel.

private JCheckBox ejemploCheckBox;

protected JPanel getSurPanel() {

if (surPanel == null) {

surPanel = new JPanel();

surPanel.setLayout(null);

surPanel.setPreferredSize(new Dimension(0, 40));

surPanel.add(getBuscarLabel());

surPanel.add(getEjemploTextField());

surPanel.add(getEjemploButton());

surPanel.add(getEjemploCheckBox());

}

return surPanel;

Page 22: Untitled

}

protected JCheckBox getEjemploCheckBox() {

if (ejemploCheckBox == null) {

ejemploCheckBox = new JCheckBox();

ejemploCheckBox.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

getEjemploTextField().setVisible(ejemploCheckBox.isSelected());

getBuscarLabel().setVisible(getEjemploTextField().isVisible());

}

});

ejemploCheckBox.setText("Mostrar búsqueda");

ejemploCheckBox.setBounds(119, 8, 153, 24);

ejemploCheckBox.setSelected(true);

}

return ejemploCheckBox;

}

5.4.6. JRadioButton y ButtonGroup

Permite al usuario seleccionar una única opción entre un grupo de elecciones. El

ButtonGroup agrupa los JRadioButtons de forma que solo pueda estar seleccionado

uno de ellos.

En el siguiente ejemplo se crea tres JRadioButton en el panel norte de la clase

“MiDialog”. Se modifica la propiedad layout del panel por null, para agregar más fácil

los componentes. Estos JRadioButton cambian el color del fondo del panel del sur por

medio de la propiedad setBackground.

private JRadioButton verdeRadioButton;

private JRadioButton azulRadioButton;

private JRadioButton blacoRadioButton;

protected JRadioButton getBlacoRadioButton() {

if (blacoRadioButton == null) {

blacoRadioButton = new JRadioButton();

blacoRadioButton.addActionListener(new ActionListener() {

Page 23: Untitled

public void actionPerformed(final ActionEvent e) {

getSurPanel().setBackground(Color.WHITE);

}

});

blacoRadioButton.setText("Blanco");

blacoRadioButton.setBounds(0, 25, 72, 24);

getAgruparButtonGroup().add(blacoRadioButton);

}

return blacoRadioButton;

}

protected JRadioButton getAzulRadioButton() {

if (azulRadioButton == null) {

azulRadioButton = new JRadioButton();

azulRadioButton.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

getSurPanel().setBackground(Color.BLUE);

}

});

azulRadioButton.setText("Azul");

azulRadioButton.setBounds(72, 25, 66, 24);

getAgruparButtonGroup().add(azulRadioButton);

}

return azulRadioButton;

}

protected JRadioButton getVerdeRadioButton() {

if (verdeRadioButton == null) {

verdeRadioButton = new JRadioButton();

verdeRadioButton.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

getSurPanel().setBackground(Color.GREEN);

}

});

verdeRadioButton.setText("Verde");

verdeRadioButton.setBounds(135, 25, 129, 24);

getAgruparButtonGroup().add(verdeRadioButton);

}

return verdeRadioButton;

}

protected ButtonGroup getAgruparButtonGroup(){

if(agruparButtonGroup == null){

agruparButtonGroup = new ButtonGroup();

}

return agruparButtonGroup;

}

Page 24: Untitled

Se modifico la propiedad setOpaque se JCheckBox en false.

5.4.7. JComboBox

Sirve para mostrar una lista desplegable de elementos.

En el siguiente ejemplo se crea un JComboBox en el panel sur de la clase “MiDialog”.

Para llenar el JComboBox de elementos se utilizo un objeto de la clase

DefaultComboBoxModel, por lo general casi la mayoría de componentes de SWING se

basan en modelos.

private JComboBox ejemploComboBox;

protected JPanel getSurPanel() {

if (surPanel == null) {

surPanel = new JPanel();

surPanel.setLayout(null);

surPanel.setPreferredSize(new Dimension(0, 40));

surPanel.add(getBuscarLabel());

surPanel.add(getEjemploTextField());

surPanel.add(getEjemploButton());

surPanel.add(getEjemploCheckBox());

surPanel.add(getEjemploComboBox());

}

return surPanel;

}

Page 25: Untitled

protected JCheckBox getEjemploCheckBox() {

if (ejemploCheckBox == null) {

ejemploCheckBox = new JCheckBox();

ejemploCheckBox.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

getEjemploTextField().setVisible(ejemploCheckBox.isSelected());

getBuscarLabel().setVisible(getEjemploTextField().isVisible());

getEjemploComboBox().setVisible(getEjemploTextField().isVisible());

}

});

ejemploCheckBox.setText("Mostrar búsqueda");

ejemploCheckBox.setBounds(99, 6, 153, 24);

ejemploCheckBox.setSelected(true);

ejemploCheckBox.setOpaque(false);

}

return ejemploCheckBox;

}

protected JComboBox getEjemploComboBox() {

if (ejemploComboBox == null) {

ejemploComboBox = new JComboBox();

ejemploComboBox.setBounds(284, 8, 78, 20);

DefaultComboBoxModel modelo = new DefaultComboBoxModel();

modelo.addElement("");

modelo.addElement("Código");

modelo.addElement("Nombre");

modelo.addElement("Apellido");

ejemploComboBox.setModel(modelo);

}

return ejemploComboBox;

}

Page 26: Untitled

5.4.8. JList

Los objetos de esta clase sirven para mostrar una lista con elementos.

5.4.9. JTable

Objetos del tipo JTable sirven para mostrar información en forma tabular.

En el siguiente ejemplo se agregar una JTable a “centroScrollPane” de la clase

“MiDialog”.

private JTable ejemploTable;

private TableRowSorter<TableModel> modeloOrdenado;

protected JScrollPane getCentroScrollPane() {

if (centroScrollPane == null) {

centroScrollPane = new JScrollPane();

centroScrollPane.setViewportView(getEjemploTable());

}

return centroScrollPane;

}

protected JTable getEjemploTable() {

if (ejemploTable == null) {

final String [] nombreCol = {"Codigo","Nombre","Telefono","Barrio"} ;

Object [] [] datos = {

{"1", "Oscar Corredor", "6453720", "La cumbre"},

{"2", "Andrea Lizcano", "6879371", "La aurora"},

{"3", "Angel Lizcano", "6879379", "Provenza"},

{"4", "Carolina Gómez", "6879373", "Niza"},

{"5", "Catalina Rodriguez", "6879374", "Diamante I" }

};

ejemploTable = new JTable(datos, nombreCol);

modeloOrdenado = new TableRowSorter<TableModel>

(ejemploTable.getModel());

ejemploTable.setRowSorter(modeloOrdenado);

}

return ejemploTable;

Page 27: Untitled

Con pasarle al JTable una instancia de TableRowSorter, a partir de ese momento,

haciendo click en la cabecera de las columnas con el ratón, ordenaremos el JTable en

orden ascendente o descendente alternativamente según esa columna.

Para filtrar por los elementos del comboBox, sólo tenemos que pasarle a nuestro

TableRowSorter un RowFilter una columna concreta, por medio del método

setRowFilter(). Este RowFilter es el que dice si un valor de esa columna (y por tanto la

fila entera del JTable) pasa o no pasa el filtro. Si el valor de esa columna no pasa el

filtro, la fila entera no lo pasa y no será visible. Podemos hacer nuestros propios

RowFilter heredando de esta clase e implementando su método abstracto include(),

pero RowFilter tiene varios métodos estáticos que nos proporcionan los filtros

habituales.

protected JComboBox getEjemploComboBox() {

if (ejemploComboBox == null) {

ejemploComboBox = new JComboBox();

ejemploComboBox.setBounds(284, 8, 78, 20);

DefaultComboBoxModel modelo = new DefaultComboBoxModel();

modelo.addElement("");

modelo.addElement("Código");

modelo.addElement("Nombre");

modelo.addElement("Telefono");

ejemploComboBox.setModel(modelo);

}

return ejemploComboBox;

}

protected JTextField getEjemploTextField() {

if (ejemploTextField == null) {

ejemploTextField = new JTextField();

ejemploTextField.addKeyListener(new KeyAdapter() {

public void keyReleased(final KeyEvent e) {

if(getEjemploComboBox().getSelectedIndex() > 0){

modeloOrdenado.setRowFilter(

RowFilter.regexFilter(

ejemploTextField.getText(),

getEjemploComboBox().getSelectedIndex()-1)

);

}

}

});

ejemploTextField.setBounds(363, 8, 74, 20);

}

return ejemploTextField;

}

En este ejemplo, se uso un filtro regex, es decir, el dato pasa el filtro si cumple un

determinado patrón, que será muy simple: pasa el filtro si tiene un "A". Para obtener

dicho RowFilter, usamos el método RowFilter.regexFilter().

Page 28: Untitled

Como primer parámetro se pasa una expresión regular (regex) que tiene que cumplir

el dato para pasar el filtro, en nuestro caso el valor de la propiedad getText de la caja

te texto que es “A”. Como segundo parámetro se pasa un entero para identificar la

columna a la que se quiere aplicar el filtro.

getSelectedIndex, es una propiedad del JComboBox que permite saber que ítem de

los elementos del combo esta seleccionado, teniendo en cuenta que el combo tiene un

elemento vacio se le restara -1 al ítem seleccionado. En este caso se selecciono el

ítem Nombre equivalente a 1.

5.4.10. JTree

Objetos de este tipo sirven para mostrar la información en forma de árbol.

En el siguiente ejemplo se hace un cambio en el diseño que se viene trabajando hasta

el ahora, se agregar un JSplitPane en la región central de “centroPanel” de la clase

“MiDialog” y en la parte derecha del JSplitPane se coloca el “centroScrollPane” de la

tabla “ejemploTable” y el la parte izquierda se coloca un JScrollPane para el JTree.

También se aumenta el tamaño del dialogo: this.setSize(new Dimension(490,

370));

private JTree ejemploTree;

private JSplitPane ejemploSplitPane;

private JScrollPane arbolScrollPane;

protected JPanel getCentroPanel() {

if (centroPanel == null) {

centroPanel = new JPanel();

Page 29: Untitled

centroPanel.setLayout(new BorderLayout());

centroPanel.add(getEjemploSplitPane());

}

return centroPanel;

}

protected JSplitPane getEjemploSplitPane() {

if (ejemploSplitPane == null) {

ejemploSplitPane = new JSplitPane();

ejemploSplitPane.setDividerSize(3);

ejemploSplitPane.setDividerLocation(140);

ejemploSplitPane.setLeftComponent(getArbolScrollPane());

ejemploSplitPane.setRightComponent(getCentroScrollPane());

}

return ejemploSplitPane;

}

protected JScrollPane getArbolScrollPane() {

if (arbolScrollPane == null) {

arbolScrollPane = new JScrollPane();

arbolScrollPane.setViewportView(getEjemploTree());

}

return arbolScrollPane;

}

protected JTree getEjemploTree() {

if (ejemploTree == null) {

ejemploTree = new JTree();

}

return ejemploTree;

}

Page 30: Untitled

Una estructura de árbol sencilla se crea de la siguiente manera:

private DefaultMutableTreeNode asignar = null;

private DefaultMutableTreeNode contienente = null;

private DefaultMutableTreeNode pais = null;

protected JTree getEjemploTree() {

if (ejemploTree == null) {

asignar = new DefaultMutableTreeNode ("El Mundo") ;

contienente = new DefaultMutableTreeNode ("America") ;

asignar.add (contienente) ;

pais = new DefaultMutableTreeNode ("Colombia") ;

contienente.add(pais) ;

pais = new DefaultMutableTreeNode ("México") ;

contienente.add(pais) ;

contienente = new DefaultMutableTreeNode ("Europa") ;

asignar.add ( contienente ) ;

pais = new DefaultMutableTreeNode ("España") ;

contienente.add (pais) ;

pais = new DefaultMutableTreeNode ("Alemania") ;

contienente.add (pais) ;

pais = new DefaultMutableTreeNode ("Italia") ;

contienente.add(pais) ;

ejemploTree = new JTree(asignar);

}

return ejemploTree;

}

Page 31: Untitled

La clase completa de los ejercicios de los componentes básicos de SWING se muestra

continuación.

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Dialog;

import java.awt.Dimension;

import java.awt.Frame;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.ButtonGroup;

import javax.swing.DefaultComboBoxModel;

import javax.swing.JButton;

import javax.swing.JCheckBox;

import javax.swing.JComboBox;

import javax.swing.JDialog;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JRadioButton;

import javax.swing.JScrollPane;

import javax.swing.JSplitPane;

import javax.swing.JTable;

import javax.swing.JTextField;

import javax.swing.JTree;

import javax.swing.RowFilter;

import javax.swing.table.TableModel;

import javax.swing.table.TableRowSorter;

import javax.swing.tree.DefaultMutableTreeNode;

public class MiDialog extends JDialog {

private JTree ejemploTree;

private JSplitPane ejemploSplitPane;

private JScrollPane arbolScrollPane;

private JTable ejemploTable;

private JComboBox ejemploComboBox;

private JRadioButton verdeRadioButton;

private JRadioButton azulRadioButton;

private JRadioButton blacoRadioButton;

private JCheckBox ejemploCheckBox;

Page 32: Untitled

private JButton ejemploButton;

private JTextField ejemploTextField;

private JLabel buscarLabel;

private JLabel ejemploLabel;

private JScrollPane centroScrollPane;

private JPanel surPanel;

private JPanel nortePanel;

private JPanel centroPanel;

private ButtonGroup agruparButtonGroup;

private TableRowSorter<TableModel> modeloOrdenado = null;

private DefaultMutableTreeNode asignar = null;

private DefaultMutableTreeNode contienente = null ;

private DefaultMutableTreeNode pais = null;

public MiDialog(Frame frame) {

super(frame,true);

inicializar();

}

public MiDialog(Dialog dialog) {

super(dialog,true);

inicializar();

}

public MiDialog() {

this((Frame) null);

}

private void inicializar(){

this.setSize(new Dimension(490, 370));

this.setResizable(false);

this.setTitle("Mi primer dialog");

this.setLocationRelativeTo(null);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e){

dispose();

}

});

getContentPane().add(getCentroPanel(), BorderLayout.CENTER);

getContentPane().add(getNortePanel(), BorderLayout.NORTH);

getContentPane().add(getSurPanel(), BorderLayout.SOUTH);

}

protected JPanel getCentroPanel() {

if (centroPanel == null) {

centroPanel = new JPanel();

centroPanel.setLayout(new BorderLayout());

centroPanel.add(getEjemploSplitPane());

}

return centroPanel;

}

protected JPanel getNortePanel() {

if (nortePanel == null) {

nortePanel = new JPanel();

nortePanel.setLayout(null);

nortePanel.setPreferredSize(new Dimension(0, 50));

nortePanel.add(getEjemploLabel());

nortePanel.add(getBlacoRadioButton());

nortePanel.add(getAzulRadioButton());

nortePanel.add(getVerdeRadioButton());

}

return nortePanel;

}

protected JPanel getSurPanel() {

if (surPanel == null) {

surPanel = new JPanel();

surPanel.setLayout(null);

surPanel.setPreferredSize(new Dimension(0, 40));

surPanel.add(getBuscarLabel());

surPanel.add(getEjemploTextField());

surPanel.add(getEjemploButton());

surPanel.add(getEjemploCheckBox());

surPanel.add(getEjemploComboBox());

}

return surPanel;

}

Page 33: Untitled

public static void main(String[] args) {

new MiDialog().setVisible(true);

}

protected JScrollPane getCentroScrollPane() {

if (centroScrollPane == null) {

centroScrollPane = new JScrollPane();

centroScrollPane.setViewportView(getEjemploTable());

}

return centroScrollPane;

}

protected JLabel getEjemploLabel() {

if (ejemploLabel == null) {

ejemploLabel = new JLabel();

ejemploLabel.setBounds(158, 5, 127, 16);

ejemploLabel.setText("Ejemplo de una JLabel");

}

return ejemploLabel;

}

protected JLabel getBuscarLabel() {

if (buscarLabel == null) {

buscarLabel = new JLabel();

buscarLabel.setText("Buscar");

buscarLabel.setBounds(281, 12, 50, 16);

}

return buscarLabel;

}

protected JTextField getEjemploTextField() {

if (ejemploTextField == null) {

ejemploTextField = new JTextField();

ejemploTextField.addKeyListener(new KeyAdapter() {

public void keyReleased(final KeyEvent e) {

if(getEjemploComboBox().getSelectedIndex() > 0){

modeloOrdenado.setRowFilter(

RowFilter.regexFilter(

ejemploTextField.getText(),

getEjemploComboBox().getSelectedIndex()-1)

);

}

}

});

ejemploTextField.setBounds(407, 10, 74, 20);

}

return ejemploTextField;

}

protected JButton getEjemploButton() {

if (ejemploButton == null) {

ejemploButton = new JButton();

ejemploButton.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

dispose();//metodo que cierra el dialogo

}

});

ejemploButton.setText("Cerrar");

ejemploButton.setBounds(10, 10, 80, 23);

}

return ejemploButton;

}

protected JCheckBox getEjemploCheckBox() {

if (ejemploCheckBox == null) {

ejemploCheckBox = new JCheckBox();

ejemploCheckBox.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

getEjemploTextField().setVisible(ejemploCheckBox.isSelected());

getBuscarLabel().setVisible(getEjemploTextField().isVisible());

getEjemploComboBox().setVisible(getEjemploTextField().isVisible());

}

});

ejemploCheckBox.setText("Mostrar búsqueda");

ejemploCheckBox.setBounds(99, 6, 153, 24);

ejemploCheckBox.setSelected(true);

ejemploCheckBox.setOpaque(false);

}

return ejemploCheckBox;

}

protected JRadioButton getBlacoRadioButton() {

if (blacoRadioButton == null) {

blacoRadioButton = new JRadioButton();

Page 34: Untitled

blacoRadioButton.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

getSurPanel().setBackground(Color.WHITE);

}

});

blacoRadioButton.setText("Blanco");

blacoRadioButton.setBounds(0, 25, 72, 24);

getAgruparButtonGroup().add(blacoRadioButton);

}

return blacoRadioButton;

}

protected JRadioButton getAzulRadioButton() {

if (azulRadioButton == null) {

azulRadioButton = new JRadioButton();

azulRadioButton.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

getSurPanel().setBackground(Color.BLUE);

}

});

azulRadioButton.setText("Azul");

azulRadioButton.setBounds(72, 25, 66, 24);

getAgruparButtonGroup().add(azulRadioButton);

}

return azulRadioButton;

}

protected JRadioButton getVerdeRadioButton() {

if (verdeRadioButton == null) {

verdeRadioButton = new JRadioButton();

verdeRadioButton.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

getSurPanel().setBackground(Color.GREEN);

}

});

verdeRadioButton.setText("Verde");

verdeRadioButton.setBounds(135, 25, 129, 24);

getAgruparButtonGroup().add(verdeRadioButton);

}

return verdeRadioButton;

}

protected ButtonGroup getAgruparButtonGroup(){

if(agruparButtonGroup == null){

agruparButtonGroup = new ButtonGroup();

}

return agruparButtonGroup;

}

protected JComboBox getEjemploComboBox() {

if (ejemploComboBox == null) {

ejemploComboBox = new JComboBox();

ejemploComboBox.setBounds(328, 10, 78, 20);

DefaultComboBoxModel modelo = new DefaultComboBoxModel();

modelo.addElement("");

modelo.addElement("Código");

modelo.addElement("Nombre");

modelo.addElement("Telefono");

ejemploComboBox.setModel(modelo);

}

return ejemploComboBox;

}

protected JTable getEjemploTable() {

if (ejemploTable == null) {

final String [] nombreCol = {"Codigo","Nombre","Telefono","Barrio"} ;

Object [] [] datos = {

{"1", "Oscar Corredor", "6453720", "La cumbre"},

{"2", "Andrea Lizcano", "6879371", "La aurora"},

{"3", "Angel Lizcano", "6879379", "Provenza"},

{"4", "Carolina Gómez", "6879373", "Niza"},

{"5", "Catalina Rodriguez", "6879374", "Diamante I" }

};

ejemploTable = new JTable(datos, nombreCol);

modeloOrdenado = new TableRowSorter<TableModel>

(ejemploTable.getModel());

ejemploTable.setRowSorter(modeloOrdenado);

}

return ejemploTable;

}

protected JScrollPane getArbolScrollPane() {

if (arbolScrollPane == null) {

Page 35: Untitled

arbolScrollPane = new JScrollPane();

arbolScrollPane.setViewportView(getEjemploTree());

}

return arbolScrollPane;

}

protected JSplitPane getEjemploSplitPane() {

if (ejemploSplitPane == null) {

ejemploSplitPane = new JSplitPane();

ejemploSplitPane.setDividerSize(3);

ejemploSplitPane.setDividerLocation(140);

ejemploSplitPane.setLeftComponent(getArbolScrollPane());

ejemploSplitPane.setRightComponent(getCentroScrollPane());

}

return ejemploSplitPane;

}

protected JTree getEjemploTree() {

if (ejemploTree == null) {

asignar = new DefaultMutableTreeNode ("El Mundo") ;

contienente = new DefaultMutableTreeNode ("America") ;

asignar.add (contienente) ;

pais = new DefaultMutableTreeNode ("Colombia") ;

contienente.add(pais) ;

pais = new DefaultMutableTreeNode ("México") ;

contienente.add(pais) ;

contienente = new DefaultMutableTreeNode ("Europa") ;

asignar.add ( contienente ) ;

pais = new DefaultMutableTreeNode ("España") ;

contienente.add (pais) ;

pais = new DefaultMutableTreeNode ("Alemania") ;

contienente.add (pais) ;

pais = new DefaultMutableTreeNode ("Italia") ;

contienente.add(pais) ;

ejemploTree = new JTree(asignar);

}

return ejemploTree;

}

}

5.5. Layout

En Java, cuando hacemos ventanas, la clase que decide cómo se reparten los

botones (Y demás controles) dentro de la ventana se llama Layout. Esta clase es la

que decide en qué posición van los botones y demás componentes, si van alineados,

en forma de matriz, cuáles se hacen grandes al agrandar la ventana, etc. Otra cosa

importante que decide el Layout es qué tamaño es el ideal para la ventana en función

de los componentes que lleva dentro. Con un layout adecuado, el método pack() de la

ventana hará que coja el tamaño necesario para que se vea todo lo que tiene dentro.

Las ventanas vienen con un Layout por defecto. En Java hay varios layouts

disponibles y podemos cambiar el de por defecto por otro.

Page 36: Untitled

5.5.1. El Layout null

Uno de los Layouts más utilizados, desde código se da la poscicion y el tamaño que

ocupa el componente.

import javax.swing.JButton;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextField;

public class EjemploLayoutNullPanel extends JPanel {

private JButton okButton;

private JTextField nombreTextField;

private JTextField codigoTextField;

private JLabel nombreLabel;

private JLabel codigoLabel;

private JLabel ejemploLayoutNullLabel;

public EjemploLayoutNullPanel() {

super();

setLayout(null);

add(getEjemploLayoutNullLabel());

add(getCodigoLabel());

add(getNombreLabel());

add(getCodigoTextField());

add(getNombreTextField());

add(getOkButton());

}

protected JLabel getEjemploLayoutNullLabel() {

if (ejemploLayoutNullLabel == null) {

ejemploLayoutNullLabel = new JLabel();

ejemploLayoutNullLabel.setText("Ejemplo Layout Null");

ejemploLayoutNullLabel.setBounds(88, 10, 121, 16);

}

return ejemploLayoutNullLabel;

}

protected JLabel getCodigoLabel() {

if (codigoLabel == null) {

codigoLabel = new JLabel();

codigoLabel.setText("Código");

codigoLabel.setBounds(10, 46, 66, 16);

}

return codigoLabel;

}

protected JLabel getNombreLabel() {

if (nombreLabel == null) {

nombreLabel = new JLabel();

nombreLabel.setText("Nombre");

nombreLabel.setBounds(10, 77, 66, 16);

}

return nombreLabel;

}

protected JTextField getCodigoTextField() {

if (codigoTextField == null) {

codigoTextField = new JTextField();

codigoTextField.setBounds(83, 44, 87, 20);

}

return codigoTextField;

}

protected JTextField getNombreTextField() {

if (nombreTextField == null) {

nombreTextField = new JTextField();

Page 37: Untitled

nombreTextField.setBounds(83, 75, 201, 20);

}

return nombreTextField;

}

protected JButton getOkButton() {

if (okButton == null) {

okButton = new JButton();

okButton.setText("Ok");

okButton.setBounds(120, 118, 50, 20);

}

return okButton;

}

}

Se agrega el panel a un JFrame

import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.JFrame;

public class EjemplosLayoutFrame extends JFrame {

private EjemploLayoutNullPanel layoutNullPanel;

public EjemplosLayoutFrame (){

this.setTitle("Ejemplo Layouts");

this.setLocationRelativeTo(null);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e){

dispose();

}

});

getContentPane().add(getLayoutNullPanel(), BorderLayout.CENTER);

this.setSize(new Dimension(293, 180));

}

protected EjemploLayoutNullPanel getLayoutNullPanel() {

if (layoutNullPanel == null) {

layoutNullPanel = new EjemploLayoutNullPanel();

}

return layoutNullPanel;

}

public static void main(String[] args) {

new EjemplosLayoutFrame().setVisible(true);

}

}

Page 38: Untitled

Esto, aunque sencillo, no es recomendable. Si estiramos la ventana los componentes

seguirán en su sitio, no se estirarán con la ventana. Si cambiamos de sistema

operativo, resolución de pantalla o fuente de letra, tenemos casi asegurado que no se

vean bien las cosas: etiquetas cortadas, letras que no caben, etc.

Además, al no haber layout, la ventana no tiene tamaño adecuado. Deberemos

dárselo nosotros con un ventana.setSize(...).

5.5.2. FlowLayout

El FlowLayout es bastante sencillo de usar. Nos coloca los componentes en fila. Hace

que todos quepan (si el tamaño de la ventana lo permite). Es adecuado para barras de

herramientas, filas de botones, etc. Este layout lo trae por defecto un JPanel.

import javax.swing.JButton;

import javax.swing.JCheckBox;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextField;

public class EjemploFlowLayoutPanel extends JPanel {

private JLabel etiquetaLabel;

private JCheckBox opcionCheckBox;

private JTextField textoTextField;

private JButton botonButton;

public EjemploFlowLayoutPanel() {

super();

add(getBotonButton());

add(getTextoTextField());

add(getOpcionCheckBox());

add(getEtiquetaLabel());

}

protected JButton getBotonButton() {

if (botonButton == null) {

botonButton = new JButton();

botonButton.setText("Boton");

}

return botonButton;

}

protected JTextField getTextoTextField() {

if (textoTextField == null) {

Page 39: Untitled

textoTextField = new JTextField(10);

}

return textoTextField;

}

protected JCheckBox getOpcionCheckBox() {

if (opcionCheckBox == null) {

opcionCheckBox = new JCheckBox();

opcionCheckBox.setText("opcion");

}

return opcionCheckBox;

}

protected JLabel getEtiquetaLabel() {

if (etiquetaLabel == null) {

etiquetaLabel = new JLabel();

etiquetaLabel.setText("etiqueta");

}

return etiquetaLabel;

}

}

Se agrega el panel a un JFrame

import java.awt.BorderLayout;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.JFrame;

public class EjemplosLayoutFrame extends JFrame {

private EjemploFlowLayoutPanel ejemploFlowLayoutPanel;

public EjemplosLayoutFrame(){

this.setTitle("Ejemplo Layouts");

this.setLocationRelativeTo(null);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e){

dispose();

}

});

getContentPane().add(getEjemploFlowLayoutPanel(), BorderLayout.CENTER);

this.pack();

}

protected EjemploFlowLayoutPanel getEjemploFlowLayoutPanel() {

if (ejemploFlowLayoutPanel == null) {

ejemploFlowLayoutPanel = new EjemploFlowLayoutPanel();

}

return ejemploFlowLayoutPanel;

}

public static void main(String[] args) {

new EjemplosLayoutFrame().setVisible(true);

}

}

Page 40: Untitled

5.5.3. BoxLayout

Es como un FlowLayout, pero mucho más completo. Permite colocar los elementos en

horizontal o vertical.

import java.awt.Component;

import javax.swing.BoxLayout;

import javax.swing.JButton;

import javax.swing.JLabel;

import javax.swing.JPanel;

public class EjemploBoxLayout extends JPanel {

private JLabel ejemploLabel;

private JButton ejemploButton;

public EjemploBoxLayout() {

super();

setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

add(getEjemploButton());

add(getEjemploLabel());

}

protected JButton getEjemploButton() {

if (ejemploButton == null) {

ejemploButton = new JButton();

ejemploButton.setText("Ejemplo");

ejemploButton.setAlignmentX(Component.CENTER_ALIGNMENT);

}

return ejemploButton;

}

protected JLabel getEjemploLabel() {

if (ejemploLabel == null) {

ejemploLabel = new JLabel();

ejemploLabel.setText("Ejemplo");

ejemploLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

}

return ejemploLabel;

}

}

Se agrega el panel a un JFrame

Page 41: Untitled

Lo de BoxLayout.Y_AXIS es para que coloque los componentes en vertical, de arriba

abajo con BoxLayout.X_AXIS los coloca igual que un FlowLayout, de izquierda a

derecha.

También hay BoxLayout.LINE_AXIS e BoxLayout.PAGE_AXIS, pero el

comportamiento por defecto es igual. El comportamiento es distinto si al contenedor le

cambiamos el setComponentOrientation(), en cuyo caso podemos conseguir que los

componentes vayan de derecha a izquierda según los vamos añadiendo o de abajo a

arriba. Para que los componentes salgan centrados (la etiqueta y el botón) hay que

llamar al método AlignmentX(Component.CENTER_ALIGNMENT).

5.5.4. GridLayout

Este layout pone los componentes en forma de matriz (cuadrícula), estirándolos para

que tengan todos los mismos tamaños. El GridLayout es adecuado para hacer

tableros, calculadoras en que todos los botones son iguales, etc.

import java.awt.GridLayout;

import javax.swing.JPanel;

import javax.swing.JTextField;

public class EjemploGridLayout extends JPanel {

private JTextField[][] textField;

private static final int COLUMNAS = 10;

private static final int FILAS = 5;

public EjemploGridLayout() {

super();

setLayout(new GridLayout(FILAS, COLUMNAS));

textField = new JTextField [FILAS][COLUMNAS];

for (int i=0;i<FILAS;i++){

for (int j=0;j<COLUMNAS;j++){

textField[i][j] = new JTextField(4);

add(textField[i][j]);

}

}

}

}

Se agrega el panel a un JFrame

import java.awt.BorderLayout;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.JFrame;

import aplicacion.EjemploGridLayout;

public class EjemplosLayoutFrame extends JFrame {

private EjemploGridLayout ejemploGridLayout;

public EjemplosLayoutFrame (){

this.setTitle("Ejemplo Layouts");

Page 42: Untitled

this.setLocationRelativeTo(null);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e){

dispose();

}

});

getContentPane().add(getEjemploGridLayout(), BorderLayout.CENTER);

this.pack();

}

protected EjemploGridLayout getEjemploGridLayout() {

if (ejemploGridLayout == null) {

ejemploGridLayout = new EjemploGridLayout();

}

return ejemploGridLayout;

}

public static void main(String[] args) {

new EjemplosLayoutFrame().setVisible(true);

}

}

5.5.5. BorderLayout

El BorderLayout divide la ventana en 5 partes: centro, arriba, abajo, derecha e

izquierda. Hará que los componentes que pongamos arriba y abajo ocupen el alto que

necesiten, pero los estirará horizontalmente hasta ocupar toda la ventana. Los

componentes de derecha e izquierda ocuparán el ancho que necesiten, pero se les

estirará en vertical hasta ocupar toda la ventana. El componente central se estirará en

ambos sentidos hasta ocupar toda la ventana. El BorderLayout es adecuado para

ventanas en las que hay un componente central importante (una tabla, una lista, etc) y

tiene menús o barras de herramientas situados arriba, abajo, a la derecha o a la

izquierda. Este es el layout por defecto para los JFrame y JDialog.

Page 43: Untitled

5.5.6. GridBagLayout

El GridBagLayout es de los layouts más versátiles y complejos de usar. Es como el

GridLayout, pone los componentes en forma de matriz (cuadrícula), pero permite que

las celdas y los componentes en ellas tengan tamaños variados.

Es posible hacer que un componente ocupe varias celdas

Un componente puede estirarse o no con su celda

Si no se estira, puede quedar en el centro de la celda o pegarse a sus bordes o

esquinas.

Las columnas pueden ensancharse o no al estirar la ventana y la proporición

podemos decidirla

Lo mismo con la filas.

import java.awt.GridBagConstraints;

import java.awt.GridBagLayout;

import javax.swing.JButton;

import javax.swing.JPanel;

public class EjemploGridBagLayout extends JPanel {

private JButton button1;

private JButton button2;

private JButton button3;

private JButton button4;

private JButton button5;

private JButton button6;

private JButton button7;

private JButton button8;

private JButton button9;

public EjemploGridBagLayout() {

super();

GridBagLayout gridbag = new GridBagLayout();

GridBagConstraints gbc = new GridBagConstraints();

setLayout(gridbag);

gbc.fill = GridBagConstraints.BOTH;

gbc.weightx = 1.0;

gridbag.setConstraints(getButton1(),gbc );

add(getButton1());

Page 44: Untitled

gridbag.setConstraints(getButton2(),gbc );

add(getButton2());

gridbag.setConstraints(getButton3(),gbc );

add(getButton3());

gbc.gridwidth = GridBagConstraints.REMAINDER;

gridbag.setConstraints(getButton4(),gbc );

add(getButton4());

gbc.weightx = 0.0;

gridbag.setConstraints(getButton4(),gbc );

add(getButton4());

gbc.gridwidth = GridBagConstraints.RELATIVE;

gridbag.setConstraints(getButton5(),gbc);

add(getButton5());

gbc.gridwidth = GridBagConstraints.REMAINDER;

gridbag.setConstraints(getButton6(),gbc );

add(getButton6());

gbc.gridwidth = 1;

gbc.gridheight = 2;

gbc.weighty = 1.0;

gridbag.setConstraints(getButton7(),gbc );

add(getButton7());

gbc.weighty = 0.0;

gbc.gridwidth = GridBagConstraints.REMAINDER;

gbc.gridheight = 1;

gridbag.setConstraints(getButton8(),gbc );

add(getButton8());

gridbag.setConstraints(getButton9(),gbc );

add(getButton9());

}

protected JButton getButton1(){

if(button1 == null){

button1 = new JButton();

button1.setText("Botón 1");

}

return button1;

}

protected JButton getButton2(){

if(button2 == null){

button2 = new JButton();

button2.setText("Botón 2");

}

return button2;

}

protected JButton getButton3(){

if(button3 == null){

button3 = new JButton();

button3.setText("Botón 3");

}

return button3;

}

protected JButton getButton4(){

if(button4 == null){

button4 = new JButton();

button4.setText("Botón 4");

}

return button4;

}

protected JButton getButton5(){

if(button5 == null){

Page 45: Untitled

button5 = new JButton();

button5.setText("Botón 5");

}

return button5;

}

protected JButton getButton6(){

if(button6 == null){

button6 = new JButton();

button6.setText("Botón 6");

}

return button6;

}

protected JButton getButton7(){

if(button7 == null){

button7 = new JButton();

button7.setText("Botón 7");

}

return button7;

}

protected JButton getButton8(){

if(button8 == null){

button8 = new JButton();

button8.setText("Botón 8");

}

return button8;

}

protected JButton getButton9(){

if(button9 == null){

button9 = new JButton();

button9.setText("Botón 9");

}

return button9;

}

}

Se agrega el panel a un JFrame

import java.awt.BorderLayout;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.JFrame;

public class EjemplosLayoutFrame extends JFrame {

private EjemploGridBagLayout ejemploGridBagLayout;

public EjemplosLayoutFrame (){

this.setTitle("Ejemplo Layouts");

this.setLocationRelativeTo(null);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e){

dispose();

}

});

getContentPane().add(getEjemploGridBagLayout(), BorderLayout.CENTER);

this.pack();

}

protected EjemploGridBagLayout getEjemploGridBagLayout() {

if (ejemploGridBagLayout == null) {

ejemploGridBagLayout = new EjemploGridBagLayout();

}

return ejemploGridBagLayout;

}

public static void main(String[] args) {

new EjemplosLayoutFrame().setVisible(true);

}

Page 46: Untitled

}

5.5.7. CardLayout

El CardLayout hace que los componentes recibidos ocupen el máximo espacio

posible, superponiendo unos a otros. Sólo es visible uno de los componentes, los otros

quedan detrás. Tiene métodos para indicar cual de los componentes es el que debe

quedar encima y verse.

El CardLayout es el que utiliza el JTabbedPane (el de las pestañas) de forma que en

función de la pestaña que pinchemos, se ve uno u otro.

5.5.8. SpringLayout

Se añaden los componentes y para cada uno de ellos tenemos que decir qué distancia

en pixel queremos que tenga cada uno de sus bordes respecto al borde del otro

componente.

5.6. Bean y Clases serializables

Un Bean es solo una clase serializable hecha en Java como cualquier otra, pero debe

seguir algunas reglas estandares para que se considere como Bean, por ejemplo, todo

Bean debe tener un Constructor por defecto, es decir, un constructor sin parametros,

puede tener muchos constructores, con parametros de todo tipo, pero debe existir el

por defecto, tambien debe haber un metodo set y get para cada atributo del Bean, etc.

import java.io.Serializable;

public class Usuario implements Serializable{

private static final long serialVersionUID = -288704532736952222L;

private String usuario;

private String contraseña;

private Boolean estado;

private String perfil;

private String nombre;

private String identificacion;

Page 47: Untitled

public Usuario() {

// TODO Auto-generated constructor stub

}

public String getContraseña() {

return contraseña;

}

public void setContraseña(String contraseña) {

this.contraseña = contraseña;

}

public Boolean getEstado() {

return estado;

}

public void setEstado(Boolean estado) {

this.estado = estado;

}

public String getIdentificacion() {

return identificacion;

}

public void setIdentificacion(String identificacion) {

this.identificacion = identificacion;

}

public String getNombre() {

return nombre;

}

public void setNombre(String nombre) {

this.nombre = nombre;

}

public String getPerfil() {

return perfil;

}

public void setPerfil(String perfil) {

this.perfil = perfil;

}

public String getUsuario() {

return usuario;

}

public void setUsuario(String usuario) {

this.usuario = usuario;

}

}

Para que un programa Java pueda convertir un objeto en un montón de bytes y pueda

luego recuperarlo, el objeto necesita ser Serializable. Al poder convertir el objeto a

bytes, ese objeto se puede enviar a través de red y después reconstruirlo al otro lado

de la red, guardarlo en un fichero y leerlo del fichero, etc.

Útil para implementar “persistencia” de objetos.

La interfaz no tiene métodos sirve sólo para identificar la semántica de que es

serializable.

Cualquier subclase de una clase serializable también lo es.

Este proceso no solo salva una imagen del objeto sino que también, de manera

recursiva, guarda todas las referencias que contiene dicho objeto.

Si está serializando en el mismo Stream se recuperará la misma estructura de

objetos sin duplicados.

Page 48: Untitled

Cuando pasamos objetos Serializable de un lado a otro tenemos un pequeño

problema. Si la clase que queremos pasar es objeto_serializable, lo normal, salvo que

usemos Carga dinámica de clases, es que en ambos lados (el que envía y el que

recibe la clase), tengan su propia copia del fichero objeto_serializable.class. Es posible

que en distintas versiones de nuestro programa la clase objeto_serializable cambie, de

forma que es posible que un lado tenga una versión más antigua que en el otro lado.

Si sucede esto, la reconstrucción de la clase en el lado que recibe es imposible.

Para evitar este problema, se aconseja que la clase objeto_serializable tenga un

atributo privado de esta forma:

private static final long serialVersionUID = -288704532736952222L;

De forma que el numerito que ponemos al final debe ser distinto para cada versión de

compilado que tengamos.

De esta forma, Java es capaz de detectar rápidamente que las versiones de

objeto_serializable.class en ambos lados son distintas. En Eclipse basta con hacer

click con el ratón sobre el símbolo de warning para que nos de las posibles soluciones

al warning. Una de ellas genera el número automáticamente.

5.7. Look and Feel

Normalmente las ventanas Java tienen su propio aspecto, su propio estilo de botones

y demás. Con java es muy fácil cambiar el aspecto (look and feel o skin) de nuestras

ventanas para que tengan aspecto Java, aspecto windows, etc. Basta con tener la

librería adecuada y una sola línea de código.

Para obtener el aspecto de ventanas propio del sistema operativo en el que estemos

(windows xp, solaris, etc), basta con estas líneas de código antes de crear ninguna

ventana:

try {

UIManager.setLookAndFeel("com.jgoodies.looks.windows.WindowsLookAndFeel");

} catch (Exception ex) {

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

} catch (Exception e){}

}

Con UIManager.getSystemLookAndFeelClassName() obtenemos el nombre del Look

and Feel por defecto del sistema operativo en el que estemos. Con

UIManager.setLookAndFeel decimos qué Look and Feel queremos.

Page 49: Untitled

5.8. Archivos de Properties

El API de Java contiene la clase Properties que nos permite hacer todo lo que

queremos, que es crear ficheros de configuración complejos y manejarlos con

facilidad. Un fichero .properties nos permite hacer casi todo lo que deseamos mientras

respetemos el formato clave = valor (o valores).

IMG-STEP-ACTIVE = /imagenes/step_48x48_active.png

IMG-STEP-INACTIVE = /imagenes/step_48x48_inactive.png

IMG-STEP-INACTIVE_PAST = /imagenes/step_48x48_inactive_past.png

IMG-STEP-INACTIVE_END = /imagenes/step_48x48_inactive_end.png

IMG-STEP-ACTIVE_INITIAL = /imagenes/step_48x48_active_initial.png

IMG-STEP-ACTIVE_END = /imagenes/step_48x48_active_end.png

IMG-STEP-LINE-ACTIVE = /imagenes/stepline_48x28_active.png

IMG-STEP-LINE-INACTIVE = /imagenes/stepline_48x28_inactive.png

IMG-OK = /imagenes/disk_blue_ok_48x48.png

Para leer los datos del fichero solo necesitamos crear un InputStream. A continuancion

una clase que permite leer la ruta de cada imagen del archivo de properties anterior. El

nombre del archivo es: IconoImagen.properties.

import java.io.InputStream;

import java.util.Properties;

import javax.swing.ImageIcon;

public class Imagen {

private static Properties properties = new Properties();

public static ImageIcon getIconoImagen(String codigo) {

ImageIcon resultado = null;

String path = null;

if(codigo == null){

return null;

}

try{

if(properties.isEmpty()) {

InputStream stream =

Imagen.class.getResourceAsStream("IconoImagen.properties");

if (stream == null){

return null;

}

properties.load(stream);

stream.close();

}

path = properties.getProperty(codigo);

if (path == null){

return null;

}

path = path.trim();

resultado = new ImageIcon(Imagen.class.getResource(path));

}

catch (Exception exception){

exception.printStackTrace();

}

return resultado;

}

}

Page 50: Untitled

El método getIconoImagen recibe un parámetro de tipo String que es la clave de la

imagen y retorna un objeto de tipo ImageIcon.

protected JButton getAgregarButton() {

if (agregarButton == null) {

agregarButton = new JButton();

agregarButton.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

setDatos();

}

});

}

agregarButton.setIcon(Imagen.getIconoImagen("IMG-OK"));

return agregarButton;

}

5.9. Tablas y Modelos

El JTable es un objeto muy potente y complejo a la vez, la mayoría de objetos SWING

manejan el paradigma vista/controlador. Este paradigma básicamente consiste en que

debe haber un objeto encargado de manipular y operar los datos y otro objeto es el

encargado de presentarlos.

El objeto JTable al utilizar el modelo vista controlador necesita de un objeto derivado

de AbstractTableModel para poder realizar la gestión de los datos.

import java.io.Serializable;

public class Cliente implements Serializable {

private static final long serialVersionUID = 1257318183448741500L;

private Integer codigo = null;

private String nombre = null;

private String apellido = null;

private String telefono = null;

private String direccion = null;

public Cliente() {

// TODO Auto-generated constructor stub

}

public Integer getCodigo() {

return codigo;

}

public void setCodigo(Integer codigo) {

this.codigo = codigo;

}

public String getNombre() {

return nombre;

}

public void setNombre(String nombre) {

this.nombre = nombre;

}

public String getApellido() {

Page 51: Untitled

return apellido;

}

public void setApellido(String apellido) {

this.apellido = apellido;

}

public String getTelefono() {

return telefono;

}

public void setTelefono(String telefono) {

this.telefono = telefono;

}

public String getDireccion() {

return direccion;

}

public void setDireccion(String direccion) {

this.direccion = direccion;

}

}

import java.util.ArrayList;

import java.util.List;

import javax.swing.table.AbstractTableModel;

import aplicacion.Cliente;

public class ClienteTableModel extends AbstractTableModel{

private static List<String> columns = new ArrayList<String>();

private List<Cliente> cliente = new ArrayList<Cliente>();

static {

columns.add("Código");

columns.add("Nombre");

columns.add("Apellido");

columns.add("Dirección");

columns.add("Teléfono");

}

public String getColumnName(int col) {

return columns.get(col);

}

public Class getColumnClass(int c) {

return String.class;

}

public int getColumnCount() {

return columns.size();

}

public int getRowCount() {

return cliente.size();

}

public Object getValueAt(int row, int col) {

Cliente cliente = this.cliente.get(row);

switch (col) {

case 0:

return cliente.getCodigo();

case 1:

return cliente.getNombre();

case 2:

return cliente.getApellido();

case 3:

Page 52: Untitled

return cliente.getDireccion();

case 4:

return cliente.getTelefono();

default:

return null;

}

}

public void setValueAt(Object value, int row, int col) {

Cliente cliente = this.cliente.get(row);

switch (col) {

case 0:

cliente.setCodigo(Integer.parseInt(value.toString()));break;

case 1:

cliente.setNombre(value.toString());break;

case 2:

cliente.setApellido(value.toString());break;

case 3:

cliente.setDireccion(value.toString());break;

case 4:

cliente.setTelefono(value.toString());break;

default:

break;

}

}

public List<Cliente> getCliente() {

return cliente;

}

public void setCliente(List<Cliente> cliente) {

this.cliente = cliente;

}

}

Para la clase ClienteTableModel se implementaron los siguientes métodos de la clase

abstracta AbstractTableModel:

public String getColumnName(int col). Devuelve el nombre de la columna.

public Class getColumnClass(int col). Devuelve la clase que corresponde al

tipo de columna.

public int getColumnCount(). Devuelve el número de columnas.

public int getRowCount(). Devuelve el número de filas.

public Object getValueAt (int row, int col). Permite leer el valor de la celda

especificada por la fila y columna (Recordar que la fila y columna empiezan por

0) esto objeto nos devolverá un tipo de datos Object el cual deberá ser

interpretado de manera adecuada por nuestro programa.

public void setValueAt (Object value, int row, int col). Permite modificar un valor

especificando la fila y columna del JTable.

Page 53: Untitled

public boolean isCellEditable (int row, int col). Es el encargado de especificar

cuando una celda se puede editar tomando como parámetros la fila y la

columna.

import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.GridBagConstraints;

import java.awt.GridBagLayout;

import java.awt.Insets;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextField;

import wizard.Imagen;

import aplicacion.Cliente;

public class ClientePanel1 extends JPanel{

private JButton agregarButton;

private JTextField telefonoTextField;

private JLabel telefonoLabel;

private JTextField direccionTextField;

private JLabel direccionLabel;

private JTextField apellidoTextField;

private JLabel apellidoLabel;

private JTextField nombreTextField;

private JTextField codigoTextField;

private JLabel nombreLabel;

private JLabel codigoLabel;

private JPanel compoesntesPanel;

private ClaseTable clienteTable;

private JScrollPane clientesScrollPane;

public ClientePanel1() {

super();

setLayout(new BorderLayout());

add(getClientesScrollPane());

add(getCompoesntesPanel(), BorderLayout.SOUTH);

}

protected JScrollPane getClientesScrollPane() {

if (clientesScrollPane == null) {

clientesScrollPane = new JScrollPane();

clientesScrollPane.setViewportView(getClienteTable());

}

return clientesScrollPane;

}

protected ClaseTable getClienteTable() {

if (clienteTable == null) {

clienteTable = new ClaseTable();

ClienteTableModel modelo = new ClienteTableModel();

clienteTable.setModel(modelo);

}

return clienteTable;

}

protected JPanel getCompoesntesPanel() {

if (compoesntesPanel == null) {

compoesntesPanel = new JPanel();

compoesntesPanel.setLayout(new GridBagLayout());

compoesntesPanel.setSize(500, 120);

compoesntesPanel.setPreferredSize(new Dimension(0, 120));

final GridBagConstraints gridBagConstraints = new GridBagConstraints();

gridBagConstraints.gridx = 0;

gridBagConstraints.gridy = 0;

gridBagConstraints.insets = new Insets(12, 66, 2, 15);

compoesntesPanel.add(getCodigoLabel(), gridBagConstraints);

final GridBagConstraints gridBagConstraints_4 = new GridBagConstraints();

gridBagConstraints_4.gridx = 1;

gridBagConstraints_4.gridy = 0;

gridBagConstraints_4.ipadx = 110;

Page 54: Untitled

gridBagConstraints_4.insets = new Insets(10, 17, 0, 86);

compoesntesPanel.add(getCodigoTextField(), gridBagConstraints_4);

final GridBagConstraints gridBagConstraints_8 = new GridBagConstraints();

gridBagConstraints_8.gridx = 2;

gridBagConstraints_8.gridy = 0;

gridBagConstraints_8.insets = new Insets(12, 7, 2, 0);

compoesntesPanel.add(getTelefonoLabel(), gridBagConstraints_8);

final GridBagConstraints gridBagConstraints_9 = new GridBagConstraints();

gridBagConstraints_9.anchor = GridBagConstraints.EAST;

gridBagConstraints_9.gridx = 3;

gridBagConstraints_9.gridy = 0;

gridBagConstraints_9.ipadx = 80;

gridBagConstraints_9.insets = new Insets(10, 12, 0, 20);

compoesntesPanel.add(getTelefonoTextField(), gridBagConstraints_9);

final GridBagConstraints gridBagConstraints_1 = new GridBagConstraints();

gridBagConstraints_1.gridx = 0;

gridBagConstraints_1.gridy = 1;

gridBagConstraints_1.insets = new Insets(8, 66, 2, 9);

compoesntesPanel.add(getNombreLabel(), gridBagConstraints_1);

final GridBagConstraints gridBagConstraints_2 = new GridBagConstraints();

gridBagConstraints_2.gridx = 0;

gridBagConstraints_2.gridy = 2;

gridBagConstraints_2.insets = new Insets(8, 66, 2, 9);

compoesntesPanel.add(getApellidoLabel(), gridBagConstraints_2);

final GridBagConstraints gridBagConstraints_3 = new GridBagConstraints();

gridBagConstraints_3.gridx = 0;

gridBagConstraints_3.gridy = 3;

gridBagConstraints_3.insets = new Insets(8, 66, 14, 0);

compoesntesPanel.add(getDireccionLabel(), gridBagConstraints_3);

final GridBagConstraints gridBagConstraints_5 = new GridBagConstraints();

gridBagConstraints_5.gridx = 1;

gridBagConstraints_5.gridy = 1;

gridBagConstraints_5.ipadx = 196;

gridBagConstraints_5.insets = new Insets(6, 17, 0, 0);

compoesntesPanel.add(getNombreTextField(), gridBagConstraints_5);

final GridBagConstraints gridBagConstraints_6 = new GridBagConstraints();

gridBagConstraints_6.gridx = 1;

gridBagConstraints_6.gridy = 2;

gridBagConstraints_6.ipadx = 196;

gridBagConstraints_6.insets = new Insets(6, 17, 0, 0);

compoesntesPanel.add(getApellidoTextField(), gridBagConstraints_6);

final GridBagConstraints gridBagConstraints_7 = new GridBagConstraints();

gridBagConstraints_7.gridx = 1;

gridBagConstraints_7.gridy = 3;

gridBagConstraints_7.ipadx = 196;

gridBagConstraints_7.insets = new Insets(6, 17, 12, 0);

compoesntesPanel.add(getDireccionTextField(), gridBagConstraints_7);

final GridBagConstraints gridBagConstraints_10 = new GridBagConstraints();

gridBagConstraints_10.gridx = 3;

gridBagConstraints_10.gridy = 1;

gridBagConstraints_10.gridheight = 3;

gridBagConstraints_10.ipady = 10;

gridBagConstraints_10.insets = new Insets(6, 12, 12, 13);

compoesntesPanel.add(getAgregarButton(), gridBagConstraints_10);

}

return compoesntesPanel;

}

protected JLabel getCodigoLabel() {

if (codigoLabel == null) {

codigoLabel = new JLabel();

codigoLabel.setText("Código");

}

return codigoLabel;

}

protected JLabel getNombreLabel() {

if (nombreLabel == null) {

nombreLabel = new JLabel();

nombreLabel.setText("Nombre");

}

return nombreLabel;

}

protected JTextField getCodigoTextField() {

if (codigoTextField == null) {

codigoTextField = new JTextField();

}

return codigoTextField;

}

Page 55: Untitled

protected JTextField getNombreTextField() {

if (nombreTextField == null) {

nombreTextField = new JTextField();

}

return nombreTextField;

}

protected JLabel getApellidoLabel() {

if (apellidoLabel == null) {

apellidoLabel = new JLabel();

apellidoLabel.setText("Apellido");

}

return apellidoLabel;

}

protected JTextField getApellidoTextField() {

if (apellidoTextField == null) {

apellidoTextField = new JTextField();

}

return apellidoTextField;

}

protected JLabel getDireccionLabel() {

if (direccionLabel == null) {

direccionLabel = new JLabel();

direccionLabel.setText("Dirección");

}

return direccionLabel;

}

protected JTextField getDireccionTextField() {

if (direccionTextField == null) {

direccionTextField = new JTextField();

}

return direccionTextField;

}

protected JLabel getTelefonoLabel() {

if (telefonoLabel == null) {

telefonoLabel = new JLabel();

telefonoLabel.setText("Telefono");

}

return telefonoLabel;

}

protected JTextField getTelefonoTextField() {

if (telefonoTextField == null) {

telefonoTextField = new JTextField();

}

return telefonoTextField;

}

protected JButton getAgregarButton() {

if (agregarButton == null) {

agregarButton = new JButton();

agregarButton.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

setDatos();

}

});

}

agregarButton.setIcon(Imagen.getIconoImagen("IMG-OK"));

return agregarButton;

}

private void setDatos(){

Cliente cliente = null;

ClienteTableModel modelo = null;

if(getCodigoTextField().getText().trim().equals("") ||

getNombreTextField().getText().trim().equals("") ||

getApellidoTextField().getText().trim().equals("") ||

getDireccionTextField().getText().trim().equals("") ||

getTelefonoTextField().getText().trim().equals("")){

JOptionPane.showMessageDialog(this,

"Faltas campos que son obligatorios.",

"Información",

JOptionPane.INFORMATION_MESSAGE

);

return;

}

cliente = new Cliente();

cliente.setCodigo(Integer.parseInt(getCodigoTextField().getText()));

Page 56: Untitled

cliente.setNombre(getNombreTextField().getText());

cliente.setApellido(getApellidoTextField().getText());

cliente.setDireccion(getDireccionTextField().getText());

cliente.setTelefono(getTelefonoTextField().getText());

modelo = (ClienteTableModel) this.getClienteTable().getModel();

for(Cliente cli : modelo.getCliente()){

if(cli.getCodigo().intValue() == cliente.getCodigo().intValue()){

JOptionPane.showMessageDialog(this,

"El código ya existe.",

"Error",

JOptionPane.ERROR_MESSAGE

);

return;

}

}

modelo.getCliente().add(cliente);

modelo.fireTableDataChanged();

getCodigoTextField().setText("");

getNombreTextField().setText("");

getApellidoTextField().setText("");

getDireccionTextField().setText("");

getTelefonoTextField().setText("");

}

}

En el método getClienteTable se construye la tabla y se instancia la clase

ClienteTableModel y se setea el modelo a la tabla con el método setModel.

protected ClaseTable getClienteTable() {

if (clienteTable == null) {

clienteTable = new ClaseTable();

ClienteTableModel modelo = new ClienteTableModel();

clienteTable.setModel(modelo);

}

return clienteTable;

}

El método setDatos permite validar que las cajas de texto que no estén vacias y

código del registro que se inserta en la tabla. Se crea un objeto Cliente con los datos

de las cajas de texto y se agregar a lista getCliente del modelo. Para que el modelo

detecte los cambios y el nuevo registro agregado se llama al método

fireTableDataChanged().

import java.awt.BorderLayout;

import java.awt.Dimension;

import javax.swing.JDialog;

import javax.swing.UIManager;

import clases.ClientePanel1;

public class ClienteDialog extends JDialog {

private ClientePanel1 clientePanel1;

public ClienteDialog() {

super();

getContentPane().add(getClientePanel1(), BorderLayout.CENTER);

this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

this.setSize(new Dimension(550,500));

this.setLocationRelativeTo(null);

}

Page 57: Untitled

protected ClientePanel1 getClientePanel1() {

if (clientePanel1 == null) {

clientePanel1 = new ClientePanel1();

}

return clientePanel1;

}

public static void main(String[] args) {

try {

UIManager.setLookAndFeel("com.jgoodies.looks.windows.WindowsLookAndFeel");

} catch (Exception ex) {

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

} catch (Exception e){}

}

new ClienteDialog().setVisible(true);

}

}

5.10. Barras de Menú y Menús Contextuales

Primero creamos las acciones para nuestro menú, cada uno de los items. Para ello,

hacemos clases que hereden de AbstractAction.

private NuevoAction nuevoAction = null;

private EditarAction editarAction = null;

private EliminarAction eliminarAction = null;

public class NuevoAction extends AbstractAction {

public NuevoAction() {

super("Nuevo...", Imagen.getIconoImagen("IMG_NUEVO"));

}

public void actionPerformed(ActionEvent arg0) {

nuevo();

}

}

public class EditarAction extends AbstractAction {

Page 58: Untitled

public EditarAction() {

super("Editar...", Imagen.getIconoImagen("IMG_EDITAR"));

}

public void actionPerformed(ActionEvent arg0) {

editar();

}

}

public class EliminarAction extends AbstractAction {

public EliminarAction() {

super("Eliminar...", Imagen.getIconoImagen("IMG_ELIMINAR"));

}

public void actionPerformed(ActionEvent arg0) {

eliminar();

}

}

El objeto JToobar permite crear una barra de herramientas en nuestras aplicaciones

Java.

public void mostrarToolbar(){

JToolBar toolBar = null;

JButton button = null;

toolBar = new JToolBar();

toolBar.setBorder(new MatteBorder(0, 0, 0, 0, Color.black));

toolBar.setPreferredSize(new Dimension(50, 27));

toolBar.setRollover(true);

toolBar.setFloatable(true);

nuevoAction = new NuevoAction();

button = new JButton(nuevoAction);

button.setHorizontalAlignment(SwingConstants.LEFT);

toolBar.add(button);

editarAction = new EditarAction();

button = new JButton(editarAction);

button.setHorizontalAlignment(SwingConstants.LEFT);

toolBar.add(button);

eliminarAction = new EliminarAction();

button = new JButton(eliminarAction);

button.setHorizontalAlignment(SwingConstants.LEFT);

toolBar.add(button);

this.add(toolBar, BorderLayout.NORTH);

}

En el método mostrarToolbar se crea una JToolbar y se crean las diferentes acciones

de las clases NuevoAction, EditarAction y EliminarAction. Estas acciones se agregar a

un JButton y el JButton se agrega a la Toolbar.

Page 59: Untitled

Para generar un menú contextual en una tabla, se recomienda crear una clase aparte

(por ejemplo ClaseTable) que hereda de una JTable y que implementa la siguiente

estructura de código.

this.addMouseListener(

new MouseAdapter() {

public void mouseReleased(MouseEvent e) {

if (e.isPopupTrigger()) showPopUpMenu(e.getPoint());

}

public void mousePressed(MouseEvent e) {

if (e.isPopupTrigger()) showPopUpMenu(e.getPoint());

}

}

);

private void showPopUpMenu(Point p) {

updateSelection(p);

JPopupMenu menu = new JPopupMenu();

List<AbstractAction> actions = getActions();

if(actions != null){

for(AbstractAction action: getActions()){

menu.add(action);

}

updateActions();

if (menu != null) menu.show(this, p.x, p.y);

}

}

private void updateSelection(Point p) {

int nRow = rowAtPoint(p);

if (nRow == -1) clearSelection();

else if (!isRowSelected(nRow))

getSelectionModel().setSelectionInterval(nRow, nRow);

}

public List<AbstractAction> getActions() {

return null;

}

public void updateActions() {

}

El componente Java para el menú contextual es un JPopupMenu. Sólo hay que

instanciarlo y por medio del método add() pasarle las acciones que queremos que

sean nuestros items del menú. Por supuesto, hay más métodos para añadir las

acciones de otra forma o para añadir incluso submenus. Los métodos getActions y

updateActions serán sobrescritos en la clase que extienda de ClaseTable.

A contunuacion el código completo de estas clases.

Page 60: Untitled

La claseTable tiene propiedades adiciones de una JTable norma. Implementa las

interfaces DropTargetListener y DragGestureListener que se trataran mas adelante y

permite tener métodos como adjustColumnWidth() que permite adjustar las columnas

al tamaño de información que existe en las celdas y también el manejo del Objeto

JPopupMenu para los menus contextuales.

public class ClaseTable extends JTable implements DropTargetListener,

DragGestureListener{

protected DropTarget dropTarget = null;

protected DragSource dragSource = null;

public ClaseTable() {

super();

initTable();

}

private void initTable() {

setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);

this.addMouseListener(

new MouseAdapter() {

public void mouseReleased(MouseEvent e) {

if (e.isPopupTrigger()) showPopUpMenu(e.getPoint());

}

public void mousePressed(MouseEvent e) {

if (e.isPopupTrigger()) showPopUpMenu(e.getPoint());

}

}

);

putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);

dropTarget = new DropTarget(this, this);

dragSource = new DragSource();

dragSource.createDefaultDragGestureRecognizer(this,

DnDConstants.ACTION_COPY_OR_MOVE, this);

}

private void updateSelection(Point p) {

int nRow = rowAtPoint(p);

if (nRow == -1) clearSelection();

else if (!isRowSelected(nRow))

getSelectionModel().setSelectionInterval(nRow, nRow);

}

private void showPopUpMenu(Point p) {

updateSelection(p);

JPopupMenu menu = new JPopupMenu();

List<AbstractAction> actions = getActions();

if(actions != null){

for(AbstractAction action: getActions()){

menu.add(action);

}

updateActions();

if (menu != null) menu.show(this, p.x, p.y);

}

}

public List<AbstractAction> getActions() {

return null;

}

public void updateActions() {

}

public void adjustColumnWidth(){

TableColumnModel columnModel = this.getColumnModel();

int totalColumn = this.getColumnCount();

int totalRows = this.getRowCount();

for(int column=0; column<totalColumn; column++){

int maxSize =0;

for(int row=0; row<totalRows; row++){

Page 61: Untitled

TableCellRenderer rend= getCellRenderer(row, column);

Object cellValue= getValueAt(row, column);

Component mintComponent= rend.getTableCellRendererComponent(this, cellValue,

false, false, row, column);

if (!(mintComponent instanceof JPanel)) {

mintComponent.setPreferredSize(null);

}

maxSize= Math.max(mintComponent.getPreferredSize().width,maxSize);

}

TableColumn tableColumn= columnModel.getColumn(column);

TableCellRenderer headerRenderer= tableColumn.getHeaderRenderer();

if(headerRenderer==null){

headerRenderer = getTableHeader().getDefaultRenderer();

}

Object headerValue=tableColumn.getHeaderValue();

Component headerComp= headerRenderer.getTableCellRendererComponent(this,

headerValue,

false,

false, 0,

column);

int tHeader=headerComp.getPreferredSize().width;

maxSize= Math.max(maxSize,tHeader)+4;

tableColumn.setPreferredWidth(maxSize);

tableColumn.setMinWidth(4);

}

}

public boolean getScrollableTracksViewportHeight() {

Component parent = getParent();

if (parent instanceof JViewport)

return parent.getHeight() > getPreferredSize().height;

return false;

}

public void dragEnter(DropTargetDragEvent dtde) {}

public void dragExit(DropTargetEvent dte) {}

public void dragOver(DropTargetDragEvent dtde) {}

public void drop(DropTargetDropEvent dtde) {}

public void dropActionChanged(DropTargetDragEvent dtde) {}

public void dragGestureRecognized(DragGestureEvent dge){}

}

La clase ClienteTable extiende de ClaseTable que a su vez extiende de una JTable.

Esta clase permite implementar las acciones que tendrá la tabla en el menú

contextual.

import java.awt.event.ActionEvent;

import java.util.ArrayList;

import java.util.List;

import javax.swing.AbstractAction;

public class ClienteTable extends ClaseTable {

private List<AbstractAction> actions = null;

private NuevoAction nuevoAction = null;

private EditarAction editarAction = null;

private EliminarAction eliminarAction = null;

public ClienteTable() {

super();

}

public class NuevoAction extends AbstractAction {

public NuevoAction() {

super("Nuevo...", Imagen.getIconoImagen("IMG_NUEVO"));

}

public void actionPerformed(ActionEvent arg0) {

ClienteTable.this.firePropertyChange("nuevo", true, false);

Page 62: Untitled

}

}

public class EditarAction extends AbstractAction {

public EditarAction() {

super("Editar...", Imagen.getIconoImagen("IMG_EDITAR"));

}

public void actionPerformed(ActionEvent arg0) {

ClienteTable.this.firePropertyChange("editar", true, false);

}

}

public class EliminarAction extends AbstractAction {

public EliminarAction() {

super("Eliminar...",Imagen.getIconoImagen("IMG_ELIMINAR"));

}

public void actionPerformed(ActionEvent arg0) {

ClienteTable.this.firePropertyChange("eliminar", true, false);

}

}

public List<AbstractAction> getActions(){

if(actions == null){

actions = new ArrayList<AbstractAction>();

}

if(nuevoAction == null){

nuevoAction = new NuevoAction();

actions.add(nuevoAction);

}

if(editarAction == null){

editarAction = new EditarAction();

actions.add(editarAction);

}

if(eliminarAction == null){

eliminarAction = new EliminarAction();

actions.add(eliminarAction);

}

return actions;

}

public void updateActions() {

int row = this.getSelectedRow();

if(editarAction != null){

editarAction.setEnabled(row > -1);

}

if(eliminarAction != null){

eliminarAction.setEnabled(row > -1);

}

}

}

Se sobreescribe los métodos getActions que permite crear las acciones y agregarlas a

una lista de AbstractAction, este método es invocado por la clase padre en este caso

“ClaseTable” cuando el usuario da clic izquierdo con el mouse y el método

updateActions que permite activar o desactivar la acción. En esta clase también se

hace uso del firePropertyChange que permite lanzar un listener a la clase donde se

este usando la tabla “ClienteTable”.

La clase “ClientePanel2” permite implementar las acciones para la barra de menú y

además construye el GUI general. Se hace uso de la interfaz

addPropertyChangeListener que permite escuchar el firePropertyChange que fue

lanzado desde la clase “ClienteTable”.

Page 63: Untitled

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.KeyboardFocusManager;

import java.awt.Window;

import java.awt.event.ActionEvent;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.beans.PropertyChangeEvent;

import java.beans.PropertyChangeListener;

import javax.swing.AbstractAction;

import javax.swing.JButton;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JToolBar;

import javax.swing.ListSelectionModel;

import javax.swing.SwingConstants;

import javax.swing.border.MatteBorder;

import javax.swing.event.ListSelectionEvent;

import javax.swing.event.ListSelectionListener;

import aplicacion.Cliente;

public class ClientePanel2 extends JPanel{

private ClienteTable clienteTable;

private JScrollPane clientesScrollPane;

private NuevoAction nuevoAction = null;

private EditarAction editarAction = null;

private EliminarAction eliminarAction = null;

public ClientePanel2() {

super();

setLayout(new BorderLayout());

add(getClientesScrollPane());

mostrarToolbar();

updateActions();

}

protected JScrollPane getClientesScrollPane() {

if (clientesScrollPane == null) {

clientesScrollPane = new JScrollPane();

clientesScrollPane.setViewportView(getClienteTable());

}

return clientesScrollPane;

}

protected ClienteTable getClienteTable() {

if (clienteTable == null) {

clienteTable = new ClienteTable();

clienteTable.addMouseListener(new MouseAdapter() {

public void mouseClicked(final MouseEvent evt) {

if(editarAction.isEnabled() && evt.getClickCount() == 2){

editar();

}

}

});

ClienteTableModel modelo = new ClienteTableModel();

clienteTable.setModel(modelo);

ListSelectionModel listSelectionModel = clienteTable.getSelectionModel();

listSelectionModel.addListSelectionListener(new ListSelectionListener() {

public void valueChanged(ListSelectionEvent e) {

updateActions();

}

});

clienteTable.addPropertyChangeListener(new PropertyChangeListener(){

public void propertyChange(PropertyChangeEvent evt) {

if(evt.getPropertyName().equals("nuevo")){

nuevo();

}

else if(evt.getPropertyName().equals("editar")){

editar();

}

else if(evt.getPropertyName().equals("eliminar")){

eliminar();

Page 64: Untitled

}

}

});

}

return clienteTable;

}

public class NuevoAction extends AbstractAction {

public NuevoAction() {

super("Nuevo...", Imagen.getIconoImagen("IMG_NUEVO"));

}

public void actionPerformed(ActionEvent arg0) {

nuevo();

}

}

public class EditarAction extends AbstractAction {

public EditarAction() {

super("Editar...", Imagen.getIconoImagen("IMG_EDITAR"));

}

public void actionPerformed(ActionEvent arg0) {

editar();

}

}

public class EliminarAction extends AbstractAction {

public EliminarAction() {

super("Eliminar...", Imagen.getIconoImagen("IMG_ELIMINAR"));

}

public void actionPerformed(ActionEvent arg0) {

eliminar();

}

}

private void nuevo(){

nuevoOeditar(null);

}

private void editar(){

ClienteTableModel modelo = (ClienteTableModel) clienteTable.getModel();

nuevoOeditar(modelo.getCliente().get(clienteTable.getSelectedRow()));

}

private void eliminar(){

ClienteTableModel modelo = (ClienteTableModel) clienteTable.getModel();

modelo.getCliente().remove(clienteTable.getSelectedRow());

modelo.fireTableDataChanged();

}

public void mostrarToolbar(){

JToolBar toolBar = null;

JButton button = null;

toolBar = new JToolBar();

toolBar.setBorder(new MatteBorder(0, 0, 0, 0, Color.black));

toolBar.setPreferredSize(new Dimension(50, 27));

toolBar.setRollover(true);

toolBar.setFloatable(true);

nuevoAction = new NuevoAction();

button = new JButton(nuevoAction);

button.setHorizontalAlignment(SwingConstants.LEFT);

toolBar.add(button);

editarAction = new EditarAction();

button = new JButton(editarAction);

button.setHorizontalAlignment(SwingConstants.LEFT);

toolBar.add(button);

eliminarAction = new EliminarAction();

button = new JButton(eliminarAction);

button.setHorizontalAlignment(SwingConstants.LEFT);

toolBar.add(button);

this.add(toolBar, BorderLayout.NORTH);

}

private void updateActions(){

int row = getClienteTable().getSelectedRow();

if(editarAction != null){

editarAction.setEnabled(row > -1);

}

if(eliminarAction != null){

Page 65: Untitled

eliminarAction.setEnabled(row > -1);

}

}

public void nuevoOeditar(final Cliente cliente){

Window window =

KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();

final int fila = getClienteTable().getSelectedRow();

final EditDialog editDialog = EditDialog.ejecutar(window,

cliente);

editDialog.addPropertyChangeListener(new PropertyChangeListener(){

public void propertyChange(PropertyChangeEvent evt){

if(evt.getPropertyName().equals("guardar")){

ClienteTableModel modelo = (ClienteTableModel) clienteTable.getModel();

if(cliente == null){

for(Cliente cli : modelo.getCliente()){

if(cli.getCodigo().intValue() == ((Cliente)

evt.getNewValue()).getCodigo().intValue()){

JOptionPane.showMessageDialog(ClientePanel2.this,

"El código ya existe.",

"Error",

JOptionPane.ERROR_MESSAGE

);

return;

}

}

modelo.getCliente().add((Cliente) evt.getNewValue());

modelo.fireTableDataChanged();

editDialog.dispose();

}

else{

modelo.getCliente().set(fila,(Cliente) evt.getNewValue());

modelo.fireTableDataChanged();

editDialog.dispose();

getClienteTable().setRowSelectionInterval(fila, fila);

}

}

}

});

editDialog.showCentered(0, 0);

}

}

Page 66: Untitled

El método “nuevoOeditar” de la clase “ClientePanel2” se llama cuando se da clic en el

menú contextual o en la barra de menú sobre las opciones Nuevo o Editar. Este

método laza un dialogo que permite agregar y modificar registros de la tabla.

import java.awt.Font;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JTextField;

public class EditarPanel extends JPanel {

private JLabel label;

private JTextField telefonoTextField;

private JButton agregarButton;

private JLabel telefonoLabel;

private JTextField direccionTextField;

private JLabel direccionLabel;

private JTextField apellidoTextField;

private JLabel apellidoLabel;

private JTextField nombreTextField;

private JLabel nombreLabel;

private JTextField codigoTextField;

private JLabel codigoLabel;

public EditarPanel() {

super();

setLayout(null);

setSize(500, 375);

add(getNombreLabel());

add(getApellidoLabel());

add(getDireccionLabel());

add(getNombreTextField());

add(getApellidoTextField());

add(getDireccionTextField());

add(getAgregarButton());

add(getLabel());

add(getCodigoLabel());

add(getCodigoTextField());

add(getTelefonoLabel());

add(getTelefonoTextField());

}

protected JLabel getCodigoLabel() {

if (codigoLabel == null) {

codigoLabel = new JLabel();

codigoLabel.setBounds(12, 63, 39, 16);

codigoLabel.setText("Código");

}

return codigoLabel;

}

protected JTextField getCodigoTextField() {

if (codigoTextField == null) {

codigoTextField = new JTextField();

codigoTextField.setBounds(83, 61, 114, 20);

}

return codigoTextField;

}

protected JLabel getNombreLabel() {

if (nombreLabel == null) {

nombreLabel = new JLabel();

nombreLabel.setBounds(12, 89, 45, 16);

nombreLabel.setText("Nombre");

}

return nombreLabel;

}

protected JTextField getNombreTextField() {

if (nombreTextField == null) {

nombreTextField = new JTextField();

nombreTextField.setBounds(83, 87, 200, 20);

}

return nombreTextField;

Page 67: Untitled

}

protected JLabel getApellidoLabel() {

if (apellidoLabel == null) {

apellidoLabel = new JLabel();

apellidoLabel.setBounds(12, 115, 45, 16);

apellidoLabel.setText("Apellido");

}

return apellidoLabel;

}

protected JTextField getApellidoTextField() {

if (apellidoTextField == null) {

apellidoTextField = new JTextField();

apellidoTextField.setBounds(83, 113, 200, 20);

}

return apellidoTextField;

}

protected JLabel getDireccionLabel() {

if (direccionLabel == null) {

direccionLabel = new JLabel();

direccionLabel.setBounds(12, 141, 54, 16);

direccionLabel.setText("Dirección");

}

return direccionLabel;

}

protected JTextField getDireccionTextField() {

if (direccionTextField == null) {

direccionTextField = new JTextField();

direccionTextField.setBounds(83, 139, 200, 20);

}

return direccionTextField;

}

protected JLabel getTelefonoLabel() {

if (telefonoLabel == null) {

telefonoLabel = new JLabel();

telefonoLabel.setBounds(290, 63, 49, 16);

telefonoLabel.setText("Telefono");

}

return telefonoLabel;

}

protected JButton getAgregarButton() {

if (agregarButton == null) {

agregarButton = new JButton();

agregarButton.setBounds(351, 87, 75, 72);

agregarButton.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

Cliente cliente = getCliente();

if(cliente != null){

EditarPanel.this.firePropertyChange("guardar", true, cliente);

}

}

});

agregarButton.setIcon(Imagen.getIconoImagen("IMG-OK"));

}

return agregarButton;

}

protected JTextField getTelefonoTextField() {

if (telefonoTextField == null) {

telefonoTextField = new JTextField();

telefonoTextField.setBounds(351, 61, 75, 20);

}

return telefonoTextField;

}

protected JLabel getLabel() {

if (label == null) {

label = new JLabel();

label.setBounds(162, 12, 177, 21);

label.setFont(new Font("", Font.BOLD, 16));

label.setText("New JLabel");

}

return label;

}

public void setTitulo(String titulo){

getLabel().setText(titulo);

}

public void setCliente(Cliente cliente){

if(cliente != null){

getCodigoTextField().setText(String.valueOf(cliente.getCodigo()));

Page 68: Untitled

getNombreTextField().setText(cliente.getNombre());

getApellidoTextField().setText(cliente.getApellido());

getDireccionTextField().setText(cliente.getDireccion());

getTelefonoTextField().setText(cliente.getTelefono());

}

}

private Cliente getCliente(){

if(getCodigoTextField().getText().trim().equals("") ||

getNombreTextField().getText().trim().equals("") ||

getApellidoTextField().getText().trim().equals("") ||

getDireccionTextField().getText().trim().equals("") ||

getTelefonoTextField().getText().trim().equals("")){

JOptionPane.showMessageDialog(this,

"Faltas campos que son obligatorios.",

"Información",

JOptionPane.INFORMATION_MESSAGE

);

return null;

}

Cliente cliente = new Cliente();

cliente.setCodigo(Integer.parseInt(getCodigoTextField().getText()));

cliente.setNombre(getNombreTextField().getText());

cliente.setApellido(getApellidoTextField().getText());

cliente.setDireccion(getDireccionTextField().getText());

cliente.setTelefono(getTelefonoTextField().getText());

return cliente;

}

}

import java.awt.BorderLayout;

import java.awt.Dialog;

import java.awt.Dimension;

import java.awt.Frame;

import java.awt.Toolkit;

import java.awt.Window;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import java.beans.PropertyChangeEvent;

import java.beans.PropertyChangeListener;

import javax.swing.JDialog;

public class EditDialog extends JDialog {

private EditarPanel editarPanel;

public EditDialog(Frame frame, Cliente cliente){

super(frame,true);

inicializar(cliente);

}

public EditDialog(Dialog dialog, Cliente cliente) {

super(dialog,true);

inicializar(cliente);

}

public EditDialog(Cliente cliente) {

this((Frame)null,cliente);

}

public static EditDialog ejecutar(Window window, Cliente cliente){

if (window instanceof Frame){

return new EditDialog((Frame) window ,cliente);

}

else if (window instanceof Dialog){

return new EditDialog((Dialog)window, cliente);

}

else{

return new EditDialog((Frame)null, cliente);

Page 69: Untitled

}

}

private void inicializar(Cliente cliente){

getContentPane().add(getEditarPanel(), BorderLayout.CENTER);

this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

this.setLocationRelativeTo(null);

this.setBounds(0, 0,460 , 205);

this.setResizable(false);

String titulo = cliente == null ? "Nuevo Cliente" :

"Editar Cliente";

this.setTitle(titulo);

getEditarPanel().setTitulo(titulo);

getEditarPanel().setCliente(cliente);

this.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent arg0) {

dispose();

}

});

}

protected EditarPanel getEditarPanel() {

if (editarPanel == null) {

editarPanel = new EditarPanel();

editarPanel.addPropertyChangeListener(new PropertyChangeListener(){

public void propertyChange(PropertyChangeEvent evt) {

if(evt.getPropertyName().equals("guardar")){

EditDialog.this.firePropertyChange("guardar", true,

evt.getNewValue());

}

}

});

}

return editarPanel;

}

public void showCentered(int xOffset, int yOffset) {

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

Dimension frameSize = getSize();

if (frameSize.height > screenSize.height){

frameSize.height = screenSize.height;

}

if (frameSize.width > screenSize.width){

frameSize.width = screenSize.width;

}

int nXPos = (screenSize.width - frameSize.width) / 2 + xOffset;

int nYPos = (screenSize.height - frameSize.height) / 2 + yOffset;

setLocation(nXPos, nYPos);

setVisible(true);

}

}

Page 70: Untitled

5.11. Drag-and-Drop

Para generar un drag-and-drop entre un componente y otro se debe implementar la

interfaz DragSourceListener donde se va hacer el drag y agregar la siguiente

estructura de código en el método constructor de la clase o en un método inicializar si

esta clase tiene varios constructores.

DragSource dragSource = new DragSource();

dragSource.createDefaultDragGestureRecognizer(this,

DnDConstants.ACTION_COPY_OR_MOVE, new DragGestureListener(){

public void dragGestureRecognized(DragGestureEvent e){

startDragTree(e);

}

});

El método startDragTree se llama cuando se presiona el clic derecho del mouse y se

arrastra.

private void startDragTree(DragGestureEvent e) {

TreePath[] selectedPaths = this.getSelectionPaths();

File files[] = null;

if(selectedPaths == null || selectedPaths.length == 0){

return;

}

files = new File[selectedPaths.length];

for(int i = 0; i<selectedPaths.length; i++){

files[i] = (File) selectedPaths[i].getLastPathComponent();

}

e.getDragSource().startDrag(

e,

Page 71: Untitled

DragSource.DefaultMoveDrop,

new TransferableTree(files),

this);

}

Para este ejemplo el método startDragTree permite capturar los nodos seleccionados

de un árbol. El objeto que se va a llevar para el drop se debe guardar en una clase que

debe implementa la interfaz Transferable, una clase que implemente está interfaz

puede manejar múltiples drag-and-drop.

import java.awt.datatransfer.DataFlavor;

import java.awt.datatransfer.Transferable;

import java.awt.datatransfer.UnsupportedFlavorException;

import java.io.File;

public class TransferableTree implements Transferable {

final static int TREE = 0;

final public static DataFlavor TREE_FLAVOR = new DataFlavor(File[].class, "tree");

static DataFlavor fFlavors[] = {TREE_FLAVOR,

DataFlavor.stringFlavor};

private File[] file;

public TransferableTree(File[] file) {

this.file = file;

}

public DataFlavor[] getTransferDataFlavors() {

return fFlavors;

}

public Object getTransferData(DataFlavor aFlavor) throws UnsupportedFlavorException{

Object lReturnObject = null;

if (aFlavor.equals(fFlavors[TREE])) {

lReturnObject = file;

}

else {

throw new UnsupportedFlavorException(aFlavor);

}

return lReturnObject;

}

public boolean isDataFlavorSupported(DataFlavor aFlavor) {

boolean lReturnValue = false;

for (int i=0, n=fFlavors.length; i<n; i++) {

if (aFlavor.equals(fFlavors[i])) {

lReturnValue = true;

break;

}

}

return lReturnValue;

}

}

En la clase donde llega el drop se debe implementar las interfaces DropTargetListener,

DragGestureListener. Para este ejemplo se permite el drag-and-drop entre un árbol

que esta en un JScrollPane y una tabla que también esta en una JScrollPane. En la

ClaseTable se hace la implementación de esas interfaces y de la siguiente

estructurura de código en el método initTable que inicializa propiedades de la tabla.

protected DropTarget dropTarget = null;

protected DragSource dragSource = null;

Page 72: Untitled

dropTarget = new DropTarget(this, this);

dragSource = new DragSource();

dragSource.createDefaultDragGestureRecognizer(this,

DnDConstants.ACTION_COPY_OR_MOVE, this);

En la clase donde esta la tabla que extienda de ClaseTable se debe sobrescribir el

método drop, tenido en cuenta el TransferableTree ya que se puede tener varios de

estos.

protected ClaseTable getDetallesTable() {

if (detallesTable == null) {

detallesTable = new ClaseTable(){

public void drop(DropTargetDropEvent dtde) {

Transferable tr = dtde.getTransferable();

File[] file = null;

try {

if(tr.isDataFlavorSupported(TransferableTree.TREE_FLAVOR)){

file = (File[]) tr.getTransferData(TransferableTree.TREE_FLAVOR);

NodosTableModel modelo = (NodosTableModel) detallesTable.getModel();

for(int i=0; i<file.length; i++){

if(!modelo.getFiles().contains(file[i])){

modelo.getFiles().add(file[i]);

}

}

modelo.fireTableDataChanged();

}

}

catch (UnsupportedFlavorException e) {

e.printStackTrace();

}

catch (IOException e) {

e.printStackTrace();

}

dtde.acceptDrop(DnDConstants.ACTION_MOVE);

dtde.dropComplete(true);

}

};

NodosTableModel modelo = new NodosTableModel();

detallesTable.setModel(modelo);

}

return detallesTable;

}

Page 73: Untitled

5.12. DefaultTableCellRenderer y DefaultCellEditor

Un JTable de Java sabe manejar algunos de los datos standard de Java, sabe dibujar

celdas que contengan un String, un Integer, etc. Es posbible que en un momento dado

queramos hacer que nuestros datos se pinten de alguna manera distinta o que

tengamos datos que el JTable no sabe manejar, alguna clase propia. Por ejemplo,

podemos querer pintar iconos en las celdas del JTable, hacer que cambie el tipo de

letra, sus colores, etc.

Para ello el JTable nos proporciona la posibilidad de cambiar su TableCellRenderer , la

clase que sabe y se encarga de dibujar los datos que hay en cada celda. Podemos

hacer nuestro propio TableCellRenderer que dibuje de forma especial esos datos o

que entienda nuevos tipos de datos. Luego basta con pasarle este TableCellRenderer

al JTable .

import java.awt.Color;

import java.awt.Component;

import javax.swing.JPasswordField;

import javax.swing.JTable;

import javax.swing.SwingConstants;

import javax.swing.table.DefaultTableCellRenderer;

public class UsuarioTableCellRenderer extends DefaultTableCellRenderer {

public Component getTableCellRendererComponent(JTable table,

Object value,

boolean isSelected,

boolean hasFocus,

int row,

int column) {

Page 74: Untitled

this.setForeground(Color.BLACK);

this.setBackground(Color.WHITE);

this.setText(value == null ? "" : String.valueOf(value));

this.setToolTipText(value == null ? "“: String.valueOf (value));

this.setIcon(null);

this.setHorizontalTextPosition(SwingConstants.RIGHT);

if(column == 0){

this.setIcon(Imagen.getIconoImagen("IMG_USUARIO"));

}

if(isSelected){

this.setBackground(table.getSelectionBackground());

this.setForeground(table.getSelectionForeground());

}

if(column == 6){

JPasswordField passwordField = new JPasswordField();

passwordField.setText(value == null ? "" :String.valueOf(value));

passwordField.setBorder(null);

if(isSelected){

passwordField.setBackground(table.getSelectionBackground());

passwordField.setForeground(table.getSelectionForeground());

}

return passwordField;

}

return this;

}

}

Este renderer coloca tooltiptest a las celdas de las columnas de la tabla y permite

colocar una imagen para la primera columna de la tabla. Tambien retorna un

componente JPasswordField para la columna 6 de la tabla.

Para agregar el renderer a las columnas de la tabla se puede utilizar un ciclo for para

recorrer todas las columnas de la tabla.

for(int i=0; i<getUsuarioTable().getColumnCount()-1; i++){

getUsuarioTable().setDefaultRenderer(getUsuarioTable().getColumnClass(i), new

UsuarioTableCellRenderer());

}

Para colocar un JComboBox o un JChecBox en una celda de una tabla hacemos uso

de la clase DefaultCellEditor. Para la siguiente clase se implemento un JComboBox y

un JPasswordField.

import java.awt.Color;

import java.awt.Component;

import java.awt.SystemColor;

import javax.swing.DefaultCellEditor;

import javax.swing.DefaultComboBoxModel;

import javax.swing.JComboBox;

import javax.swing.JPasswordField;

import javax.swing.JTable;

import javax.swing.JTextField;

import javax.swing.border.LineBorder;

public class UsuarioTableCellEditor extends DefaultCellEditor{

private JTextField textoTextField;

private JPasswordField passwordField;

private JComboBox tipoUsuario;

private int col = 0;

public UsuarioTableCellEditor(){

Page 75: Untitled

super(new JTextField());

setClickCountToStart(1);

textoTextField = (JTextField) this.getComponent();

textoTextField.setBorder(new LineBorder(Color.BLACK));

llenarComboTipoUsuario();

}

protected JComboBox getTipoUsuarioComboBox(){

if(tipoUsuario == null){

tipoUsuario = new JComboBox();

tipoUsuario.setBorder(new LineBorder(Color.BLACK));

tipoUsuario.setBackground(SystemColor.control);

}

return tipoUsuario;

}

protected JPasswordField getPasswordField(){

if(passwordField == null){

passwordField = new JPasswordField();

passwordField.setBackground(SystemColor.control);

passwordField.setBorder(null);

}

return passwordField;

}

private void llenarComboTipoUsuario(){

DefaultComboBoxModel model = null;

model = new DefaultComboBoxModel();

for(ETipoUsuario tipoUsuario :ETipoUsuario.values()){

model.addElement(tipoUsuario);

}

getTipoUsuarioComboBox().setModel(model);

}

public Component getTableCellEditorComponent(JTable table, Object value, boolean

isSelected, int row, int col) {

this.col = col;

if(table.getSelectedRow() == -1){

return null;

}

if(col == 4){

getTipoUsuarioComboBox().setSelectedItem(value);

return getTipoUsuarioComboBox();

}

if(col == 6){

getPasswordField().setText(value == null ? "" : String.valueOf(value));

return getPasswordField();

}

textoTextField = (JTextField) super.getTableCellEditorComponent(table, value,

isSelected, row, col);

textoTextField.setText(value == null ? "" : String.valueOf(value));

return textoTextField;

}

public Object getCellEditorValue(){

if(col == 4){

return getTipoUsuarioComboBox().getSelectedItem();

}

if(col == 6){

return getPasswordField().getText();

}

return textoTextField.getText().toUpperCase();

}

}

El JComboBox se llena con los datos del siguiente enumerado:

public enum ETipoUsuario {

ADMINISTRADOR{

public int getId(){

return 1;

}

public String getNombre(){

return "Administrador";

}

},

Page 76: Untitled

EMPLEADO{

public int getId(){

return 2;

}

public String getNombre(){

return "Empleado";

}

};

public abstract int getId();

public abstract String getNombre();

}

Para agregar el cellEditor a las columnas de la tabla se puede utilizar un ciclo for para

recorrer todas las columnas de la tabla.

for(int i=0; i<getUsuarioTable().getColumnCount(); i++){

getUsuarioTable().setDefaultEditor(getUsuarioTable().getColumnClass(i),

new UsuarioTableCellEditor());

}

5.13. Ejemplos

El siguiente WIZARD permite ver en un solo JDialog los últimos cuatro ejemplo de:

Tablas y Molelos, Barras de Menú y Menús contextuales, Drag-and-drop y

DefaultTableCellRenderer y DefaultCellEditor. Este diálogo maneja una transición

entre los cuatro paneles. Los .jar que permiten este tipo de animaciones son:

AnimatedTransitions-0.11.jar y TimingFramework-1.0.jar.

Page 77: Untitled

import java.awt.BorderLayout;

import javax.swing.JComponent;

import org.jdesktop.animation.timing.Animator;

import org.jdesktop.animation.transitions.ScreenTransition;

import org.jdesktop.animation.transitions.TransitionTarget;

public class TransitionPanel extends JComponent implements TransitionTarget{

private Animator animator = null;

private ScreenTransition transition = null;

private JComponent component = null;

private int milliseconds = 1500;

private final float acceleration = 0.2f;

public TransitionPanel(JComponent component){

init(component);

}

public void init(JComponent component){

this.animator = new Animator(this.milliseconds);

this.transition = new ScreenTransition(this, this, this.animator);

this.animator.setAcceleration(this.acceleration);

this.animator.setDeceleration(this.acceleration);

this.setLayout(new BorderLayout());

this.add(component);

}

public void setupNextScreen(){

this.removeAll();

this.add(this.component);

}

public void startTransition(){

this.transition.start();

}

public void setComponent(JComponent component) {

this.component = component;

}

public Animator getAnimator() {

if(animator == null) {

animator = new Animator(this.milliseconds);

}

return animator;

}

public int getMilliseconds() {

return milliseconds;

}

}

Esta clase permite la transición entre los componetes del wizard. En el dialogo los

componentes inicialmente son agregados de esta manera.

private TransitionPanel transitionPanel;

private JComponent component;

private JComponent getComponente(){

if(component == null){

component = new JPanel();

component.setLayout(new BorderLayout());

}

return component;

}

Page 78: Untitled

public JPanel getContainerPanel() {

if(containerPanel == null) {

containerPanel = new JPanel();

containerPanel.setLayout(new BorderLayout());

getComponente().add(getStepGuidePanel(0), BorderLayout.NORTH);

getComponente().add(getClientePanel(), BorderLayout.CENTER);

transitionPanel = new TransitionPanel(getComponente());

containerPanel.add(transitionPanel, BorderLayout.CENTER);

}

return containerPanel;

}

this.add(getContainerPanel(), BorderLayout.CENTER);

El manejo de paso de un panel a otro se hace mediante esta estructura de codigo:

public void gotoStep(int step) {

this.currentStep = step;

this.component = null;

getComponente().add(getStepGuidePanel(step), BorderLayout.NORTH);

switch(step) {

case 0: getComponente().add(getClientePanel(), BorderLayout.CENTER);

break;

case 1: getComponente().add(getClientePanel2(), BorderLayout.CENTER);

break;

case 2: getComponente().add(getTreePanel(), BorderLayout.CENTER);

break;

case 3: getComponente().add(getPropiedadesPanel(), BorderLayout.CENTER);

default:

break;

}

transitionPanel.setComponent(getComponente());

transitionPanel.startTransition();

updateNavigationButtons();

getContainerPanel().repaint();

getContainerPanel().revalidate();

}

Page 79: Untitled
Page 80: Untitled

Sistema de Historias Clinicas

1. Diagrama de casos de uso

a. Especificación de Actores

Nombre Médico

Descripción Breve Registra, consulta y actualiza las historias clínicas

Características Registra diagnósticos

Consulta Historias clínicas

Consulta, registra y modifica procedimientos

Consulta, registra y modifica formulas

Relaciones Sistema de citas

Secretaria

Nombre Secretaria

Descripción Breve Persona encargada de hacer de los datos básicos de los pacientes

Características Registra información de los pacientes

Asigna citas

Relaciones Sistema de citas

Medico

Page 81: Untitled

Nombre Sistema de citas

Descripción Breve Sistema encargado de administrar los recursos para la asignación de citas

Características Registra citas

Consulta datos básicos

Genera reportes de las citas diarias

Relaciones Sistema de citas

Medico

Nombre Administrador

Descripción Breve Persona encargada de administrar el sistema de historias clínicas.

Características Administra los procedimientos

Administra la información de los medicamentos

Relaciones Sistema de citas

Medico

Secretaria

b. Especificación de Caso de Uso

Nombre Registro paciente

Descripción Representa el caso de uso por medio del cual el actor va a realizar el registro de la historia clínica del paciente.

Flujo de eventos Flujo Básico

Ingresar la identificación del paciente. El actor ingresa el dato de la identificación, dicha identificación es el número de identificación del paciente que este registrado en el sistema de citas (cedula de ciudadanía, pasaporte, cedula de extranjería, etc.)

El sistema valida la identificación y muestra la pantalla con el formulario para llenar: Dicho formulario se compone por los siguientes datos:

o Identificación: Este campo representa la identificación del paciente (cedula de ciudadanía, pasaporte, cedula de extranjería, etc.)

o Nombre: Este campo representa el nombre completo del paciente

o Estatura: Este campo representa la estatura del paciente o Tipo de sangre: Este campo representa el tipo de sangre del

paciente o Ocupación: Este campo representa la ocupación actual del

paciente o Fecha de nacimiento: Este campo representa la fecha de

nacimiento del paciente

Page 82: Untitled

o Dirección: Este campo representa la dirección actual del paciente

o Peso: Este campo representa el peso en kilogramos del paciente.

La secretaria ingresa los datos al sistema

El sistema valida los datos y guarda la historia clínica terminando el proceso.

Flujos Alternativos Flujo alternativo historia existente A partir del paso 1 del flujo básico, el sistema valida la identificación mostrando el mensaje “Historia Clínica existente”

Flujo alternativo datos inválidos A partir del paso 3 del flujo básico, el sistema valida los datos mostrando un mensaje de error “No se puede registrar la información debido a que existen datos inválidos”, con el cual se le indica al actor que existen datos inválidos y sigue mostrando la pantalla actual.

Precondiciones El paciente debe estar afiliado a una EPS

Poscondiciones La historia es creada en el sistema y puede ser consultada por los diferentes usuarios autorizados

Nombre Consultar datos básicos del paciente

Descripción Representa el caso de uso por medio del cual el actor va a consultar los datos básicos de un paciente determinado.

Flujo de eventos Flujo Básico

El actor recibe la identificación del paciente, dicha identificación es el número de identificación del paciente que este registrado en el sistema de citas (cedula de ciudadanía, pasaporte, cedula de extranjería, etc.) y envía al sistema de historia clínicas la identificación del paciente

El sistema de historias clínicas valida la identificación y envía al sistema de citas los datos básicos.

Flujos Alternativos Historia no existe A partir del paso 1 del flujo básico, el sistema muestra un mensaje “La historia clínica asociada a la identificación ingresada no existe en el sistema” indicando que la historia clínica no existe.

Precondiciones El paciente debe estar registrado en el sistema de citas

Poscondiciones La historia clínica queda asignada a la cita respectiva.

Nombre Consultar historia

Descripción Representa el caso de uso por medio del cual el actor va a consultar la historia clínica de un paciente determinado.

Flujo de eventos Flujo Básico

El medico ingresa la identificación del paciente dicha

Page 83: Untitled

identificación es el número de identificación del paciente que este registrado en el sistema de citas (cedula de ciudadanía, pasaporte, cedula de extranjería, etc.)

El sistema valida la identificación y muestra la pantalla con la historia clínica.

Dicho formulario mostrará la siguiente información:

o Identificación: Este campo representa la identificación del

paciente (cedula de ciudadanía, pasaporte, cedula de extranjería, etc.)

o Nombre: Este campo representa el nombre completo del paciente

o Estatura: Este campo representa la estatura del paciente o Tipo de sangre: Este campo representa el tipo de sangre del

paciente o Ocupación: Este campo representa la ocupación actual del

paciente o Fecha de nacimiento: Este campo representa la fecha de

nacimiento del paciente o Dirección: Este campo representa la dirección actual del

paciente o Peso: Este campo representa el peso en kilogramos del

paciente o Lista de controles médicos: Lista de los controles médicos

llegado el caso de que los tuviere.

Flujos Alternativos historia no existe A partir del paso 1 del flujo básico, el sistema muestra un mensaje “La historia clínica asociada a la identificación suministrada no existe”, indicando al actor que la historia clínica no existe.

Precondiciones El paciente debe estar registrado en el sistema de citas

Nombre Consultar historia de citas del día

Descripción Representa el caso de uso por el medio del cual el actor va a consultar todas las historias clínicas de las citas que tiene programada para la fecha actual.

Flujo de eventos Flujo Básico

El medico ingresa su identificación, dicha identificación es el numero de identificación del medio (cedula de ciudadanía, pasaporte, cedula de extranjería, etc)

El sistema valida la identificación y le muestra el listado de las historias clínicas de la fecha actual

Flujos Alternativos Indentificacion medico no valida A partir del paso 1 del flujo básico, el sistema muestra un mensaje “La identificación no esta autorizada para realizar la consulta” indicando que el actor no esta autorizado para realizar la consulta.

Page 84: Untitled

Nombre CRUD Medicamentos

Descripción Este caso de uso describe los pasos que debe hacer el actor para consultar, crear, actualizar y/o borrar una formula medica en la historia clínica.

Flujo de eventos Flujo Básico

El sistema muestra la ventana de mantenimiento de medicamentos, dicha ventana le mostrara una lista con la información de todos los medicamentos, se le mostrara el código medicamento y nombre del medicamento.

El actor escoge la opción especifica (leer, consultar, insertar o eliminar).

El sistema le mostrara una ventana con la información del medicamento, dicha ventana tendrá el código y el nombre.

El actor realiza el proceso de mantenimiento1 del medicamento.

El sistema valida el resultado de la operación y termina el mantenimiento del medicamento, llevándolo a la ventana de mantenimiento de medicamentos.

Flujos Alternativos Operación invalida A partir del paso 4 del flujo básico, el sistema valida los datos mostrando un mensaje de error “La operación no se puede realizar debido a que existen datos invalidos” indicando al actor que existen datos invalidos y sigue mostrando la pantalla actual.

Precondiciones El paciente debe esta afiliado a una EPS

Poscondiciones La historia es actualizada en el sistema y puede ser consultada por los diferentes usuarios autorizados.

Nombre CRUD Procedimiento

Descripción Este caso de uso describe los pasos que debe hacer el actor para consultar, crear, actualizar y/o borrar un procedimiento en la historia clinica

Flujo de eventos Flujo Básico

El sistema muestra la ventana de mantenimiento del procedimiento, dicha ventana le mostrara una lista con la información de todos los procedimientos del sistema, se le mostrara el identificador y el nombre.

El actor escoge la opción especifica (leer, consultar, insertar o eliminar)

El sistema le mostrara una ventana con la información del procedimiento, dicha ventana tendrá la identificación y la descripción.

El actor realiza el proceso de mantenimiento2 del procedimiento

El sistema valida el resultado de la operación y termina el

1 EL proceso de mantenimiento se refiere a consultar, insertar, editar un determinado registro

Page 85: Untitled

mantenimiento del procedimiento, llevándolo a la ventana de mantenimiento de procedimientos.

Flujos Alternativos Operación invalida A partir del paso 4 del flujo básico, el sistema valida los datos

mostrando un mensaje de error “La operación no se puede realizar debido a que existen datos invalidos” indicando al actor que existen datos invalidos y sigue mostrando la pantalla actual.

Precondiciones El paciente debe esta afiliado a una EPS

Poscondiciones La historia es actualizada en el sistema y puede ser consultadpor los diferentes usuarios autorizados.

Nombre Registrar diagnostico actual

Descripción Este caso de uso describe los pasos que debe hacer el actor para registrar un diagnostico a la historia clínica del paciente determinado.

Flujo de eventos Flujo Básico

El sistema de citas solicita las historias clínicas de las citas de la fecha actural.

El sistema selecciona las historias de la fecha actual y las muestra como disponibles, mostrando una pantalla con la lista de las historias clínicas de la fecha actual.

Nombre Enviar citas de hoy

Descripción Este caso de uso describe los pasos que debe hacer el actor para enviar las historias clínicas de las citas programadas para la fecha actual.

Flujo de eventos Flujo Básico

El actor ingresa la identificación del paciente, dicha identificación es el número de identificación del paciente que está registrado en el sistema de citas (cedula de ciudadanía, pasaporte, cedula e extranjería, etc.).

El sistema valida la identificación y muestra la pantalla con la historia clínica actual

Dicho formulario mostrará la siguiente información:

o Identificación: Este campo representa la identificación del paciente (cedula de ciudadanía, pasaporte, cedula de extranjería, etc.)

o Nombre: Este campo representa el nombre completo del paciente

o Estatura: Este campo representa la estatura del paciente o Tipo de sangre: Este campo representa el tipo de sangre del

paciente o Ocupación: Este campo representa la ocupación actual del

paciente

Page 86: Untitled

o Fecha de nacimiento: Este campo representa la fecha de nacimiento del paciente

o Dirección: Este campo representa la dirección actual del paciente

o Peso: Este campo representa el peso en kilogramos del paciente

o Lista de controles médicos: Lista de los controles médicos llegado el caso de que los tuviere.

El actor ingresa el diagnostico

El sistema valida los datos y actualiza la historia clínica agregando el diagnostico y dando por terminado el proceso.

Flujos Alternativos Flujo alternativo historia no existe A partir del paso 1 del flujo básico, el sistema valida la identificación mostrando un mensaje ” La historia clínica asociada a la identificación suministrada no existe” indicando que la historia No existe

Flujo alternativo diagnostico inválido A partir del paso 3 del flujo básico, el sistema valida los datos mostrando un mensaje de error error “La operación no se puede realizar debido a que existen datos inválidos” indicándole al actor que existen datos inválidos y sigue mostrando la pantalla actual.

Precondiciones El paciente debe estar afiliado a una EPS

Poscondiciones La historia es actualizada en el sistema y puede ser consultada por los diferenrentes usuarios autorizados.

1. Diagrama de Clases

Page 87: Untitled

Nombre Paciente

Descripción Esta clase representa a un paciente que es un usuario del sistema, al cual se le van a asignar historias clínicas.

Atributos Identificación: Este campo representa la identificación del paciente Nombre: Este campo representa el nombre completo del paciente Estatura: Este campo representa la estatura del paciente Tipo de sangre: Este campo representa el tipo de sangre del paciente Ocupación: Este campo representa la ocupación actual del paciente Fecha de nacimiento: Este campo representa la fecha de nacimiento del paciente Dirección: Este campo representa la dirección actual del paciente Peso: Este campo representa el peso en kilogramos del paciente.

Metodos calcularEdad: Este método permite calcular la edad a partir de la fecha de nacimiento.

Nombre Historia clínica

Descripción Esta clase representa una historia clínica determinada, una historia clínica es un documento, el cual surge en el contacto entre el equipo de salud y los pacientes.

Atributos fechaCreacion: Este campo representa fecha de creación de la historia clínica

Nombre Control medico

Descripción Esta clase representa un control médico, un control médico es el registro de sintomatología y diagnostico del paciente

Atributos fechaControl: Este campo representa fecha del control medico

Nombre Formula medica

Descripción Esta clase representa una formula medica, Una formula medica es un documento en el cual está la lista de medicamentos asignados a un paciente según la sintomatología presentada

Atributos Id: Este campo representa el número de identificación de la formula medica, puede ser un consecutivo.

Nombre Procedimiento

Descripción Esta clase representa un procedimiento medico. Un procedimiento medico son las diferentes actividades que ofrece la entidad que pueden ser asignada según la sintamotologia por ejemplo una operación.

Atributos Identificación: Este campo representa la identificación interna del procedimiento. Descripción: Este campo representa la descripción breve del procedimiento

Nombre Medicamento

Descripción Esta clase representa un medicamento.

Atributos códigoMedicamento: Este campo representa la identificación interna del medicamento

Page 88: Untitled

nombreMedicamento: Este campo representa el nombre del medicamento.

Nombre Usuario

Descripción Esta clase representa al usuario del sistema de historias clínicas. Toda persona que va a hacer uso del sistema.

Atributos Identificación: Este campo representa la identificación del usuario Nombre: Este campo representa el nombre completo del usuario Usuario: Este campo representa el usuario con el cual va a hacer el proceso de login al sistema de historias clínicas Contraseña: Este campo representa la contraseña con el cual el usuario se va a identificar al momento de hacer login al sistema Estado: Este campo representa el estado del usuario en el sistema, con el cual se podrá hacer las respectivas validaciones de permisos para poder acceder al sistema. Perfil: Este campo representa los diferentes tipos de roles que puede tener el usuario, y con el cual el sistema de historias clínicas habilitar las respectivas operaciones que puede realizar.

Nombre Medico

Descripción Esta clase representa a un medico, y hereda todos los atributos de la clase usuario

Atributos Tarjeta profesional: Este campo representa la tarjeta profesional del medico. Especialización: Este campo representa la especialización del medico.

Nombre Cita

Descripción Esta clase representa a una cita, la cual es la reunión planeada entre un paciente y un medico, para realizar un diagnostico o un chequeo de la sintomatología presentada por el paciente.

Atributos FechaCita: Este campo representa la fecha de la cita LugarCita Este campo representa el lugar de la cita (sede, consultorio, etc.)

Nombre Controlador general

Descripción Esta clase representa al controlador, encargado de administrar las diferentes ventanas del sistema.

Nombre Controlador historia

Descripción Esta clase representa el controlador encargado de administrar toda la información de una historia clínica

Nombre Ventana validación informacion

Descripción Esta clase representa una ventana la cual está diseñada para recibir

Page 89: Untitled

la información del usuario.

Nombre Ventana Ingreso datos

Descripción Esta clase representa una ventana la cual está diseñada para manejar toda la información de las historias clínicas del paciente.

Nombre Ventana acerca de

Descripción Ventana donde se muestra los nombres de las personas desrrolladoras del sistema.

Nombre Ventana procedimiento

Descripción Ventana donde se muestra la informacion del procedimiento

Nombre Ventana Medicamento

Descripción Ventana donde se muestra la informacion del medicamento

Nombre Ventana Administracion de Historias

Descripción Ventana principal del sistema, en donde se muestran las diferentes opciones.

Nombre Ventana Controles medicos

Descripción Ventana donde se muetran los diferentes controles medicos asociados a una historia clínica

Nombre CRUD procedimientos

Descripción Ventana donde se muetran una lista con los procedimientos del sistema junto con las 4 opciones del CRUD

Nombre Control medicamentos

Descripción Esta clase representa el controlador encargado de administrar toda la información de una medicamento

Nombre Control procedimientos

Descripción Esta clase representa el controlador encargado de administrar toda la información de un procedimiento

Este es el frame principal de la aplicación, tiene las opciones de Registrar Paciente,

Modificar Paciente, Consultar Historia, Acerca de y Salir.

Page 90: Untitled

En “Registrar Paciente” sale un diálogo donde se digita la identificación de paciente

que vamos a registrar. Si le identificación ya existe saldrá un mensaje de información

“Historia Clinica Existente”.

El siguiente dialogo permite capturar los datos básicos del paciente.

Page 91: Untitled

La opción “Modificar Paciente” del Menu principal permite modificar los datos de un

paciente y revisar los controles médicos del mismo.

Prototipo de Software para gestión de Información de Matriculas y Pensiones de

Colegios Privados de Educación Media.

Page 92: Untitled

Diagrama de Clases.

Page 93: Untitled

Ingreso Al Sistema

Modulo Archivos

o Estudiante

Page 94: Untitled

o Docente

o Grupo

Page 95: Untitled

o Opciones de ordenamiento

o Opciones de búsqueda

Page 96: Untitled

o Dialogo para guardar y modificar.

o Mensajes de Información, Error y Confirmación.

o Calendario


Recommended