Puede darse el caso de que ninguno de los controles que SWT proporciona satisfaga las necesidades de la aplicación. Si es así, puede ampliar SWT implementando el widget personalizado. SWT proporciona el paquete org.eclipse.swt.custom, que contiene controles personalizados que no se encuentran en el conjunto principal de controles de SWT, pero que se necesitan para implementar el entorno de trabajo de la plataforma.
Control
|
Finalidad
|
Estilos
|
Eventos |
---|---|---|---|
Similar a Combo, pero dibujado de manera personalizada para poder utilizar un cuadro combinado sin borde. Esta clase se ha desarrollado para utilizar cuadros combinados dentro de las casillas de una tabla. |
BORDER, FLAT, READ_ONLY |
Dispose, Control*, Selection | |
Similar a Label, pero soporta el recorte de texto con puntos suspensivos. También soporta un efecto gradual del color de fondo tal como se ve en la vista de entorno de trabajo activa. No soporta la acomodación. |
CENTER, LEFT, RIGHT, SHADOW_IN, SHADOW_OUT, SHADOW_NONE |
Dispose, Control* | |
Similar a TabFolder, pero soporta una configuración adicional del aspecto visual de las pestañas (superiores o inferiores) y los bordes. |
BORDER, FLAT, BOTTOM, TOP |
Dispose, Control*, Selection | |
Objeto seleccionable de la interfaz de usuario que corresponde a una pestaña de una página en una carpeta con pestañas (CTabFolder). |
|
Dispose, Control* | |
Control de Composite que dispone sus hijos en filas o columnas y utiliza un objeto Sash para separarlos de manera que el usuario pueda redimensionarlos. |
BORDER, HORIZONTAL, VERTICAL |
Dispose, Control* | |
Control de Composite que desplaza su contenido y, opcionalmente, lo estira para ocupar el espacio disponible. |
BORDER, H_SCROLL, V_SCROLL |
Dispose, Control* | |
Control editable que permite al usuario escribir texto. Los rangos del texto dentro del control pueden tener distintos fonts y colores (primer plano y fondo). |
BORDER, FULL_SELECTION, MULTI, SINGLE, WRAP, READ_ONLY |
Dispose, Control*, ExtendedModify, LineGetBackground, LineGetSegments, LineGetStyle, Modify, Selection, Verify, VerifyKey | |
Control seleccionable que muestra una lista jerárquica de los elementos que el usuario puede seleccionar. Los elementos se presentan en filas que visualizan múltiples columnas para representar los diferentes aspectos de los elementos. |
BORDER, SINGLE, MULTI, CHECK, FULL_SELECTION |
Dispose, Control*, Selection, DefaultSelection, Collapse, Expand | |
En la interfaz del usuario, objeto seleccionable que representa una jerarquía de los elementos de árbol de un árbol de tabla (TableTree). |
|
||
Control de Composite que dispone tres hijos en dirección horizontal y permite el control programático de los parámetros de diseño y borde. Se utiliza en el entorno de trabajo para implementar la etiqueta/barra de herramientas/barra de menús local de una vista. |
BORDER, FLAT |
Dispose, Control* |
Control* = Eventos heredados de Control: FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick, MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove, Move, Paint, Resize
Antes de implementar un widget personalizado, debe tomar en consideración varios aspectos importantes:
Una vez que haya determinado que necesita un widget personalizado y decidido qué plataformas deben estar soportadas, puede tomar en consideración varias técnicas de implementación del widget. Estas técnicas se pueden combinar y emparejar en función de lo que esté disponible en la plataforma de OS subyacente.
Si la aplicación exige un widget nativo no proporcionado por el SWT, tendrá que implementarlo de manera nativa. Podría ser un widget de plataforma, un widget de otra compañía, o cualquier otro widget de una biblioteca compartida de la plataforma.
Cada plataforma de SWT se envía con una biblioteca compartida (por ejemplo, una DLL en Windows) y con un JAR (para los archivos de clase Java). La biblioteca compartida contiene todas las funciones nativas necesarias para SWT, pero esto no significa que formen un conjunto completo de las funciones disponibles en la plataforma. Para exponer las funciones nativas o los widgets nativos no expuestos por el SWT, debe escribir su propia biblioteca compartida. Si está utilizando una combinación de código nativo en una plataforma y código transportable en otra, asegúrese de que llama a la biblioteca compartida en la plataforma que contiene el widget nativo, y al jar en la plataforma que contiene el widget transportable.
Para implementar un widget nativo, debe entender la interfaz Java nativa (JNI), la API del widget de la biblioteca compartida y las API de la plataforma de OS subyacente de C.
El proceso básico de la implementación es decidir qué parte de la API del widget nativo se expondrá en la API Java, y escribir el código Java que llama a los nativos que implementan la función. Para llamar a la biblioteca compartida, hay que escribir código C de JNI.
Es una buena idea seguir las reglas de diseño utilizadas para implementar SWT cuando construya su propia implementación de widget nativo. Por ejemplo, los nativos de JNI deben correlacionarse biunívocamente con las llamadas de API que se efectúan en la biblioteca compartida.
En el tema Crear sus propios widgets utilizando SWT encontrará un ejemplo completo de una implementación personalizada de widgets nativos.
Si el nuevo widget es similar en cuanto a concepto o implementación a un widget existente, tal vez le interese envolver un widget de SWT existente. Esta es la técnica que se utiliza para la implementación de TableTree.
Para envolver un widget, creará una subclase del widget Composite o del widget Canvas (en función de si el control tiene hijos o no). En el constructor del widget personalizado, cree el widget envuelto. El widget resultante será 100% transportable a Java, porque usted estará llamando a la API del widget envuelto para su implementación.
Para implementar los widgets personalizados, suele ser más sencillo envolver un widget que empezarlo desde cero. Sin embargo, debe actuar con precaución a la hora de diseñar la API del nuevo widget. A continuación se proporcionan algunos consejos importantes:
Determine si el widget es un "tipo de" widget envuelto o si solo utiliza uno para su implementación. Por ejemplo, un árbol de tabla no es un tipo de tabla. No hace referencia a los elementos por el índice del número de la fila. TableTree solo utiliza una tabla para implementar la presentación y añade un comportamiento de árbol. Si va a envolver un widget únicamente por motivos de implementación, la API puede no ser parecida a la API del widget subyacente.
Reenvíe la cantidad menor posible de métodos y eventos. No vuelva a implementar toda la API del widget envuelto, porque sino tendrá que ponerse al día constantemente cuando la API envuelta cambie en un release futuro. Deben reenviarse los métodos que sean comunes a la mayoría de los widgets, como setFont, setForeground y setBackground.
Si tiene que implementar la mayor parte de la API del widget envuelto, plantéese la posibilidad de exponer el widget envuelto a nivel de API y dejar que el código de la aplicación utilice directamente el widget envuelto. En este caso, podría interesarle replantearse qué sentido puede tener proporcionar un nuevo widget. Tal vez sería mejor implementar la característica como "adaptador" que aporte un comportamiento a un widget, sin pretender ser un widget. (Los visores de JFace siguen este patrón).
Nota: lo tratado hasta ahora se ha centrado únicamente en ampliar el comportamiento de un widget envolviéndolo. La técnica de ampliar un widget haciendo que sea una subclase es totalmente desaconsejable, porque el widget dependería de la implementación de la superclase.
Podría darse el caso de que no tenga código nativo ni widgets existentes que le ayuden a implementar el nuevo widget. Esto significa que debe diseñar el widget usted mismo utilizando llamadas de gráficos de SWT. Aunque esta técnica puede resultar bastante complicada, tiene la ventaja de producir una implementación totalmente transportable.
Los controles de dibujo personalizados se implementan creando una subclase de las clases Canvas o Composite según estas reglas:
En un control de diseño personalizado, el estado interno se conserva en las variables de instancia Java. Definirá la API y los estilos de acuerdo con los requisitos del widget.
La implementación interna de un widget de diseño personalizado suele implicar las siguientes tareas básicas:
Muchos de los widgets implementados en org.eclipse.swt.custom utilizan este planteamiento. Encontrará un ejemplo simple en CLabel.
En el tema Crear sus propios widgets utilizando SWT encontrará más información sobre los widgets personalizados.