3.4 Creación de componentes, visuales y no visuales.

3.4 Creación de componentes, visuales y no visuales.

COMPONENTES VISUALES Y NO VISUALES

Se puede establecer muchas clasificaciones para los componentes. Una de ellas es la de visuales o controles, frente a no visuales.
Un componente es visual cuando tiene una representación gráfica en tiempo de diseño y ejecución (botones, barras de scroll, cuadros de edición, etc.), y se dice no visual en caso contrario (temporizadores, cuadros de diálogo-no visibles en la fase de diseño, etc). Por lo demás no existen más diferencias entre ellos, excepto, claro está, las derivadas de la visualización del componente.
 Los componentes no visuales se pueden colocar en los formularios de la misma manera que los controles, aunque en este caso su posición es irrelevante.
Para empezar, los componentes visuales podemos dividirlos a su vez en dos tipos:
-Componentes interactivos: permiten que el usuario final los manipule, ya sea introduciendo datos, seleccionado elementos, etc. De forma que estos componentes pueden recibir el foco (con SetFocus) así como los eventos propios del teclado y del ratón. Normalmente, el propio sistema operativo es el encargado de dibujar el aspecto del componente, haciendo el componente las llamadas correspondientes para que este aspecto cambie.

-Componente gráficos: el propio componente es el encargado de dibujar en la pantalla lo que crea oportuno, bien a través de las funciones básicas del API de Windows (con el objeto TCanvas) o bien a través de otras librerías gráficas, como OpenGL, DirectX, etc. Estos componentes, no suelen recibir eventos del usuario final, aunque si eventos del propio programador, ya que su cometido no suele ir más allá de mostrar ciertos gráficos o imágenes en la pantalla.
 Si tuviéramos que crear un componente interactivo desde el principio, sería demasiado complejo, ya que tendríamos que luchar encontrar el propio API del sistema operativo, gestionando sus mensajes, las llamadas las funciones a bajo nivel, etc. Sin embargo, podemos aprovechar la mayoría del trabajo hecho por Borland en la VCL, y crear componentes interactivos a partir de otros ya existentes, aplicado la técnica de herencia.
Dado que un componente es un objeto como otro cualquiera, podremos aplicar en el todas las técnicas de la orientación a objetos: encapsulación, herencia y polimorfismo.
La encapsulación ya la hemos utilizado sin apenas darnos cuenta, simplemente definiendo ciertos atributos como privados, para que no puedan ser accedidos desde fuera de la clase, y otros públicos o publicados (pulished) para ser usados por el programador que utilice el componente.    

La herencia nos permite reutilizar código, haciendo que una  clase dada (que llamaremos clase hija) adquirida a todos los atributos y métodos públicos y protegidos de otra, llamada clase padre. De este método, podemos aprovechar mucho código escrito, simplemente heredando de una clase ya escrita. Por si fuera poco, también es posible que una clase hijo tenga a su vez mas descendencia, adquiriendo estos las características del padre y del "padre del padre", es decir: del abuelo.
La técnica de la herencia, aplicada a los componentes, nos permite personalizar cualquier componente, o porque queremos ampliar las posibilidades del componente.

La propia VCL utiliza la herencia continuamente, bien para utilizar código de clases padre, o bien para ofrecernos clases padre de las que nosotros podemos heredar. Muchas "suites de componentes" hacen también esto, proporcionando un componente heredando a partir de cada uno de los básicos, y añadiendo en estas nuevas características.

Para explicar cómo crear un componente interactivo, vamos a hacerlo a través de un ejemplo práctico: supongamos que necesitamos mostrar un árbol que muestre los directorios a partir de una carpeta dada, incluso pongamos que necesitamos mostrar el típico árbol de "MI PC", mostrando todas las unidades y las carpetas de cada una.

