07 - Eclipse Plugin Views Tutorial: Page 2 of 2

You might face issues understanding above code if you have not gone through JFace Viewers chapter. I would briefly discuss main points of complete listing below – for detailed information on SWT/JFace viewers please read respective chapters.

Lines 32 - 125: Nothing special here - Most of the SWT/JFace concepts have been put to practice. TreeObject and TreeParent represents the model objects for our TreeViewer class. We have used TreeViewer class here because we need to show property files under “WorkSpace Property Files” folder, so it is more like tree rather then a table. 

TreeParent represent Folders whereas TreeObject represent Files in specific folder. These two classes are essentially wrappers/adapters over the IResource objects. In our example we will use TreeParent to represent “WorkSpace Property Files” folder and TreeObject to represent various property files.

ViewContentProvider: A content provider is another common adapter type used in viewers. This provider is used to map a domain model object used as the input to the viewer and the internal structure needed by the viewer itself. We have implemented ITreeContentProvider interface. This interface adds support for retrieving an item's parent or children within a tree. Special attention is required for the method.

89.          public Object[] getElements(Object parent) {
90.                    if (parent.equals(getViewSite())) {
91.                             if (invisibleRoot == null)
92.                                       initialize();

93.                             return getChildren(invisibleRoot);
94.                    }

95.                    return getChildren(parent);
96.          }

getElements method is defined in the interface IStructuredContentProvider as shown below

          interface IStructuredContentProvider

This method returns the elements to display in the viewer. This method is called internally by the viewer and reference to the parent object is passed as an argument. In line 90, we are comparing parent with the ViewSite returned by getViewSite() method. Views are contained in a view site (org.eclipse.ui.IViewSite) and ViewSite is in turn contained in a workbench page (org.eclipse.ui.IWorkbenchPage). Basically at this time we want to know whether the elements are demanded by View itself or TreeParent object(folder). If it is demanded by View itself then we will initialize our model object and return it to viewer. 
ViewLabelProvider: This provider is used to map a domain model object into one or more images and text strings displayable in the viewer's widget. We will use this provider to display names of property files as well as folder. Also, we have used this provider to display images in the view.

Line 126: Initialize method is used to initialize our domain model.

Line 127: We have created TreeParent to represent “WorkSpace Property Files” folder which will act as a parent folder for all property files in workspace.

Line 129: he handle of workspace through Resources plug-in. Resource plugin is used for any workspace/resource modifications problems.

Line 130: workspace.getRoot() returns the root resource of this workspace. It is basically container of all projects in the workspace. IWorkspaceRoot.getProjects() returns the collection of projects which exist under this root. The projects can be open or closed.

126.         public void initialize() {
127.            TreeParent root = new TreeParent("WorkSpace Property Files");
128.            try {
129.                 IWorkspace workspace = ResourcesPlugin.getWorkspace();

130.                 IProject[] projects = workspace.getRoot().getProjects();

131.                 for (int i = 0; i < projects.length; i++) {
132.                       IResource[] folderResources = projects[i].members();

133.                       for (int j = 0; j < folderResources.length; j++) {

134.                           if (folderResources[j] instanceof IFolder) {
135.                               IFolder resource = (IFolder) folderResources[j];
136.                               if (resource.getName().equalsIgnoreCase("Property Files")) {
137.                                   IResource[] fileResources = resource.members();
138.                                   for (int k = 0; k < fileResources.length; k++) {
139.                                      if (fileResources[k] instanceof IFile &&
                                             fileResources[k].getName().endsWith(".properties")) {
140.                                            TreeObject obj = new TreeObject(fileResources[k]
                                          .getName());
141.                                               obj.setResouce(fileResources[k]);
142.                                               root.addChild(obj);
143.                                         }
144.                                    }
145.                                }
146.                            }
147.                        }
148.                    }
149.               }catch (Exception e) {
                       // log exception
150.               }
151.               invisibleRoot = new TreeParent("");
152.               invisibleRoot.addChild(root);
153.         }

Line 131 – 151: Here we are iterating over projects in a workspace. For each project we are looking for folder named “Property Files”. In this folder we are looking for files with extension “.properties” and if they exist we create our domain model TreeObject and add this object to TreeParent created above by using root.addChild(obj) method. Following figure shows the hierarchy of IResource interface. For complete API listing refer Eclipse Platform Documentation.

        hierarchy of Resource interface

Lines 151 - 152. Basically we have created an invisible node (TreeParent) which will act as a root node of tree but it will not be visible to user. This node will also act as a parent node for all the folders in the tree. We are adding root node which represents “Workspace Property Files” folder as child to invisible node.

