component-based developmentpro.unibz.it/staff/mscotto/cbd/cbd3ex - views.pdf · 2005-05-04 ·...
TRANSCRIPT
2Component-Based Development
Outline
Views • Introduction• View Declaration• View Model• Content Provider• Label Provider
3Component-Based Development
Introduction (1/5)
Many plug-ins either add a new Eclipse view or enhance an existing Eclipse view as a way to provide information to the user
4Component-Based Development
Introduction (2/5)
Views must implement the org.eclipse.ui.IViewPart interface. Typically views are subclasses of org.eclipse.ui.part.ViewPart and thus indirectly subclasses of org.eclipse.ui.part.WorkbenchPart, inheriting much of the behavior needed to implement the IViewPart interface
5Component-Based Development
Introduction (3/5)
6Component-Based Development
Introduction (4/5)
Views are contained in a view site, (an instance of org.eclipse.ui.IViewSite), which in turn are contained in a workbench page (an instance of org.eclipse.ui.IWorkbenchPage). In the spirit of lazy initialization, the IWorkbenchPage holds on to instances of org.eclipse.ui.IViewReference rather than the view itself so that views can be enumerated and referenced without actually loading the plug-in defining the view.
7Component-Based Development
Introduction (5/5)
Because there are potentially 100’s of views in the workbench, views are organized into categories. The Show View dialog presents a list of views organized by category so that the user can more easily find the desired view.
8Component-Based Development
View Declaration
There are three parts involved in creating a new view:• Define the view category in the plug-in
manifest file• Define the view in the plug-in manifest file• Create the view part containing the code
9Component-Based Development
Declaring a View Category (1/4)
First, to define the new view category, edit the plug-in manifest and navigate to the Extensions pageClick the Add… button to add the org.eclipse.ui.views extension if it is not already present
10Component-Based Development
Declaring a View Category (2/4)The Main View Settings dialog is used modify the attributes of the viewFor the category containing the Tasks view, the attributes would be as follows:• Java Package Name – “it.unibz.plugins.tasks.views”
the package of the view class • View Class Name – “TasksView”
the name of the class defining the view and implementing the org.eclipse.ui.IViewPart interface. The class is instantiated using its no argument constructor, but may be parameterized using the IExecutableExtension interface.
• name – “Tasks View”the human readable name for the view displayed in the view’s title bar and in the Show View dialog
• View Category Id – “it.unibz.plugins”the unique identifier for the category
• View Category Name – “UniBZ plugins”the human readable name for the category that appears in the Show View dialog
11Component-Based Development
Declaring a View Category (3/4)
12Component-Based Development
Declaring a View Category (4/4)
Click on NextUnselect all checkboxesClick on “Finish”
13Component-Based Development
ViewPart
The code defining the view’s behavior is found in a class implementing the org.eclipse.ui.IViewPart interface, typically by subclassing the org.eclipse.ui.part.ViewPart abstract class
14Component-Based Development
View Methods (1/2)
createPartControl(Composite) – required. Create the controls comprising the view. Typically this method simply calls more finely grained methods such as createTable, createSortActions, createFilters, etc. dispose() – Cleanup any platform resources, such as images, clipboard, etc, that were created by this class. This follows the if you create it you destroy it theme that runs throughout Eclipse
15Component-Based Development
View Methods (2/2)getAdapter(Class) – Returns the adapter associated with the specified interface so that the view can participate in various workbench actions. Adapters returned by views include IShowInSource, IShowInTarget, and IContributedContentsView among otherssaveState(IMemento) - Save the local state of this view, such as the current selection, current sorting, current filter, etc.setFocus() – required. Set focus to the appropriate control within the view
16Component-Based Development
View Controls (1/4)
Views can contain any type and number of controls, but typically a view such as the Tasks view contains a single table or tree control
17Component-Based Development
View Controls (2/4)
The Tasks view could use the SWT table widget directly, but the higher level JFacetable viewer wraps the SWT table widget and is easier to use• It handles much of the underlying grunt work,
allowing us to add, select, and remove our model objects directly rather than dealing with the underlying instances of TableItem
18Component-Based Development
View Controls (3/4)With this in mind, we start by enhancing the createPartControl(…) method
Table table = new Table(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
table.setHeaderVisible(true);table.setLinesVisible(true);TableColumn column = new TableColumn(table, SWT.NONE, 0);column.setText("Completed");column.setWidth(50);column.setAlignment(SWT.LEFT);column = new TableColumn(table, SWT.NONE, 1);column.setText("Description");column.setWidth(100);column.setAlignment(SWT.LEFT);column = new TableColumn(table, SWT.NONE, 2);column.setText("Owner");column.setWidth(100);column.setAlignment(SWT.LEFT);
19Component-Based Development
View Controls (4/4)column = new TableColumn(table, SWT.NONE, 3);column.setText("Percentage");column.setWidth(50);column.setAlignment(SWT.LEFT);viewer = new TableViewer(table);viewer.setContentProvider(new TaskViewContentProvider());viewer.setLabelProvider(new TaskViewLabelProvider());viewer.setInput(TaskManager.getManager());
20Component-Based Development
View Model
A view may have its own internal model such as the our view, or use existing model objects such as an IResource and its subtypes, or not have any model at allIn our case, we create:• Task – a class that represents our business
objects• TaskManager – holds task objects
21Component-Based Development
Task class (1/2)package it.unibz.plugins.tasks.model;
public class Task {
private boolean completed = false;private String description = "";private String owner = "?";private int percentComplete = 0;
public Task(String string) {
super();setDescription(string);
}
public boolean isCompleted() {return completed;
}
public String getDescription() {return description;
}
22Component-Based Development
Task class (2/2)public String getOwner() {
return owner;}
public int getPercentComplete() {return percentComplete;
}
public void setCompleted(boolean b) {completed = b;
}
public void setDescription(String string) {description = string;
}
public void setOwner(String string) {owner = string;
}
public void setPercentComplete(int i) {percentComplete = i;
}}
23Component-Based Development
TaskManager class (1/3)package it.unibz.plugins.tasks.model;
import java.util.*;
public class TaskManager {private static TaskManager manager = null;private Collection tasks;private List listeners = new ArrayList();
private TaskManager() {}
public static TaskManager getManager() {if (manager == null)
manager = new TaskManager();return manager;
}
public Task[] getTasks() {if (tasks == null)
loadTasks();return (Task[]) tasks.toArray(new Task[tasks.size()]);
}
24Component-Based Development
TaskManager class (2/3)public void addTask(Task[] items) {
Task[] removedTasks = new Task[] {}; if (tasks == null)
loadTasks();if (tasks.addAll(Arrays.asList(items)))
fireTaskChanged(items, removedTasks);}
public void removeTask(Task[] items) {Task[] addedTasks = new Task[] {}; if (tasks == null)
loadTasks();if (tasks.removeAll(Arrays.asList(items)))
fireTaskChanged(addedTasks, items);}private void loadTasks() {
tasks = new HashSet(5);Task t1 = new Task("Maintainance");tasks.add(t1);Task t2 = new Task("Development");t2.setOwner("teamA");t2.setPercentComplete(20);tasks.add(t2);
}
25Component-Based Development
TaskManager class (3/3)
/////// TaskManagerListener methods ////////////public void addTasksManagerListener(
TaskManagerListener listener) {if (!listeners.contains(listener))
listeners.add(listener);}
public void removeTaskManagerListener(TaskManagerListener listener) {
listeners.remove(listener);}
private void fireTaskChanged(Task[] itemsAdded, Task[] itemsRemoved) {
TaskManagerEvent event = new TaskManagerEvent(this, itemsAdded, itemsRemoved);for (Iterator iter = listeners.iterator(); iter.hasNext();)
((TaskManagerListener) iter.next()).taskChanged(event);}
}
26Component-Based Development
TaskManagerEvent classpackage it.unibz.plugins.tasks.model;
public class TaskManagerEvent {
private Task[] added;private Task[] removed;private TaskManager manager;
public TaskManagerEvent(TaskManager manager, Task[] added, Task[] removed) {
this.manager = manager;this.added = added;this.removed = removed;
}
public Task[] getItemsRemoved() {
return removed;}
public Task[] getItemsAdded() {
return added;}
}
27Component-Based Development
TaskManagerListener interfacepackage it.unibz.plugins.tasks.model;
public interface TaskManagerListener {
/*** @param event*/
public void taskChanged(TaskManagerEvent event);}
28Component-Based Development
Content Provider
Once the model objects have been created, they need to be linked into the viewA content provider is responsible for extracting objects from an input object, in this case the TaskManager, and handing them to the table viewer for displaying, one object in each row of the tableAlthough the IStructuredContentProvider does not specify this, we will also make the content provider responsible for updating the viewer when the TasksManager’s content changes
29Component-Based Development
Content Provider Class (1/2)package it.unibz.plugins.tasks.views;
import org.eclipse.jface.viewers.*;import it.unibz.plugins.tasks.model.*;
class TaskViewContentProvider implements IStructuredContentProvider, TaskManagerListener
{private TableViewer viewer;private TaskManager manager;
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {this.viewer = (TableViewer) viewer;if (manager != null)
manager.removeTaskManagerListener(this);manager = (TaskManager) newInput;if (manager != null)
manager.addTasksManagerListener(this);}
30Component-Based Development
Content Provider Class (2/2)public void dispose() { }
public Object[] getElements(Object parent) {
return manager.getTasks();}
public void taskChanged(TaskManagerEvent event){
viewer.getTable().setRedraw(false);try {
viewer.remove(event.getItemsRemoved());viewer.add(event.getItemsAdded());
}finally {
viewer.getTable().setRedraw(true);}
}}
31Component-Based Development
Label Provider
The label provider takes a table row object returned by the content provider and extracts the value to be display in a column. After refactoring the FavoritesView.ViewLabelProvider inner class into a top-level class, and reworking it to extract values from the newly created model object, it looks something like the code shown below:
32Component-Based Development
Label Provider Class (1/2)package it.unibz.plugins.tasks.views;
import it.unibz.plugins.tasks.model.Task;
import org.eclipse.jface.viewers.*;import org.eclipse.swt.graphics.*;
class TaskViewLabelProvider extends LabelProviderimplements ITableLabelProvider
{
public String getColumnText(Object obj, int index) {Task t = (Task) obj;
switch (index) {case 0 : // Completed column
if (t.isCompleted())return "yes";
elsereturn "no";
33Component-Based Development
Label Provider Class (2/2)case 1 : // Description columnreturn t.getDescription();
case 2 : // Location columnreturn t.getOwner();
case 3 :return new Integer(t.getPercentComplete()).toString();
default :return "";
}}public Image getColumnImage(Object obj, int index) {return null;
}}