Una vista es el componente del entorno de trabajo que permite navegar por una jerarquía de información o visualizar las propiedades de un objeto. En una página del entorno de trabajo solo se abre una instancia de una vista dada. Cuando el usuario realiza selecciones u otros cambios en una vista, dichos cambios quedan inmediatamente reflejados en el entorno de trabajo. A menudo se proporcionan vistas para dar soporte al correspondiente editor. Por ejemplo, una vista Esquema muestra la información de un editor de manera estructurada. Una vista Propiedades muestra las propiedades de un objeto que se está editando.
El punto de extensión org.eclipse.ui.views permite a los conectores añadir vistas al entorno de trabajo. Los conectores que contribuyen con una vista deben registrarla en el archivo plugin.xml y proporcionar información de configuración acerca de la vista, como puede ser la clase de implementación, la categoría (o el grupo) de vistas a la que pertenece, y el nombre y el icono que hay que usar para describir la vista en los menús y en las etiquetas.
La interfaz de las vistas se define en IViewPart, pero los conectores pueden ampliar la clase ViewPart, en lugar de implementar IViewPart desde cero.
En el ejemplo de Hello World, implementamos una extensión de una vista muy sencilla. Ahora veremos una que tiene en cuenta la existencia de las otras vistas del entorno de trabajo y que responde a la navegación de los usuarios y a los cambios de selección realizados en el entorno de trabajo. En primer lugar, veamos la declaración de la extensión en el archivo plugin.xml.
<extension point="org.eclipse.ui.views"> <category id="org.eclipse.ui.examples.readmetool" name="%Views.category"> </category> <view id="org.eclipse.ui.examples.readmetool.views.SectionsView" name="%Views.ReadmeSections" icon="icons/view16/sections.gif" category="org.eclipse.ui.examples.readmetool" class="org.eclipse.ui.examples.readmetool.ReadmeSectionsView"> </view> </extension>
Esto debería resultarle bastante familiar. Vemos que se ha contribuido suministrando una vista nueva, ReadmeSectionsView, al entorno de trabajo. Los parámetros view id, name y category se han especificado tal como vimos anteriormente. También se proporciona un parámetro icon de la vista, que utiliza una vía de acceso relativa al directorio de instalación del conector.
Veamos la clase ReadmeSectionsView. Las vistas del entorno de trabajo se muestran eligiendo las opciones Ventana->Mostrar vista->Otras... y seleccionando la vista deseada en la lista Mostrar vista.
Cuando se muestra ReadmeSectionsView, aparece una vista con una lista. La lista estará vacía, a menos que pulsemos un archivo cuya extensión sea .readme, en cuyo caso la lista se poblará de secciones procedentes del archivo readme.
¿Cómo reconoce el conector el archivo readme y cómo se entera de los cambios de selección? Las respuestas a estas preguntas nos permitirán comprender la manera de construir conectores integrados en el entorno de trabajo.
Empezaremos por el método createPartControl, que le resultará familiar. Tal como vimos en el ejemplo de Hello World, aquí es donde se crean los widgets que representan una vista. Pasaremos por alto parte del código de iniciación.
public void createPartControl(Composite parent) { viewer = new ListViewer(parent); ... // añadirse uno mismo como escuchador de selección global getSite().getPage().addSelectionListener(this); // poner a punto la selección selectionChanged(null, getSite().getPage().getSelection()); }
La vista crea y almacena un visor de listas (ListViewer) y se registra como escuchador de selección en su página. Obtiene la página a partir de una interfaz IViewSite, que contiene información sobre el contexto de la vista, como puede ser la ventana Entorno de trabajo, la página continente y el conector. ¿Qué sucede cuando recibimos la notificación de un cambio de selección? Se ejecuta el código siguiente:
public void selectionChanged(IWorkbenchPart part, ISelection sel) { //si la selección es un archivo readme, obtener sus secciones. AdaptableList input = ReadmeModelFactory.getInstance().getSections(sel); viewer.setInput(input); }
Es como si la clase ReadmeModelFactory fuese la encargada de convertir la selección en las secciones del readme y las secciones funcionasen a modo de entrada del visor que creamos en el método createPartControl.
¿Cómo ha conseguido el visor llenar con información los widgets de lista? Por ahora, supondremos que, una vez que se ha indicado al visor su elemento de entrada, él ya sabe cómo llenar el widget de lista con la información, porque por algo es un visor de lista (ListViewer). Si desea saber ahora mismo cómo es este visor, consulte el tema Visores.
Todavía no sabemos cómo se detectan los archivos readme ni de dónde procede la información sobre las secciones del archivo. Encontraremos alguna aclaración al respecto en el tema ReadmeModelFactory.
public AdaptableList getSections(ISelection sel) { // Si sel no es una selección estructurada, retornar. if (!(sel instanceof IStructuredSelection)) return null; IStructuredSelection structured = (IStructuredSelection)sel; //si la selección es un archivo readme, obtener sus secciones. Object object = structured.getFirstElement(); if (object instanceof IFile) { IFile file = (IFile) object; String extension = file.getFileExtension(); if (extension != null && extension.equals(IReadmeConstants.EXTENSION)) { return getSections(file); } } //el objeto seleccionado no es un archivo readme return null; }
Comprobamos la selección para ver si es estructurada (múltiple). (El concepto de selección estructurada procede de los visores de JFace). Para el primer objeto de la selección, comprobamos si se trata de un recurso de archivo (IFile). Si es así, comprobamos si su extensión coincide con la extensión ".readme". Una vez que sabemos que se trata de un archivo readme, podemos utilizar otros métodos para analizar las secciones. Puede examinar el resto de ReadmeModelFactory, MarkElement y DefaultSectionsParser para conocer los detalles relativos al análisis de archivos.
Al tratar esta extensión, hemos descrito muchos conceptos comunes del entorno de trabajo. Ahora pasaremos a otras extensiones del entorno de trabajo y examinaremos de qué otra manera puede contribuir su conector a la UI del entorno de trabajo.