Lines 156 – 163: we are overriding createPartControl (Composite) method defined in WorkbenchPart Class. This method is responsible for creating SWT/Jface components for our properties view. In this method we are creating TreeViewer and providing content , label providers to the viewer. For more information on this refer to Jface viewer chapter. Viewer.setInput method is used to provide the initial input to the viewer. We have used getViewSite method to get site reference which is passed to viewer as initial input. That is the reason that we are checking for parent.equals(viewsite) at line 90. We could have very well used invisibleroot in setinput method instead. Point is that our domain model gets to meet viewer control with the help of setInput method.

156.         public void createPartControl(Composite parent) {
157.                  viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
158.                  viewer.setContentProvider(new ViewContentProvider());
159.                  viewer.setLabelProvider(new ViewLabelProvider());
160.                  viewer.setInput(getViewSite());
161.                  hookContextMenu();
162.                  hookDoubleCLickAction();
163.         }

Next we have called to methods to provide context menu and doubleclick action to our property view.

Lines 164 – 185: Here we are using viewer.addDoubleClickListener method to provide doubleclickListener. On line 167, we are using event object to retrieve current selection. IStructuredSelection represent multiple selected elements. It is possible that user has selected more than one element in the view.

       Selecting multiple elements in view

164.         private void hookDoubleCLickAction() {
165.                  viewer.addDoubleClickListener(new IDoubleClickListener() {
166.                      public void doubleClick(DoubleClickEvent event) {
167.                          ISelection selection = event.getSelection();
168.                                 Object obj = ((IStructuredSelection) selection)
                                .getFirstElement();
169.                                 if (!(obj instanceof TreeObject)) {
170.                                           return;
171.                                 }else {
172.                                     TreeObject tempObj = (TreeObject) obj;
173.                                     IFile ifile = ResourcesPlugin.getWorkspace().getRoot()
                        .getFile(tempObj.getResouce().getFullPath());
174.                                     IWorkbenchPage dpage =
                                                      PropertyManagerView.this.getViewSite()
                                       .getWorkbenchWindow().getActivePage();
175.                                          if (dpage != null) {
176.                                                 try {
177.                                                      IDE.openEditor(dpage, ifile,true);
178.                                                 }catch (Exception e) {
179.                                                          // log exception
180.                                                 }
181.                                           }
182.                                     }
183.                            };
184.                  });
185.         }

On line 168, we are retrieving first element from the structured selection. Next we are checking if current selection is a property file by comparing it to TreeObject. Remember that TreeObject is our domain model which we have created in the initialize method and it represents the property file. Next we are retrieving Ifile handle with the help of TreeObject. Remember TreeObject saves the instance of corresponding Resource Object. On line 177, we are opening up the editor with the help of IDE.openEditor method.

public static IEditorPart openEditor(IWorkbenchPage page, IFile input,boolean activate) throws PartInitException

The above method opens the editor for the given file resource. This method will attempt to resolve the editor based on content-type bindings as well as traditional name/extension bindings. * If the page already has an editor open on the target object then that editor is brought to front; otherwise, a new editor is opened. If activate == true the editor will be activated.

Lines 186 – 198 : Nothing special here, your knowledge about actions have been put to practice here. Essentially we have created new action which will perform viewer.refresh() – This will refresh the tree starting from invisible node. We can also use public void refresh (final Object element) to perform refresh action on a particular folder by passing TreeParent object.

186.         private void hookContextMenu() {
187.                  MenuManager menuMgr = new MenuManager("#PopupMenu");
188.                  Menu menu = menuMgr.createContextMenu(viewer.getControl());
189.                  viewer.getControl().setMenu(menu);
190.                  Action refresh =new Action() {
191.                            public void run() {
192.                                 initialize();
193.                                 viewer.refresh();
194.                            }
195.                  };
196.                  refresh.setText("Refresh");
197.                  menuMgr.add(refresh);
198.         }

Lines 199 – 201: We have overridden setFocus method defined in WorkbechPart class. This method asks view to take focus within the workbench.

199.         public void setFocus() {
200.                  viewer.getControl().setFocus();
201.         }

Let’s Test Properties View

Testing the modifications you have just made involves launching the Runtime Workbench. Open up Property Manager View (Window > ShowView > Other)

         Open Property Manager View

It will open up Property Manager View as shown below.

          Propery Manager View

Next, create a new project as shown below

     Create New Project

Click Next, Name it Testing and click finish

     Give Name to the project

Now create a new Folder inside the project

      Create Folde inside Project

Make sure that you name this folder “Property Files”

      Eclipse Plugin Naming the ne Folder

Next, create some property files inside the Property Files Folder

       Create Property Files

Make sure that you provide right extension for these files:

     Eclipse plugin Provide extentions to files

Once you have created a property file, Right click on WorkSpace Property Files Folder in the property manager view and click refresh.

     Refresh Worspace Property File  

 

You will notice that newly created file(s) is listed in property view as shown in figure below.

         Eclipse Plugin Newly created file listed in property

Like us on Facebook