|
Eclipse: Building Commercial Quality Plug-ins,
Second Edition by Eric Clayberg and Dan Rubel. Addison-Wesley Second Edition Published: March 20, 2006 Originally Published: June 21, 2004 ISBN: 032142672X Order from Barnes & Noble now for $44.99 |
Please report any problems you find to info@qualityeclipse.com
Errata are currently available for the following chapters:
General note on deprecated APIs - In several places in the book, we are using deprecated Eclipse APIs. In some cases, these are due to last minute changes made to the Eclipse API after the book had already been finalized. We will try to identify those here in the errata. In some cases, however, deprecated APIs can be a better choice as they will allow your plugin to run in both Eclipse 2.1 and 3.0 (where the newer API would lock you into Eclipse 3.0 only).
General note on compile time classpath settings - If you run into a compilation problem due to an unknown class, it is likely due to a classpath problem. Several core Eclipse plugins were split into finer grained pieces late in the Eclipse 3.0 development cycle. This means that you will need to add additional plugins in order for certain classes to resolve properly. An updated .classpath file for the favorites project is available here. If you use this file, you shouldn't run into any classpath-related compilation issues when working through the book examples.
General note on runtime time classpath settings - At runtime, Eclipse looks at the "runtime" and "requires" sections of the plugin.xml file for classpath information. In ensure that all of the example code works at runtime, you should use the following in the "requires" section of your plugin.xml file.
<requires>
<import plugin="org.eclipse.core.resources"/>
<import plugin="org.eclipse.core.runtime"/>
<import plugin="org.eclipse.debug.ui"/>
<import plugin="org.eclipse.help"/>
<import plugin="org.eclipse.help.ui"/>
<import plugin="org.eclipse.jdt.core"/>
<import plugin="org.eclipse.jdt.ui"/>
<import plugin="org.eclipse.jface"/>
<import plugin="org.eclipse.jface.text"/>
<import plugin="org.eclipse.swt"/>
<import plugin="org.eclipse.text"/>
<import plugin="org.eclipse.ui"/>
<import plugin="org.eclipse.ui.editors"/>
<import plugin="org.eclipse.ui.views"/>
<import plugin="org.eclipse.ui.workbench"/>
<import plugin="org.eclipse.ui.workbench.texteditor"/>
<import plugin="org.eclipse.core.runtime.compatibility" optional="true"/>
<import plugin="org.eclipse.osgi" optional="true"/>
<import plugin="org.eclipse.ui.ide" optional="true"/>
</requires>
General note on installing, running and updating a plugin - Eclipse 3.0 has a fairly significant bug that may cause it to not immediately recognize new or updated plugins. This occurs because Eclipse 3.x caches plug-in information for a faster startup at the cost of not recognizing changes to the installed plugins. To workaround this problem, include the "-clean" option on the command line used to startup Eclipse. The "-clean" option causes Eclipse to reparse and recache the plug-in information, picking up any newly installed or revised features. Once the plug-in information has been recached and your plugin appears as expected, you can remove the "-clean" option. Deleting the Eclipse "configuration" directory (it is recreated on startup) and re-starting Eclipse should also have the same effect. Alternatively, you can use the technique described in the Eclipse 3.0 readme file:
When features and plug-ins are manually installed on top of an Eclipse-based product install located on a FAT file system that has already been run at least once, the product must be explicitly restarted with the system property osgi.checkConfiguration set to true. This property can be set in the eclipse/configuration/config.ini file, or passed to the eclipse command line via the -vmargs option. For example, restart with the following command eclipse.exe -vmargs -Dosgi.checkConfiguration=true. Then, open Help > Software Updates > Manage Configuration dialog and toggle on the "Show disabled features" button its toolbar. Select the newly "installed" feature and press on the "Enable feature" action on the right pane (or select the action from the feature's context menu).
The "running man" icon decorator has been replaced with a small, green triangle in Eclipse 3.0.
-- thanks to James Carroll for finding this
The tip at the end of this section says that the Maximum file size field can be set to "1,000". Eclipse actually limits this value to "100" (which should be more than enough to track a year of changes).
-- thanks to Tony Weddle for finding this
The "running man" icon decorator has been replaced with a small, green triangle in Eclipse 3.0.
-- thanks to James Carroll for finding this
The PDE wizard screen shots in Chapter 2 are all slightly different than those you will see in the Eclipse 3.0 final release. There were a number of minor changes made in the last few weeks of the Eclipse 3.0 development cycle (a couple of weeks after the book was finalized). One fairly significant change is that the properties of various extensions are no longer shown in the Properties view. They are now shown directly in the Extensions page of the plug-in manifest editor.
The options shown on the wizard page should be unchecked as stated on p88.
-- thanks to James Carroll for finding this
In the ant build script, "<-Plugin directory" should read "<-- Plugin directory".
Also, if you get an error on the first line, to make sure there's not an extra line above it; if the <?xml isn't on LINE 1 it complains correctly.
-- thanks to James Carroll for finding this
Extract the files to the eclipse directory and verify that the plugin ends up in the /plugins directory.
-- thanks to James Carroll for suggesting this
Figure 2-24 should have a "Debug" button rather than a "Run" button.
-- thanks to James Carroll for finding this
The third bullet point in this section should read
- Uncheck the Create a plug-in using one of these templates checkbox
At the bottom of the page, ignore the references to "Workspace Plug-ins category" and "External Plug-ins category" because those distinctions no longer existing in the Eclipse 3.0 plug-in manifest editor. The two bullet points at the bottom of the page should be
- com.qualityeclipse.favorites
- org.junit
-- thanks to Karen Ploski for finding this
Replace "import org.eclipse.core.internal.resources.*;" with "import org.eclipse.core.runtime.Platform;".
The imports for java.util and org.eclipse.jface.dialogs.are not needed.
-- thanks to James Carroll for finding this
The build.xml listing has a mistake in the new 'location' for plugin_dir. It is missing the underscore between the identifier and the version. It should read:
<property name="plugin_dir" location="${temp_dir}/QualityEclipseTools/eclipse/ plugins/com.qualityeclipse.favorites _${product_version}"/>-- thanks to Brian Vosburgh for finding this
The illustration of the new directory structure of the resulting zip file is incorrect. The three entries are missing the word 'eclipse' that should be between QualityEclipseTools and plug-in. It should read
QualityEclipseTools/eclipse/plugins/com.qualityeclipse.favorites_1.0.0/favorites.jar
QualityEclipseTools/eclipse/plugins/com.qualityeclipse.favorites_1.0.0/icons/sample.gif
QualityEclipseTools/eclipse/plugins/com.qualityeclipse.favorites_1.0.0/plugin.xml.-- thanks to Peter Nye for finding this
The "prefixes" feature no longer applies to Eclipse 3.x-only plugins. It does apply to plugins designed to run under both Eclipse 2.1 and 3.0. Eclipse 3.0 still seems to be using this construct (you can see it used in many of the plugin.xml files within the base Eclipse plugins). The Eclipse 3.0 docs suggest it only needs to be used for "Eclipse 2.1" plugins (and is a no-op for Eclipse 3.0 plugins). With Eclipse 2.1 based IDEs still is common use out in the world (e.g., WSAD), it is probably a good idea to use constructs (including various deprecated methods) that span both Eclipse 2.1 and 3.0 so that your plugin will run anywhere.
-- thanks to Chris lott for finding this
The log() method and the createStatus() method signatures don't match those given in the javadoc (specifically we are no longer passing in the pluginid and instead are retrieving it directly from the plugin class).
-- thanks to David Watkins for finding this
Note that the getUniqueIdentifier() API has been deprecated in favor of the bundle.getSymbolicName() API in Eclipse 3.0. Rather than FavouritesPlugin.getDefault().getDescriptor().getUniqueIdentifier(), you could use FavouritesPlugin.getDefault().getBundle().getSymbolicName() to retrieve the plugin identifier. Be aware, however, if you do this that your plugin will be locked into only running under Eclipse 3.0. The older API, while deprecated, works fine in both Eclipse 2.x and 3.0. If you do choose to use the newer API, you will need to add "ECLIPSE_HOME/plugins/org.eclipse.osgi_3.0.0/osgi.jar" to your Java Build Path.
-- thanks to Tony Saveski for finding this
"Line 2 - ........will be disposed of in Line 14" - the Display actually get's disposed on line 16.
-- thanks to David Watkins for finding this
"...Each method with a non-void return type will list it's return type prior to it's name" - the return type is only given in the narrative text.
-- thanks to David Watkins for finding this
In the last paragraph on the page, "list widget" should read "label widget".
-- thanks to Tony Saveski for finding this
The description of the Tree method "getItems()" should read: "Returns the items contained in the receiver that are direct item children of the receiver."
-- thanks to Simon Archer for finding this
The first sentence in the section should read: ""The TabFolder widget is used to organize information within a window frame into multiple pages that appear as a set of notebook tabs."
-- thanks to Simon Archer for finding this
In order to run the JFace demos standalone, you need to add the following entries to your Java Build Path:
ECLIPSE_HOME/plugins/org.eclipse.core.runtime_3.0.0/runtime.jar
ECLIPSE_HOME/plugins/org.eclipse.jface_3.0.0/jface.jar
ECLIPSE_HOME/plugins/org.eclipse.jface.text_3.0.0/jfacetext.jar
ECLIPSE_HOME/plugins/org.eclipse.osgi_3.0.0/osgi.jar
ECLIPSE_HOME/plugins/org.eclipse.swt.win32_3.0.0/ws/win32/swt.jar
ECLIPSE_HOME/plugins/org.eclipse.text_3.0.0/text.jar-- thanks to Tony Saveski for finding this
The getImage(Object) should read getImage(Object element) and the getText(Object) should read getText(Object element).
-- thanks to Mike Wilkins & Tony Saveski for finding this
The words ", and a set of columns" should be removed, since Tree widgets do not columns.
-- thanks to Simon Archer for finding this
The getChildren(Object) should read getChildren(Object element) and the getParent(Object) should read getParent(Object element).
-- thanks to Tony Saveski for finding this
In order to run the JFace text demo standalone, you need to add the following entries to your Java Build Path:
ECLIPSE_HOME/plugins/org.eclipse.jface.text_3.0.0/jfacetext.jar
ECLIPSE_HOME/plugins/org.eclipse.text_3.0.0/text.jar-- thanks to Tony Saveski for finding this
In the last line on the page, "SWT.VSCROLL" should read "SWT.V_SCROLL".
-- thanks to Tony Saveski for finding this
In order for the ActionDelegate's selectionChanged() method to be called, you need to call getViewSite().setSelectionProvider(viewer) in your view's createPartControl() method. This advice applies to Section 6.3.2 as well.
-- thanks to Tony Saveski for suggesting this
The Favorites action is only displayed when one or more objects are selected due to
enablesFor="+"in the declaration shown in section 6.3.2.5 on page 258. This means that when you test the Favorites menu, you must have at least one project created in your runtime workbench and select at least one resource in the Navigator view when you activate the context menu. If you right click without selecting anything, you will only see an abbreviated context menu that does not have the Favorites menu.
-- thanks to Brian Penn for suggesting this
Hint: the test project needs the resources.jar from org.eclipse.core.resources_3.0.0 on the build path.
-- thanks to Bernd Essann for suggesting this
The line "menuId = org.eclipse.jdt.debug.ui.MonitorsView" is repeated three times.
-- thanks to Tony Saveski for finding this
The reference to Section 6.7.2, "Action enablement delay." should really be a reference to Section 6.6.2, "Commands".
-- thanks to Eric Hein for finding this
In the code snippet at the bottom of the page, the three TableColumn variables should be declared as fields rather than local variables. In addition, the second half of the paragraph above that code snippet should be reworked to make it clear what is being accomplished. Therefore, from the sentence in the middle of that paragraph
With this in mind, we'll start by enhancing ...
to the end of the page should be changed to
With this in mind, we'll start by adding three new fields to the FavoritesView class:
private TableColumn typeColumn; private TableColumn nameColumn; private TableColumn locationColumn;And continue by enhancing the createPartControl(...) method that was generated as part of building the Favorites plug-in (see Section 2.3.3) so that the table has three columns. The SWT.FULL_SELECTION style bit causes the entire row to be highlighted when the user makes a selection:
viewer = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); final Table table = viewer.getTable(); typeColumn = new TableColumn(table, SWT.LEFT); typeColumn.setText(""); typeColumn.setWidth(18); nameColumn = new TableColumn(table, SWT.LEFT); nameColumn.setText("Name"); nameColumn.setWidth(200); locationColumn = new TableColumn(table, SWT.LEFT); locationColumn.setText("Location"); locationColumn.setWidth(450); table.setHeaderVisible(true); table.setLinesVisible(false);Later, when we want to get more involved, we could auto-size the columns in the table (see Section 7.8 "Auto-sizing Table Columns").
so that it is clear which class should contain the new field.
-- thanks to Bruce Gruenbaum for suggesting this
Near the bottom of the page, the line
"We will introduce a new field to hold the sorer instance:"
should be changed to
"We will introduce a new field in FavoritesView to hold the sorer instance:"
so that it is clear which class should contain the new field.
-- thanks to Bruce Gruenbaum for suggesting this
The last sentence of the introductory paragraph for this section should be changed to:
"This section covers adding an action to a view programmatically and registering that view so that others can contribute their own actions via the plug-in manifest, whereas Section 6.4 "View Actions," discussed adding an action using declarations in the plug-in manifest."
-- thanks to Bruce Gruenbaum for suggesting this
The code at the bottom of the page should include the following field declaration:
private ISelection selection;-- thanks to Bruce Gruenbaum for suggesting this
The 2nd sentence of the introductory paragraph for this section should be modified to read:
"There are several steps to create a view's context menu programmatically. If you want other plug-ins to contribute actions to your view's context menu via declarations in the plug-in manifest, then there are several more steps you must take to register your view (See Sections ......
-- thanks to Bruce Gruenbaum for suggesting this
Hover images for actions are deprecated and unused as of Eclipse 3.0, so you can delete the following lines from createActions() method:
ImageDescriptor removeImageHover = PlatformUI .getWorkbench() .getSharedImages() .getImageDescriptor( ISharedImages.IMG_TOOL_DELETE_HOVER);removeAction.setHoverImageDescriptor( removeImageHover);-- thanks to Bruce Gruenbaum for suggesting this
The 1st sentence of the introductory paragraph for this section should read:
"At this point, the Favorites view context menu appears as it should, but if your view publishes its selection as referenced in Section 7.3.2.4 and described in Section 7.4.1, then the context menu will incorrectly contain the Favorites submenu with the Add menu item that was defined in Section 6.3.1."
In addition, there is a better way to filter out unwanted actions.
Replace the last sentence of the introductory paragraph for section 7.3.2.5 with:"To accomplish this, revisit the object contribution outlined in Section 6.3.1 and insert the following visibility element:
<visibility> <not> <objectClass name="com.qualityeclipse.favorites.model.IFavoriteItem"/> </not> </visibility>so that the object contribution looks like:
<objectContribution objectClass="org.eclipse.core.resources.IResource" adaptable="true" id="com.qualityeclipse.favorites.popupMenu"> ... etc ... <visibility> <not> <objectClass name="com.qualityeclipse.favorites.model.IFavoriteItem"/> </not> </visibility> </objectContribution>(See Section 6.3.2.2 on page 255 for more about the visibility element)
-- thanks to Bruce Gruenbaum for suggesting this
Line 8 in "createViewPulldownMenu()" method should read "menu.add(filterAction)" rather than "menu.add(filter)".
-- thanks to Eric Hein for finding this
In the code snippet defining hookGlobalActions replace the deprecated constant
IWorkbenchActionConstants.DELETEwith
ActionFactory.DELETE.getId();-- thanks to Bruce Gruenbaum for providing this additional information
Some additional IMemento information about where Eclipse stores memento-based view and editor state information
-- thanks to Simon J Archer for providing this additional information
The first code snippet should read "table.setLayout(new AutoResizeTableLayout(table));" (note the additional constructor argument).
The following additional explanatory text should be included:
For each column, you will need to supply additional layout information. For Example:
// fixed width column
layout.addColumnData(new ColumnPixelData(18));// weighted column
layout.addColumnData(new ColumnWeightData(50));The FavoritesView can use the AutoResizeTableLayout class by modifying the code shown in Section 7.2.2, "View controls," after which the columns in the view will automatically be resized when the view is resized
viewer = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
final Table table = viewer.getTable();
TableColumn typeColumn = new TableColumn(table, SWT.LEFT);
typeColumn.setText("");
//typeColumn.setWidth(18);
layout.addColumnData(new ColumnPixelData(18));
TableColumn nameColumn = new TableColumn(table, SWT.LEFT);
nameColumn.setText("Name");
//nameColumn.setWidth(200);
layout.addColumnData(new ColumnWeightData(200));
TableColumn locationColumn = new TableColumn(table, SWT.LEFT);
locationColumn.setText("Location");
//locationColumn.setWidth(450);
layout.addColumnData(new ColumnWeightData(200));
table.setHeaderVisible(true);
table.setLinesVisible(false);-- thanks to Jim Norris for finding this
The id value should be "com.qualityeclipse.favorites.editors.PropertiesEditor". It's missing the 's' on the ".editors." part of the qualifier.
-- thanks to Jim Wingard for finding this
The method "getEditorArea()" is not a method in IResourceDelta.
-- thanks to Chris lott for finding this
The discussion of "setCanceled()" should read "true" instead of "false"
-- thanks to Chris lott for finding this
CHAR_END and CHAR_START are relative to the file, not to the line.
-- thanks to Chris lott for finding this
The Eclipse Wiki, originally located at eclipsewiki.swiki.net has moved to http://eclipse-wiki.info
The Wiki Editor has moved to http://eclipsewiki.sourceforge.net
IMemento - p290, 335-9,
org.eclipse.ui.popupMenus - p253, 270