Para ello, podríamos escribir un componente desde cero, gestionando todo lo referente a la estructura en árbol, el dibujo en pantalla, la gestión de mensajes,etc. Podríamos utilizar la herencia para utilizar el código ya escrito, concretamente basándose en el componente ATTreeVienw, que es el que nos permite mostrar en un formulario estructuras del tipo árbol. Sin embargo, el TTreeVienw que viene por defecto en el Delphi, es muy genérico, y sirve para mostrar cualquier ripo de árbol. Nuestro caso es mas  específico: necesitamos mostrar un árbol, sí, pero más concretamente un árbol de directorios. Llamaremos a nuestra nueva creación TArbolDirectorios.
Sólo vamos a fijarnos a partir TComponent:
TComponent: este nos resulta familiar, ya que es la clase a partir de la que hemos creado en nuestro conversor de monedas de anteriores números. Los componentes  no-visuales deben heredar directamente de TComponent, ya que este proporciona las características básicas.
TControl: se trata de la clase padre para todos los componentes visuales, ya sean gráficos o no.
TWinControl: de esta clase descenderán todos los componentes dibujados directamente por Windows. La principal característica de estos objetos (llamados ventanas o Windows) es que están identificados por un número único llamado descriptor o manejadores de ventana (en inglés handle).
TCustomTreeView: se trata de la clase que permite mostrar un árbol dentro de un formulario de Delphi. La peculiaridad es que esta clase no contiene ningún método ni propiedad en la sección published, por lo que puedes ser manejada desde el entorno de Delphi.
TTreeView: esta ya es la clase o componente final, que aparece registrado en la paleta de componentes, y que puede ser configurado en tiempo de diseño. En realidad, todo el trabajo de esta clase se limita a publicar las propiedades y eventos que han sido programados en la clase TCustomTreeVienw.
Ahora que ya sabemos quíen va  a ser el padre de nuestro componente, tenemos que decir qué propiedades y eventos vamos a proporcionar a nuestros usuarios del componente.
CarpetaRaiz: se trata de una cadena que contendrá la carpeta a partir de que se creará el árbol de directorios. Puede ser la carpeta raíz de una unidad de disco(p.e."C:\") para mostrar los directorios de toda la unidad, o bien una carpeta cualquiera , para mostrar las subcarpetas de esta. Un caso se dará cuando esta propiedad contenga el valor "Mi PC", con en el que mostraremos cada una de las unidades disponibles en nuestro sistemas, pudiendo expandir estas unidades para mostrar sus carpetas.
CarpetaActual: es el valor de tipo cadena que contiene la ruta de la carpeta seleccionada en el árbol, por ejemplo. Si, por ejemplo, tenemos seleccionada la carpeta de primer nivel "Datos", y el nodo raíz es "C:\Temporal", esta propiedad contendrá el valor  "C:\Temporal\Datos". También se puede modificar su valor, seleccionándose en ese caso el modo correspondiente en el árbol (si el valor establecido es correcto).
MostarPadre: es un valor booleano (true o false) que nos permite configurar la aparición no del nodo padre. Es decir: si en la propiedad "CarpetaRaiz" hemos introducido  el valor  "C:\Delphi", en el árbol aparecerá un nodo raíz llamado "Delphi", y colgado de él, todas las demás subcarpetas. Si establecemos esta propiedad a falso, el nodo raíz desaparecerá, mostrándose todas las subcarpetas en un primer nivel, sin colgar de ningún nodo padre.

Una interfaz grafica está construida en base a elementos gráficos básicos, los componentes.Típicos ejemplos de estos componentes son los botones, barras de desplazamientos, etiquetas, listas, cajas de selección o campos de textos. Los componentes permiten al usuario a interactuar con la aplicación y proporcionar información  desde el programa al usuario sobre el estado del programa. En el AWT, todos los componentes de la interfaz de usuario son instancias de la clase componente o uno de sus subtipos.

Los componentes no se encuentran aislados, si no agrupados dentros de contenedores. Los contenedores contienen y organizan la situación de los componentes y como tales pueden ser situados  dentro de otros contenedores. También contienen el código necesario para el control de eventos, cambiar la forma del cursor o modificar el icono de la aplicación. En el AWT todos los contenedores son instancias de la clase Container o uno de sus subtipos.

La clase componente es una clase abstracta que representa todo lo que tiene una posición, un tamaño, puede ser pintado en pantalla y puede recibir eventos. No tiene constructores públicos, ni puede ser instanciada. Sin embargo, la clase Component puede ser extendida para proporcionar una nueva característica incorporada a java, conocida como componentes ligeros  o Lightweight.

Los objetos derivados de la clase Component que se incluyen en el abstract window Toolkit son los que aparecen a continuación:

Button                                             Label
Canvas                                            List
Checkbox                                        Scrollbar
Choice                                           TextComponent
Container                                        TextArea
Panel                                               TextField
Window
Dialog
Frame

Sobre estos componentes se podrán hacer mas agrupaciones y quizá la más significativa fuese la que diferencie a los componentes según el tipo de entrada. A si habría componentes con entrada de tipo no-textual como los botones de pulsación (Button), las listas (List), botones de marcación (checkbox), botones de seleccion (Choice), y botones de comprobación (CheckboxGroup); componentes de entrada y salida textual como los campos de texto (TextField), las áreas de texto (TextArea) y las etiquetas (Label); y, otros componentes sin acomodo fijo en ningún lado, en donde se encontrarían componentes como las barras de desplazamiento(Scrollbar), zonas de dibujo (Canvas) e incluso los contenedores (Panel, Window, Dialog y Frame), que también pueden considerarse como componentes.

La clase Button es aquella que produce un componente de tipo boton con un titulo.El constructor mas utilizado es el que permite pasarle como parametro una cadena, que sera la que aparezca como titulo e identificador del boton en la interfaz de usuario.

Botones de selección 
Los botones de selección (Choice) permiten el rápido acceso a una lista de elementos, presentándose como titulo en el item que se encuentre seleccionado.
La clase choice extiende la clase component e implementa la interfaz ItemSelectable, que es aquella que mantiene un conjunto de items en los que puede haber, o no, alguno seleccionado.
Botones de comprobación
La clase CheckBox extiende la clase Componet e implementa la interfaz ItemSelectable, que es aquella que contiene un conjunto de ítems entre los que puede haber o no alguna seleccionado.

Los botones de comprobación (Checkbox) se puede agrupar para formar una interfaz de botón de radio (CheckboxGroup),que son agrupaciones de botones de comprobación de exclusión múltiple es decir, en la que siempre hay un único botón activo.

PROGRAMA:
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Java1403{
  public static void main( String args[] ){
//Se instancia un objeto Interfaz Hombre-Máquina
IHM ihm = new IHM();
   }
}

// Clase de la Interfaz gráfica
Class IHM {
  // Constructor de la clase
    public IHM()  {
        // Se crea un objeto CheckboxGroup
        CheckboxGroup miCheckboxGroup = new CheckboxGroup();

        //Ahora se crea un objeto Button y  se registra un objeto
        //ActionListener sobre él
      Button miBoton = new Button( "Aceptar" );
      miBotton.addActionListener(
          new MiActionListener ( miCheckboxGroup )  );

        // Se crea un objeto Frame para contener los objetos Checkbox y el
        // objeto Button. Se fija un Flowlayout, se incorporan a él los
        // objetos, se fija el tamaño y se hace visible
        Frame miFrame = new Frame (  " Tutorial de Java, AWT " );
        miFrame.setLayout( new FlowLayout() );
        miFrame.add( new Checkbox( "A", true,miCheckboxGroup ) );
        miFrame.add( new Checkbox( "B", false,miCheckboxGroup ) );
        miFrame.add( new Checkbox( "C", false,miCheckboxGroup ) );
        miFrame.add( new Checkbox( "D", false,miCheckboxGroup ) );
        miFrame.add( miBoton );
        miFrame.setSize( 250,100 );
        miFrame.setVisible( true );

        //Instanciamos y registramos un receptor para terminar la
        //ejecución de la aplicación, cuando el usuario cierre la
        //ventana
        miFrame.addWindowListener( new Conclusion() );
        }
    }
   
     // Esta clase indica la caja de selección que esta seleccionada
     // cuando se pulsa el botón de Aceptar
     class MiActionListener implements ActionListener {
     CheckboxGroup oCheckBoxGroup;

     MiActionListener( CheckboxGroup checkBGroup ) {
      oCheckBoxGroup = checkBGroup;
}
public void actionPerformed( ActionEvent evt ) {
    System .out.println( oCheckBoxGroup.getSelectedCheckbox().getName()+
" "  +  oCheckBoxGroup.getSelectedCheckBox().getLabel () );
   }
}

//Concluye la aplicación cuando el usuario cierra la ventana
class Conclusion extends WindowAdapter {
  public void windowClosing( WindowEvent evt  ) {
     System.exit( 0 );
     }
}

Comentarios

Entradas populares