miércoles
Introducción Muchas veces he leído en los distintos foros referidos a Visual FoxPro, mensajes sobre el tema de crear una barra de herramientas en un formulario. En este artículo expondré un ejemplo de un formulario SDI (Interfaz de un solo documento - Single Document Interface) en el cual crearemos una barra de herramientas en tiempo de ejecución.
Lo necesario Para crear un formulario SDI, Visual FoxPro cuenta con un tipo de formulario llamado "formulario de nivel superior". Estos formularios aparecen como ventanas independientes sobre el escritorio de Windows y también aparecen en la barra de tareas de Windows. Para lograr un formulario de nivel superior, solo debemos configurar la propiedad ShowWindow = 2 (Como formulario de nivel superior). Para crear la barra de herramientas contenida en un formulario de nivel superior, debemos indicar esto configurando la propiedad ShowWindow = 1 (En formulario de nivel superior)
La clase ToolBar Vamos a definir nuestra barra de herramientas programáticamente a partir de la clase ToolBar. Cuando se crea una barra de herramientas, VFP coloca los controles de izquierda a derecha en el orden que aparecen en la definición de la clase. Escribiremos en los métodos Clicks de los controles añadidos, un código simple como un MESSAGEBOX("Hola !") para mostrar el funcionamiento de cada control dentro de la barra de tareas.
El formulario En formulario del ejemplo vamos a incorporar varios botones de comandos: uno crear la barra de herramientas, cuatro para acoplar la barra de herramientas en las distintas posiciones permitidas, y otro para desacoplar la barra de herramientas. Vamos a crear la propiedad personalizada ThisForm.oMiToolBar para crear y mantener la barra de herramientas dentro del alcance del formulario
JSPLITPANE:
JsplitPane se usa para dividir con una barrita divisoria dos y solo dos componentes, mismos que pueden ser alineados de izquierda a derecha o de arriba hacia abajo.
Sus propiedades mas importantes son:
Autoscrolls(), Background(), Border(), Bounds(), Cursor(), DividerSize(), Enabled(), Font(), Foreground(),Insets(), Layouts(), Name(), Opaque(), Orientation(), Text(), ToolTipText(), Visible(), VisibleRect().
Sus escuchadores mas importantes son:
WINDOW: WindowActivated(), WindowClosed(), WindowClosing(), WindowDeactivated(), WindowOpened().
MOUSE: MouseClicked(), MouseDragged(),MouseEntered(), MouseExited(),MouseMoved(), MousePressed(), MouseReleased().
KEY: KeyPressed(), KeyReleased(), KeyTyped().
Text: TEXT_VALUE_CHANGED
Programa Ejemplo:
import java.lang.*;import java.awt.*;import java.awt.event.*;import javax.swing.*;
public class prog8 {
//declaracion, creacion e inicializacion de componentes, objetos y variables
static JFrame ventana= new JFrame();
// abajo se creando con orientacion vertical u horizontal
static JSplitPane panel1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
static JLabel jl1 = new JLabel("en split1 label1");
static JLabel jl2 = new JLabel("en split2 label2");
// parte principal de programa
public static void main(String[] args)
{ // area de definicion de propiedades de el objeto
ventana.setTitle("mi programa");
ventana.setDefaultCloseOperation(ventana.EXIT_ON_CLOSE);
//cargando splitpanel panel1 con sus dos componentes
panel1.add(jl1); panel1.add(jl2);
// cargando la ventana con splitpanel
ventana.getContentPane().add(panel1,BorderLayout.CENTER);
ventana.pack();
ventana.setVisible(true);
//area de asociacion de objeto-eventos
}; // termina main
} // termina clase
Corrida:
Las barras de desplazamiento tienen dos usos:
- Una barra de desplazamiento puede actuar como un deslizador que el usuario manipula para seleccionar un valor. Un ejemplo de esto está en el programa Converter de la página La Anatomía de un Programa basado en GUI.
- Las barras de desplazamiento le pueden ayudar a mostrar una parte de una región que es demasiado grande para el área de dibujo. Las barras de desplazamiento le permiten al usuario elegir exactamente la parte de la región que es visible. Aquí tiene un ejemplo (podría tardar un poco en cargarse la imagen):
Para crear una barra de desplazamiento, necesitas crear un ejemplar de la clase Scrollbar. También se pueden inicializar los siguientes valores, o bien especificándolos al Constructor de Scrollbar o llamando al método setValues() antes de que la barra de desplazamiento sea visible.
- int orientation
- Indica si la barra de desplazamiento debe ser vertical u horizontal. Especificado con Scrollbar.HORIZONTAL o Scrollbar.VERTICAL.
- int value
- El valor inicial de la barra de desplazamiento. Para barras de desplazamiento que controlan un área desplazable, esto significa el valor x (para las barras horizontales, o el valor y (para las verticales) de la parte del área que es visible cuando el usuario la visita por primera vez. Por ejemplo, el applet anterior arranca en las posiciones 0 tanto vertical como horizontal y la porción de imagen representada empieza en (0,0).
- int visible
- El tamaño en pixels de la porción visible del área desplazable. Este valor, si se selecciona antes de que la barra de desplazamiento sea visible, determina cuantos pixels se desplazará la imagen con una pulsación en la barra de desplazamiento (pero no en el botón). Seleccionar este valor después de que la barra de desplazamiento sea visible no tiene ningún efecto.Después de que la barra de desplazamiento sea visible, se debería utilizar el método setPageIncrement() para obtener el mismo efecto.
- int minimum
- El valor mínimo que puede tener la barra de desplazamiento. Para barras de desplazamiento que controlan áreas desplazables este valor normalmente es 0 (la parte superior izquierda del área).
- int maximum
- El valor máximo que puede tener la barra de desplazamiento. Para barras de desplazamiento que controlan áreas desplazables este valor normalmente es:(la anchura o altura total , en pixels, del componente que está siendo parcialmente representada) - (la anchura o altura visible actualmente del área desplazable).
Aquí tienes el código del applet anterior. Este código define dos clases. La primera es una sencilla subclase de Canvas (ScrollableCanvas) que dibuja una imagen. La segunda es una subclase de Panel (ImageScroller, que realmente desciende de Applet) que crea y conteniene un ScrollableCanvas y dos Scrollbars. Este programa ilustra unos pocos detalles importantes sobre el manejo de un área despalzable:
- El manejo de eventos para una barra de desplazamiento es bastante sencillo. El progama solo debe responder a los eventos de desplazamiento guardando los nuevos valores de la barra de desplazamiento en un lugar accesible para que el componente pueda mostrarse dentro del área desplazable, y luego llamar al método repaint() del Componente.
public boolean handleEvent(Event evt) {
switch (evt.id) {
case Event.SCROLL_LINE_UP:
case Event.SCROLL_LINE_DOWN:
case Event.SCROLL_PAGE_UP:
case Event.SCROLL_PAGE_DOWN:
case Event.SCROLL_ABSOLUTE:
if (evt.target == vert) {
canvas.ty = ((Integer)evt.arg).intValue();
canvas.repaint();
}
if (evt.target == horz) {
canvas.tx = ((Integer)evt.arg).intValue();
canvas.repaint();
}
}
return super.handleEvent(evt);
} - El Componente que se muestra a sí mismo dentro de un área desplazable puede ser muy sencillo. Todo lo que necesita es dibujarse a sí mismo en el origen especificado por los valores de sus barras de desplazamiento. Un Componente puede cambiar su origen (y así no tener que cambiar su código de dibujo normal), poniéndo el siguiente código al principio de sus métodos paint() o update():
g.translate(-tx, -ty);
- Cuando ocurre el desplazamiento, probablemente notarás parpadeo en el área de display, Si no se quiere que esto ocurra, se necesita implementar el método update() en el componente representado, y posiblemente también el doble buffer. Cómo hacer esto se explica en la página Eliminar el Parpadeo.
- Si el área desplazable puede redimensionarse, cuidado con un problema cómun del desplazamiento. Ocurre cuando el usuario desplaza el área hacia abajo y la derecha y luego agranda el área. Si no se tiene cuidado, el ára mostrará un espacio en blanco en su parte inferior derecha. Después de que el usuario desplace y vuelve a la parte inferior derecha, el espacio en blanco no está más allí. Para evitar mostrar un espacio en blanco innecesario, cuando el área desplazable se agranda debe desplazar también el origen del Componente para aprovechar el nuevo espacio disponible. Aquí tienes un ejemplo:
int canvasWidth = canvas.size().width;
//Desplaza todo a la derecha si se está mostrando un espacio vacío
//en el lado derecho.
if ((canvas.tx + canvasWidth) > imageSize.width) {
int newtx = imageSize.width - canvasWidth;
if (newtx < 0) {
newtx = 0;
}
canvas.tx = newtx;
}
JSLIDER:
Se utiliza un JSlider para permitir que el usuario introduzca un valor numérico limitado por una valor máximo y un valor mínimo. Mediante la utilización de un Slider en vez de text field, se eliminan errores de entrada.
Aquí tenemos una imagen de una aplicación que utiliza un Slider para controlar la velocidad de una animación:
Aquí está el código de SliderDemo.java que crea el Slider el programa anterior.JSlider framesPerSecond = new JSlider(JSlider.HORIZONTAL, 0, 30, FPS_INIT);
Por defecto, el espacio para las marcas mayores y menores es cero. Para ver estas marcas, debemos especificar el espaciado de los ticks mayor o menor (o ambos) a un valor distinto de cero y llamar a setPaintTicks(true) (llamar sólo a setPaintTicks(true) no es suficiente). Para salidas estándard, las etiquetas numéricas en la posición marcas mayores seleccionan el mayor espaciado entre marcas, luego se llama setPaintLabels(true). El programa de ejemplo proporciona la etiqueta para sus deslizadores de esta forma. Sin embargo, las etiquetas del Slider son altamente configurables. Puedes ver un ejemplo en Proporcionar Etiquetas para Deslizadores.
framesPerSecond.addChangeListener(new SliderListener());
framesPerSecond.setMajorTickSpacing(10);
framesPerSecond.setMinorTickSpacing(1);
framesPerSecond.setPaintTicks(true);
framesPerSecond.setPaintLabels(true);
framesPerSecond.setBorder(BorderFactory.createEmptyBorder(0,0,10,0));
. . .
//add the slider to the content pane
contentPane.add(framesPerSecond);Cuando se mueve el deslizador, se llama al método stateChanged del ChangeListener del deslizador, cambiando la velocidad de la animación:
class SliderListener implements ChangeListener {
Si movemos el deslizador hasta cero, la animación se para.
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider)e.getSource();
if (!source.getValueIsAdjusting()) {
int fps = (int)((JSlider)e.getSource()).getValue();
if (fps == 0) {
if (!frozen) stopAnimation();
} else {
delay = 1000 / fps;
timer.setDelay(delay);
if (frozen) startAnimation();
}
}
}
}Observa que el método stateChanged sólo cambia la velocidad de la animación si getValueIsAdjusting devuelve false. Muchos eventos change se disparan cuando el usuario mueve el deslizador. Este programa sólo está interesado en el resultado final de la acción del usuario.
Porporcionar Etiquetas para Deslizadores
Para mostrar etiquetas en un deslizador, debemos llamar a setPaintLabels(true) y proporcionar un conjunto de etiquetas que indiquen las posiciones y valores para cada etiqueta. Las etiquetas pueden especificarse utilizando una de las siguientes técnicas:
- Llamar a setMajorTickSpacing con un valor distinto de cero. Haciéndolo de esta manera, las etiquetas idendifican el valor de cada marca de pulsación mayor. Esta es la técnica utiliza por SliderDemo.java.
- Crear un Hashtable que contenga el valor para cada etiqueta y su posición. Se proporciona el Hashtable como un argumento a setLabelTable.
SliderDemo2.java, utiliza esta técnica:
Aquí está el código de SliderDemo2.java que crea el deslizador:
//Create the sliderEste código crea explícitamente un Hashtable y lo rellena con los valores de las etiquetas y sus posiciones. Cada valor de etiqueta debe ser un Component y en este programa, son simples etiquetas de texto. También podemos utilizar etiquetas con iconos. Si queremos etiquetas numéricas posicionadas a intervalor específicos, podemos utilizar el método createStandardLabels de JSlider.
JSlider framesPerSecond = new JSlider(JSlider.VERTICAL, 0, 30, FPS_INIT);
framesPerSecond.addChangeListener(new SliderListener());
framesPerSecond.setMajorTickSpacing(10);
framesPerSecond.setPaintTicks(true);
//Create the label table
Dictionary labelTable = new Hashtable();
labelTable.put( new Integer( 0 ), new JLabel("Stop") );
labelTable.put( new Integer( 3 ), new JLabel("Slow") );
labelTable.put( new Integer( 30 ), new JLabel("Fast") );
framesPerSecond.setLabelTable( labelTable );
framesPerSecond.setPaintLabels(true);
framesPerSecond.setBorder(BorderFactory.createEmptyBorder(0,0,0,10));El API Slider
Las siguiente tablas listan los métodos y constructores más utilizados de JSlider. Otros métodos interesantes son definidos por las clases JComponent y Component.
Ajsute Fino de la Apariencia del Deslizador Método Propósito void setValue(int)
int getValue()Seleciona u obtiene el valor actual del Slider. El marcador del deslizador está en esta posición. void setOrientation(int)
int getOrientation()Seleciona u obtiene la orientación del Slider. Los posibles valores son JSlider.HORIZONTAL o JSlider.VERTICAL void setInverted(boolean)
boolean getInverted()Seleciona u obtiene si el máximo se muestra a la izquierda en un deslizador horizontal o abajo en uno vertical, por lo tanto invierte el rango del deslizador. void setMinimum(int)
int getMinimum()
void setMaximum(int)
int getMaximum()Seleciona u obtiene los valores máximos o mínimos del deslizador. Juntos selecionan u obtienen el rango del deslizador. void setMajorTickSpacing(int)
int getMajorTickSpacing()
void setMinorTickSpacing(int)
int getMinorTickSpacing()Seleciona u obtiene el rango entre marcas mayores y menores. Debemos llamar a setPaintTicks(true) para que aparezcan las marcas. void setPaintTicks(boolean)
boolean getPaintTicks()Seleciona u obtiene si se dibujan las marcas en el deslizador. void setLabelTable(Dictionary)
Dictionary getLabelTable()Seleciona u obtiene las etiquetas para el deslizador. Debemos llamar a setPaintLabels(true) para que aparezcan las etiquetas. createStandardLabels es un método de conveniencia para crear un conjunto de etiquetas estándard. void setPaintLabels(boolean)
boolean getPaintLabels()Seleciona u obtiene si se dibujan las etiquetas de un deslizador. Las etiquetas se seleccionan con setLabelTable o configurando el espaciado entre marcas mayores.
En general, no se crea directamente un objeto JRootPane. En su lugar, se obtiene un JRootPane (tanto si se quiere como si no!) cuando se ejemplariza un JInternalFrame o uno de los contenedores Swing de alto nivel -- JApplet, JDialog, JFrame, y JWindow.
La página Reglas Generales para Usar Componentes Swing explica lo básico sobre el uso de paneles raíz -- obtener el panel de contenido, seleccionar su controlador de distribución, y añadirle componentes Swing. Esta página explica más cosas sobe los paneles raíz, incluyendo los componentes que crean un panel raíz, y cómo poder utilizarlos.
Un panel raíz se divide en cuatro partes:
- El Panel de Cristal
- Oculto, por defecto. Si se hace visible, es como si se pusiera una hoja de cristal sobre las otras partes del panel raiz. Es completamente transparente (a menos que hagamos que el método paint haga algo) e intercepta los eventos de entrada para el panel raíz. En la siguiente sección, veremos un ejemplo de utilización de un panel de cristal.
- El panel de capas
- Sirve para posicionar sus contenidos, que consisten en el panel de contenido y la barra de menú opcional. También puede contener otros componentes en un orden Z especificado. Para más información puedes ver Cómo usar Layered Panes.
- El Panel de Contenido
- El contenedor de los componentes visibles del panel raíz, excluyendo la barra de menú.
- La barra de menú opcional
- El hogar para los menús del panel de contenido. Si el contenedor tiene una barra de menús, generalmente se utilizan los métodos setMenuBar o setJMenuBar del contenedor para poner la barra de menú en el lugar apropiado.
Método | Propósito |
---|---|
JRootPane getRootPane() (en JApplet, JDialog, JFrame, JInternalFrame, y JWindow) | Obtiene el panel raíz del applet, dialog, frame, internal frame, o window. |
JRootPane SwingUtilities.getRootPane(Component) | Si el componente tiene un panel raíz, lo devuelve. Si no es así, devuelve el panel raíz (si existe) que contiene el componente. |
JRootPane getRootPane() (en JComponent) | Invoca al método SwingUtilitiesgetRootPane sobre JComponent. |
void setDefaultButton(JButton) JButton getDefaultButton() | Selecciona u obtiene qué botón (si existe) es el botón por defecto del panel raíz. Una acción específica del aspecto y comportamiento, como pulsar ENTER, hace que se realice la acción del botón. |
Método Propósito setGlassPane(Component)
Component getGlassPane()
(en JApplet, JDialog, JFrame, JInternalFrame, JRootPane, y JWindow) Selecciona u obtiene elpanel de cristal.
Método Propósito setContentPane(Container)
Container getContentPane()
(en JApplet, JDialog, JFrame, JInternalFrame, JRootPane, y JWindow) Selecciona u obtiene el panel de contenido.
JPROGRESSBAR.
Una barra de progreso que muestra gráficamente qué cantitad total de la tarea se ha terminado.
Aquí podemos ver una imagen de una pequeña aplicación que utiliza una barra de progreso para medir el progreso de una tarea que se ejecuta:
JOPTIONPANE:
Es un componente al estilo Pop Up que sirve como un promt o ventana de datos donde se puede pedir o desplegar información.
Siempre que pensemos usar la clase JOptionPane, devemos primero importarla.
import javax.swing.JOptionPane;
———————————————————————————————————————————
Solicitar datos:
Al solicituar informacion, este se guarda en un String usando el metodo showInputDialog
Codigo:
String nombre;
nombre = JOptionPane.showInputDialog("Ingrese su nombre");
———————————————————————————————————————————
Mostrar mensaje:
Para mostrar un mensaje en una ventana solo debemos usar el metodo showMessageDialog
Codigo:
JOptionPane.showMessageDialog(null,"Hola"+nombre+" Bienvenido ! !");
showMessageDialog
Es un diálogo simple que presenta un boton de “Aceptar”. Se puede especificar fácilmente el mensaje, el icono, y el título que el diálogo exhibe. Aquí están algunos ejemplos del showMessageDialog que se usan:
Codigo:
JOptionPane.showMessageDialog(ventana, “El cielo es de color azul.”, “Dialogo sencillo”, JOptionPane.INFORMATION_MESSAGE);
Codigo:
JOptionPane.showMessageDialog(ventana, “Quieres usar el Question Dialog ”+ “(como esto)\n” + “para preguntar, OK?”, “Dialogo sencillo”, JOptionPane.QUESTION_MESSAGE);
Codigo:
JOptionPane.showMessageDialog(ventana,“El cielo es de color azul.”, “Dialogo sencillo”, JOptionPane.ERROR_MESSAGE);
Codigo:
JOptionPane.showMessageDialog(ventana, “El cielo es de color azul.”, “Dialogo sencillo”, JOptionPane.INFORMATION_MESSAGE, icono);
JOptionPane.showMessageDialog(ventana, “El cielo es de color azul.”, “Dialogo sencillo”, JOptionPane.PLAIN_MESSAGE);
Los argumentos:
———————————————————————————————————————————
- Component parentComponent: Es el componente padre del diálogo, si el argumento pasa como null simplemente el diálogo se mostrará en centro de la pantalla y no tendra el foco principal si hay JFrame o alguna otra ventana
- Object message: El mensaje a mostrar, es el texto principal
- String title: El titulo que lleva el diálogo en la barra de tareas
- int optionType: El tipo de diálogo, puede ser del tipo DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION, OK_CANCEL_OPTION
- int messageType: El tipo de icono que tendrá el diálogo, puede ser PLAIN_MESSAGE (sin icono), ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE
- Icon icon: El icono personalizado que tendra el diálogo
- Object[] options: Estas son las opciones que tendrá el diálogo, son útiles cuando creamos nuestros propios diálogos