diff --git a/docs/ApiRemovalProcess.md b/docs/ApiRemovalProcess.md index 35586cbe56a..2056e9f2139 100644 --- a/docs/ApiRemovalProcess.md +++ b/docs/ApiRemovalProcess.md @@ -4,7 +4,7 @@ See [Eclipse Project Deprecation Policy](Eclipse_API_Central_Deprecation_Policy. For new API planned removals use: -* For Java code use the @Deprecated annotation (see below for an example) and optional additional Javadoc. +* For Java code use the @Deprecated annotation (see below for an example) and optional additional Javadoc. An extra entry in the removal document from [removal document](https://help.eclipse.org/latest/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fporting%2Fremovals.html) is not necessary anymore * If appropriate the @noextend @noreference and @noinstantiate Javadoc annotation should be added to code @@ -15,7 +15,7 @@ Javadoc generates a detailed [list of forRemoval](https://help.eclipse.org/lates Example of a deprecation comment: -``` +```java * XXX * @noreference * @noextend @@ -23,7 +23,7 @@ Example of a deprecation comment: * @deprecated This XXX (class/method/field) will be removed in a future release. Use XXX instead. */ @Deprecated(forRemoval = true, since = "2025-06") -``` +``` * The PMC may decide to back out of an API removal * In general, removing a deprecated API does NOT cause the increase of the major version segment. diff --git a/docs/Coding_Conventions.md b/docs/Coding_Conventions.md index 4dd6ab98f96..086b22845fd 100644 --- a/docs/Coding_Conventions.md +++ b/docs/Coding_Conventions.md @@ -3,8 +3,8 @@ Coding Conventions Oracle has established coding standards that are generally considered reasonable, as evidenced by their widespread adoption by other Java-based development efforts. One of the goals is to make the Eclipse Platform blend in with the Java platform. This goal is furthered by our following suit. -[Oracle's Code Conventions for the Java Programming Language](https://www.oracle.com/java/technologies/javase/codeconventions-contents.html) covers filenames, file organization, indentation, comments, declarations, statements, white space, naming conventions, and programming practices. -All code written for the Eclipse Platform should follow these conventions except as noted below. +[Oracle's Code Conventions for the Java Programming Language](https://www.oracle.com/java/technologies/javase/codeconventions-contents.html) covers filenames, file organization, indentation, comments, declarations, statements, white space, naming conventions, and programming practices. +All code written for the Eclipse Platform should follow these conventions except as noted below. We deviate only in places where our needs differ from Oracle's; when we do deviate, we explain why. (The section numbers shown below are Oracle's.) * Section 3.1.1 Beginning Comments @@ -21,10 +21,11 @@ The Eclipse project has more specific naming conventions. See Eclipse Project [N Modifiers should be ordered as specified in the JLS and summarized in [AST#newModifiers(int)](http://help.eclipse.org/neon/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/AST.html#newModifiers-int-): +```java public protected private abstract default static final synchronized native strictfp transient volatile - +``` For Javadoc conventions, see Oracle's [How to Write Doc Comments for the Javadoc Tool](https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html) and [Eclipse/API_Central](API_Central.md). diff --git a/docs/Eclipse_API_Central_Deprecation_Policy.md b/docs/Eclipse_API_Central_Deprecation_Policy.md index 9103d4eb529..bbff2771f15 100644 --- a/docs/Eclipse_API_Central_Deprecation_Policy.md +++ b/docs/Eclipse_API_Central_Deprecation_Policy.md @@ -1,14 +1,14 @@ Eclipse/API Central/Deprecation Policy ====================================== -This page contains Eclipse Project guidelines on API deprecation. +This page contains Eclipse Project guidelines on API deprecation. This page is maintained by the [Eclipse/PMC](https://eclipse.dev/eclipse/team-leaders.php). What is Deprecation? ==================== -API deprecation is used to inform API clients that a particular API element is no longer recommended for use. +API deprecation is used to inform API clients that a particular API element is no longer recommended for use. The deprecation comment should describe the reason for the deprecation, and directions for how to replace their usage with the new recommended way of doing things. Deprecation does not necessary implies that the API will be deleted in a future release unless it is explicitely marked for deletion. @@ -20,7 +20,7 @@ Process to deprecate an API Identifying Deprecated API ========================== -This section describes how clients can identify what API is deprecated. +This section describes how clients can identify what API is deprecated. To identify API from non-API, see [Provisional API Guidelines](Provisional_API_Guidelines.md) Java API @@ -31,16 +31,17 @@ Java API is deprecated through use of the @Deprecate annotation. If it is planned to be removed in the future set the forRemoval = true property. In this case, the since tag should include the release in which is was marked for deletion. +```java @Deprecated(forRemoval = true, since="2024-12") +``` - -Older code used @deprecated javadoc tag on types, methods, and fields. +Older code used @deprecated javadoc tag on types, methods, and fields. The javadoc paragraph following the @deprecated tag defines the rationale for the deprecation and instructions on moving to equivalent new API. Extension Points ---------------- -Elements and attributes in extension points are deprecated by setting the "Deprecated" property to true in the PDE extension point schema editor. +Elements and attributes in extension points are deprecated by setting the "Deprecated" property to true in the PDE extension point schema editor. The entire extension point can be deprecated by deprecating the "extension" element, which is the top level element at the root of any contribution to the extension point. ![Schema-deprecation.png](images/Schema-deprecation.png) diff --git a/docs/Evolving-Java-based-APIs-3.md b/docs/Evolving-Java-based-APIs-3.md index fccc76ffdb1..a779c7bd29f 100644 --- a/docs/Evolving-Java-based-APIs-3.md +++ b/docs/Evolving-Java-based-APIs-3.md @@ -10,7 +10,7 @@ Other notes Data Compatibility ------------------ -The Component implementation may need to store and retrieve its internal data from a file. For example, Microsoft Word stores a document in a file. When one of these files may live from release to release, clients would break if the format or interpretation of that data changed in an incompatible way. +The Component implementation may need to store and retrieve its internal data from a file. For example, Microsoft Word stores a document in a file. When one of these files may live from release to release, clients would break if the format or interpretation of that data changed in an incompatible way. **Data compatibility** is an additional issue for components with persistent data. The standard technique is to tag all stored data with its format version number. The format version number is increased when the format is changed from one release to the next. The Component implementation contains readers for the current format version and for all past versions, but usually only the writer for the current format version (unless for some reason there is an ongoing need to write older versions). @@ -34,9 +34,11 @@ Even simpler than Deprecate and Forward, the Component API and implementation ca Here is a simple technique for adding an argument to a method that is intended to be overridden by subclasses. For example the `Viewer.inputChanged(Object input)` method should get an additional argument `Object oldInput`. Adding the argument results in pre-existing clients overridding the wrong method. The workaround is to call the old method as the default implementation of the new method: +```java public void inputChanged(Object input, Object oldInput) { inputChanged(input); } +``` Pre-existing clients which override the old method continue to work; and all calls to the old method continue to work. New or upgraded clients will override the new method; and all calls to the new method will work, even if they happen to invoke an old implementation. @@ -48,29 +50,36 @@ Since Java 8, this technique also works for interface methods (new method is a d The first release of an API callback-style interface didn't work as well as hoped. For example, the first release contained: +```java public interface IProgressMonitor { void start(); void stop(); } - +``` + You now wish you had something like: +```java public interface IProgressMonitor { void start(int total); void worked(int units); void stop(); } - +``` + But it's too late to change `IProgressMonitor` to be that API. So you mark `IProgressMonitor` as deprecated and introduce the new and improved one under the name `IProgressMonitor2` (a name everyone recognizes as the second attempt): +```java public interface IProgressMonitor2 extends IProgressMonitor { void start(int total); void worked(int units); void stop(); } - +``` + By declaring the new interface to extend the old one, any object of type `IProgressMonitor2` can be passed to a method expecting an old `IProgressMonitor`. Don't forget to mention `IProgressMonitor2` in the API of `IProgressMonitor`, even if you don't deprecate it, e.g.: +```java /** * [...] * @see IProgressMonitor2 @@ -78,7 +87,8 @@ By declaring the new interface to extend the old one, any object of type `IProgr public interface IProgressMonitor { [...] } - +``` + ### COM Style The "COM style" is to not implement interfaces directly but to ask for an interface by using `getAdapter(someInterfaceID)`. This allows adding new interfaces in the implementation without breaking existing classes. @@ -168,5 +178,5 @@ On the other hand, clients should avoid all `Class.getDeclared_XXX_` methods as Versioning ---------- -It should be easy for API clients to know whether a new version of your components broke APIs or not. +It should be easy for API clients to know whether a new version of your components broke APIs or not. Eclipse projects implement semantic versioning according to the [Version Numbering](VersionNumbering.md) specification. diff --git a/docs/Evolving-Java-based-APIs.md b/docs/Evolving-Java-based-APIs.md index 40c6c594a98..07d225f13e1 100644 --- a/docs/Evolving-Java-based-APIs.md +++ b/docs/Evolving-Java-based-APIs.md @@ -7,8 +7,8 @@ Document is currently split in 3 parts: * [Part 2: Achieving API Binary Compatibility](Evolving-Java-based-APIs-2.md) * [Part 3: Other Notes](Evolving-Java-based-APIs-3.md) -This document is about how to evolve Java-based APIs while maintaining compatibility with existing client code. -Without loss of generality, we'll assume that there is a generic **Component** with a **Component API**, with one party providing the Component and controlling its API. +This document is about how to evolve Java-based APIs while maintaining compatibility with existing client code. +Without loss of generality, we'll assume that there is a generic **Component** with a **Component API**, with one party providing the Component and controlling its API. The other party, or parties, write **Client** code that use the Component's services through its API. This is a very typical arrangement. @@ -43,7 +43,7 @@ Changing an API in a way that is incompatible with existing Clients would mean t As the Component API evolves, all pre-existing Clients are expected to continue to work, both in principle and in practice. -Suppose a Client was written to a given release of the Component and abided by the contracts spelled out in the Component API specification. +Suppose a Client was written to a given release of the Component and abided by the contracts spelled out in the Component API specification. The first requirement is that when the Component API evolves to follow-on releases, all pre-existing Client must still be legal according to the contracts spelled out in the revised Component API specification, without having to change the Clients source code. This is what is meant by continuing to work in principle. > **API Contract Compatibility:** _API changes must not invalidate formerly legal Client code._ @@ -79,11 +79,11 @@ Note that in some cases, the contractual roles are reversed. The party responsib When contemplating changing an existing API contract, the key questions to ask are: -* What roles does the API contract involve? +* What roles does the API contract involve? For a method contract, there is the caller and the implementor. In the case of frameworks, there is also an additional contract between superclass and subclass regarding default behavior, extending, and overriding. -* Which role or roles will each party play? +* Which role or roles will each party play? For many Component API methods, the Component plays the role of exclusive implementor and the Client plays the role of caller. In the case of Component callbacks, the Component plays the caller role and the Client plays the implementor role. In some cases, the Client might play more than one role. -* Is a role played exclusively by the Component? +* Is a role played exclusively by the Component? Component API changes coincide with Component releases, making it feasible to change Component code to accommodate the changed APIs. * For roles played by Clients, would the contemplated API change render invalid a hypothetical Client making legal usage of the existing API? @@ -95,24 +95,30 @@ Standard method contracts have two roles: caller and implementor. Method postcon Consider the following API method specification: +```java /** Returns the list of children of this widget. * @return a non-empty list of widgets */ Widget[] getChildren(); +``` The contemplated API change is to allow the empty list of widgets to be returned as well, as captured by this revised specification: +```java /** Returns the list of children of this widget. * @return a list of widgets */ Widget[] getChildren(); +``` Would this change break compatibility with existing Clients? It depends on the role played by the Client. Looking at the caller role, this change would break a hypothetical pre-existing caller that legitimately counts on the result being non-empty. The relevant snippet from this hypothetical caller might read: +```java Widget[] children = widget.getChildren(); Widget firstChild = children[0]; +``` Under the revised contract, this code would be seen to be in error because it assumes that the result of invoking `getChildren` is non-empty; under the previous contract, this assumption was just fine. This API change weakens a postcondition for the caller, and is not contract compatible for the caller role. The contemplated change would break Clients playing the caller role. @@ -128,17 +134,21 @@ Method preconditions are those things that a caller must arrange to be true befo Consider the following API method specification: +```java /** Removes the given widgets from this widget's list of children. * @param widgets a non-empty list of widgets */ void remove(Widget[] widgets); - +``` + The contemplated API change is to allow empty lists of widgets to be passed in as well: +```java /** Removes the given widgets from this widget's list of children. * @param widgets a list of widgets */ void remove(Widget[] widgets); +``` Would this change break compatibility with existing Clients? Again, it hinges on the role played by the Client. @@ -146,7 +156,9 @@ Looking at the caller role, this change would not break hypothetical pre-existin The relevant snippet from this hypothetical implementor might read: +```java Widget firstChild = widgets[0]; +``` Under the revised contract, this code would be seen to be in error because it assumes that the argument is non-empty; under the previous contract, this assumption was just fine. This API change weakens a method precondition, and is not contract compatible for the implementor role. The contemplated change would break Clients that implement this method. @@ -156,15 +168,19 @@ Fields can be analyzed as having two roles: a getter and a setter. The Java lang Consider the following API field specification: +```java /** This widget's list of children, or null. */ Widget[] children; - +``` + The contemplated API change is to get rid of the possibility of the `null` value: +```java /** This widget's list of children. */ Widget[] children; +``` Would this change break compatibility with existing Clients? @@ -182,7 +198,7 @@ However, if the method is added to a class which Clients may subclass, then the ### General Rules for Contract Compatibility -Whether a particular Component API change breaks or maintains contract compatibility with hypothetical pre-existing Clients hinges on which role, or roles, the Client plays in the API contract(s) being changed. The following table summarizes the pattern seen in the above examples: +Whether a particular Component API change breaks or maintains contract compatibility with hypothetical pre-existing Clients hinges on which role, or roles, the Client plays in the API contract(s) being changed. The following table summarizes the pattern seen in the above examples:   | | | | | | --- | --- | --- | --- | diff --git a/docs/FAQ.md b/docs/FAQ.md index fd8cbf1582d..d469535ea99 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -18,7 +18,7 @@ Installation, Startup and Runtime ### Where can I get Eclipse? -* Use the [downloads page](http://www.eclipse.org/downloads/) or [download package](https://www.eclipse.org/downloads/packages/) to get the latest releases. +* Use the [downloads page](http://www.eclipse.org/downloads/) or [download package](https://www.eclipse.org/downloads/packages/) to get the latest releases. ### What's the difference between all the different packages? What do they contain? Do they contain source code? @@ -72,17 +72,17 @@ The simplest way: If you need to add additional command-line parameters, then you will need to get to a command prompt and run something like: - /path/to/eclipse/eclipse -data /path/to/workspace -vm /path/to/jvm/bin/java -vmargs -Xms256M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M - + /path/to/eclipse/eclipse -data /path/to/workspace -vm /path/to/jvm/bin/java -vmargs -Xms256M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M + + - \- or - - c:\path\to\eclipse\eclipse.exe -data c:\path\to\workspace -vm c:\path\to\jvm\bin\java.exe -vmargs -Xms256M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M - + c:\path\to\eclipse\eclipse.exe -data c:\path\to\workspace -vm c:\path\to\jvm\bin\java.exe -vmargs -Xms256M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M + + - Note that any arguments for the JVM, including setting properties, must come after the _-vmargs_. @@ -180,7 +180,7 @@ There are a couple of things you can try. 1. Delete the `workspace/.metadata/.lock` file. 2. Check your running processes to make sure there aren't any remaining Java or Eclipse processes running. When in doubt, restart your computer. :) -3. Try starting Eclipse on a different workspace (from the workspace selection dialog, or by using a command line argument like `-data /home/user/tmp-workspace`), then switch +3. Try starting Eclipse on a different workspace (from the workspace selection dialog, or by using a command line argument like `-data /home/user/tmp-workspace`), then switch back to your original workspace. If none of these solution work, could you be trying to create the workspace on a folder mounted via NFS? If yes, please make sure you are using NFS v4. @@ -248,9 +248,9 @@ A number of Ubuntu/Linux users have complained about the update manager being un The Eclipse launcher is currently ignoring the VM arguments in the `eclipse.ini` file due to the change in branding of the HotSpot VM from Sun to Oracle. The workaround is to set the argument directly via the command line or to append it to your shortcut/script. eclipse.exe -vmargs -XX:MaxPermSize=256m - - + + Please see [bug 319514](https://bugs.eclipse.org/bugs/show_bug.cgi?id=319514) for more details. @@ -258,15 +258,15 @@ Please see [bug 319514](https://bugs.eclipse.org/bugs/show_bug.cgi?id=319514) fo On the .log-File (workbench/.metadata/.log) i see an error like: - + The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes. - - -So check if the file **.snap** exist in your Workbench-Folder on: .metadata/.plugins/org.eclipse.core.resources. Than remove, or rename the file and start eclipse again. - + + +So check if the file **.snap** exist in your Workbench-Folder on: .metadata/.plugins/org.eclipse.core.resources. Than remove, or rename the file and start eclipse again. + Eclipse ------- @@ -382,9 +382,9 @@ See [Platform Plug-in Developer Guide > Programmer's Guide > Advanced workbench Window > Preferences... > General > Keys [x] Include unbound commands - - + + * To find other commands, if the above didn't work: @@ -394,25 +394,25 @@ See [Platform Plug-in Developer Guide > Programmer's Guide > Advanced workbench [ ] Filter uncategorized commands <-- this one is particularly useful - + ### Why did Content Assist stop working? First, select: Window > Preferences... > General > Keys - - + + Scroll to "Content Assist" and verify that Ctrl+Space is still the hotkey. If content assist is displaying an empty proposal window, then check your default proposal generators by navigating to: Window > Preferences... > Java > Editor > Content Assist > Advanced - - + + Ensure the top-most table (defining the default content assist list) has your desired proposal generators. You'll likely want "Java Proposals" @@ -429,9 +429,9 @@ One known process that can interfere with Ctrl+Space is Logitech's QuickCam10.ex Make sure that you're opening the file with the correct editor. You may have several associated editors for a given file type, such as .php or .xml. Whatever was installed last is probably the default. If this is not your preferred editor, select: Window > Preferences... > General > Editors > File Associations - - + + and set a better default. Note that the last editor you used for a file will be used next time, so you might have to use Open With instead of Open to select the correct editor. @@ -449,6 +449,7 @@ Many tools now add an option to "add the xyz nature", usually via the project's For a PHP project, this could be: +```xml org.eclipse.php.core.PhpIncrementalProjectBuilder @@ -462,9 +463,11 @@ For a PHP project, this could be: org.eclipse.php.core.PHPNature +``` For a Plug-in project: +```xml org.eclipse.jdt.core.javabuilder @@ -483,6 +486,7 @@ For a Plug-in project: org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature +``` Note also: @@ -566,6 +570,7 @@ The code snippet below should be able to help you. You may also wish to refer to The code below is largely copy and pasted from `org.eclipse.core.internal.runtime.auth.AuthorizationDatabase`, `org.eclipse.core.internal.runtime.auth.CipherInputStream`, and `org.eclipse.core.internal.runtime.auth.Cipher`. +```java public static void main(String\[\] args) { String s = "/home/user/eclipse/configuration/org.eclipse.core.runtime/.keyring"; //$NON-NLS-1$   @@ -735,6 +740,7 @@ The code below is largely copy and pasted from `org.eclipse.core.internal.runtim return result; } } +``` ### My line delimiter changes are not being persisted to the file. What's going on? @@ -882,7 +888,7 @@ Plug-in Development ### How do I test my plug-ins? -See [here](/PDE./FAQ#How_do_test_my_plug-ins.md "PDE./FAQ")..md +See [here](/PDE./FAQ#How_do_test_my_plug-ins.md "PDE./FAQ")..md ### I get an unhandled event loop exception in my console. What gives? See [here](/Graphical_Eclipse_FAQs#I_get_an_unhandled_event_loop_exception_in_my_console._What_gives.3F "Graphical Eclipse FAQs"). diff --git a/docs/FAQ/FAQ_Can_I_create_an_application_that_doesnt_have_views_or_editors.md b/docs/FAQ/FAQ_Can_I_create_an_application_that_doesnt_have_views_or_editors.md index f9c773a9a6a..7bf4bd55f6e 100644 --- a/docs/FAQ/FAQ_Can_I_create_an_application_that_doesnt_have_views_or_editors.md +++ b/docs/FAQ/FAQ_Can_I_create_an_application_that_doesnt_have_views_or_editors.md @@ -5,9 +5,10 @@ FAQ Can I create an application that doesn't have views or editors? When you create an RCP application using a workbench advisor, you are still constrained to using the standard Eclipse UI constructs of views, editors, and perspectives. If you have very different UI requirements but still want to use the plug-in infrastructure, you can always create an application built on only SWT and JFace. This has been possible since the first release of Eclipse as SWT and JFace have no other dependencies outside the base runtime plug-in. JFace provides a basic ApplicationWindow with optional menus, toolbar, and status line. - + Configuration of a JFace application works through subclassing rather than plugging in an advisor. Your application needs to subclass the JFace class called ApplicationWindow and override the various methods that are used to customize the appearance and behavior of the window. The following is a simple JFace application window from the FAQ examples plug-in. As with other applications, you begin by creating a class that implements IPlatformRunnable: +```java public class JFaceApp implements IPlatformRunnable { public Object run(Object args) throws Exception { Display display = new Display(); @@ -21,11 +22,13 @@ Configuration of a JFace application works through subclassing rather than plugg return EXIT_OK; } } +``` JFaceAppWindow is a subclass of the framework class ApplicationWindow. The subclass creates a simple window with a menu bar, a status line, and a single button inside the main window that is used to exit the application (Figure 16.2). Complete source for the class can be found in the FAQ Examples plug-in, but here is the basic structure: +```java public class JFaceAppWindow extends ApplicationWindow { public JFaceAppWindow() { super(null); @@ -38,10 +41,11 @@ Complete source for the class can be found in the FAQ Examples plug-in, but here } ... } +``` The subclass also needs to override the createContents method to create the SWT widgets that will appear in the window's main content area. Override createMenuManager to populate the window's menus, createToolBarManager to populate the toolbar, and so on. If you browse through the ApplicationWindow class, you will see that many other hook methods allow your application to customize the appearance of the top-level window. - + See Also: --------- diff --git a/docs/FAQ/FAQ_Can_I_use_the_actions_from_the_Navigator_in_my_own_plug-in.md b/docs/FAQ/FAQ_Can_I_use_the_actions_from_the_Navigator_in_my_own_plug-in.md index 6118058a5ea..a71b56e9ab5 100644 --- a/docs/FAQ/FAQ_Can_I_use_the_actions_from_the_Navigator_in_my_own_plug-in.md +++ b/docs/FAQ/FAQ_Can_I_use_the_actions_from_the_Navigator_in_my_own_plug-in.md @@ -5,13 +5,14 @@ FAQ Can I use the actions from the Navigator in my own plug-in? Yes. All the resource actions in the Navigator view, including **Copy**, **Move**, **Delete**, **Build**, and **Refresh**, are available as API. These actions are found in the org.eclipse.ui.actions package of the org.eclipse.ui.ide plug-in. These actions expect a selection of either IResource objects or IAdaptable objects that are able to adapt to IResource. You must either install the actions as selection change listeners, such as on a TreeViewer, or supply them with the selection before running them: +```java IResource r = ...;//resource to delete IStructuredSelection ss = new StructuredSelection(r); DeleteResourceAction delete = new DeleteResourceAction(shell); delete.selectionChanged(ss); delete.run(); +``` - See Also: --------- diff --git a/docs/FAQ/FAQ_Can_fragments_be_used_to_patch_a_plug-in.md b/docs/FAQ/FAQ_Can_fragments_be_used_to_patch_a_plug-in.md index 17ae1eea701..5f3553e6737 100644 --- a/docs/FAQ/FAQ_Can_fragments_be_used_to_patch_a_plug-in.md +++ b/docs/FAQ/FAQ_Can_fragments_be_used_to_patch_a_plug-in.md @@ -7,12 +7,15 @@ A common misconception is that a fragment can be used to patch or replace functi Nonetheless, it is possible to design a plug-in so that it allows a portion of its functionality to be implemented or replaced by a fragment. Let's look at a notable example of how this is applied in the org.eclipse.swt plug-in. The SWT plug-in manifest declares a runtime library by using a special path-substitution variable: +```xml +``` When the plug-in manifest is loaded, the platform will substitute the $ws$ variable with a string describing the windowing system of the currently running operating system. Each windowing system has a separate SWT plug-in fragment that will provide this library. For example, when running on windows, $ws$ will resolve to ws/win32. You can make use of this path-substitution facility in your own plug-in code by using the Plugin.find methods. The fragment org.eclipse.swt.win32 supplies the swt.jar library at the path org.eclipse.swt.win32/ws/win32/swt.jar. Thus, in this case the fragment will supply a library that was specified by its host plug-in. The same principle can be used to allow a fragment to provide a patch to a host plug-in. The host plug-in can specify both its own library and a patch library in its plug-in manifest: +```xml @@ -21,8 +24,8 @@ The same principle can be used to allow a fragment to provide a patch to a host +``` - The host plug-in puts all its code in main.jar and does not specify a patch.jar at all. When no patch is needed, the patch.jar library is simply missing from the classpath. This allows a fragment to be added later that contributes the patch.jar library. Because the host plug-in has defined patch.jar at the front of its runtime classpath, classes in the patch library will be found before classes in the original library. This technique is used in Eclipse 3.0 to provide backward-compatibility support for plug-ins based on Eclipse 2.1 or earlier. The plug-in org.eclipse.ui.workbench defines a library called compatibility.jar at the start of its classpath. When the platform detects a plug-in written prior to Eclipse 3.0, a fragment called org.eclipse.ui.workbench.compatibility containing compatibility.jar is automatically added to the plug-in's classpath. This library adds back some old API that was moved in Eclipse 3.0. The beauty of this mechanism is that it allows the backward-compatibility support to be added or removed with no impact on the host plug-in. diff --git a/docs/FAQ/FAQ_Does_the_platform_have_support_for_concurrency.md b/docs/FAQ/FAQ_Does_the_platform_have_support_for_concurrency.md index 8d5c1b0b0d8..15225e3b76f 100644 --- a/docs/FAQ/FAQ_Does_the_platform_have_support_for_concurrency.md +++ b/docs/FAQ/FAQ_Does_the_platform_have_support_for_concurrency.md @@ -7,6 +7,7 @@ In Eclipse 3.0, infrastructure was added to support running application code con The basic unit of concurrent activity in Eclipse is provided by the Job class. Jobs are a cross between the interface java.lang.Runnable and the class java.lang.Thread. Jobs are similar to runnables because they encapsulate behavior inside a run method and are similar to threads because they are not executed in the calling thread. This example illustrates how a job is used: +```java Job myJob = new Job("Sample Job") { public IStatus run(IProgressMonitor monitor) { System.out.println("This is running in a job"); @@ -14,6 +15,7 @@ The basic unit of concurrent activity in Eclipse is provided by the Job class. J } }; myJob.schedule(); +``` When schedule is called, the job is added to a queue of jobs waiting to be run. Worker threads then remove them from the queue and invoke their run method. This system has a number of advantages over creating and starting a Java thread: diff --git a/docs/FAQ/FAQ_How_and_when_do_I_save_the_workspace.md b/docs/FAQ/FAQ_How_and_when_do_I_save_the_workspace.md index 13ec37b9fc5..cfa3d53de61 100644 --- a/docs/FAQ/FAQ_How_and_when_do_I_save_the_workspace.md +++ b/docs/FAQ/FAQ_How_and_when_do_I_save_the_workspace.md @@ -11,6 +11,7 @@ Nonetheless, it is possible for your plug-in to explicitly request a workspace s The following example saves the workspace: +```java final MultiStatus status = new MultiStatus(...); IRunnableWithProgress runnable = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { @@ -26,6 +27,7 @@ The following example saves the workspace: if (!status.isOK()) { ErrorDialog.openError(...); } +``` Note that the save method can indicate minor problems by returning an IStatus object, or major problems by throwing an exception. You should check both of these results and react accordingly. To request a workspace snapshot, the code is almost identical: pass false as the first parameter to the save method. diff --git a/docs/FAQ/FAQ_How_are_resources_created.md b/docs/FAQ/FAQ_How_are_resources_created.md index 6b4e121d4dd..3726152b331 100644 --- a/docs/FAQ/FAQ_How_are_resources_created.md +++ b/docs/FAQ/FAQ_How_are_resources_created.md @@ -5,6 +5,7 @@ FAQ How are resources created? The workspace is manipulated using _resource handles_. Resource handles are lightweight pointers to a particular project, folder, or file in the workspace. You can create a resource handle without creating a resource, and resources can exist regardless of whether any handles exist that point to them. To create a resource, you first have to create a resource handle and then tell it to create the resource. The following snippet uses resource handles to create a project, a folder, and a file. +```java IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceRoot root = workspace.getRoot(); IProject project = root.getProject("MyProject"); @@ -13,13 +14,14 @@ The workspace is manipulated using _resource handles_. Resource handles are ligh //at this point, no resources have been created if (!project.exists()) project.create(null); if (!project.isOpen()) project.open(null); - if (!folder.exists()) + if (!folder.exists()) folder.create(IResource.NONE, true, null); if (!file.exists()) { byte[] bytes = "File contents".getBytes(); InputStream source = new ByteArrayInputStream(bytes); file.create(source, IResource.NONE, null); } +``` This example defensively checks that the resource doesn't already exist before trying to create it. This kind of defensive programming is a good idea because an exception is thrown if you try to create a resource that already exists. This way, the example can be run more than once in the same workspace without causing an error. The null parameters to the creation methods should be replaced by a progress monitor in a real application. diff --git a/docs/FAQ/FAQ_How_can_Content_Assist_make_me_the_fastest_coder_ever.md b/docs/FAQ/FAQ_How_can_Content_Assist_make_me_the_fastest_coder_ever.md index eca2d8e11ee..6399b6a5f0a 100644 --- a/docs/FAQ/FAQ_How_can_Content_Assist_make_me_the_fastest_coder_ever.md +++ b/docs/FAQ/FAQ_How_can_Content_Assist_make_me_the_fastest_coder_ever.md @@ -5,53 +5,55 @@ FAQ How can Content Assist make me the fastest coder ever? When extending Eclipse, plug-in authors are confronted with an overwhelming selection of API to choose from. In the good old days, books could be published with API references, and programmers could study the material and recite the proper incantations to drive the relatively simple APIs. With modern APIs, this is no longer possible. There simply is too much to read and remember. Content Assist to the rescue! - + Content Assist can take the guesswork out of coding in a number of ways: - + * _Finding a given type_. Assume that you are writing some code and want to use a button in your UI. You start typing the letter B and don't remember the rest of the word. Simply press Ctrl+Space, and the Java tooling will present you with a list of all types that start with the letter B. The list starts with Boolean. Keep typing, and the list narrows down. After typing But, you get to choose between java.awt.Button and org.eclipse.swt.widgets.Button. Choose the one you like, and the editor inserts the class _and_ inserts an import statement for the class at the same time. - - + + * _Finding a given field or method_. After typing a dot after a certain expression, Content Assist will suggest all possible fields and methods applicable to the expression's result type. This functionality is very useful for discovering what operations can be applied to a given object. Combined with pervasive use of getters and setters, browsing an API is really simple. For the Button example, continuations for get show all attributes that can be obtained from a button. The ones starting with set show the attributes that can be modified. Another frequent prefix used while writing plug-ins is add to add event listeners. Having Content Assist at your fingertips definitely improves coding speed by combining intuition with content-assisted browsing. - + * _Entering method parameter values_. When entering Ctrl+Space after the ( for a method call, Content Assist will provide the expected type name for each parameter. When you advance to the next parameter-by pressing a comma-the Content Assist hints move along with you. This is especially useful for overloaded methods with ambiguous signatures and for methods with many parameters. - + * _Overriding inherited methods_. Invoke Content Assist when the cursor is between method declarations. Proposals will be shown for all possible methods that can be overridden from superclasses. - + * _Generating getters and setters_. Between two method declarations, type get, and invoke Content Assist. Proposals will be shown for creating accessor methods for any fields in the class that do not yet have an accessor. The same applies for generating setter methods by invoking Content Assist on the prefix set. - + * _Creating anonymous inner classes_. Eclipse likes loose coupling and hence works a lot with listeners that are registered on demand. The listeners implement a given interface with methods that are called when the event of interest happens. Typical usage is to declare an anonymous inner class, as in this example: +```java button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { // do something here } }); +``` Here is how an experienced Eclipse user might enter that code using Content Assist. @@ -60,17 +62,17 @@ Here is how an experienced Eclipse user might enter that code using Content Assi new Sel**** select 'SelectionAdapter' () { **** select 'widgetSelected' - + Note that Content Assist is also available inside javadoc comments and can help when declaring fields and can assist with named local variables and method arguments. In [FAQ How do I add Content Assist to my language editor?](./FAQ_How_do_I_add_Content_Assist_to_my_language_editor.md "FAQ How do I add Content Assist to my language editor?") we explain how Content Assist is implemented in Eclipse. - + Also note that Content Assist can be fully customized from the **Java > Editor** preference page. - - + + See Also: --------- diff --git a/docs/FAQ/FAQ_How_can_I_be_notified_of_changes_to_the_workspace.md b/docs/FAQ/FAQ_How_can_I_be_notified_of_changes_to_the_workspace.md index 9510a97d80c..1b9ec1c148d 100644 --- a/docs/FAQ/FAQ_How_can_I_be_notified_of_changes_to_the_workspace.md +++ b/docs/FAQ/FAQ_How_can_I_be_notified_of_changes_to_the_workspace.md @@ -5,16 +5,20 @@ FAQ How can I be notified of changes to the workspace? Resource change listeners are notified of most changes that occur in the workspace, including when any file, folder, or project is created, deleted, or modified. Listeners can also be registered for some special events, such as before projects are deleted or closed and before and after workspace autobuilds. Registering a resource change listener is easy: +```java IWorkspace workspace = ResourcesPlugin.getWorkspace(); IResourceChangeListener rcl = new IResourceChangeListener() { public void resourceChanged(IResourceChangeEvent event) { } }; workspace.addResourceChangeListener(rcl); +``` Always make sure that you remove your resource change listener when you no longer need it: +```java workspace.removeResourceChangeListener(rcl); +``` Look at the javadoc for IWorkspace.addResourceChangeListener for more information on the various types of resource change events you can listen to and the restrictions that apply. It is important to keep performance in mind when writing a resource change listener. Listeners are notified at the end of every operation that changes the workspace, so any overhead that you add in your listener will degrade the performance of all such operations. If your listener needs to do expensive processing, consider off-loading some of the work into another thread, preferably by using a Job as described in [FAQ Does the platform have support for concurrency?](./FAQ_Does_the_platform_have_support_for_concurrency.md "FAQ Does the platform have support for concurrency?") diff --git a/docs/FAQ/FAQ_How_can_I_change_the_name_or_tooltip_of_my_action.md b/docs/FAQ/FAQ_How_can_I_change_the_name_or_tooltip_of_my_action.md index 0c922e31912..10e56532f5a 100644 --- a/docs/FAQ/FAQ_How_can_I_change_the_name_or_tooltip_of_my_action.md +++ b/docs/FAQ/FAQ_How_can_I_change_the_name_or_tooltip_of_my_action.md @@ -5,7 +5,8 @@ FAQ How can I change the name or tooltip of my action? Actions contributed via XML have statically defined names, images, and tooltips. Often, you want to change these attributes dynamically, based on the current selection or some other state. Owing to the lazy-loading nature of the platform, you can't do this until your action has been run once. A common solution is to specify generic attributes in the XML and then make attributes more dynamic after the action has been run. For example, the action to enable or disable breakpoints is called **Toggle Breakpoint** when the platform is first started. After it has been run once, the action dynamically sets its name to be either **Enable Breakpoint** or **Disable Breakpoint**, depending on whether the selected breakpoint is enabled. Here is an example action that implements this behavior: - class ToggleAction +```java + class ToggleAction implements IWorkbenchWindowActionDelegate { private boolean state = false; public void run(IAction action) { @@ -15,13 +16,13 @@ Actions contributed via XML have statically defined names, images, and tooltips. action.setToolTipText(name); } } +``` - You can change many more action properties, including the action's image, accelerator key, and enablement. Look at the methods on IAction to see what other properties can be changed. It is also common to update action properties when the selection changes. Although the preceding example uses a workbench window action delegate, which is not notified of selection changes by default, the action can register itself as a selection listener in the init method and then update its state during the selectionChanged callback. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_can_I_share_a_JAR_among_various_plug-ins.md b/docs/FAQ/FAQ_How_can_I_share_a_JAR_among_various_plug-ins.md index 165571d45df..2cf343d150d 100644 --- a/docs/FAQ/FAQ_How_can_I_share_a_JAR_among_various_plug-ins.md +++ b/docs/FAQ/FAQ_How_can_I_share_a_JAR_among_various_plug-ins.md @@ -5,35 +5,36 @@ FAQ How can I share a JAR among various plug-ins? Suppose that plug-in _A_ and plug-in _B_ both use xmlparser.jar. In your workspace are two projects (for _A_ and _B_), each containing a copy of the xmlparser.jar library. This is clearly not ideal: Two copies of the JAR are loaded at runtime, and classes from those JARs will not be compatible with each other, as they are loaded by different class loaders. (You will get a ClassCastException if you try to cast a type from one library into a type from the other library.) - + Declaring xmlparser.jar as an external JAR does not work, as there is no easy way during deployment of your plug-ins to manipulate your plug-in's classpath so that they can see the library. The best way to share libraries is to create a new plug-in that wraps the library you want to share. - + Declare a new plug-in, _C_, to contain the library JAR, and make both plug-in _A_ and plug-in _B_ dependent on plug-in _C_. Make sure that plug-in _C_ exports its library so other plug-ins can see it: +```xml +``` - When you deploy these three plug-ins, they will all share the same library. Note that in some situations, sharing libraries between plug-ins is not possible. If two plug-ins require different or incompatible versions of the same library, they have no choice but to each have a copy of the library. - - - + + + See Also: --------- [FAQ\_What\_is\_the\_classpath\_of\_a_plug-in?](./FAQ_What_is_the_classpath_of_a_plug-in.md "FAQ What is the classpath of a plug-in?") - + [FAQ\_How\_do\_I\_add\_a\_library\_to\_the\_classpath\_of\_a\_plug-in?](./FAQ_How_do_I_add_a_library_to_the_classpath_of_a_plug-in.md "FAQ How do I add a library to the classpath of a plug-in?") diff --git a/docs/FAQ/FAQ_How_can_I_track_the_lifecycle_of_jobs.md b/docs/FAQ/FAQ_How_can_I_track_the_lifecycle_of_jobs.md index 30416ce081f..6c7cea2d94b 100644 --- a/docs/FAQ/FAQ_How_can_I_track_the_lifecycle_of_jobs.md +++ b/docs/FAQ/FAQ_How_can_I_track_the_lifecycle_of_jobs.md @@ -5,6 +5,7 @@ FAQ How can I track the lifecycle of jobs? It is quite simple to find out when jobs, including those owned by others, are scheduled, run, awoken, and finished. As with many other facilities in the Eclipse Platform, a simple listener suffices: +```java IJobManager manager = Job.getJobManager() manager.addJobChangeListener(new JobChangeAdapter() { public void scheduled(IJobChangeEvent event) { @@ -12,6 +13,7 @@ It is quite simple to find out when jobs, including those owned by others, are s System.out.println("Job scheduled: " + job.getName()); } }); +``` By subclassing JobChangeAdapter, rather than directly implementing IJobChangeListener, you can pick and choose which job change events you want to listen to. Note that the done event is sent regardless of whether the job was cancelled or failed to complete, and the result status in the job change event will tell you how it ended. diff --git a/docs/FAQ/FAQ_How_do_I_access_the_active_project.md b/docs/FAQ/FAQ_How_do_I_access_the_active_project.md index 605c3c3a261..5c391e1b084 100644 --- a/docs/FAQ/FAQ_How_do_I_access_the_active_project.md +++ b/docs/FAQ/FAQ_How_do_I_access_the_active_project.md @@ -9,6 +9,7 @@ Often people are really asking for the currently selected project, folder, or fi Once you have the selection, you can extract the selected resource as follows: +```java IResource extractSelection(ISelection sel) { if (!(sel instanceof IStructuredSelection)) return null; @@ -22,22 +23,25 @@ Once you have the selection, you can extract the selected resource as follows: Object adapter = adaptable.getAdapter(IResource.class); return (IResource) adapter; } +``` If you are looking for the active editor, you can determine that from the IPartService. If an editor is active, you can extract the resource, if available, like this: +```java IResource extractResource(IEditorPart editor) { IEditorInput input = editor.getEditorInput(); if (!(input instanceof IFileEditorInput)) return null; return ((IFileEditorInput)input).getFile(); } +``` The code above has a minor error: - +```java IEditorInput input = editor.getEditorInput(); - +``` To obtain the project from the resource use IResource.getProject(). Beware that while Eclipse uses "selected" rather than "active" for the active project, it uses "active" rather than "selected" for the active editor. Or is that "selected editor" ;-). For example, - +```java IWorkbench iworkbench = PlatformUI.getWorkbench(); if (iworkbench == null)... IWorkbenchWindow iworkbenchwindow = iworkbench.getActiveWorkbenchWindow(); @@ -45,7 +49,7 @@ To obtain the project from the resource use IResource.getProject(). Beware that IWorkbenchPage iworkbenchpage = iworkbenchwindow.getActivePage(); if (iworkbenchpage == null) ... IEditorPart ieditorpart = iworkbenchpage.getActiveEditor(); - +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_add_Content_Assist_to_my_editor.md b/docs/FAQ/FAQ_How_do_I_add_Content_Assist_to_my_editor.md index 7bbad47af0d..bbdb7a26c99 100644 --- a/docs/FAQ/FAQ_How_do_I_add_Content_Assist_to_my_editor.md +++ b/docs/FAQ/FAQ_How_do_I_add_Content_Assist_to_my_editor.md @@ -5,6 +5,7 @@ FAQ How do I add Content Assist to my editor? As with most editor features, Content Assist is added to a text editor from your editor's SourceViewerConfiguration. In this case, you need to override the getContentAssistant method. Here is the implementation of this method in our HTML editor example: +```java public IContentAssistant getContentAssistant(ISourceViewer sv) { ContentAssistant ca = new ContentAssistant(); IContentAssistProcessor pr = new TagCompletionProcessor(); @@ -13,6 +14,7 @@ As with most editor features, Content Assist is added to a text editor from your ca.setInformationControlCreator(getInformationControlCreator(sv)); return ca; } +``` Although IContentAssistant is the top-level type that provides Content Assist, most of the work is done by an IContentAssistProcessor. Documents are divided into _partitions_ to represent different logical segments of the text, such as comments, keywords, and identifiers. The IContentAssistant's main role is to provide the appropriate processor for each partition of your document. In our HTML editor example, the document is divided into three partitions: comments, tags, and everything else, represented by the default content type. @@ -28,17 +30,20 @@ Context information, if applicable, is displayed in a pop-up after the user has The final step in implementing Content Assist in your editor is to add an action that will allow the user to invoke Content Assist. The text framework provides an action for this purpose, but it is not installed in the abstract text editor because it isn't applicable to all flavors of text editors. The action is installed by overriding your editor's createActions method. The action class is ContentAssistAction. Here is a snippet from the createActions method in our example HTML editor: - Action action = new ContentAssistAction(resourceBundle, "ContentAssistProposal.", this); +```java + Action action = new ContentAssistAction(resourceBundle, "ContentAssistProposal.", this); String id = ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS action.setActionDefinitionId(id); - setAction("ContentAssistProposal", action); + setAction("ContentAssistProposal", action); markAsStateDependentAction("ContentAssistProposal", true); +``` Line 1 creates the Action instance, supplying a resource bundle where the display strings should be taken from, along with a prefix for that action. The message bundle on disk would look something like this: - +```java ContentAssistProposal.label=Content assist ContentAssistProposal.tooltip=Content assist ContentAssistProposal.description=Provides Content Assistance +``` Line 3 associates a well-known ID with the action that will tell the UI's command framework that this is the action for Content Assist. This allows the user to change the key binding for Content Assist generically and have it apply automatically to all editors that provide Content Assist. diff --git a/docs/FAQ/FAQ_How_do_I_add_Content_Assist_to_my_language_editor.md b/docs/FAQ/FAQ_How_do_I_add_Content_Assist_to_my_language_editor.md index 608d282b24f..be53779767c 100644 --- a/docs/FAQ/FAQ_How_do_I_add_Content_Assist_to_my_language_editor.md +++ b/docs/FAQ/FAQ_How_do_I_add_Content_Assist_to_my_language_editor.md @@ -15,8 +15,8 @@ If it's your own editor In [FAQ How do I write an editor for my own language?](./FAQ_How_do_I_write_an_editor_for_my_own_language.md "FAQ How do I write an editor for my own language?") we describe how Content Assist is installed through our configuration class, as follows: - +```java class Configuration extends SourceViewerConfiguration { public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { ContentAssistant ca = new ContentAssistant(); @@ -25,15 +25,16 @@ In [FAQ How do I write an editor for my own language?](./FAQ_How_do_I_write_an_e ca.setInformationControlCreator(getInformationControlCreator(sourceViewer)); return ca; } +``` Example of IContentAssistProcessor ---------------------------------- A completion processor takes the current insertion point in the editor and figures out a list of continuation proposals for the user to choose from. Our completion processor looks something like this: - - class EScriptCompletionProcessor implements IContentAssistProcessor { +```java + class EScriptCompletionProcessor implements IContentAssistProcessor { private final IContextInformation[] NO_CONTEXTS = { }; private final char[] PROPOSAL_ACTIVATION_CHARS = { 's','f','p','n','m', }; private ICompletionProposal[] NO_COMPLETIONS = { }; @@ -66,7 +67,7 @@ A completion processor takes the current insertion point in the editor and figur } private String lastIndent(IDocument doc, int offset) { try { - int start = offset-1; + int start = offset-1; while (start >= 0 && doc.getChar(start)!= '\n') start--; int end = start; while (end < offset && Character.isSpaceChar(doc.getChar(end))) end++; @@ -76,7 +77,7 @@ A completion processor takes the current insertion point in the editor and figur } return ""; } - public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) { + public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) { return NO_CONTEXTS; } char[] getCompletionProposalAutoActivationCharacters() { @@ -84,6 +85,7 @@ A completion processor takes the current insertion point in the editor and figur } // ... remaining methods are optional ... } +``` Basically, Content Assist completion has three steps. First, we have to figure out what string has already been started by the user (see lastWord). Second, we have to find appropriate completions. Third, we have to return strings so that when they are inserted, they lay out acceptably (see the use of lastIndent). diff --git a/docs/FAQ/FAQ_How_do_I_add_a_builder_to_a_given_project.md b/docs/FAQ/FAQ_How_do_I_add_a_builder_to_a_given_project.md index 71dcb9ab301..8d0e2769f77 100644 --- a/docs/FAQ/FAQ_How_do_I_add_a_builder_to_a_given_project.md +++ b/docs/FAQ/FAQ_How_do_I_add_a_builder_to_a_given_project.md @@ -5,6 +5,7 @@ FAQ How do I add a builder to a given project? To register the eScript builder for a given project, add the builder to the project's build specification as follows: +```java private void addBuilder(IProject project, String id) { IProjectDescription desc = project.getDescription(); ICommand[] commands = desc.getBuildSpec(); @@ -21,17 +22,20 @@ To register the eScript builder for a given project, add the builder to the proj desc.setBuildSpec(nc); project.setDescription(desc, null); } +``` Alternatively, you could edit the project description directly on disk by modifying the .project file: +```xml - org.eclipse.escript.builder.Builder + org.eclipse.escript.builder.Builder +``` A builder is normally added to a project in the project creation wizard but can be added later on. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_add_actions_to_a_views_menu_and_toolbar.md b/docs/FAQ/FAQ_How_do_I_add_actions_to_a_views_menu_and_toolbar.md index f7a9b684466..b48eeccd2a7 100644 --- a/docs/FAQ/FAQ_How_do_I_add_actions_to_a_views_menu_and_toolbar.md +++ b/docs/FAQ/FAQ_How_do_I_add_actions_to_a_views_menu_and_toolbar.md @@ -9,16 +9,17 @@ Each view has a drop-down menu in two locations: This menu contains layout and view-manipulation actions. You don't have any control over this menu; its actions are all added by the platform. - + * _in the view's toolbar_. The drop-down menu on the right-hand side, a small downward-pointing triangle, is controlled by your view. This menu will exist only if you add actions to it. - + Actions are added to the menu and toolbar by using the IActionBars interface. This interface is used to access the standard JFace menu and toolbar manager objects used for creating menus throughout Eclipse. The following code, usually invoked from the view's createPartControl method, adds a single action to the view's menu and toolbar: +```java Action action = ...; IActionBars actionBars = getViewSite().getActionBars(); IMenuManager dropDownMenu = actionBars.getMenuManager(); @@ -26,8 +27,8 @@ Actions are added to the menu and toolbar by using the IActionBars interface. Th dropDownMenu.add(action); toolBar.add(action); actionBars.updateActionBars(); +``` - See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_add_actions_to_the_global_toolbar.md b/docs/FAQ/FAQ_How_do_I_add_actions_to_the_global_toolbar.md index 1f7cabec3d3..dcdaa3b7791 100644 --- a/docs/FAQ/FAQ_How_do_I_add_actions_to_the_global_toolbar.md +++ b/docs/FAQ/FAQ_How_do_I_add_actions_to_the_global_toolbar.md @@ -5,20 +5,21 @@ FAQ How do I add actions to the toolbar? Actions are added to the workbench window's toolbar by using the org.eclipse.ui.actionSets extension point. Here is a sample action element that contributes an action to the workbench window toolbar: +```xml +``` - The class attribute is the fully qualified name of the action that will be run when the toolbar button is clicked. This class must implement the interface IWorkbenchWindowActionDelegate. The toolbarPath attribute has two segments-the toolbar ID and the group ID-separated by a slash (/) character. The toolbar ID is used to indicate which toolbar the action belongs to. This value isn't currently used because the platform defines only one toolbar, but the convention is to use the string Normal to represent the default toolbar. The group ID is used to place similar actions together. All actions with the same group ID will be placed in a fixed group in the toolbar. The string in the tooltip attribute is shown when the user hovers over the toolbar button. - + You can specify many more attributes on your action, including criteria for when your action should be visible and when it should be enabled. However, the four attributes shown earlier are the minimum set you need for a toolbar action. Some of the other action attributes are discussed in other FAQs. - + See Also -------- diff --git a/docs/FAQ/FAQ_How_do_I_add_actions_to_the_main_menu.md b/docs/FAQ/FAQ_How_do_I_add_actions_to_the_main_menu.md index 5b3d82fe982..6f41b41a285 100644 --- a/docs/FAQ/FAQ_How_do_I_add_actions_to_the_main_menu.md +++ b/docs/FAQ/FAQ_How_do_I_add_actions_to_the_main_menu.md @@ -8,23 +8,25 @@ Overview As with menus and toolbar buttons, menu actions are added to the main menu by using the org.eclipse.ui.actionSets extension point. The FAQ Examples plug-in has many actions that are contributed to the menu in this way. Here is a sample action definition (a subelement of the actionSets element): +```xml +``` The class attribute specifies the fully qualified path of the Action class, which must implement IWorkbenchWindowActionDelegate. When the action is selected by the user, the action's run method will be invoked. - + The menubarPath attribute specifies the location of the action within the menus. This path is one of the greatest sources of confusion-and one of the biggest FAQs-for new users of action sets, so it is worth explaining it here in detail. The path has two parts, both of which are required. Everything up to the last slash character (/) represents the path of the menu that the action will belong to. For top-level menus, this is a simple string. The IWorkbenchActionConstants interface contains constants for the standard top-level menu names. For example, file is the path of the **File** menu, and window is the path of the **Window** menu. For menus defined in other plug-ins, consult the plugin.xml file to see the ID of their menus. When contributing to a submenu, the menu path will be a slash-delimited string containing the IDs of each menu in the hierarchy. The FAQ Examples plug-in defines a top-level menu with ID exampleMenu, and a submenu below this with ID exampleFile. The menubarPath of an action contributed to this submenu would therefore start with exampleMenu/exampleFile. - + The final part of the menubarPath attribute-after the last slash-is the group name. All menus are divided into groups as a means of organizing the actions within them. When contributing an action, you must specify the name of the group your action belongs to within that menu. Each action can belong to only one group in a single menu. Once again, the standard group names used in the top-level menus are defined in IWorkbenchActionConstants. Some examples of menubarPath attributes will help to illustrate how they are used. Here is the path for an action in the import/export group within the top-level **File** menu: @@ -41,7 +43,7 @@ Finally, an action contributed to the **Editor** submenu in the **FAQ Examples** Note that the group name is required even for menus that have only one group. - + Menu actions have many more optional attributes, including those for specifying the action's visibility and enablement. Consult the extension point documentation for complete details. Common Menupaths diff --git a/docs/FAQ/FAQ_How_do_I_add_activities_to_my_plug-in.md b/docs/FAQ/FAQ_How_do_I_add_activities_to_my_plug-in.md index 0ceed24014d..02331eed4c0 100644 --- a/docs/FAQ/FAQ_How_do_I_add_activities_to_my_plug-in.md +++ b/docs/FAQ/FAQ_How_do_I_add_activities_to_my_plug-in.md @@ -5,19 +5,22 @@ FAQ How do I add activities to my plug-in? You don't. An important feature of activities is that they are not defined in the plug-ins alongside the functionality they describe. Because activities are designed to solve a scaling problem when large numbers of plug-ins are used together, attempting to define them at the plug-in level would be futile. For example, let's say that you create a small handful of plug-ins that implement development tools for the PHP programming language. If you are providing only basic editing and debugging functionality, chances are that your plug-ins alone do not present a UI scalability problem. However, if someone then takes your small handful of plug-ins and combines them with 500 more plug-ins from other sources, the UI starts to become cluttered and difficult to use. If you introduced a couple of activities in your plug-in to separate different types of PHP development and if the other 500 plug-ins also introduced activities, the activities themselves would become cluttered and unusable. The moral of the story is that activities need to be defined at the level where the scalability problem exists. - + Typically activities will be defined by an administrator or product manager who is assembling an end-user application from a large pool of plug-ins. A power user who wants to coordinate a large set of plug-ins downloaded from the Web also may establish some activities. The administrator or power user defines activities entirely declaratively in a plugin.xml file in a plug-in. No Java code is involved! Let's dig into the actual mechanics of defining activities. Before you create any activities, you need to establish one or more activity _categories_. A category is simply a container for one or more activities. Here is a simple category defined in the FAQ Examples plug-in: +```xml +``` _Note:_ All configuration elements in this FAQ must be contained in an extension to the org.eclipse.ui.activities extension point. The ID and name of the extension itself are not used. - + Next, you need to define one or more activities and connect them to a category. +```xml @@ -26,6 +29,7 @@ Next, you need to define one or more activities and connect them to a category. activityId="org.eclipse.faq.faqActivity" categoryId="org.eclipse.faq.faqCategory"> +``` Note that activities, categories, and bindings are all separate top-level elements. This allows you to define each of them in different plug-ins if desired. @@ -35,22 +39,26 @@ When an activity is enabled, all functionality that matches the identifier patte This all sounds very confusing, so let's look at a concrete example from the FAQ Examples plug-in: +```xml +``` This pattern binding says, when faqActivity is disabled, hide all functionality associated with any plug-in whose ID starts with org.eclipse.faq. Let's try a slightly more complicated pattern: +```xml +``` This pattern is much more selective. It will disable functionality only in the org.eclipse.faq.examples plug-in whose ID ends with the string addingWizard. This will disable only the addingWizard extension from the org.eclipse.faq.examples plug-in. By selecting your patterns carefully, you can define precisely which parts of the UI are filtered by a given activity. - + To learn more about regular expressions in Java, see Jeffrey E. F. Friedl, _Mastering Regular Expressions_ (O'Reilly, 1997). diff --git a/docs/FAQ/FAQ_How_do_I_add_hover_support_to_my_text_editor.md b/docs/FAQ/FAQ_How_do_I_add_hover_support_to_my_text_editor.md index f909d255a8f..62ad8410734 100644 --- a/docs/FAQ/FAQ_How_do_I_add_hover_support_to_my_text_editor.md +++ b/docs/FAQ/FAQ_How_do_I_add_hover_support_to_my_text_editor.md @@ -19,24 +19,25 @@ If it's your own editor In [FAQ How do I write an editor for my own language?](./FAQ_How_do_I_write_an_editor_for_my_own_language.md "FAQ How do I write an editor for my own language?") we describe how text hover is enabled for our editor through our configuration class: - +```java class Configuration extends SourceViewerConfiguration { ... - public ITextHover getTextHover(ISourceViewer sv, + public ITextHover getTextHover(ISourceViewer sv, String contentType) { return '''new EScriptTextHover()'''; } ... } +``` Example of ITextHover implementation ------------------------------------ When the user moves the mouse over an area that corresponds to a given node in our AST, it is easy for us to provide a symbolic description of the node. Namely, the editor framework helps out by registering for the mouse events, setting timers, calling us at the right time, and drawing the box that will show the text hover. All that we need to do is match a certain location in the editor to a symbolic string.We do this by providing our own implementation of org.eclipse.jface.text.ITextHover as follows: - +```java public class EScriptTextHover implements ITextHover { public IRegion getHoverRegion(ITextViewer tv, int off) { return new Region(off, 0); @@ -48,17 +49,18 @@ When the user moves the mouse over an area that corresponds to a given node in o return em.getElementAt(r.getOffset()). getHoverHelp(); } - catch (Exception e) { - return ""; + catch (Exception e) { + return ""; } } } +``` The first method we implement is meant for optimizing the drawing of the text hover. We answer the question, If I am going to show a hover for character x in the text viewer, for what region should the hover be the same? We don't try to be too smart here. We simply return an empty region. The next method implements the real logic of the text hover. We convert the current cursor location to an AST element in the document and ask it to return a string relevant to the current context. Note that we assume that the EscriptModel implements a cache and that the getModel method is inexpensive as we will call it many times during editing. - + See Also -------- diff --git a/docs/FAQ/FAQ_How_do_I_add_label_decorations_to_my_viewer.md b/docs/FAQ/FAQ_How_do_I_add_label_decorations_to_my_viewer.md index df5a4449036..e9ccd1f65ea 100644 --- a/docs/FAQ/FAQ_How_do_I_add_label_decorations_to_my_viewer.md +++ b/docs/FAQ/FAQ_How_do_I_add_label_decorations_to_my_viewer.md @@ -5,9 +5,11 @@ FAQ How do I add label decorations to my viewer? Suppose that your viewer contains model elements for which other plug-ins have defined label decorators. To make those decorations appear in your viewer, you need to install a decorating label provider. Assuming that you have already written your own basic label provider, simply do the following to add declarative decorations from other plug-ins: +```java ILabelProvider lp = ... // your basic label provider implementing ILabelProvider ILabelDecorator decorator = PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator(); viewer.setLabelProvider(new DecoratingLabelProvider(lp, decorator)); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_add_menus_to_the_main_menu.md b/docs/FAQ/FAQ_How_do_I_add_menus_to_the_main_menu.md index d6e1c9aa3a4..856d518d6f8 100644 --- a/docs/FAQ/FAQ_How_do_I_add_menus_to_the_main_menu.md +++ b/docs/FAQ/FAQ_How_do_I_add_menus_to_the_main_menu.md @@ -5,11 +5,13 @@ FAQ How do I add menus to the main menu? Menus and submenus are added to the main menu by using the org.eclipse.ui.actionSets extension point. Here is an example of a top-level menu defined by the FAQ Examples plug-in: +```xml +``` Each menu contains one or more separator elements that define _groups_ within that menu. The menu ID, along with the separator name, is used by actions contributing to that menu. If you want to create a submenu, you also need to define a path attribute that specifies what menu and group your menu should appear under. This path attribute has the same syntax as the menubarPath attribute on action definitions. To add a submenu to the menu defined earlier, you would add the following attribute: @@ -21,7 +23,7 @@ To add a submenu to the **File** menu after the **New** submenu, the path would The syntax of menu paths is described in more detail in FAQ 223. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_add_my_own_external_tools.md b/docs/FAQ/FAQ_How_do_I_add_my_own_external_tools.md index 539fea5b3b0..cb16150eab0 100644 --- a/docs/FAQ/FAQ_How_do_I_add_my_own_external_tools.md +++ b/docs/FAQ/FAQ_How_do_I_add_my_own_external_tools.md @@ -3,12 +3,13 @@ FAQ How do I add my own external tools? ======================================= - + External tools are applications or scripts that typically act as extensions to your development environment. For example, they may be used to execute scripts to package and deploy your application or to run an external compiler on your source files. External tools allow an end user to achieve a basic level of integration for a non-Eclipse-aware tool without writing a plug-in. External tools are created and configured via **Run > External Tools > External Tools** or from the drop-down menu on the **Run** button with the toolbox overlay. If you want to write your own category of external tool, such as support for a different scripting language, you need to write a plug-in. The process for defining external tools is almost identical to writing your own launch configuration. Essentially, an external tool is a launch-configuration type that belongs to the special external-tools category: +```xml +``` - See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_add_my_wizard_to_the_New_Import_or_Export_menu_categories.md b/docs/FAQ/FAQ_How_do_I_add_my_wizard_to_the_New_Import_or_Export_menu_categories.md index dee1bed508d..391dbd6bb0e 100644 --- a/docs/FAQ/FAQ_How_do_I_add_my_wizard_to_the_New_Import_or_Export_menu_categories.md +++ b/docs/FAQ/FAQ_How_do_I_add_my_wizard_to_the_New_Import_or_Export_menu_categories.md @@ -5,6 +5,7 @@ FAQ How do I add my wizard to the New, Import, or Export menu categories? Some special kinds of wizards have to be registered with the platform in your plugin.xml file. These wizards are found under the **File > New**, **File > Import**, and **File > Export** menu actions. These wizards are declared using the org.eclipse.ui newWizards, importWizards, and exportWizards extension points, respectively. Once you have declared your wizard with the appropriate extension point, the platform will take care of displaying it in the appropriate places. Following is an example declaration of a new wizard: +```xml +``` This wizard will appear by default under **File > New > Other...**. To make the wizard appear under the new-project category, add the attribute project="true" to the extension declaration. To add your own wizard category, use - - - - + - parentCategory="org.eclipse.faq.examples.MyWizard" - + parentCategory="org.eclipse.faq.examples.MyWizard" + +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_ask_a_simple_yes_or_no_question.md b/docs/FAQ/FAQ_How_do_I_ask_a_simple_yes_or_no_question.md index e2cc959862d..ec329a23ede 100644 --- a/docs/FAQ/FAQ_How_do_I_ask_a_simple_yes_or_no_question.md +++ b/docs/FAQ/FAQ_How_do_I_ask_a_simple_yes_or_no_question.md @@ -5,17 +5,19 @@ FAQ How do I ask a simple yes or no question? The MessageDialog class provides a couple of convenience methods for asking questions with Boolean answers. The openQuestion method will present a dialog with Yes and No buttons and will return the result. The openConfirm method is similar but uses Ok and Cancel as the button labels. If you want to use different button labels or have more buttons, such as Yes/No/Always/Never, you can construct a customized dialog yourself: +```java MessageDialog dialog = new MessageDialog( null, "Title", null, "Question", MessageDialog.QUESTION, new String[] {"Yes", "No", "Always", "Never"}, 0);, // yes is the default int result = dialog.open(); +``` The return value from the open method will be the index of the button in the label array. If the user cancels or closes the dialog, a result of one is returned by convention. This means that you should try to make your second button match the behavior that makes sense for your circumstances. If you want completely different behavior for dialog cancellation, you will need to subclass MessageDialog and override the cancelPressed method. - - + + The MessageDialogWithToggle class-introduced in Eclipse 3.0-is an extension of MessageDialog that adds the capability of remembering the user's selection to avoid having to prompt them again. This can be used for introductory warning messages that advanced users want to be able to turn off. MessageDialogWithToggle has similar static convenience methods as MessageDialog for common questions, but you can use the constructor to provide a customized set of buttons if necessary. diff --git a/docs/FAQ/FAQ_How_do_I_associate_an_action_with_a_command.md b/docs/FAQ/FAQ_How_do_I_associate_an_action_with_a_command.md index 2ecc4ed50b2..66f0cbfaedf 100644 --- a/docs/FAQ/FAQ_How_do_I_associate_an_action_with_a_command.md +++ b/docs/FAQ/FAQ_How_do_I_associate_an_action_with_a_command.md @@ -5,6 +5,7 @@ FAQ How do I associate an action with a command? Actions are associated with commands in various ways depending on how the actions are defined. For actions contributed via the actionSets extension point, the association with a command is done directly in the action definition. The definitionId attribute of the action element must match the ID of the command it is associated with: +```xml +``` For actions created programmatically, associating the action with a command is a two-step process. As with declarative actions, the first step is to set the action's definition ID to match the ID of the command. The command must still be defined declaratively, using the command extension point. The definition ID is set by calling Action.setDefinitionId. The second step is to register the action with the platform, using the key-binding service. This service can be accessed from the IWorkbenchPartSite, which is accessible to both views and editors. Here is an example of these steps for an action in a view: +```java action.setActionDefinitionId("some.unique.id"); view.getSite().getKeyBindingService().registerAction(action); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_build_menus_and_toolbars_programmatically.md b/docs/FAQ/FAQ_How_do_I_build_menus_and_toolbars_programmatically.md index b8255c56eb8..a1564d66adb 100644 --- a/docs/FAQ/FAQ_How_do_I_build_menus_and_toolbars_programmatically.md +++ b/docs/FAQ/FAQ_How_do_I_build_menus_and_toolbars_programmatically.md @@ -7,6 +7,7 @@ Menus and toolbars in JFace are based on two key interfaces: IContributionItem a So, for each toolbar or menu, you need to create a contribution manager. For menus, including drop-down menus, context menus, and submenus, create an instance of MenuManager. For toolbars or cool bars, create an instance of ToolBarManager or CoolBarManager, respectively. The following snippet creates a top-level menu and a submenu, each with one action: +```java IMenuManager mainMenu = ...;//get ref to main menu manager MenuManager menu1 = new MenuManager("Menu &1", "1"); menu1.add(new Action("Action 1") {}); @@ -14,6 +15,7 @@ So, for each toolbar or menu, you need to create a contribution manager. For men MenuManager menu2 = new MenuManager("Menu &2", "2"); menu2.add(new Action("Action 2") {}); menu1.add(menu2); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_change_the_selection_on_a_double-click_in_my_editor.md b/docs/FAQ/FAQ_How_do_I_change_the_selection_on_a_double-click_in_my_editor.md index 23d27fc0bd9..4d11b023b8f 100644 --- a/docs/FAQ/FAQ_How_do_I_change_the_selection_on_a_double-click_in_my_editor.md +++ b/docs/FAQ/FAQ_How_do_I_change_the_selection_on_a_double-click_in_my_editor.md @@ -5,9 +5,10 @@ FAQ How do I change the selection on a double-click in my editor? By default, double-clicking in a text editor will cause the complete word under the mouse to be selected. When creating your own text-based editor, you can change this behavior from your SourceConfiguration by overriding the method getDoubleClickStrategy. The method must return an instance of ITextDoubleClickStrategy, a simple interface that gets called whenever the user double-clicks within the editor area. - + When double-clicking in a text-based editor, the selection will typically change to incorporate the nearest enclosing syntactic unit. For example, clicking next to a brace in the Java editor will expand the selection to include everything in the matched set of braces. Double-clicking in the sample HTML editor will cause the word under the mouse to be selected or, if no word is under the mouse, the entire HTML element. This involves scanning the document forwards and backwards from the current cursor position and then setting the selection accordingly. The following example is a bit contrived and is English-specific, but it illustrates the usual steps by selecting the text range up to the next vowel. If no vowel is found, nothing is selected: +```java public void doubleClicked(ITextViewer part) { final int offset = part.getSelectedRange().x; int length = 0; @@ -21,7 +22,7 @@ When double-clicking in a text-based editor, the selection will typically change } part.setSelectedRange(offset, length); } +``` - Of course, double-clicking doesn't have to change the selection. You can perform any manipulation you want on the editor or its document from within a double-click strategy implementation. For example, double-clicking could trigger Content Assist or present possible refactorings. The only real restriction is that you can't use double-click to perform a manipulation on an existing text selection as the first click of the double-click will have eliminated any previous selection. diff --git a/docs/FAQ/FAQ_How_do_I_contribute_help_contexts.md b/docs/FAQ/FAQ_How_do_I_contribute_help_contexts.md index 2fae69caa0d..f8924d8ba66 100644 --- a/docs/FAQ/FAQ_How_do_I_contribute_help_contexts.md +++ b/docs/FAQ/FAQ_How_do_I_contribute_help_contexts.md @@ -3,16 +3,18 @@ FAQ How do I contribute help contexts? ====================================== - + Help contexts are added by using the org.eclipse.help.contexts extension point. Contexts are usually specified by using a separate help plug-in, making it easier to switch help content for various languages. The context extension specifies the path of a separate XML file where the data is stored: +```xml +``` The contexts file includes a description for each context and can, optionally, add links to HTML help content files in the plug-in. See the help documentation for more details on the format of help context files. diff --git a/docs/FAQ/FAQ_How_do_I_create_Java_elements.md b/docs/FAQ/FAQ_How_do_I_create_Java_elements.md index c56fa236c97..82d788bf4ac 100644 --- a/docs/FAQ/FAQ_How_do_I_create_Java_elements.md +++ b/docs/FAQ/FAQ_How_do_I_create_Java_elements.md @@ -3,31 +3,33 @@ FAQ How do I create Java elements? ================================== - + The Java model is made up of IJavaElement objects. Java elements represent all levels of a Java project, from the project itself all the way down to the types, methods, and fields. The Java model can be seen as a logical view of the underlying IWorkspace resource model. - + An important characteristic of IJavaElements is that they are _handle objects_. This means that simply obtaining a Java element instance does not imply that the Java element exists. You can create IJavaElement handles for Java projects, packages, and compilation units that do not exist in your workspace. Conversely, IJavaElement instances do not always exist for all portions of the Java projects that do exist. IJavaElement handles are created lazily as they are requested by various clients. If multiple clients request handles on the same Java element, they will get equal, but not necessarily identical, handle objects. - + The implication here is that creating a Java element has two meanings. You can create IJavaElement handles by asking the parent element for one. For example, IType.getMethod will return an IMethod handle but will not create that method in the file on disk. The JavaCore class also provides factory methods for creating Java elements for a given file, folder, or project in the workspace. For example, the following will create an ICompilationUnit handle for a given file handle: +```java IFile file = ...;//a file handle - ICompilationUnit unit = + ICompilationUnit unit = JavaCore.createCompilationUnitFrom(file); +``` - To create the contents on disk, you need to use the various create methods on the handle objects. For example, IType.createMethod will create a Java method on disk. Because creation will fail if such a method already exists, you should first use a method handle to find out whether the method already exists: +```java IType type = ...; String body = "public String toString() {"+ "return super.toString();}"; IMethod method = type.'''getMethod'''("toString", new String\[0\]); if (!method.exists()) method = type.createMethod(body, null, false, null); +``` - See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_create_a_Compare_dialog.md b/docs/FAQ/FAQ_How_do_I_create_a_Compare_dialog.md index 35390c5368f..c869651b345 100644 --- a/docs/FAQ/FAQ_How_do_I_create_a_Compare_dialog.md +++ b/docs/FAQ/FAQ_How_do_I_create_a_Compare_dialog.md @@ -3,14 +3,15 @@ FAQ How do I create a Compare dialog? ===================================== - - + + The Eclipse SDK includes actions for comparing and replacing files in the workspace with one another and with editions in the local history. The same mechanisms can be used for comparing any kind of text content, regardless of its source. EditionSelectionDialog is used to ask the user to select from an array of input elements. The inputs must implement several interfaces. First, they must implement ITypedElement to provide the name, image, and content type of the object to be compared. Second, they must implement IModificationDate to provide a timestamp of the object's creation or modification date. The timestamp is used to sort the input elements chronologically. Finally, they must implement IStreamContentAccessor to supply the content to be compared. Here is an example of a class that implements all these interfaces for string-based content: +```java class CompareItem implements IStreamContentAccessor, ITypedElement, IModificationDate { private String contents, name; @@ -29,9 +30,10 @@ to supply the content to be compared. Here is an example of a class that impleme public String getString() {return contents;} public String getType() {return ITypedElement.TEXT_TYPE;} } +``` The most interesting method here is the getType method, which should return the file extension of the input element. The file extension is used to determine the viewer for displaying the contents of the object. - + The method EditionSelectionDialog.selectEdition accepts an array of objects that implement all the interfaces mentioned earlier. It will open a dialog, allow the user to select one of the available editions, and return the chosen result. The EditionSelectionDialog instance is initialized in a somewhat unorthodox manner by requiring a ResourceBundle object in the constructor. This bundle must supply all the text messages that appear in the dialog, in addition to such parameters as the dialog's default width and height. See the EditionSelectionDialog constructor comment for more details. In the FAQ Examples plug-in, see the CompareStringsAction example for a complete illustration of how this dialog is used. diff --git a/docs/FAQ/FAQ_How_do_I_create_a_Java_project.md b/docs/FAQ/FAQ_How_do_I_create_a_Java_project.md index eaac3ef74c9..b0075f63600 100644 --- a/docs/FAQ/FAQ_How_do_I_create_a_Java_project.md +++ b/docs/FAQ/FAQ_How_do_I_create_a_Java_project.md @@ -5,33 +5,41 @@ FAQ How do I create a Java project? Several steps are required to create and properly initialize a Java project. Start by creating and opening an IProject: +```java String name = "MyProject"; IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceRoot root= workspace.getRoot(); IProject project= root.getProject(name); project.create(null); project.open(null); +``` Next, you need to add the Java nature to the project. This in turn will cause the Java builder to be added to the project: +```java IProjectDescription desc = project.getDescription(); desc.setNatureIds(new String[] { JavaCore.NATURE_ID}); project.setDescription(desc); +``` Next, you must set the Java builder's output folder, typically called bin. This is where the Java builder will place all compiled *.class files: +```java IJavaProject javaProj = JavaCore.create(project); IFolder binDir = project.getFolder("bin"); IPath binPath = binDir.getFullPath(); javaProj.setOutputLocation(binPath, null); +``` Finally, you need to set the project's classpath, also known as the build path. You will need to minimally create a classpath entry that points to the Java runtime library, rt.jar, and additional entries for any other libraries and projects that the project requires: +```java String path = "c:\\jre\\lib\\rt.jar"; IClasspathEntry cpe= JavaCore.newLibraryEntry( path, null, null); javaProj.setRawClasspath(new IClasspathEntry[] {cpe}); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_create_a_Rich_Client_application.md b/docs/FAQ/FAQ_How_do_I_create_a_Rich_Client_application.md index 385d23643fc..1d2047b7d08 100644 --- a/docs/FAQ/FAQ_How_do_I_create_a_Rich_Client_application.md +++ b/docs/FAQ/FAQ_How_do_I_create_a_Rich_Client_application.md @@ -1,7 +1,7 @@ FAQ: How do I create a Rich Client Application? =============================================== -An Eclipse RCP application in Eclipse 4 (e4) leverages the application model for defining the user interface and behavior. +An Eclipse RCP application in Eclipse 4 (e4) leverages the application model for defining the user interface and behavior. Unlike Eclipse 3.x, where WorkbenchAdvisor played a central role, Eclipse 4 RCP applications are more declarative, using application models and dependency injection. ## Step 1: Set Up Your Project @@ -21,16 +21,18 @@ In Eclipse 4, you implement your application's business logic in classes annotat Example of an Eclipse 4 RCP Application Entry Point for a handler called via a menu. +```java import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.swt.widgets.Shell; public class Application { - + @Execute public void run(Shell shell) { // Your application logic here } } +``` The @Execute annotation marks the method to be run once the menu entry connnected with this handler is called. @@ -38,6 +40,7 @@ The @Execute annotation marks the method to be run once the menu entry connnecte Unlike Eclipse 3.x, most of the configuration in Eclipse 4 is done through the application model (Application.e4xmi). However, you still need to define your application's ID and point to the application model in your plugin.xml: +```xml @@ -50,11 +53,12 @@ Unlike Eclipse 3.x, most of the configuration in Eclipse 4 is done through the a +``` Make sure to replace "path/to/your/Application.e4xmi" with the actual path to your application model file. ## Conclusion -Eclipse 4 RCP development focuses on the application model and dependency injection, providing a more flexible and modular approach to building rich client applications compared to the traditional Eclipse 3.x RCP. The rest of your RCP application development involves creating and populating perspectives, views, and other UI components using the Eclipse 4 application model. +Eclipse 4 RCP development focuses on the application model and dependency injection, providing a more flexible and modular approach to building rich client applications compared to the traditional Eclipse 3.x RCP. The rest of your RCP application development involves creating and populating perspectives, views, and other UI components using the Eclipse 4 application model. See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_create_a_compare_editor.md b/docs/FAQ/FAQ_How_do_I_create_a_compare_editor.md index 9d91b7b193a..1f2fc961c9c 100644 --- a/docs/FAQ/FAQ_How_do_I_create_a_compare_editor.md +++ b/docs/FAQ/FAQ_How_do_I_create_a_compare_editor.md @@ -3,43 +3,46 @@ FAQ How do I create a compare editor? ===================================== - - + + Compare dialogs are typically used in simple contexts that ask the user to select from a list of available editions. For richer comparisons, a compare editor is typically used. The advantage of using an editor is that the user can take as long as needed to browse, modify, and merge the contents. - + Compare editors display a tree of DiffNode elements, where each node represents a logical entity, such as a file or programming-language element. These nodes represent either a two-way or a three-way comparison, where the optional third element is the common ancestor of the two elements being compared. Each DiffNode references a left- and right-side element and, possibly, a third element representing the common ancestor. As with compare dialogs, these compare elements should implement ITypedElement and IStreamContentAccessor. You can construct these node trees manually or use the supplied Differencer class to help you construct it. - + The DiffNode tree is computed by a CompareEditorInput subclass that is passed as an input to the editor. The subclass must implement the prepareInput method to return the tree represented by the DiffNode. The following example illustrates a compare editor input that uses the CompareItem class described in [FAQ\_How\_do\_I\_create\_a\_Compare_dialog?](./FAQ_How_do_I_create_a_Compare_dialog.md "FAQ How do I create a Compare dialog?") +```java class CompareInput extends CompareEditorInput { public CompareInput() { super(new CompareConfiguration()); } protected Object prepareInput(IProgressMonitor pm) { - CompareItem ancestor = + CompareItem ancestor = new CompareItem("Common", "contents"); - CompareItem left = + CompareItem left = new CompareItem("Left", "new contents"); - CompareItem right = + CompareItem right = new CompareItem("Right", "old contents"); - return new DiffNode(null, Differencer.CONFLICTING, + return new DiffNode(null, Differencer.CONFLICTING, ancestor, left, right); } } +``` Once you have a compare editor input, opening a compare editor on that input is trivial. Here is an example action that opens a compare editor, using the preceding input: - public class CompareEditorAction implements +```java + public class CompareEditorAction implements IWorkbenchWindowActionDelegate { public void run(IAction action) { CompareUI.openCompareEditor(new CompareInput()); } } +``` - If you want to support merging as well as comparing, two extra steps are involved. First, you need to specify which of the elements is editable. This is done by the CompareConfiguration object that is passed to the CompareEditorInput constructor. Use the setLeftEditable and setRightEditable methods to specify which of the comparison panes should support modification. Second, your editor input class should override the save method to perform the save of the editor contents. diff --git a/docs/FAQ/FAQ_How_do_I_create_a_dialog_with_a_details_area.md b/docs/FAQ/FAQ_How_do_I_create_a_dialog_with_a_details_area.md index 5dc07d054f6..ef2ba0d82ac 100644 --- a/docs/FAQ/FAQ_How_do_I_create_a_dialog_with_a_details_area.md +++ b/docs/FAQ/FAQ_How_do_I_create_a_dialog_with_a_details_area.md @@ -5,10 +5,11 @@ FAQ How do I create a dialog with a details area? Many dialogs in Eclipse have a **Details** button that shows or hides an extra area with more information. This functionality is provided by the JFace ErrorDialog. The naming of this class is a bit unfortunate as it doesn't fully express all the things it can be used for. A better name might have been StatusDialog as it is used to display any IStatus object, which can represent information, warnings, or errors. The dialog looks at the severity of the supplied status and uses an appropriate icon: an exclamation mark for errors, a yield sign for warnings, and an _i_ character for information. - + If you want to provide more information in the details area, you need to supply a MultiStatus object. The dialog will obtain the message string from the MultiStatus parent, and one line in the details area will be for the message from each child status. The following example uses an error dialog to display some information-the date-with more details provided in the details area: +```java Date date = new Date(); SimpleDateFormat format = new SimpleDateFormat(); String[] patterns = new String[] { @@ -26,10 +27,10 @@ If you want to provide more information in the details area, you need to supply info.add(new Status(IStatus.INFO, PID, 1, msg[2], null)); info.add(new Status(IStatus.INFO, PID, 1, msg[3], null)); ErrorDialog.openError(window.getShell(), "Time", null, info); +``` + - - See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_create_a_form-based_editor_such_as_the_plug-in_Manifest_Editor.md b/docs/FAQ/FAQ_How_do_I_create_a_form-based_editor_such_as_the_plug-in_Manifest_Editor.md index bb4a3751758..d94b7104700 100644 --- a/docs/FAQ/FAQ_How_do_I_create_a_form-based_editor_such_as_the_plug-in_Manifest_Editor.md +++ b/docs/FAQ/FAQ_How_do_I_create_a_form-based_editor_such_as_the_plug-in_Manifest_Editor.md @@ -5,5 +5,5 @@ FAQ How do I create a form-based editor, such as the plug-in Manifest Editor? The org.eclipse.ui.forms plug-in provides a framework for building form-based editors. The components in this plug-in have long been the framework for building the PDE and Install/Update editors and views but have been made into official API only in the Eclipse 3.0 release. -To give you a quick overview, a form-based editor is created by subclassing the abstract FormEditor class. This class allows you to add any number of tabbed pages, which can be either traditional editor components or form-based pages (IFormPage). Each form page creates the displays for a single IForm, and each form may contain multiple FormParts representing each section in the form. There are various flavors of IForm subtypes, depending on whether you want multiple sections, scrolling, or different layout styles. An example of a form-based editor is the PDE plug-in Manifest Editor, implemented by the ManifestEditor class in the org.eclipse.pde.ui plug-in. +To give you a quick overview, a form-based editor is created by subclassing the abstract FormEditor class. This class allows you to add any number of tabbed pages, which can be either traditional editor components or form-based pages (`IFormPage`). Each form page creates the displays for a single IForm, and each form may contain multiple FormParts representing each section in the form. There are various flavors of IForm subtypes, depending on whether you want multiple sections, scrolling, or different layout styles. An example of a form-based editor is the PDE plug-in Manifest Editor, implemented by the ManifestEditor class in the org.eclipse.pde.ui plug-in. diff --git a/docs/FAQ/FAQ_How_do_I_create_a_repeating_background_task.md b/docs/FAQ/FAQ_How_do_I_create_a_repeating_background_task.md index b9087c622e1..dc4b159c09c 100644 --- a/docs/FAQ/FAQ_How_do_I_create_a_repeating_background_task.md +++ b/docs/FAQ/FAQ_How_do_I_create_a_repeating_background_task.md @@ -5,6 +5,7 @@ FAQ How do I create a repeating background task? It is common to have background work that repeats after a certain interval. For example, an optional background job refreshes the workspace with repository contents. The workspace itself saves a snapshot of its state on disk every few minutes, using a background job. Setting up a repeating job is not much more difficult than setting up a simple job. The following job reschedules itself to run once every minute: +```java public class RepeatingJob extends Job { private boolean running = true; public RepeatingJob() { @@ -29,21 +30,21 @@ It is common to have background work that repeats after a certain interval. For */ - RepeatingJob job = new RepeatingJob("BackupScheduler"+jobNumber++,nextDelay) { - protected IStatus run(IProgressMonitor monitor){ + RepeatingJob job = new RepeatingJob("BackupScheduler"+jobNumber++,nextDelay) { + protected IStatus run(IProgressMonitor monitor){ schedule(repeatDelay-cpuTimeTakenbyJob); return org.eclipse.core.runtime.Status.OK_STATUS; } }; - job.schedule(delay); // start after 20 seconds + job.schedule(delay); // start after 20 seconds return job; } public abstract class RepeatingJob extends Job{ private boolean running = true; - protected long repeatDelay = 0; - public RepeatingJob(String jobName,long repeatPeriod){ + protected long repeatDelay = 0; + public RepeatingJob(String jobName,long repeatPeriod){ super(jobName); repeatDelay = repeatPeriod; }/** @@ -51,7 +52,7 @@ It is common to have background work that repeats after a certain interval. For schedule(repeatDelay); return Status.OK_STATUS; } - */ + */ public boolean shouldSchedule() { return running; } @@ -59,7 +60,7 @@ It is common to have background work that repeats after a certain interval. For running = false; } } +``` - The same schedule method that is used to get the job running in the first place is also used to reschedule the job while it is running. Calling schedule while a job is running will flag the job to be scheduled again as soon as the run method exits. It does not mean that the same job instance can be running in two threads at the same time, as the job is added back to the waiting queue only after it finishes running. Repeating jobs always need some rescheduling condition to prevent them from running forever. In this example, a simple flag is used to check if the job needs to be rescheduled. Before adding a job to the waiting queue, the framework calls the shouldSchedule method on the job. This allows a job to indicate whether it should be added to the waiting job queue. If the call to shouldSchedule returns false, the job is discarded. This makes it a convenient place for determining whether a repeating job should continue. diff --git a/docs/FAQ/FAQ_How_do_I_create_an_Outline_view_for_my_own_language_editor.md b/docs/FAQ/FAQ_How_do_I_create_an_Outline_view_for_my_own_language_editor.md index 6ea8b7a37ea..6d623bc0929 100644 --- a/docs/FAQ/FAQ_How_do_I_create_an_Outline_view_for_my_own_language_editor.md +++ b/docs/FAQ/FAQ_How_do_I_create_an_Outline_view_for_my_own_language_editor.md @@ -5,6 +5,7 @@ The Outline view is not generated by the editor framework. In fact, this view is In plugin.xml, define an adapter for your editor to content outline page: +```xml +``` - and the Java code - +```java public class CoolLanguageEditorToOutlineAdapterFactory implements IAdapterFactory { @Override public Object getAdapter(Object adaptableObject, Class required) { @@ -31,12 +32,12 @@ and the Java code return new Class[] { IContentOutlinePage.class }; } } +``` - Most programming languages are inherently hierarchical. Therefore, to show the content outline of a certain program file, most editors deploy a tree. If you think that a tree is the most appropriate way to show the outline of your programs, you should consider subclassing from class ContentOutlinePage in the org.eclipse.ui.views.contentoutline package. This class already sets you up with a TreeViewer, and all you need to provide are a content provider, a label provider, and the input: - +```java public void createControl(Composite parent) { super.createControl(parent); TreeViewer viewer= getTreeViewer(); @@ -45,20 +46,22 @@ Most programming languages are inherently hierarchical. Therefore, to show the c viewer.addSelectionChangedListener(this); viewer.setInput(myInput); } +``` You will want to update the selection in your Outline view when the cursor is moved in the editor. Similarly, if the structure of the program changed-code added or removed-the outline has to be updated. This is typically performed with a JFace text model reconciler. When the user selects a node in the Outline view, the editor should change selection to the selected element and make it visible. - + When [Bug 507205](https://bugs.eclipse.org/bugs/show_bug.cgi?id=507205) is fixed, a recommended way would be to rely on the Common Navigator Framework in order to implement Tree-based navigation outline pages. For the moment, you can already write your own outline view consuming the CommonViewer class. - +```java public void createControl(Composite parent) { CommonViewer viewer = new CommonViewer(ID, parent, SWT.V_SCROLL | SWT.H_SCROLL); viewer.setInput(myInput); } +``` With ID being the name of the common navigator defined in org.eclipse.ui.navigator.viewer extension. Then the outline should receive most features as expected by the common navigator framework. This approach allows a better refactoring as multiple viewers can very easily share some common parts. diff --git a/docs/FAQ/FAQ_How_do_I_create_an_application.md b/docs/FAQ/FAQ_How_do_I_create_an_application.md index 81609d0a7bc..2f0c4b7ddfa 100644 --- a/docs/FAQ/FAQ_How_do_I_create_an_application.md +++ b/docs/FAQ/FAQ_How_do_I_create_an_application.md @@ -5,21 +5,24 @@ FAQ How do I create an application? To create an application, you need a plug-in that adds an extension to the org.eclipse.core.runtime.applications extension point. An example application definition from a plugin.xml file is as follows: +```xml +``` - The class attribute of the run element must specify a class that implements org.eclipse.core.boot.IPlatformRunnable. Here is the source of a trivial application: +```java public class HelloWorld implements IPlatformRunnable { public Object run(Object args) throws Exception { System.out.println("Hello from Eclipse application"); return EXIT_OK; } } +``` To run the application, you need to specify the fully qualified ID of your application extension definition, using the application command-line argument when launching Eclipse: diff --git a/docs/FAQ/FAQ_How_do_I_create_an_executable_JAR_file_for_a_stand-alone_SWT_program.md b/docs/FAQ/FAQ_How_do_I_create_an_executable_JAR_file_for_a_stand-alone_SWT_program.md index 7b6754e8971..b74c4325672 100644 --- a/docs/FAQ/FAQ_How_do_I_create_an_executable_JAR_file_for_a_stand-alone_SWT_program.md +++ b/docs/FAQ/FAQ_How_do_I_create_an_executable_JAR_file_for_a_stand-alone_SWT_program.md @@ -10,12 +10,12 @@ The detailed instructions for creating an executable JAR file for a stand-alone 1. Create a runtime folder for the desired runtime target on your system (e.g., c:\\swt\\runtime-linux). Note that the target platform does not need to be the same as your development platform. 2. Find the correct SWT JAR file for the desired target platform. You can download the desired ZIP file from [the SWT website](https://www.eclipse.org/swt/). For example, for Eclipse 3.3 and a target platform of Linux, download the file swt-3.3.1.1-gtk-linux-x86.zip. Expand this ZIP file and copy the swt.jar file to the runtime folder. Remember that this swt.jar file is specific to one platform, in this case Linux. 3. Create a manifest file for your application using the Eclipse text editor (e.g., myapplication-manifest.txt). The text of the manifest should be as follows: - + Manifest-Version: 1.0 - Class-Path: swt.jar + Class-Path: swt.jar Main-Class: mypackage.MyClassWithMainMethod (blank line at end of file) - + 4. Make sure the manifest file ends with a blank line. Put the name of your package and class that contains the main() method for the Main-Class. 5. In Eclipse, select File/Export/Java/Jar file and press Next. 6. On the JAR File Specification dialog, select the source files for the classes you want in the application. In the export destination, browse to the runtime folder and enter in the desired name of the JAR file (e.g., myapplication.jar or myapplication_linux.jar). Press Next. diff --git a/docs/FAQ/FAQ_How_do_I_create_an_external_tool_builder.md b/docs/FAQ/FAQ_How_do_I_create_an_external_tool_builder.md index b3e32cfa75e..b3206900ce3 100644 --- a/docs/FAQ/FAQ_How_do_I_create_an_external_tool_builder.md +++ b/docs/FAQ/FAQ_How_do_I_create_an_external_tool_builder.md @@ -7,6 +7,7 @@ An external tool builder is an external tool that runs every time the projects i As with ordinary external tools, you can define your own type of external tool builder by creating a new launch configuration type. In your launch configuration declaration, you must specify the category for external tool builder launch configurations: +```xml +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_create_an_image_registry_for_my_plug-in.md b/docs/FAQ/FAQ_How_do_I_create_an_image_registry_for_my_plug-in.md index cd0e23caa2d..768cefbb325 100644 --- a/docs/FAQ/FAQ_How_do_I_create_an_image_registry_for_my_plug-in.md +++ b/docs/FAQ/FAQ_How_do_I_create_an_image_registry_for_my_plug-in.md @@ -5,6 +5,7 @@ FAQ How do I create an image registry for my plug-in? If you're writing a plug-in with UI components, it should be a subclass of AbstractUIPlugin. This superclass already provides you with an empty image registry accessible by calling getImageRegistry. When the registry is first accessed, the hook method initializeImageRegistry will be called. You should override this method to populate your image registry with the image descriptors you need. You don't have to use this registry if you don't need it, and because it is created lazily on first access, there is no performance overhead if you never use it. Here is an example of a plug-in that adds a sample.gif image to its image registry: +```java public class ExamplesPlugin extends AbstractUIPlugin { public static final String PLUGIN_ID = "org.eclipse.faq.examples"; public static final String IMAGE_ID = "sample.image"; @@ -17,17 +18,17 @@ If you're writing a plug-in with UI components, it should be a subclass of Abstr registry.put(IMAGE_ID, desc); } } +``` - ### Comments: This FAQ seems misleading given the API comment on AbstractUIPlugin.getImageRegistry(): -The image registry contains the images used by this plug-in that are very -frequently used and so need to be globally shared within the plug-in. Since -many OSs have a severe limit on the number of images that can be in memory at -any given time, a plug-in should only keep a small number of images in their +The image registry contains the images used by this plug-in that are very +frequently used and so need to be globally shared within the plug-in. Since +many OSs have a severe limit on the number of images that can be in memory at +any given time, a plug-in should only keep a small number of images in their registry. See Also: diff --git a/docs/FAQ/FAQ_How_do_I_create_and_examine_an_AST.md b/docs/FAQ/FAQ_How_do_I_create_and_examine_an_AST.md index ddb133ed27a..39728278d4d 100644 --- a/docs/FAQ/FAQ_How_do_I_create_and_examine_an_AST.md +++ b/docs/FAQ/FAQ_How_do_I_create_and_examine_an_AST.md @@ -2,13 +2,14 @@ FAQ How do I create and examine an AST? ======================================= - + An AST is created by using an instance of ASTParser, created using the newParser factory method. You will typically create an AST for a compilation unit in the workspace, but you can also create ASTs for class files or source code from other locations. A powerful feature introduced in Eclipse 3.0 is the ability to produce a partial AST. For example, you can create a skeletal AST representing only the principal structure of the file or with only a single method body fully resolved. This offers a considerable performance gain over a full-blown AST if you need to extract information from only a small portion of a file. See the javadoc of ASTParser for more details. - + Once an AST is created, the most common way to traverse or manipulate it is through a visitor. As with the traditional visitor pattern, each variety of AST node has a different visit method, so you can implement a visitor that analyzes only certain kinds of expressions or statements. Outside of visitors, each AST node offers accessor methods for each child type that is appropriate for that node. For example, a MethodDeclaration node has getBody and setBody methods for accessing or replacing the block statement representing the body of the method. There are no methods for generically accessing the children of a node, although there is a generic getParent method for accessing the parent of a node. - + The PrintASTAction class in the FAQ Examples plug-in shows a simple example of constructing and traversing an AST for the currently selected compilation unit. A visitor prints out the name of each AST node in the file with braces surrounding the children of each node: +```java class ASTPrinter extends ASTVisitor { StringBuffer buffer = new StringBuffer(); public void preVisit(ASTNode node) { @@ -37,14 +38,14 @@ The PrintASTAction class in the FAQ Examples plug-in shows a simple example of c ICompilationUnit unit = ...; ASTParser parser = ASTParser.newParser(AST.JLS2); parser.setKind(ASTParser.K\_COMPILATION\_UNIT); - CompilationUnit ast = + CompilationUnit ast = (CompilationUnit)parser.createAST(null); ASTPrinter printer = new ASTPrinter(); ast.accept(printer); - MessageDialog.openInformation(shell, "AST for: " + + MessageDialog.openInformation(shell, "AST for: " + unit.getElementName(), printer.buffer.toString()); +``` - See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_create_fixed_views_and_perspectives.md b/docs/FAQ/FAQ_How_do_I_create_fixed_views_and_perspectives.md index a1fff1bbc4e..ecac8818567 100644 --- a/docs/FAQ/FAQ_How_do_I_create_fixed_views_and_perspectives.md +++ b/docs/FAQ/FAQ_How_do_I_create_fixed_views_and_perspectives.md @@ -7,13 +7,14 @@ New APIs in Eclipse 3.0 allow perspectives more control over how their views are A _stand-alone view_, created with the method addStandaloneView, cannot be stacked together with other views and can optionally hide its title bar. A view with its title bar hidden cannot be closed, minimized, or moved. For further control over whether views can be closed or moved, you can obtain an IViewLayout instance for any view in the perspective. Following is an example of a fixed perspective that creates a stand-alone view above the editor area that cannot be moved or closed. +```java class RecipePerspective implements IPerspectiveFactory { public void createInitialLayout(IPageLayout page) { page.setEditorAreaVisible(true); page.setFixed(true); page.addStandaloneView( - RecipePlugin.VIEW_CATEGORIES, - false, IPageLayout.TOP, 0.2f, + RecipePlugin.VIEW_CATEGORIES, + false, IPageLayout.TOP, 0.2f, IPageLayout.ID\_EDITOR\_AREA); IViewLayout view = page.getViewLayout( RecipePlugin.VIEW_CATEGORIES); @@ -21,10 +22,11 @@ A _stand-alone view_, created with the method addStandaloneView, cannot be stack view.setMoveable(false); } } +``` You can add fixed and stand-alone views to perspectives from other plug-ins using the perspectiveExtensions extension point. See the extension point documentation for more details. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_create_my_own_editor.md b/docs/FAQ/FAQ_How_do_I_create_my_own_editor.md index 57c8d5e75a1..27c7fda5f4a 100644 --- a/docs/FAQ/FAQ_How_do_I_create_my_own_editor.md +++ b/docs/FAQ/FAQ_How_do_I_create_my_own_editor.md @@ -4,9 +4,10 @@ FAQ How do I create my own editor? ================================== All editors start by making a subclass of EditorPart from the org.eclipse.ui.part package. At this basic level, editors are very generic. They take an input object that implements IEditorInput, they know how to draw themselves by implementing the createPartControl method, and they may know how to respond to a request to save their contents. To create a bare-bones editor, you have to implement only a small handful of methods. Figure 11.1 shows a working editor that displays a simple label. - + Some required methods, declared abstract in EditorPart, have been omitted from this snippet, but the editor will work if their implementations are empty: +```java public class MinimalEditor extends EditorPart { private Label contents; public void createPartControl(Composite parent) { @@ -22,9 +23,11 @@ Some required methods, declared abstract in EditorPart, have been omitted from t contents.setFocus(); } } +``` The plug-in manifest entry for defining this editor is as follows: +```xml +``` - The extensions attribute describes what file types this editor will automatically be associated with. In this case, the editor will be associated with files ending in min. An editor can instead be associated with a particular file name by replacing the extensions attribute with a filenames attribute. Either of these attributes can specify a comma-separated list for associating an editor with multiple file name extensions and/or file names. A user can always choose to associate an editor with a different file name or extension from the **Workbench > File Associations** preference page. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_create_my_own_key-binding_configuration.md b/docs/FAQ/FAQ_How_do_I_create_my_own_key-binding_configuration.md index 01e34c52aa3..1600ee16b24 100644 --- a/docs/FAQ/FAQ_How_do_I_create_my_own_key-binding_configuration.md +++ b/docs/FAQ/FAQ_How_do_I_create_my_own_key-binding_configuration.md @@ -9,12 +9,14 @@ To see the current key configuration and its keyboard shortcuts, choose the **Wi There are no APIs for defining key-binding configurations programmatically, but you can create them in a plug-in by using the org.eclipse.ui.commands extension point. First, you need to define your new configuration: +```xml +``` By specifying a parent, you are saying that your configuration should inherit key bindings from the parent unless they are explicitly set in your configuration. When key bindings are defined, they will refer to the configuration they belong to. If you write your own configuration, you'll also need to define new key bindings for all the commands that you want to belong to your configuration. diff --git a/docs/FAQ/FAQ_How_do_I_create_my_own_tasks_problems_bookmarks_and_so_on.md b/docs/FAQ/FAQ_How_do_I_create_my_own_tasks_problems_bookmarks_and_so_on.md index b0226d0a8b6..3940d305fbb 100644 --- a/docs/FAQ/FAQ_How_do_I_create_my_own_tasks_problems_bookmarks_and_so_on.md +++ b/docs/FAQ/FAQ_How_do_I_create_my_own_tasks_problems_bookmarks_and_so_on.md @@ -5,11 +5,13 @@ FAQ How do I create my own tasks, problems, bookmarks, and so on? Annotations can be added to resources in the workspace by creating IMarker objects. These markers are used to represent compile errors, to-do items, bookmarks, search results, and many other types of annotations. You can create your own marker types for storing annotations for use by your own plug-in. Each marker can store an arbitrary set of attributes. Attributes are keyed by a string, and the values can be strings, Booleans, or integers. The IMarker interface defines some common attribute types, but you are free to create your own attribute names for your markers. Here is an example snippet that creates a marker, adds some attributes, and then deletes it: +```java final IFile file = null; IMarker marker = file.createMarker(IMarker.MARKER); marker.setAttribute(IMarker.MESSAGE, "This is my marker"); marker.setAttribute("Age", 5); marker.delete(); +``` When markers are created, modified, or deleted, a resource change event will be broadcast, telling interested parties about the change. You can search for markers by using the findMarkers methods on IResource. diff --git a/docs/FAQ/FAQ_How_do_I_create_problem_markers_for_my_compiler.md b/docs/FAQ/FAQ_How_do_I_create_problem_markers_for_my_compiler.md index 2466f953191..59f63bb19e7 100644 --- a/docs/FAQ/FAQ_How_do_I_create_problem_markers_for_my_compiler.md +++ b/docs/FAQ/FAQ_How_do_I_create_problem_markers_for_my_compiler.md @@ -5,20 +5,22 @@ FAQ How do I create problem markers for my compiler? Adding problem markers for eScript compilation happens in two simple steps. - + * Right before we compile the resource, we remove all problem markers from the resource: +```java void compileResource(IResource resource) { - resource.deleteMarkers(IMarker.PROBLEM, - true, IResource.DEPTH_INFINITE); + resource.deleteMarkers(IMarker.PROBLEM, + true, IResource.DEPTH_INFINITE); doCompileResource(resource); } +``` - * During compilation, errors are attached to the resource as follows: +```java void reportError(IResource resource, int line, String msg) { IMarker m = resource.createMarker(IMarker.PROBLEM); m.setAttribute(IMarker.LINE_NUMBER, line); @@ -26,8 +28,9 @@ Adding problem markers for eScript compilation happens in two simple steps. m.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH); m.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); } +``` + - To simplify matters, we use the existing problem-marker type. See the online Eclipse article called _Mark My Words_, for an explanation how to declare your own marker types. Simply by attaching a marker to a resource, the IDE will take care of placing visual indicators at the two indicator bars in the editor. The IDE will also add entries to the Problems view. If we indicated additional information in the marker for IMarker.CHAR_START and IMarker.CHAR_END, the editor will also draw a red squiggly line under the offending problem. Figure 19.4 shows the result of a compilation of a problematic eScript file. diff --git a/docs/FAQ/FAQ_How_do_I_customize_the_menus_in_an_RCP_application.md b/docs/FAQ/FAQ_How_do_I_customize_the_menus_in_an_RCP_application.md index 9835f2398a7..ca3081d7e9e 100644 --- a/docs/FAQ/FAQ_How_do_I_customize_the_menus_in_an_RCP_application.md +++ b/docs/FAQ/FAQ_How_do_I_customize_the_menus_in_an_RCP_application.md @@ -5,29 +5,32 @@ FAQ How do I customize the menus in an RCP application? Your RCP application must specify what menus and actions, if any, to include by default in the main workbench window menu bar. This is done by overriding the WorkbenchAdvisor fillActionBars method. Note that although other plug-ins are always free to create their own menus, it is common for plug-ins to assume the existence of some basic menus. You are responsible for creating the menus that you expect all plug-ins to your application to contribute to. - + Here is a simple example of an advisor that creates two menus-**Window** and **Help**-and adds a single action to each: +```java public void fillActionBars(IWorkbenchWindow window, IActionBarConfigurer configurer, int flags) { if ((flags & FILL_MENU_BAR) == 0) return; IMenuManager mainMenu = configurer.getMenuManager(); - MenuManager windowMenu = new MenuManager("&Window", + MenuManager windowMenu = new MenuManager("&Window", IWorkbenchActionConstants.M_WINDOW); mainMenu.add(windowMenu); windowMenu.add(ActionFactory.MAXIMIZE.create(window)); - MenuManager helpMenu = new MenuManager("&Help", + MenuManager helpMenu = new MenuManager("&Help", IWorkbenchActionConstants.M_HELP); mainMenu.add(helpMenu); helpMenu.add(new AboutAction()); } +``` Note how the menu IDs are taken from IWorkbenchActionConstants. It is important to use the standard menu IDs as plug-ins contributing to the actionSets extension point will be expecting these standard IDs. The action added to the **Window** menu is taken from the standard set of actions available from org.eclipse.ui.actions.ActionFactory. You will find many of the standard perspective, view, and editor manipulation actions here. The AboutAction in this snippet is a simple custom action that displays program information and credits, conventionally added by most applications at the bottom of the **Help** menu. - + For simplicity, this snippet creates new actions each time fillActionBars is called. In a real application, you should create the actions only once and return the cached instances whenever this method is called. Because actions often add themselves as selection or part-change listeners, creating multiple action instances would introduce performance problems. A common place to store action instances is in the data cache provided by IWorkbenchWindowConfigurer. Because each workbench window has its own configurer instance, this is an ideal place to store state specific to a given window. You can use a convenience method such as the following to lazily initialize and store your created actions: +```java //configurer is provided by initialize method private IWorkbenchConfigurer configurer = ...; private static final String MENU_ACTIONS = &menu.actions&; @@ -42,8 +45,8 @@ For simplicity, this snippet creates new actions each time fillActionBars is cal } return actions; } +``` - It is common practice to factor out action management code into a helper class and then store an instance of this helper class in the window configurer's cache. diff --git a/docs/FAQ/FAQ_How_do_I_display_search_results.md b/docs/FAQ/FAQ_How_do_I_display_search_results.md index 257bf3012ce..4a94121e6e6 100644 --- a/docs/FAQ/FAQ_How_do_I_display_search_results.md +++ b/docs/FAQ/FAQ_How_do_I_display_search_results.md @@ -7,56 +7,57 @@ FAQ How do I display search results? Marker-based search results can be displayed in the Search Results view provided by the org.eclipse.search plug-in. To do this, you first need to add org.eclipse.search plugin to your plugin.xml dependencies. Then make sure that the Search Results view is created and then obtain a reference via the NewSearchUI class: +```java NewSearchUI.activateSearchResultView(); ISearchResultViewPart view = NewSearchUI.getSearchResultView(); +``` - Before you begin adding search results to the view, you need to call ISearchResultView.searchStarted. This method lets the view know that the series of matches about to be added belong to a single search query. This method takes the following: -* IActionGroupFactory, a factory object for creating the actions that will +* `IActionGroupFactory`, a factory object for creating the actions that will appear in the context menu when a search result is selected. -* String, the label to use in the view title bar when there is exactly one +* `String`, the label to use in the view title bar when there is exactly one search result. This label should describe the search thoroughly because it will also appear in the search history list that allows the user to add old searches back to the view. -* String, the same label as the preceding, but for multiple search results. The +* `String`, the same label as the preceding, but for multiple search results. The string should contain the pattern {0}, which will be replaced with the exact number of occurrences. -* ImageDescriptor, the image to use for this group of results. This will +* `ImageDescriptor`, the image to use for this group of results. This will also appear in the search history drop-down list. If you don't provide one, a default icon will be used. -* String, the ID of the Search dialog page that generated this +* `String`, the ID of the Search dialog page that generated this set of search results. This is the ID attribute from the search page extension declaration. -* ILabelProvider, the label provider to use for displaying each search result. If +* `ILabelProvider`, the label provider to use for displaying each search result. If not provided, a reasonable default will be used. -* IAction, the action that will cause your search result to be opened in an +* `IAction`, the action that will cause your search result to be opened in an editor. -* IGroupByKeyComputer (described in the next paragraph). -* IRunnableWithProgress, a runnable that will execute the search query +* `IGroupByKeyComputer` (described in the next paragraph). +* `IRunnableWithProgress`, a runnable that will execute the search query over again. This can be the exact runnable executed from the Search dialog. - + The Search Results view shows results in groups, where each line in the view is a single group. A group typically corresponds to a logical unit, such as a file or a Java method, where the match was found. This serves to reduce clutter in the view so that a large number of results can be aggregated into a smaller space. The IGroupByKeyComputer object provided in the searchStarted method is used to map from search results to the group that corresponds to each result. If you don't want to group your search results, you don't need to provide this object. - + Once the search has been started, each search result is added to the view by using the addMatch method. This method takes a description string, a resource handle, the search result marker, and an object that represents the group that the result belongs to. A typical grouping is to use the file as the group identifier. That way, all search results for a given file will be aggregated together in the Search Results view. If you don't want to group search results at all, use the marker itself as the group marker. - + Finally, when you have finished adding search results, call the method searchFinished on the Search Results view. This method must be called in all circumstances, including failure and cancellation, so it is a good idea to put it in a finally block at the end of your search operation. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_distinguish_between_internal_and_external_JARs_on_the_build_path.md b/docs/FAQ/FAQ_How_do_I_distinguish_between_internal_and_external_JARs_on_the_build_path.md index ff730bfde09..569fe098814 100644 --- a/docs/FAQ/FAQ_How_do_I_distinguish_between_internal_and_external_JARs_on_the_build_path.md +++ b/docs/FAQ/FAQ_How_do_I_distinguish_between_internal_and_external_JARs_on_the_build_path.md @@ -5,6 +5,7 @@ FAQ How do I distinguish between internal and external JARs on the build path? The Java build path differentiates between internal JARs and external JARs. To find the file-system location for an internal JAR, the workspace path needs to be converted into a file-system location, as follows: +```java IClasspathEntry entry = ... IPath path = entry.getPath(); IWorkspace workspace = ResourcesPlugin.getWorkspace(); @@ -14,6 +15,7 @@ The Java build path differentiates between internal JARs and external JARs. To f } else { // must be an external JAR (or invalid classpath entry) } +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_dynamically_register_an_editor_to_handle_a_given_extension.md b/docs/FAQ/FAQ_How_do_I_dynamically_register_an_editor_to_handle_a_given_extension.md index 6e79e150ff7..5d04faa2092 100644 --- a/docs/FAQ/FAQ_How_do_I_dynamically_register_an_editor_to_handle_a_given_extension.md +++ b/docs/FAQ/FAQ_How_do_I_dynamically_register_an_editor_to_handle_a_given_extension.md @@ -5,17 +5,18 @@ FAQ How do I dynamically register an editor to handle a given extension? You can't. Editors, like most other extensions to the platform, must be specified declaratively in the plug-in manifest file. You cannot dynamically install a new editor except by dynamically installing a new plug-in containing the new editor. - + The only thing you _can_ currently do programmatically is specify the default editor to use for a given file name or extension. The editor must already be registered with the platform through a plug-in and must already declare that it supports files with that name or extension. Here is an example snippet that sets the default editor for text files to be the built-in platform text editor: - IEditorRegistry registry = +```java + IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry(); - registry.setDefaultEditor("*.txt", + registry.setDefaultEditor("*.txt", "org.eclipse.ui.DefaultTextEditor"); +``` - See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_enable_global_actions_such_as_Cut_Paste_and_Print_in_my_editor.md b/docs/FAQ/FAQ_How_do_I_enable_global_actions_such_as_Cut_Paste_and_Print_in_my_editor.md index ac94a91863f..bfccf5e1834 100644 --- a/docs/FAQ/FAQ_How_do_I_enable_global_actions_such_as_Cut_Paste_and_Print_in_my_editor.md +++ b/docs/FAQ/FAQ_How_do_I_enable_global_actions_such_as_Cut_Paste_and_Print_in_my_editor.md @@ -5,6 +5,7 @@ FAQ How do I enable global actions such as Cut, Paste, and Print in my editor? Your editor's IEditorActionBarContributor, defined in the editor definition in the plugin.xml file, is responsible for enabling global actions. Whenever your editor becomes the active part, the method setActiveEditor is called on the action bar contributor. This is where you can retarget the global actions for your editor. Keep in mind that each editor type has only one editor action bar contributor, so you need to update your actions to reflect the current editor. In this example, the global **Print** action is being retargeted to the active editor: +```java IAction print = ...; public void setActiveEditor(IEditorPart part) { IActionBars bars= getActionBars(); @@ -15,8 +16,8 @@ Your editor's IEditorActionBarContributor, defined in the editor definition in t IWorkbenchActionConstants.PRINT, print); bars.updateActionBars(); } +``` - See Also -------- diff --git a/docs/FAQ/FAQ_How_do_I_enable_the_Save_and_Revert_actions.md b/docs/FAQ/FAQ_How_do_I_enable_the_Save_and_Revert_actions.md index 03afe66fa41..838241aab2e 100644 --- a/docs/FAQ/FAQ_How_do_I_enable_the_Save_and_Revert_actions.md +++ b/docs/FAQ/FAQ_How_do_I_enable_the_Save_and_Revert_actions.md @@ -5,6 +5,7 @@ FAQ How do I enable the Save and Revert actions? An editor with unsaved changes is said to be _dirty_. If an editor is closed while dirty, changes made in the editor since the last save should be discarded. The framework asks an editor whether it is dirty by calling the IEditorPart method isDirty. When the dirty state of an editor changes, it lets the world know by firing a property change event, IEditorPart.PROP_DIRTY, on the property. Here are the relevant minimal-editor example sections that control the dirty state: +```java public class MinimalEditor extends EditorPart { protected boolean dirty = false; ... @@ -16,11 +17,12 @@ An editor with unsaved changes is said to be _dirty_. If an editor is closed whi firePropertyChange(PROP_DIRTY); } } - +``` + - The editor **Save** action should persist the current editor contents and then set the dirty state to false. Unlike most actions that are defined within an instance of IAction, the editor **Save** and **Save As...** actions are built directly into the editor part. These actions are always enabled when the editor is in a dirty state. The editor must support these actions by implementing the methods on ISaveablePart, which is extended by IEditorPart. Here are trivial implementations of these methods from the minimal-editor example: +```java public void doSave(IProgressMonitor monitor) { setDirty(false); } @@ -30,11 +32,11 @@ The editor **Save** action should persist the current editor contents and then s public boolean isSaveAsAllowed() { return false; } +``` - Unlike the **Save** action, the **Revert** action is not built into the editor framework. The **Revert** action is one of the standard workbench global actions and is entirely optional for editors to implement. The global action is hooked in just like other global actions. The **Revert** action should be equivalent to closing an editor without saving, then reopening on the previously saved contents. Like the **Save** action, it should change the dirty state to false and fire a property change event on IEditorPart.PROP_DIRTY when it completes successfully. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_find_all_the_plug-ins_that_contribute_to_my_extension_point.md b/docs/FAQ/FAQ_How_do_I_find_all_the_plug-ins_that_contribute_to_my_extension_point.md index a57006a2690..72244de41b4 100644 --- a/docs/FAQ/FAQ_How_do_I_find_all_the_plug-ins_that_contribute_to_my_extension_point.md +++ b/docs/FAQ/FAQ_How_do_I_find_all_the_plug-ins_that_contribute_to_my_extension_point.md @@ -5,19 +5,21 @@ FAQ How do I find all the plug-ins that contribute to my extension point? Assuming that you used an element attribute named class to encode the name of the class that your contributors have to provide, you can obtain a list of all the plug-in classes that contribute to your extension point by using the following piece of code: +```java IExtensionRegistry reg = Platform.getExtensionRegistry(); IExtensionPoint ep = reg.getExtensionPoint(extensionID); IExtension[] extensions = ep.getExtensions(); ArrayList contributors = new ArrayList(); for (int i = 0; i < extensions.length; i++) { IExtension ext = extensions[i]; - IConfigurationElement[] ce = + IConfigurationElement[] ce = ext.getConfigurationElements(); for (int j = 0; j < ce.length; j++) { Object obj = ce[j].createExecutableExtension("class"); contributors.add(obj); } } +``` From a given extension point, it is straightforward to get a list of extensions that contribute to it. For each extension, we create an executable extension using the value of the class property. We save all the executable extensions in an array list and return it. @@ -26,8 +28,10 @@ How to get all IConfigurationElement objects more simply? You can also get all IConfigurationElement objects without retrieving each extension by using following code: +```java IExtensionRegistry reg = Platform.getExtensionRegistry(); IConfigurationElement[] elements = reg.getConfigurationElementsFor("Extension Point ID"); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_find_out_the_install_location_of_a_plug-in.md b/docs/FAQ/FAQ_How_do_I_find_out_the_install_location_of_a_plug-in.md index 000312975fb..ab8729df5f9 100644 --- a/docs/FAQ/FAQ_How_do_I_find_out_the_install_location_of_a_plug-in.md +++ b/docs/FAQ/FAQ_How_do_I_find_out_the_install_location_of_a_plug-in.md @@ -7,14 +7,16 @@ You should generally avoid making assumptions about the location of a plug-in at The following snippet opens an input stream on a file called sample.gif located in a subdirectory, called icons, of a plug-in's install directory: +```java Bundle bundle = Platform.getBundle(yourPluginId); Path path = new Path("icons/sample.gif"); URL fileURL = FileLocator.find(bundle, path, null); InputStream in = fileURL.openStream(); +``` If you need to know the file system location of a plug-in, you need to use FileLocator.resolve(URL). This method converts a platform URL to a standard URL protocol, such as HyperText Transfer Protocol (HTTP), or file. Note that the Eclipse Platform does not specify that plug-ins must exist in the local file system, so you cannot rely on this method's returning a file system URL under all circumstances in the future. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_find_out_what_object_is_selected.md b/docs/FAQ/FAQ_How_do_I_find_out_what_object_is_selected.md index 90981e20348..6d032f614c9 100644 --- a/docs/FAQ/FAQ_How_do_I_find_out_what_object_is_selected.md +++ b/docs/FAQ/FAQ_How_do_I_find_out_what_object_is_selected.md @@ -3,10 +3,11 @@ FAQ How do I find out what object is selected? ============================================== -The ISelectionService tracks all selection changes within the views and editors of a workbench window or page. By adding a listener to this service, you will be notified whenever the selection changes. Selections in views are typically returned as IStructuredSelection instances, and selections in editors typically implement ITextSelection. You should avoid any expensive computation from within a selection listener, because this event fires quite frequently as the user is moving around in the UI and typing in editors. A more efficient approach is to avoid adding a listener, and simply asking the selection service for the current selection when you need it. +The ISelectionService tracks all selection changes within the views and editors of a workbench window or page. By adding a listener to this service, you will be notified whenever the selection changes. Selections in views are typically returned as `IStructuredSelection` instances, and selections in editors typically implement `ITextSelection`. You should avoid any expensive computation from within a selection listener, because this event fires quite frequently as the user is moving around in the UI and typing in editors. A more efficient approach is to avoid adding a listener, and simply asking the selection service for the current selection when you need it. -You can also ask for the selection in a particular view by passing the view ID as a parameter to the getSelection method: +You can also ask for the selection in a particular view by passing the view ID as a parameter to the `getSelection` method: +```java IWorkbenchPage page = ...; //the current selection in the entire page ISelection selection = page.getSelection(); @@ -22,8 +23,9 @@ You can also ask for the selection in a particular view by passing the view ID a //add a listener to selection changes only //in the navigator view page.addSelectionListener(sl, IPageLayout.ID\_RES\_NAV); +``` -IWorkbenchPage implements ISelectionService directly. You can also access a selection service to track selection within a workbench window by using IWorkbenchWindow.getSelectionService. +`IWorkbenchPage` implements `ISelectionService` directly. You can also access a selection service to track selection within a workbench window by using `IWorkbenchWindow.getSelectionService`. See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_find_out_what_view_or_editor_is_selected.md b/docs/FAQ/FAQ_How_do_I_find_out_what_view_or_editor_is_selected.md index a691532983d..a38c92c4f11 100644 --- a/docs/FAQ/FAQ_How_do_I_find_out_what_view_or_editor_is_selected.md +++ b/docs/FAQ/FAQ_How_do_I_find_out_what_view_or_editor_is_selected.md @@ -5,6 +5,7 @@ To find out what view or editor is selected, use the IPartService. As with ISele Two types of listeners can be added to the part service: IPartListener and the poorly named IPartListener2. You should always use this second one as it can handle part-change events on parts that have not yet been created because they are hidden in a stack behind another part. This listener will also tell you when a part is made visible or hidden or when an editor's input is changed: +```java IWorkbenchPage page = ...; //the active part IWorkbenchPart active = page.getActivePart(); @@ -16,8 +17,9 @@ Two types of listeners can be added to the part service: IPartListener and the p ... other listener methods ... }; page.addPartListener(pl); +``` -IWorkbenchPage implements IPartService directly. You can also access a activation service by using IWorkbenchWindow.getPartService. +`IWorkbenchPage` implements `IPartService` directly. You can also access a activation service by using `IWorkbenchWindow.getPartService`. See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_find_out_whether_a_particular_job_is_running.md b/docs/FAQ/FAQ_How_do_I_find_out_whether_a_particular_job_is_running.md index d45a6ea0f4b..cf9c90924a7 100644 --- a/docs/FAQ/FAQ_How_do_I_find_out_whether_a_particular_job_is_running.md +++ b/docs/FAQ/FAQ_How_do_I_find_out_whether_a_particular_job_is_running.md @@ -7,8 +7,10 @@ If you have a reference to a job instance, you can use the method Job.getState t The job infrastructure makes things easier for you by generally being very tolerant of methods called at the wrong time. For example, if you call wakeUp on a job that is not sleeping or cancel on a job that is already finished, the request is silently ignored. Thus, you can generally forgo the state check and simply try the method you want to call. For example, you do not need to do this: +```java if (job.getState() == Job.NONE) job.schedule(); +``` Instead, you can invoke job.schedule() immediately. If the job is already scheduled or sleeping, the schedule request will be ignored. If the job is currently running, it will be rescheduled as soon as it completes @@ -16,10 +18,12 @@ If you need to be certain of when a job enters a particular state, register a jo If you do not have a job reference, you can search for it by using the method IJobManager.find. This method will find only job instances that are running, waiting, or sleeping. To give a concrete example, the Eclipse IDE uses this method when the user launches an application. The method searches for the autobuild job and, if it is running, waits for autobuild to complete before launching the application. Here is a snippet that illustrates this behavior; the actual code is more complex because it first consults a preference setting and might decide to prompt the user: +```java IJobManager jobMan = Job.getJobManager(); - Job[] build = jobMan.find(ResourcesPlugin.FAMILY_AUTO_BUILD); + Job[] build = jobMan.find(ResourcesPlugin.FAMILY_AUTO_BUILD); if (build.length == 1) build[0].join(); +``` Again, it is safe to call join here without checking whether the job is still running. The join method will return immediately in this case. diff --git a/docs/FAQ/FAQ_How_do_I_find_out_whether_the_Eclipse_Platform_is_running.md b/docs/FAQ/FAQ_How_do_I_find_out_whether_the_Eclipse_Platform_is_running.md index aac868201b9..9ae1caa68e3 100644 --- a/docs/FAQ/FAQ_How_do_I_find_out_whether_the_Eclipse_Platform_is_running.md +++ b/docs/FAQ/FAQ_How_do_I_find_out_whether_the_Eclipse_Platform_is_running.md @@ -5,18 +5,19 @@ FAQ How do I find out whether the Eclipse Platform is running? If you have a library of code that can be used within both the Eclipse Platform and a stand-alone application, you may need to find out programmatically whether the Eclipse Platform is running. In Eclipse 3.0, this is accomplished by calling Platform.isRunning. In 2.1, call BootLoader.isRunning. You will need to set up the classpath of your stand-alone application to make sure that the boot or runtime plug-in's library is reachable. Alternatively, you can reference the necessary class via reflection. - - + + You can find out whether an Ant script is running from within Eclipse by querying the state of the variable eclipse.running. You can use this information to specify targets that are built only when Ant is invoked from within Eclipse: +```xml +``` + + - - - See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_find_the_active_workbench_page.md b/docs/FAQ/FAQ_How_do_I_find_the_active_workbench_page.md index 6f0ccaf15a9..9740b36d1d7 100644 --- a/docs/FAQ/FAQ_How_do_I_find_the_active_workbench_page.md +++ b/docs/FAQ/FAQ_How_do_I_find_the_active_workbench_page.md @@ -7,14 +7,15 @@ Many workbench APIs are accessible only from IWorkbenchWindow or IWorkbenchPage. As it turns out, the answer isn't always straightforward. There appears to be an obvious API on IWorkbench for getting this (caution: _please read below before using this code!_): - +```java IWorkbench wb = PlatformUI.getWorkbench(); IWorkbenchWindow win = wb.getActiveWorkbenchWindow(); IWorkbenchPage page = win.getActiveWorkbenchPage();   // on new versions it may need to be changed to: IWorkbenchPage page = win.getActivePage(); +``` However, if you read the fine print on these methods, you'll see that they can — and do! — return null if the active shell is not a window. This means that when a dialog or other shell has focus, you might not be able to use these APIs to access the active window or page. @@ -28,26 +29,27 @@ Within a Workbench Part From within the implementation of any view or editor, you can do the following: - +```java IWorkbenchPage page = getSite().getPage(); +``` -Workbench sites are IServiceLocator. +Workbench sites are `IServiceLocator`. Within a Command Handler ------------------------ The HandlerUtil class provides a number of helper methods to obtain the active window, editor, part, etc. from the ExecutionEvent provided to the handler. -A special case is a handler that implements IElementUpdater as the updateElements() method is provided an UIElement rather than an ExecutionEvent. But the UIElement does provide an IServiceLocator. +A special case is a handler that implements `IElementUpdater` as the `updateElements()` method is provided an `UIElement` rather than an `ExecutionEvent`. But the `UIElement` does provide an `IServiceLocator`. Within an Action ---------------- From an action defined in a workbench action set, you can access the window from the init method: - +```java class MyAction implements IWorkbenchWindowActionDelegate { private IWorkbenchWindow window; ... @@ -55,6 +57,7 @@ From an action defined in a workbench action set, you can access the window from this.window = win; } } +``` Similarly, actions contributed to the popupMenus extension point always have an initialization method that sets the current part before the action's run method is called. All wizard extension points also have an IWorkbenchWizard init method that supplies the wizard with the current workbench window before the wizard is launched. In short, if you look carefully, you can almost always get at the current window or page, no matter where you are in the Eclipse UI. @@ -63,8 +66,8 @@ From an IEclipseContext or IServiceLocator Service locators are similar to Eclipse Contexts (IEclipseContext): - +```java IServiceLocator locator = …; IWorkbenchWindow window = locator.get(IWorkbenchWindow.class); - +``` diff --git a/docs/FAQ/FAQ_How_do_I_get_a_Display_instance.md b/docs/FAQ/FAQ_How_do_I_get_a_Display_instance.md index cadca98c3f7..ec280889439 100644 --- a/docs/FAQ/FAQ_How_do_I_get_a_Display_instance.md +++ b/docs/FAQ/FAQ_How_do_I_get_a_Display_instance.md @@ -7,13 +7,15 @@ Most users deploy Eclipse as one top-level window and manage their code in persp If you call Display.getCurrent, it returns the display that was created in that thread, if any. Here is an example: +```java public static Display getDisplay() { Display display = Display.getCurrent(); //may be null if outside the UI thread if (display == null) display = Display.getDefault(); - return display; + return display; } +``` A calling thread that does not have an active display will return null. Therefore, this method is useful only when you are absolutely certain that you are in the thread that created the display. This brings us to the second way you can obtain a display instance: Display.getDefault(). It will return the first display that was created. If your application has only one display, this is an acceptable way of obtaining the display. diff --git a/docs/FAQ/FAQ_How_do_I_get_started_with_creating_a_custom_text_editor.md b/docs/FAQ/FAQ_How_do_I_get_started_with_creating_a_custom_text_editor.md index da9754d155f..95f14de0b0d 100644 --- a/docs/FAQ/FAQ_How_do_I_get_started_with_creating_a_custom_text_editor.md +++ b/docs/FAQ/FAQ_How_do_I_get_started_with_creating_a_custom_text_editor.md @@ -22,6 +22,7 @@ The FAQs in this chapter will use a running example of a simple HTML editor. We Here is the skeleton of the HTMLEditor class, showing the customization entry points: +```java public class HTMLEditor extends AbstractTextEditor { public HTMLEditor() { //install the source configuration @@ -34,6 +35,7 @@ Here is the skeleton of the HTMLEditor class, showing the customization entry po //... add other editor actions here } } +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_hook_into_global_actions_such_as_Copy_and_Delete.md b/docs/FAQ/FAQ_How_do_I_hook_into_global_actions_such_as_Copy_and_Delete.md index 829951aed9f..435d22c9256 100644 --- a/docs/FAQ/FAQ_How_do_I_hook_into_global_actions_such_as_Copy_and_Delete.md +++ b/docs/FAQ/FAQ_How_do_I_hook_into_global_actions_such_as_Copy_and_Delete.md @@ -7,17 +7,19 @@ Certain standard toolbar and menu entries can be shared among several views and A view typically registers its global action handlers in the createPartControl method: +```java IActionBars actionBars= getViewSite().getActionBars(); actionBars.setGlobalActionHandler( ActionFactory.COPY.getId(), - copyAction); + copyAction); +``` You have to do this only once for each view that is created. The platform remembers your action handler and retargets the action each time the view becomes active. To unregister from a global action, simply invoke setGlobalActionHandler again and pass in a null value for the handler. - + The IWorkbenchActionConstants interface in the org.eclipse.ui package contains a complete list of global actions. Look for constants in this interface with a comment saying Global action. In Eclipse 3.0, you can also look at the ActionFactory and IDEActionFactory classes, which define factory objects for creating a variety of common actions. - + See Also -------- diff --git a/docs/FAQ/FAQ_How_do_I_hook_my_editor_to_the_Back_and_Forward_buttons.md b/docs/FAQ/FAQ_How_do_I_hook_my_editor_to_the_Back_and_Forward_buttons.md index de0d215ca4e..4a18072fa6b 100644 --- a/docs/FAQ/FAQ_How_do_I_hook_my_editor_to_the_Back_and_Forward_buttons.md +++ b/docs/FAQ/FAQ_How_do_I_hook_my_editor_to_the_Back_and_Forward_buttons.md @@ -5,17 +5,18 @@ FAQ How do I hook my editor to the Back and Forward buttons? Each workbench page maintains a navigation history of interesting locations that have been visited in the page's editors. All editors, not only text editors, can contribute locations to this history, allowing the user to quickly jump between these locations by using the **Back** and **Forward** buttons on the toolbar. To enable this, your editor must implement INavigationLocationProvider. This interface is used to ask an editor to create an INavigationLocation object, which is a representation of the current editor state. When the user clicks the **Back** or **Forward** button, the previous or next location in the history restores its position using the restoreLocation method on INavigationLocation. - + The contract that should be followed for an INavigationLocation is that when the user jumps in one direction, a subsequent jump in the opposite direction should take the user back to the starting point. To support this, your implementation of restoreLocation must add a history entry for the current location before restoring the old location. You can imagine that this will quickly lead to duplication of entries if the user continues to jump backward and forward several times. This duplication is avoided by the mergeInto method on INavigationLocation. If the location to be merged is the same as or overlapping the receiver location, the method should merge the two entries and return true. If the locations don't overlap, it simply returns false. - + A navigation location can also choose to support persistence. When an editor closes, any locations associated with that editor are asked to store their state in an IMemento. When the user jumps back to a location in an editor that has been closed, the location will be given the editor's IEditorInput object and the IMemento that was stored. Using this information, the location instance must be able to restore its state and navigate to its location in the editor. Note that you can easily obtain the editor instance from the input object by using IWorkbenchPage.findEditor(IEditorInput). - + Now we know how to create and restore editor locations, but how are entries added to the navigation history in the first place? Anyone can mark an interesting location in an open editor by calling the markLocation method on INavigationHistory. Code that causes the cursor or selection to jump to another location in an editor should call this method both before and after performing the jump. As mentioned, implementations of restoreLocation should also mark the current location before restoring an old one. Regardless of whether the specific editor has any support for navigation history, markLocation will work. If the editor doesn't implement INavigationLocationProvider, a history entry will be added, allowing the user to jump back to that editor but without returning to any particular location. The following snippet shows an action that is added to the sample HTML editor. When the action is invoked, it will add the current cursor position to the navigation history: +```java public class MarkLocationAction extends Action { private IEditorPart editor; public MarkLocationAction(IEditorPart editor) { @@ -27,4 +28,4 @@ Now we know how to create and restore editor locations, but how are entries adde page.getNavigationHistory().markLocation(editor); } } - +``` diff --git a/docs/FAQ/FAQ_How_do_I_implement_Quick_Fixes_for_my_own_language.md b/docs/FAQ/FAQ_How_do_I_implement_Quick_Fixes_for_my_own_language.md index 205a39ab5bc..ae33e916859 100644 --- a/docs/FAQ/FAQ_How_do_I_implement_Quick_Fixes_for_my_own_language.md +++ b/docs/FAQ/FAQ_How_do_I_implement_Quick_Fixes_for_my_own_language.md @@ -5,16 +5,18 @@ FAQ How do I implement Quick Fixes for my own language? The JDT has support for so-called Quick Fixes. Whenever a marker is generated, a set of resolutions is associated with it for users to click on and choose an automatic fix of the problem as shown in Figure 19.5. Quick Fixes are implemented through the org.eclipse.ui.ide.markerResolution extension point: +```xml +``` - The implementation class implements the IMarkerResolutionGenerator interface. Use the IMarkerResolutionGenerator2 when resolutions are expensive to implement. See the javadoc for the interface for an explanation. Here is what the implementation class may look like: +```java public class QuickFixer implements IMarkerResolutionGenerator { public IMarkerResolution[] getResolutions(IMarker mk) { try { @@ -29,11 +31,13 @@ The implementation class implements the IMarkerResolutionGenerator interface. Us } } } +``` An array of Quick Fixes has to be returned for the problem associated with the current marker. Each marker resolution, or Quick Fix, implements IMarkerResolution or, when a description and an image are available, IMarkerResolution2. Here is what the implementation may look like: +```java public class QuickFix implements IMarkerResolution { String label; QuickFix(String label) { @@ -47,6 +51,7 @@ Each marker resolution, or Quick Fix, implements IMarkerResolution or, when a de "This quick-fix is not yet implemented"); } } +``` The problem indicator-in our sample, the WhatsUp attribute- is associated with the marker by the parser. Typically, the Quick Fix handler that resolves the problem, as shown in this example, lives somewhere in the UI. Following this paradigm is advisable as it separates the problem detection in the compiler/parser from how it is presented to the user. diff --git a/docs/FAQ/FAQ_How_do_I_implement_a_DOM_for_my_language.md b/docs/FAQ/FAQ_How_do_I_implement_a_DOM_for_my_language.md index bdfe45b7151..6be870beb9e 100644 --- a/docs/FAQ/FAQ_How_do_I_implement_a_DOM_for_my_language.md +++ b/docs/FAQ/FAQ_How_do_I_implement_a_DOM_for_my_language.md @@ -18,25 +18,29 @@ A DOM represents the structure of your programming language. Its design and impl The inheritance hierarchy for the DOM defines the following fields: +```java int startOffset, endOffset; // source positions Hashtable attributes; // things like ID, label, ... ArrayList children; // children of this element Element parent; // the owner of this element String hoverHelp; // cached value of hover help ...more fields.... +``` The subclasses of Element implement useful methods: +```java public String getAttributeValue(String name) public String getHoverHelp() - public void getContentProposals(...., ArrayList result) + public void getContentProposals(...., ArrayList result) +``` For instance, the getHoverHelp method easily allows us to use the DOM to find the element at a given offset and then ask it for what hover help is appropriate. - - + + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_implement_a_search_operation.md b/docs/FAQ/FAQ_How_do_I_implement_a_search_operation.md index d2dc3724c30..1934ace7bc4 100644 --- a/docs/FAQ/FAQ_How_do_I_implement_a_search_operation.md +++ b/docs/FAQ/FAQ_How_do_I_implement_a_search_operation.md @@ -5,7 +5,8 @@ FAQ How do I implement a search operation? A search operation is initiated from the performAction method on a search page. The search can run either in a blocking manner, thus preventing the user from doing further work until the search is done, or in the background. To run the search in a blocking manner, use the IRunnableContext available from the ISearchPageContainer instance: - class SearchSizePage extends DialogPage +```java + class SearchSizePage extends DialogPage implements ISearchPage { private ISearchPageContainer container; public boolean performAction() { @@ -18,15 +19,17 @@ A search operation is initiated from the performAction method on a search page. this.container = spc; } } +``` To run your query in the background, create and schedule a subclass of Job. Regardless of whether the search is run in the foreground or the background, the mechanics of the search operation itself will usually be the same. - + If your search is operating on files in the workspace, you should ensure that changes are batched to prevent autobuilds every time a search result is created. Do this by making your operation subclass WorkspaceModifyOperation in the blocking case or WorkspaceJob in the nonblocking case. For the rest of this FAQ, we'll assume that you're writing a search on the workspace. - + The purpose of your search operation is to locate the files that match the search parameters and to generate search result markers for each match. One common method of doing this is to use a resource visitor. Here is the general structure of a simple search operation: +```java class SearchOperation extends WorkspaceModifyOperation implements IResourceProxyVisitor { public void execute(IProgressMonitor monitor) { @@ -39,12 +42,13 @@ The purpose of your search operation is to locate the files that match the searc public boolean visit(IResourceProxy proxy) { if (proxy.getType() == IResource.FILE) { IFile file = (IFile) proxy.requestResource(); - if (isMatch(file)) + if (isMatch(file)) file.createMarker(SearchUI.SEARCH_MARKER); } return true; } } +``` If your search is located within a specific portion of the file, you should fill in the appropriate attributes on the search result marker (LINE_NUMBER, CHAR_START, and CHAR_END from IMarker). None of these attributes is required; in some cases, a search can simply identify an entire file. diff --git a/docs/FAQ/FAQ_How_do_I_implement_an_incremental_project_builder.md b/docs/FAQ/FAQ_How_do_I_implement_an_incremental_project_builder.md index 3074c52c445..bd165f40601 100644 --- a/docs/FAQ/FAQ_How_do_I_implement_an_incremental_project_builder.md +++ b/docs/FAQ/FAQ_How_do_I_implement_an_incremental_project_builder.md @@ -5,9 +5,10 @@ FAQ How do I implement an incremental project builder? To implement an incremental project builder, you first have to create an extension for org.eclipse.core.resources.builders: - @@ -16,12 +17,13 @@ To implement an incremental project builder, you first have to create an extensi +``` - The second step is to create a builder class that must extend the abstract IncrementalProjectBuilder superclass: - public class Builder extends IncrementalProjectBuilder { - protected IProject[] build(int kind, Map args, +```java + public class Builder extends IncrementalProjectBuilder { + protected IProject[] build(int kind, Map args, IProgressMonitor monitor) { if (kind == IncrementalProjectBuilder.FULL_BUILD) { fullBuild(monitor); @@ -34,8 +36,8 @@ The second step is to create a builder class that must extend the abstract Incre } } return null; - } - private void incrementalBuild(IResourceDelta delta, + } + private void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) { System.out.println("incremental build on "+delta); try { @@ -54,6 +56,7 @@ The second step is to create a builder class that must extend the abstract Incre System.out.println("full build"); } } +``` It is important to return true in the visit method for those folders that contain the resources of interest. If you return false, the children of the resource delta are not visited. diff --git a/docs/FAQ/FAQ_How_do_I_inform_the_user_of_a_problem.md b/docs/FAQ/FAQ_How_do_I_inform_the_user_of_a_problem.md index 46b2a45428e..d5b6554e33c 100644 --- a/docs/FAQ/FAQ_How_do_I_inform_the_user_of_a_problem.md +++ b/docs/FAQ/FAQ_How_do_I_inform_the_user_of_a_problem.md @@ -5,20 +5,21 @@ FAQ How do I inform the user of a problem? Warnings and errors can be reported to the user by using an ErrorDialog. Here is a very simple example of an Error dialog displaying a warning message: - IStatus warning = new Status(IStatus.WARNING, +```java + IStatus warning = new Status(IStatus.WARNING, ExamplesPlugin.ID, 1, "You have been warned.", null); - ErrorDialog.openError(window.getShell(), + ErrorDialog.openError(window.getShell(), "This is your final warning", null, warning); +``` - The null parameter to the status constructor is for supplying an exception object. The exception object is not used by the Error dialog, so we'll leave it blank in this case. If you're creating a status object for another purpose, such as logging, you'll want to supply the exception, if there is one. The openError method has parameters for a title and a message, but both of these parameters are optional. If you don't supply a title, the method will use the generic **Problems Occurred** message. If you don't supply a message, the method will take the message from the supplied status object. - - - + + + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_insert_text_in_the_active_text_editor.md b/docs/FAQ/FAQ_How_do_I_insert_text_in_the_active_text_editor.md index d6f7d0f9c14..9e5d983378d 100644 --- a/docs/FAQ/FAQ_How_do_I_insert_text_in_the_active_text_editor.md +++ b/docs/FAQ/FAQ_How_do_I_insert_text_in_the_active_text_editor.md @@ -7,6 +7,7 @@ Text editors have no public API to insert text. Furthermore, they do not expose Text editors obtain a document model by using a _document provider_. This provider functions as synchronizer for multiple editors, notifying each when the other changes the document. By acting as one of the editors on a document, one can easily insert text into the editor of choice. The next code snippet locates the active editor, gets its document provider, requests the underlying document, and inserts some text into it: +```java IWorkbenchPage page = ...; IEditorPart part = page.getActiveEditor(); if (!(part instanceof AbstractTextEditor) @@ -16,6 +17,7 @@ Text editors obtain a document model by using a _document provider_. This provid IDocument doc = dp.getDocument(editor.getEditorInput()); int offset = doc.getLineOffset(doc.getNumberOfLines()-4); doc.replace(offset, 0, pasteText+"\n"); +``` The provider will notify all other editors to update their presentation as a result. @@ -24,5 +26,5 @@ See Also: [FAQ How do I use the text document model?](./FAQ_How_do_I_use_the_text_document_model.md "FAQ How do I use the text document model?") - + diff --git a/docs/FAQ/FAQ_How_do_I_launch_a_Java_program.md b/docs/FAQ/FAQ_How_do_I_launch_a_Java_program.md index 8e3fbad2cf9..be3e45707b0 100644 --- a/docs/FAQ/FAQ_How_do_I_launch_a_Java_program.md +++ b/docs/FAQ/FAQ_How_do_I_launch_a_Java_program.md @@ -14,22 +14,24 @@ JDT has support for launching Java programs. First, add the following plug-ins t With those plug-ins added to your dependent plug-in list, your Java program can be launched using the JDT in two ways. In the first approach, an IVMRunner uses the currently installed VM, sets up its classpath, and asks the VM runner to run the program: +```java void launch(IJavaProject proj, String main) { IVMInstall vm = JavaRuntime.getVMInstall(proj); if (vm == null) vm = JavaRuntime.getDefaultVMInstall(); IVMRunner vmr = vm.getVMRunner(ILaunchManager.RUN_MODE); String[] cp = JavaRuntime. computeDefaultRuntimeClassPath(proj); - VMRunnerConfiguration config = + VMRunnerConfiguration config = new VMRunnerConfiguration(main, cp); - ILaunch launch = new Launch(null, + ILaunch launch = new Launch(null, ILaunchManager.RUN_MODE, null); vmr.run(config, launch, null); } +``` - The second approach is to create a new launch configuration, save it, and run it. The cfg parameter to this method is the name of the launch configuration to use: +```java void launch(IJavaProject proj, String cfg, String main) { DebugPlugin plugin = DebugPlugin.getDefault(); ILaunchManager lm = plugin.getLaunchManager(); @@ -38,18 +40,19 @@ The second approach is to create a new launch configuration, save it, and run it ILaunchConfigurationWorkingCopy wc = t.newInstance( null, cfg); wc.setAttribute( - IJavaLaunchConfigurationConstants.ATTR\_PROJECT\_NAME, + IJavaLaunchConfigurationConstants.ATTR\_PROJECT\_NAME, proj.getElementName()); wc.setAttribute( - IJavaLaunchConfigurationConstants.ATTR\_MAIN\_TYPE_NAME, + IJavaLaunchConfigurationConstants.ATTR\_MAIN\_TYPE_NAME, main); - ILaunchConfiguration config = wc.doSave(); + ILaunchConfiguration config = wc.doSave(); config.launch(ILaunchManager.RUN_MODE, null); } +``` More information is available at **Help > Help Contents > JDT Plug-in Developer Guide** \> JDT Debug > Running Java code**.** - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_launch_the_preference_page_that_belongs_to_my_plug-in.md b/docs/FAQ/FAQ_How_do_I_launch_the_preference_page_that_belongs_to_my_plug-in.md index a9903c10f5e..62a7033f99a 100644 --- a/docs/FAQ/FAQ_How_do_I_launch_the_preference_page_that_belongs_to_my_plug-in.md +++ b/docs/FAQ/FAQ_How_do_I_launch_the_preference_page_that_belongs_to_my_plug-in.md @@ -7,10 +7,12 @@ Sometimes, you want to allow the user to edit preferences for a plug-in quickly, The `org.eclipse.ui.dialogs.PreferencesUtil` in bundle `org.eclipse.ui.workbench` can be used for this: +```java PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn( - shell, "org.eclipse.licensing.ui.licensesPreferencePage", + shell, "org.eclipse.licensing.ui.licensesPreferencePage", new String[] {"org.eclipse.licensing.ui.licensesPreferencePage"}, null); dialog.open(); +``` Alternative solution -------------------- @@ -21,6 +23,7 @@ This solution works by launching the Preference dialog yourself with a customize For each preference page you want to display, create a PreferenceNode instance that contains a reference to your page and some unique page ID. Pages are then added to a preference manager. If you want to create a hierarchy of pages, use the PreferenceManager method addTo, where the path is a period-delimited series of page IDs above the page being added. Finally, create an instance of PreferenceDialog, passing in the preference manager you have created. Here is sample code for opening the Preference dialog on a single preference page called MyPreferencePage: +```java IPreferencePage page = new MyPreferencePage(); PreferenceManager mgr = new PreferenceManager(); IPreferenceNode node = new PreferenceNode("1", page); @@ -29,6 +32,7 @@ For each preference page you want to display, create a PreferenceNode instance t dialog.create(); dialog.setMessage(page.getTitle()); dialog.open(); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_load_and_save_plug-in_preferences.md b/docs/FAQ/FAQ_How_do_I_load_and_save_plug-in_preferences.md index 307603ead04..7e3e907a30f 100644 --- a/docs/FAQ/FAQ_How_do_I_load_and_save_plug-in_preferences.md +++ b/docs/FAQ/FAQ_How_do_I_load_and_save_plug-in_preferences.md @@ -8,6 +8,7 @@ Current Practice As of 3.1 the technique to modify preference values goes something like this: +```java private void savePluginSettings() { // saves plugin preferences at the workspace level Preferences prefs = @@ -31,6 +32,7 @@ As of 3.1 the technique to modify preference values goes something like this: this.someStr = prefs.get(KEY1); this.someBool= prefs.getBoolean(KEY2); } +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_make_a_view_respond_to_selection_changes_in_another_view.md b/docs/FAQ/FAQ_How_do_I_make_a_view_respond_to_selection_changes_in_another_view.md index 6a985c41429..eb76ef6f064 100644 --- a/docs/FAQ/FAQ_How_do_I_make_a_view_respond_to_selection_changes_in_another_view.md +++ b/docs/FAQ/FAQ_How_do_I_make_a_view_respond_to_selection_changes_in_another_view.md @@ -11,16 +11,18 @@ Follow three simple steps to make use of an ISelectionService in your views. Fir Second, register the view-selection provider with the selection service. The view that wants to broadcast selection changes simply has to register itself with the ISelectionService by supplying an implementation of org.eclipse.jface.viewers ISelectionProvider. In most cases, your view will contain a JFace viewer, all of which implement ISelectionProvider directly. If your view does not contain a viewer, you will have to implement the ISelectionProvider interface directly. Here is a sample of a view's createPartControl method, which creates a viewer and then registers it with the page-selection service: +```java public void createPartControl(Composite parent) { int style = SWT.SINGLE | SWT.H\_SCROLL | SWT.V\_SCROLL; viewer = new TableViewer(parent, style); getSite().setSelectionProvider(viewer); ... } +``` - The final step is to register a selection listener with the selection service. The view that wants to respond to selection changes must register an implementation of org.eclipse.ui ISelectionListener with the selection service. The following example defines the Chapters view described earlier. This view responds to selection changes where the selection is a book and displays the chapters of that book. It is important for your selection listener to ignore selections that it does not understand. The selection service will be broadcasting all kinds of selection changes that are not relevant to your view, so you need to listen selectively. +```java public class ChaptersView extends ViewPart { private TableViewer viewer; ISelectionListener listener = new ISelectionListener() { @@ -40,10 +42,11 @@ The final step is to register a selection listener with the selection service. T getSite().getPage().removeSelectionListener(listener); } } +``` Again, note how this example completely ignores selections that don't contain books. If the selection contains a single book, the view will display its chapters. If the selection contains several books, it will display nothing. Also note in this example that the view is responsible for removing the selection listener when it closes. As a general rule with listeners, the code for adding a listener should never be very far from the code for removing the listener. If you forget to remove your listener when the view is closed, your selection listener will cause errors later on. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_make_key_bindings_work_in_an_RCP_application.md b/docs/FAQ/FAQ_How_do_I_make_key_bindings_work_in_an_RCP_application.md index 2935a25b749..50c1863d932 100644 --- a/docs/FAQ/FAQ_How_do_I_make_key_bindings_work_in_an_RCP_application.md +++ b/docs/FAQ/FAQ_How_do_I_make_key_bindings_work_in_an_RCP_application.md @@ -7,6 +7,7 @@ When actions are contributed via the actionSets extension point, key bindings ar Now that your action is linked to a command, you need to register the action with the platform. You should do this the first time the platform calls your implementation of WorkbenchAdvisor.fillActionBars: +```java public void fillActionBars(IWorkbenchWindow window, IActionBarConfigurer configurer, int flags) { ... @@ -16,6 +17,7 @@ Now that your action is linked to a command, you need to register the action wit } menu.add(maximizeAction); } +``` The method registerGlobalAction will let the platform know that your action exists. When the key binding is invoked by the user, it will now be able locate and run your action. diff --git a/docs/FAQ/FAQ_How_do_I_make_menus_with_dynamic_contents.md b/docs/FAQ/FAQ_How_do_I_make_menus_with_dynamic_contents.md index ab8a717466d..be0e2ab477c 100644 --- a/docs/FAQ/FAQ_How_do_I_make_menus_with_dynamic_contents.md +++ b/docs/FAQ/FAQ_How_do_I_make_menus_with_dynamic_contents.md @@ -7,12 +7,15 @@ By default, menu managers in JFace are static; that is, contributions are added If you want the contents of your menus to change every time the menu is opened, you should make your menu manager dynamic. When the menu manager is created, make it dynamic by calling setRemoveAllWhenShown: +```java IMenuManager menu = new MenuManager("Name"); menu.add(new Action("never shown entry"){}); //needed if it's a submenu menu.setRemoveAllWhenShown(true); +``` By setting this flag, the menu manager will remove all actions and submenus from the menu every time the menu is about to be shown. If the menu is a submenu you **must** include a fake item **or the dynamic menu will not be shown** (see [Bug #149890](https://bugs.eclipse.org/bugs/show_bug.cgi?id=149890)). Next, you need to install on the menu a listener that will add your actions: +```java IMenuListener listener = new IMenuListener() { public void menuAboutToShow(IMenuManager m) { if (daytime) { @@ -24,6 +27,7 @@ By setting this flag, the menu manager will remove all actions and submenus from } }; menu.addMenuListener(listener); +``` This menu will now have different actions, depending on the value of the daytime variable. diff --git a/docs/FAQ/FAQ_How_do_I_make_my_plug-in_connect_to_other_plug-ins.md b/docs/FAQ/FAQ_How_do_I_make_my_plug-in_connect_to_other_plug-ins.md index 0af22a15a6e..c3c226cb228 100644 --- a/docs/FAQ/FAQ_How_do_I_make_my_plug-in_connect_to_other_plug-ins.md +++ b/docs/FAQ/FAQ_How_do_I_make_my_plug-in_connect_to_other_plug-ins.md @@ -5,48 +5,51 @@ FAQ How do I make my plug-in connect to other plug-ins? Like members of a community, plug-ins do not generally live in isolation. Most plug-ins make use of services provided by other plug-ins, and many, in turn, offer services that other plug-ins can consume. Some groups of plug-ins are tightly related, such as the group of plug-ins providing Java development tools-the JDT plug-ins-and other plug-ins, such as SWT, stand alone without any awareness of the plug-ins around them. Plug-ins can also expose a means for other plug-ins to customize the functionality they offer, just as a handheld drill has an opening that allows you to insert other attachments such as screwdrivers and sanders. When designing a plug-in, you need to think about what specific plug-ins or services it will need, what it will expose to others, and in what ways it wants to allow itself to be customized by others. - - + + To rephrase all this in Eclipse terminology, plug-ins define their interactions with other plug-ins in a number of ways. First, a plug-in can specify what other plug-ins it _requires_, those that it absolutely cannot live without. A UI plug-in will probably require the SWT plug-in, and a Java development tool will usually require one or more of the JDT plug-ins. Plug-in requirements are specified in the _plug-in manifest file_ (plugin.xml). The following example shows a plug-in that requires only the JFace and SWT plug-ins: +```xml +``` Your plug-in can reference _only_ the classes and interfaces of plug-ins it requires. Attempts to reference classes in other plug-ins will fail. - - + + Conversely, a plug-in can choose which classes and interfaces it wants to expose to other plug-ins. Your plug-in manifest must declare what libraries (JARs) it provides and, optionally, what classes it wants other plug-ins to be able to reference. This example declares a single JAR file and exposes classes only in packages starting with the prefix com.xyz.*: +```xml - + +``` + - - Finally, a plug-in manifest can specify ways that it can be customized (_extension points_) and ways that it customizes the behavior of other plug-ins (_extensions_). - - - + + + See Also: --------- \[\[FAQ\_What\_is\_the\_plug-in\_manifest\_file_%28%3Ctt%3Eplugin.xml%3C%2Ftt%3E%29%3F\]\] - + [FAQ\_What\_are\_extensions\_and\_extension\_points?](./FAQ_What_are_extensions_and_extension_points.md "FAQ What are extensions and extension points?") - + [FAQ\_What\_is\_the\_classpath\_of\_a_plug-in?](./FAQ_What_is_the_classpath_of_a_plug-in.md "FAQ What is the classpath of a plug-in?") diff --git a/docs/FAQ/FAQ_How_do_I_make_my_plug-in_dynamic_aware.md b/docs/FAQ/FAQ_How_do_I_make_my_plug-in_dynamic_aware.md index 1cf0b8c08a2..dcf869d4709 100644 --- a/docs/FAQ/FAQ_How_do_I_make_my_plug-in_dynamic_aware.md +++ b/docs/FAQ/FAQ_How_do_I_make_my_plug-in_dynamic_aware.md @@ -7,18 +7,21 @@ Dynamic awareness requires extra steps that were not required prior to the intro The following is an example of a simple class that maintains its own cache of the set of extensions installed for a given extension point. This example is a bit contrived as simply caching the extension objects has no value. Typically, your plug-in will process the extensions to extract useful information and possibly load one or more classes associated with that extension. The basic structure of this cache example is as follows: +```java public class ExtCache implements IRegistryChangeListener { private static final String PID = "my.plugin"; - private static final String PT_ID = + private static final String PT_ID = PID + "." + "extension.point"; private final HashSet extensions = new HashSet(); ... } +``` The extensions field stores the set of installed extensions for a particular extension point. The cache has a startup method that loads the initial set of extensions and then adds an extension registry listener in order to be notified of future changes: +```java public void startup() { IExtensionRegistry reg = Platform.getExtensionRegistry(); IExtensionPoint pt = reg.getExtensionPoint(PT_ID); @@ -27,11 +30,13 @@ The cache has a startup method that loads the initial set of extensions and then extensions.add(ext[i]); reg.addRegistryChangeListener(this); } +``` The class implements the IRegistryChangeListener interface, which has a single method that is called whenever the registry changes: +```java public void registryChanged(IRegistryChangeEvent event) { - IExtensionDelta[] deltas = + IExtensionDelta[] deltas = event.getExtensionDeltas(PID, PT_ID); for (int i = 0; i < deltas.length; i++) { if (deltas[i].getKind() == IExtensionDelta.ADDED) @@ -40,14 +45,17 @@ The class implements the IRegistryChangeListener interface, which has a single m extensions.remove(deltas[i].getExtension()); } } +``` This class is now dynamic aware but is not yet dynamic enabled; that is, the class does not yet support itself being dynamically removed. The final step is to implement a shutdown method that clears all values from the cache and removes the listener from the extension registry: +```java public void shutdown() { extensions.clear(); IExtensionRegistry reg = Platform.getExtensionRegistry(); reg.removeRegistryChangeListener(this); } +``` This shutdown method must be called from the shutdown method of the plug-in that defines the cache. For the complete source code of this example, see the ExtCache class in the FAQ Examples plug-in. diff --git a/docs/FAQ/FAQ_How_do_I_make_my_view_appear_in_the_Show_In_menu.md b/docs/FAQ/FAQ_How_do_I_make_my_view_appear_in_the_Show_In_menu.md index 3e8e439f6e9..ec40113e833 100644 --- a/docs/FAQ/FAQ_How_do_I_make_my_view_appear_in_the_Show_In_menu.md +++ b/docs/FAQ/FAQ_How_do_I_make_my_view_appear_in_the_Show_In_menu.md @@ -7,17 +7,19 @@ The **Navigate > Show In** menu displays a list of views that the user can jump The active perspective gets to decide what views appear in this list, but you can contribute your views to this list by using the perspectiveExtensions extension point. Here is an extension definition that adds the bookshelf example Chapters view to the **Show In** menu of the Resource perspective: +```xml - +``` - The Chapters view then implements the show method from the IShowInTarget interface. This method is called by the platform when the user selects the view in the **Show In** menu. The method has a parameter, ShowInContext, that is passed from the view that is the source of the **Show In** action. The method must return true if it accepts the context as a valid input for that view and false otherwise. Here is the example implementation from the Chapters view: +```java public boolean show(ShowInContext context) { if (viewer == null || context == null) return false; @@ -32,12 +34,15 @@ The Chapters view then implements the show method from the IShowInTarget interfa } return false; } +``` A view that wants to act as a source for the **Show In** menu must implement IShowInSource. This interface defines the method getShowInContext, which creates the context object to be passed to the target. In our bookshelf example, the Books view will act as a **Show In** source by implementing the getShowInContext method as follows: +```java public ShowInContext getShowInContext() { return new ShowInContext(null, viewer.getSelection()); } +``` The context instance may contain an input object and a selection. If your view needs to provide extra context information, you can create your own ShowInContext subclass that carries additional data. Of course, only views that know about that special subclass will be able to make use of the extra information, so you should also provide the basic context information if you can. diff --git a/docs/FAQ/FAQ_How_do_I_make_my_wizard_appear_in_the_UI.md b/docs/FAQ/FAQ_How_do_I_make_my_wizard_appear_in_the_UI.md index db3fc3febb0..056844b87f7 100644 --- a/docs/FAQ/FAQ_How_do_I_make_my_wizard_appear_in_the_UI.md +++ b/docs/FAQ/FAQ_How_do_I_make_my_wizard_appear_in_the_UI.md @@ -5,10 +5,12 @@ FAQ How do I make my wizard appear in the UI? To make a wizard appear, you need an implementation of the wizard interface called IWizardContainer. The container is responsible for all the presentation outside the pages themselves, including a title area, button bar, and progress indicator. You can implement this interface yourself if you want to embed a wizard into a custom control. JFace provides a default wizard container that is a simple modal dialog: WizardDialog. The following code snippet opens a wizard in a wizard dialog: +```java Shell shell = window.getShell(); AddingWizard wizard = new AddingWizard(); WizardDialog dialog = new WizardDialog(shell, wizard); int result = dialog.open(); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_open_a_Property_dialog.md b/docs/FAQ/FAQ_How_do_I_open_a_Property_dialog.md index bb635fe9a66..0cdc0b7f5b6 100644 --- a/docs/FAQ/FAQ_How_do_I_open_a_Property_dialog.md +++ b/docs/FAQ/FAQ_How_do_I_open_a_Property_dialog.md @@ -5,9 +5,10 @@ FAQ How do I open a Property dialog? The Property dialog appears when you select an object in a view and choose **Properties...** from the context menu or **File** menu. If you want such an action for your own view or editor, you can simply add an instance of org.eclipse.ui.dialogs.PropertyDialogAction to your view's context menu. This action will compute what property pages are applicable for the current selection and then open a dialog on those property pages. - + You can also open a Property dialog on a set of property pages of your own choosing. This works exactly like the JFace Preference dialog: You supply the dialog with a PreferenceManager instance that knows how to build the set of pages to be shown. The only difference with the Property dialog is that you must also supply it with the current selection: +```java ISelection sel = ... obtain the current selection PropertyPage page = new MyPropertyPage(); PreferenceManager mgr = new PreferenceManager(); @@ -17,6 +18,7 @@ You can also open a Property dialog on a set of property pages of your own choos dialog.create(); dialog.setMessage(page.getTitle()); dialog.open(); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_open_an_editor_on_a_file_in_the_workspace.md b/docs/FAQ/FAQ_How_do_I_open_an_editor_on_a_file_in_the_workspace.md index 775a9785bfb..d4bd84b2ed0 100644 --- a/docs/FAQ/FAQ_How_do_I_open_an_editor_on_a_file_in_the_workspace.md +++ b/docs/FAQ/FAQ_How_do_I_open_an_editor_on_a_file_in_the_workspace.md @@ -5,20 +5,22 @@ FAQ How do I open an editor on a file in the workspace? In Eclipse 2.1, use the openEditor methods on IWorkbenchPage to open files in the workspace. In 3.0, this API was moved to the IDE class in order to remove the dependency between the generic workbench and the workspace. If you use openEditor(IFile), the platform will guess the appropriate editor to use, based on the file extension. - + To open an editor to a particular position, you can create a marker in the file and then use openEditor(IMarker). Be sure to get rid of the marker when you're done. You can specify what editor to open by setting the EDITOR_ID_ATTR on the marker. If you don't do this, the workbench will guess what kind of editor to open from the file extension. The following code snippet opens the default text editor to line 5, using a marker: +```java IFile file = ; IWorkbenchPage page = ; HashMap map = new HashMap(); map.put(IMarker.LINE_NUMBER, new Integer(5)); - map.put(IWorkbenchPage.EDITOR\_ID\_ATTR, + map.put(IWorkbenchPage.EDITOR\_ID\_ATTR, "org.eclipse.ui.DefaultTextEditor"); IMarker marker = file.createMarker(IMarker.TEXT); marker.setAttributes(map); //page.openEditor(marker); //2.1 API IDE.openEditor(marker); //3.0 API marker.delete(); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_open_an_editor_on_a_file_outside_the_workspace.md b/docs/FAQ/FAQ_How_do_I_open_an_editor_on_a_file_outside_the_workspace.md index c796ff60874..79766cb5cbe 100644 --- a/docs/FAQ/FAQ_How_do_I_open_an_editor_on_a_file_outside_the_workspace.md +++ b/docs/FAQ/FAQ_How_do_I_open_an_editor_on_a_file_outside_the_workspace.md @@ -5,6 +5,7 @@ FAQ How do I open an editor on a file outside the workspace? Since 3.3 you can use the new EFS support to open an text editor on a file outside the workspace: +```java String name = new FileDialog(aShell, SWT.OPEN).open(); if (name == null) return; @@ -18,9 +19,11 @@ Since 3.3 you can use the new EFS support to open an text editor on a file outsi /* some code */ } } +``` Alternatively, you can create a _linked resource_ in an existing project, which points to a file elsewhere in the file system. This example snippet creates a project called External Files, and then prompts the user to select any file in the file system. The code then creates a linked resource in the project to that external file, allowing the platform to open the file in read/write mode in one of the standard editors: +```java IWorkspace ws = ResourcesPlugin.getWorkspace(); IProject project = ws.getRoot().getProject("External Files"); if (!project.exists()) @@ -37,6 +40,7 @@ Alternatively, you can create a _linked resource_ in an existing project, which IWorkbenchPage page = window.getActivePage(); if (page != null) page.openEditor(file); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_open_an_editor_on_something_that_is_not_a_file.md b/docs/FAQ/FAQ_How_do_I_open_an_editor_on_something_that_is_not_a_file.md index 68d89f056c9..b87b58ad3a2 100644 --- a/docs/FAQ/FAQ_How_do_I_open_an_editor_on_something_that_is_not_a_file.md +++ b/docs/FAQ/FAQ_How_do_I_open_an_editor_on_something_that_is_not_a_file.md @@ -7,6 +7,7 @@ Since 3.3 you can use the new EFS support to open an text editor on a file store Most editors will accept as input either an IFileEditorInput or an IStorageEditorInput. The former can be used only for opening files in the workspace, but the latter can be used to open a stream of bytes from anywhere. If you want to open a file on a database object, remote file, or other data source, IStorage is the way to go. The only downside is that this is a read-only input type, so you can use it only for viewing a file, not editing it. To use this approach, implement IStorage so that it returns the bytes for the file you want to display. Here is an IStorage that returns the contents of a string: +```java class StringStorage implements IStorage { private String string;   @@ -35,13 +36,14 @@ Most editors will accept as input either an IFileEditorInput or an IStorageEdito return true; } } +``` The class extends PlatformObject to inherit the standard implementation of IAdaptable, which IStorage extends. The getName and getFullPath methods can return null if they are not needed. In this case, we've implemented getName to return the first five characters of the string. The next step is to create an IStorageEditorInput implementation that returns your IStorage object: - +```java class StringInput implements IStorageEditorInput { private IStorage storage; StringInput(IStorage storage) {this.storage = storage;} @@ -61,13 +63,14 @@ The next step is to create an IStorageEditorInput implementation that returns yo return null; } } +``` Again, many of the methods here are optional. The getPersistable method is used for implementing persistence of your editor input, so the platform can automatically restore your editor on start-up. Here, we've implemented the bare essentials: the editor name, and a tool tip. The final step is to open an editor with this input. This snippet opens the platform's default text editor on a given string: - +```java IWorkbenchWindow window = ...; String string = "This is the text file contents"; IStorage storage = new StringStorage(string); @@ -75,6 +78,7 @@ The final step is to open an editor with this input. This snippet opens the plat IWorkbenchPage page = window.getActivePage(); if (page != null) page.openEditor(input, "org.eclipse.ui.DefaultTextEditor"); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_open_an_editor_programmatically.md b/docs/FAQ/FAQ_How_do_I_open_an_editor_programmatically.md index 18acffe8474..a417501bb69 100644 --- a/docs/FAQ/FAQ_How_do_I_open_an_editor_programmatically.md +++ b/docs/FAQ/FAQ_How_do_I_open_an_editor_programmatically.md @@ -5,11 +5,13 @@ FAQ How do I open an editor programmatically? Use the openEditor methods on org.eclipse.ui.IWorkbenchPage to open an editor on a given input. The openEditor methods require you to supply the ID of the editor to open. You can use the editor registry to find out what editor ID is appropriate for a given file name, using the getDefaultEditor method on IEditorRegistry. In Eclipse 3.0, the editor opening methods that were specific to IFile were moved to the IDE class. +```java IWorkbenchPage page = ...; IFile file = ...; IEditorDescriptor desc = PlatformUI.getWorkbench(). getEditorRegistry().getDefaultEditor(file.getName()); page.openEditor(new FileEditorInput(file), desc.getId()); +``` This code needs to run on the UI thread and result from getActiveWorkbenchWindow() and getActivePage() need to be checked against null. @@ -18,6 +20,7 @@ Opening External Files in Eclipse 3.3 The code below is for opening files that are not in the workspace (and hence are not IFiles) in Eclipse 3.3 and higher using [EFS](/EFS "EFS"). +```java import java.io.File; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; @@ -40,6 +43,7 @@ The code below is for opening files that are not in the workspace (and hence are } else { //Do something if the file does not exist } +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_open_an_external_editor.md b/docs/FAQ/FAQ_How_do_I_open_an_external_editor.md index cc4f8cad942..3a7e3725259 100644 --- a/docs/FAQ/FAQ_How_do_I_open_an_external_editor.md +++ b/docs/FAQ/FAQ_How_do_I_open_an_external_editor.md @@ -5,11 +5,13 @@ FAQ How do I open an external editor? A special editor ID is used to indicate that a file should be opened using an external editor. When you ask it to open an editor with this ID, the platform delegates to the operating system to select and open an appropriate editor for the given input. This ID can be used to open an editor on IFile instances or on any other kind of input that implements IPathEditorInput. Here is an example snippet that opens an external editor on an IFile instance: +```java IWorkbenchPage page = ...; IFile file = ...; page.openEditor( new FileEditorInput(file), IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID); +``` Note that this technique applies only to Eclipse 3.0 or greater. On older versions of Eclipse, a special convenience method, openSystemEditor on IWorkbenchPage, accomplished the same task. This method was removed from the workbench API as part of the Eclipse 3.0 rich client refactoring. diff --git a/docs/FAQ/FAQ_How_do_I_open_multiple_instances_of_the_same_view.md b/docs/FAQ/FAQ_How_do_I_open_multiple_instances_of_the_same_view.md index f94485e37f9..d555822022d 100644 --- a/docs/FAQ/FAQ_How_do_I_open_multiple_instances_of_the_same_view.md +++ b/docs/FAQ/FAQ_How_do_I_open_multiple_instances_of_the_same_view.md @@ -5,13 +5,15 @@ FAQ How do I open multiple instances of the same view? Eclipse 3.0 lifts the restriction of allowing only a single instance of each view type. You can now open any number of copies of a given view. Each copy needs a secondary ID to disambiguate the view reference. Here is a snippet that opens two copies of the Books view from the FAQ Examples plug-in: +```java IWorkbenchPage page = ...; String id = "org.eclipse.faq.examples.BooksView"; page.showView(id, "1", IWorkbenchPage.VIEW_VISIBLE); page.showView(id, "2", IWorkbenchPage.VIEW_ACTIVATE); +``` The first parameter is the view ID from the extension definition in the plugin.xml file. The second parameter is an arbitrary string that is used to identify that particular copy of the view. Finally, the third parameter is used to specify whether the view should be created but not made visible (VIEW_CREATE), created and made visible but not made active (VIEW_VISIBLE), or created and made visible and active (VIEW_ACTIVATE). - + Once multiple copies of a view exist, they can be located by using the method IWorkbenchPage.findViewReference, where the primary and secondary view IDs are passed as a parameter. diff --git a/docs/FAQ/FAQ_How_do_I_prevent_builds_between_multiple_changes_to_the_workspace.md b/docs/FAQ/FAQ_How_do_I_prevent_builds_between_multiple_changes_to_the_workspace.md index 399273d80bb..dcdf3df9b26 100644 --- a/docs/FAQ/FAQ_How_do_I_prevent_builds_between_multiple_changes_to_the_workspace.md +++ b/docs/FAQ/FAQ_How_do_I_prevent_builds_between_multiple_changes_to_the_workspace.md @@ -7,6 +7,7 @@ Every time resources in the workspace change, a resource change notification is Two different mechanisms are available for batching changes. To run a series of changes in the current thread, use IWorkspaceRunnable. Here is an example of a workspace runnable that creates two folders: +```java final IFolder folder1 = ..., folder2 = ...; workspace.run(new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) { @@ -14,12 +15,14 @@ Two different mechanisms are available for batching changes. To run a series of folder2.create(IResource.NONE, true, null); } }, null); +``` The other mechanism for batching resource changes is a WorkspaceJob. Introduced in Eclipse 3.0, this mechanism is the asynchronous equivalent of IWorkspaceRunnable. When you create and schedule a workspace job, it will perform the changes in a background thread and then cause a single resource change notification and autobuild to occur. Here is sample code using a workspace job: +```java final IFolder folder1 = ..., folder2 = ...; Job job = new WorkspaceJob("Creating folders") { - public IStatus runInWorkspace(IProgressMonitor monitor) + public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { folder1.create(IResource.NONE, true, null); folder2.create(IResource.NONE, true, null); @@ -27,6 +30,7 @@ The other mechanism for batching resource changes is a WorkspaceJob. Introduced } }; job.schedule(); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_prevent_two_jobs_from_running_at_the_same_time.md b/docs/FAQ/FAQ_How_do_I_prevent_two_jobs_from_running_at_the_same_time.md index c8eb397d5d4..e8aaf693688 100644 --- a/docs/FAQ/FAQ_How_do_I_prevent_two_jobs_from_running_at_the_same_time.md +++ b/docs/FAQ/FAQ_How_do_I_prevent_two_jobs_from_running_at_the_same_time.md @@ -5,6 +5,7 @@ FAQ How do I prevent two jobs from running at the same time? The platform job mechanism uses a pool of threads, allowing it to run several jobs at the same time. If you have many jobs that you want to run in the background, you may want to prevent more than one from running at once. For example, if the jobs are accessing an exclusive resource, such as a file or a socket, you won't want them to run simultaneously. This is accomplished by using job-scheduling rules. A scheduling rule contains logic for determining whether it conflicts with another rule. If two rules conflict, two jobs using those rules will not be run at the same time. The following scheduling rule will act as a mutex, not allowing two jobs with the same rule instance to run concurrently: +```java public class MutexRule implements ISchedulingRule { public boolean isConflicting(ISchedulingRule rule) { return rule == this; @@ -13,9 +14,11 @@ The platform job mechanism uses a pool of threads, allowing it to run several jo return rule == this; } } +``` The rule is then used as follows: +```java Job job1 = new SampleJob(); Job job2 = new SampleJob(); MutexRule rule = new MutexRule(); @@ -23,6 +26,7 @@ The rule is then used as follows: job2.setRule(rule); job1.schedule(); job2.schedule(); +``` When this example is executed, job1 will start running immediately, and job2 will be blocked until job1 finishes. Once job1 is finished, job2 will be run automatically. diff --git a/docs/FAQ/FAQ_How_do_I_prompt_the_user_to_select_a_file_or_a_directory.md b/docs/FAQ/FAQ_How_do_I_prompt_the_user_to_select_a_file_or_a_directory.md index a0343ed266d..4f33ca43ec8 100644 --- a/docs/FAQ/FAQ_How_do_I_prompt_the_user_to_select_a_file_or_a_directory.md +++ b/docs/FAQ/FAQ_How_do_I_prompt_the_user_to_select_a_file_or_a_directory.md @@ -3,13 +3,15 @@ FAQ How do I prompt the user to select a file or a directory? SWT provides native dialogs for asking the user to select a file (FileDialog) or a directory (DirectoryDialog). Both dialogs allow you to specify an initial directory (setFilterPath), and FileDialog also allows you to specify an initial selection (setFileName). Neither of these settings will restrict the user's ultimate choice as the dialogs allow the user to browse to another directory regardless of the filter path. FileDialog also allows you to specify permitted file extensions (setFilterExtensions), and the dialog will not let the user select a file whose extension does not match one of the filters. The following example usage of FileDialog asks the user to open an HTML file: +```java FileDialog dialog = new FileDialog(shell, SWT.OPEN); dialog.setFilterExtensions(new String [] {"*.html"}); dialog.setFilterPath("c:\\temp"); String result = dialog.open(); - +``` + By default, FileDialog allows the user to select only a single file, but with the SWT.MULTI style bit, it can be configured for selecting multiple files. In this case, you can obtain the result by using the getFileNames method. The returned file names will always be relative to the filter path, so be sure to prefix the filter path to the result to obtain the full path. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_provide_F1_help.md b/docs/FAQ/FAQ_How_do_I_provide_F1_help.md index ae09da585d7..de6b608fd49 100644 --- a/docs/FAQ/FAQ_How_do_I_provide_F1_help.md +++ b/docs/FAQ/FAQ_How_do_I_provide_F1_help.md @@ -5,23 +5,27 @@ FAQ How do I provide F1 help? When the user presses F1, context-sensitive help is displayed that briefly describes the action or widget that is currently in focus and provides links to related help topics. You can implement this form of help for your plug-in by associating a _help context ID_ with the actions, menus, and controls in your plug-in. Help is designed in such a way that disruption in the code is kept to an absolute minimum. The help text and links are provided via an extension point and don't even need to reside in the same plug-in as the code that the help text refers to. This makes it easy to make help an optional part of your plug-in or to provide help in various languages. - + The only code required to associate help with your UI component is to link a help context ID to it. This is accomplished by using the various setHelp methods on the WorkbenchHelp class. For example, adding help to a view can be done in the view's createPartControl method: +```java public void createPartControl(Composite parent) { ... - PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, + PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "org.eclipse.faq.examples.books_view"); } +``` The setHelp methods can be used to add help contexts to actions, menus, and arbitrary controls. Because context-sensitive help operates on the control that is in focus, it makes sense to associate help contexts only with controls that are able to take focus. See the help documentation for more details. For actions that are contributed declaratively, help contexts are contributed in the XML action definition. For example, for an action in an actionSet, the context is specified using the helpContextId attribute: +```xml +``` Help contexts are specified declaratively for the following extension points in the Eclipse SDK: @@ -34,7 +38,7 @@ Help contexts are specified declaratively for the following extension points in * org.eclipse.debug.ui.launchShortcuts * org.eclipse.debug.ui.launchConfigurationTabGroups - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_provide_a_keyboard_shortcut_for_my_action.md b/docs/FAQ/FAQ_How_do_I_provide_a_keyboard_shortcut_for_my_action.md index b0caf8184c8..91f8ec48e44 100644 --- a/docs/FAQ/FAQ_How_do_I_provide_a_keyboard_shortcut_for_my_action.md +++ b/docs/FAQ/FAQ_How_do_I_provide_a_keyboard_shortcut_for_my_action.md @@ -24,19 +24,21 @@ Keyboard shortcuts can also be created by defining a _key sequence_, using the o You can also define a key binding that applies only to a particular locale or platform. For example, you can define an accelerator that applies only to a German Linux GTK installation of Eclipse. See the command extension point documentation for more details on these advanced features. -The following is an example key-binding definition. +The following is an example key-binding definition. This binding sets up a toggle comment accelerator for a hypothetical AMPLE language editor, which by default has no key binding: +```xml +``` The difference between a scheme and a context can be confusing at first. The scheme is explicitly set by the user; once it is set, it does not change. The context can be changed programmatically by any plug-in. For example, you can change the context whenever your view or editor becomes active, using AbstractTextEditor.setKeyBindingScopes(). - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_provide_syntax_coloring_in_an_editor.md b/docs/FAQ/FAQ_How_do_I_provide_syntax_coloring_in_an_editor.md index b316aa28a94..bde95cc6cdb 100644 --- a/docs/FAQ/FAQ_How_do_I_provide_syntax_coloring_in_an_editor.md +++ b/docs/FAQ/FAQ_How_do_I_provide_syntax_coloring_in_an_editor.md @@ -7,12 +7,13 @@ Syntax coloring in a JFace text editor is performed by a _presentation reconcile The tokens produced by the presentation reconciler are much more fine-grained than the ones produced by the partition scanner. For example, a Java file may be divided into partitions representing either javadoc or code. Within each partition, the presentation reconciler will produce separate tokens for each set of characters that have the same color and font. So, a Java keyword would be one token, and a string literal would be another. Each partition can have a different presentation reconciler installed, allowing for different rules to be used, depending on the type of content in the partition. - + Once the initial presentation of a document is calculated, it needs to be incrementally maintained as the document is modified. The presentation reconciler uses two helper classes to accomplish this: a damager and a repairer. The damager takes as input a description of how the document changed and produces as output a description of the regions of the document whose presentation needs to be updated. For example, if a user deletes the > character representing the end of a tag in an HTML file, the region up to the next > character now needs to be colored as an HTML tag. The repairer's job is to update the presentation for all the damaged regions. - + This all sounds very complicated, but the text framework will usually do most of this work for you. Typically you simply need to create a set of rules that describe the various tokens in your document. The framework has a default presentation reconciler that allows you to plug these rules into it, and the rest of the reconciling work is done for you. As an example, this is a scanner created by the sample HTML editor for scanning HTML tags: +```java ITokenScanner scanner = new RuleBasedScanner(); IToken string = createToken(colorString); IRule[] rules = new IRule[3]; @@ -24,31 +25,36 @@ This all sounds very complicated, but the text framework will usually do most of rules[2] = new WhitespaceRule(whitespaceDetector); scanner.setRules(rules); scanner.setDefaultReturnToken(createToken(colorTag)); +``` This scanner creates unique tokens for string literals within a tag so it can color them differently. Outside of strings, the rest of the tag is divided into white-space-separated tokens, using a white-space rule. The createToken method instantiates a Token object for a particular color: +```java private IToken createToken(Color color) { return new Token(new TextAttribute(color)); } +``` This scanner is finally fed to a standard presentation reconciler in the SourceConfiguration subclass. You need to specify a different damager/repairer for each partition of your document: +```java public IPresentationReconciler getPresentationReconciler( ISourceViewer sv) { PresentationReconciler rec = new PresentationReconciler(); - DefaultDamagerRepairer dr = + DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getTagScanner()); rec.setDamager(dr, HTML_TAG); rec.setRepairer(dr, HTML_TAG); ... same for other partitions ... return rec; } +``` For more complex documents or for optimized reconciling, you can build your own custom damager and repairer instances by directly implementing IPresentationDamager and IPresentationRepairer, respectively. However, for most kinds of documents, a simple rule-based approach is sufficient. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_react_to_changes_in_source_files.md b/docs/FAQ/FAQ_How_do_I_react_to_changes_in_source_files.md index 1f0288ee76b..eda22060bb3 100644 --- a/docs/FAQ/FAQ_How_do_I_react_to_changes_in_source_files.md +++ b/docs/FAQ/FAQ_How_do_I_react_to_changes_in_source_files.md @@ -5,6 +5,7 @@ FAQ How do I react to changes in source files? Register a workspace resource change listener. Inside our eScript plug-in class, we call +```java IResourceChangeListener rcl = new IResourceChangeListener() { public void resourceChanged(IResourceChangeEvent event) { IResource resource = event.getResource(); @@ -14,6 +15,7 @@ Register a workspace resource change listener. Inside our eScript plug-in class, } }; ResourcesPlugin.getWorkspace().addResourceChangeListener(rcl); +``` We will be notified whenever the file is changed in the workspace under Eclipse's control. Changes made to the files outside Eclipse will not be detected unless the workspace is being explicitly refreshed. Alternatively, a separate worker thread could be used to monitor the file system and inform Eclipse of any files having changed. diff --git a/docs/FAQ/FAQ_How_do_I_run_a_lengthy_process_in_a_wizard.md b/docs/FAQ/FAQ_How_do_I_run_a_lengthy_process_in_a_wizard.md index 71557a9c24c..d223b32fba3 100644 --- a/docs/FAQ/FAQ_How_do_I_run_a_lengthy_process_in_a_wizard.md +++ b/docs/FAQ/FAQ_How_do_I_run_a_lengthy_process_in_a_wizard.md @@ -5,6 +5,7 @@ FAQ How do I run a lengthy process in a wizard? The IWizardContainer passed to your wizard extends the interface called IRunnableContext. This means that you can pass it an IRunnableWithProgress and that it will give progress feedback to the user while it runs. Keep in mind that as with all long-running operations, the container will generally fork a different thread to run your operation. If you want to manipulate any widgets from the operation, you'll have to use Display.asyncExec. The FAQ Examples plug-in includes a sample wizard, called AddingWizard, that computes the sum of two integers, using the wizard container's progress monitor: +```java getContainer().run(true, true, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { int sum = n1 + n2; @@ -18,6 +19,7 @@ The IWizardContainer passed to your wizard extends the interface called IRunnabl monitor.done(); } }); +``` Your wizard can specify whether it needs a progress bar or a simple busy cursor. For operations that may take more than a second, you should use a progress bar. This is done by implementing needsProgressMonitor method on IWizard to return true. diff --git a/docs/FAQ/FAQ_How_do_I_run_an_external_builder_on_my_source_files.md b/docs/FAQ/FAQ_How_do_I_run_an_external_builder_on_my_source_files.md index 592e579124e..c11b4c5535a 100644 --- a/docs/FAQ/FAQ_How_do_I_run_an_external_builder_on_my_source_files.md +++ b/docs/FAQ/FAQ_How_do_I_run_an_external_builder_on_my_source_files.md @@ -7,6 +7,7 @@ Use the default Eclipse text editor to edit the eScript source files, and use an A simple Ant script (build.xml) may look like this: +```xml @@ -15,15 +16,16 @@ A simple Ant script (build.xml) may look like this: - - - +``` Of course, this script can be made more elegant, but it serves to highlight the main problems with the approach. First, we have to compute the project's classpath, which can be quite complex for a plug-in, and pass it to the eScript compiler. Second, we have to explicitly pass in the name of the source file. Third, we need to replicate the JDT's behavior by copying the resulting class file to the project's bin directory. Finally, we have to refresh the workspace so that Eclipse gets notified of the changes in the class files and can rebuild dependant components in the workspace. diff --git a/docs/FAQ/FAQ_How_do_I_save_settings_for_a_dialog_or_a_wizard.md b/docs/FAQ/FAQ_How_do_I_save_settings_for_a_dialog_or_a_wizard.md index 3a24c49679a..29d0846e004 100644 --- a/docs/FAQ/FAQ_How_do_I_save_settings_for_a_dialog_or_a_wizard.md +++ b/docs/FAQ/FAQ_How_do_I_save_settings_for_a_dialog_or_a_wizard.md @@ -11,6 +11,7 @@ Once you have a settings instance, you simply store the data values you want to Finally, the settings must be saved to disk at some point. If you're using the AbstractUIPlugin settings instance, it is saved automatically when the plug-in is shut down. If you created the settings yourself, you have to save the settings manually when you're finished changing them by calling the save method. Note that each plug-in has a state location allotted to it, and you can find out the location by calling getStateLocation on your plug-in instance. The following example loads a settings file from disk, changes some values, and then saves it again: +```java IPath path = ExamplesPlugin.getDefault().getStateLocation(); String filename = path.append("settings.txt").toOSString(); DialogSettings settings = new DialogSettings("Top"); @@ -18,6 +19,7 @@ Finally, the settings must be saved to disk at some point. If you're using the A settings.put("Name", "Joe"); settings.put("Age", 35); settings.save(filename); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_set_the_title_of_a_custom_dialog.md b/docs/FAQ/FAQ_How_do_I_set_the_title_of_a_custom_dialog.md index 97c5d5c88f1..6d449697102 100644 --- a/docs/FAQ/FAQ_How_do_I_set_the_title_of_a_custom_dialog.md +++ b/docs/FAQ/FAQ_How_do_I_set_the_title_of_a_custom_dialog.md @@ -5,10 +5,12 @@ FAQ How do I set the title of a custom dialog? If you have created your own subclass of the JFace Dialog class, you can set the dialog title by overriding the configureShell method: +```java protected void configureShell(Shell shell) { super.configureShell(shell); shell.setText("My Dialog"); } +``` The configureShell method can also be used to set the dialog menu bar image (Shell.setImage), the font (Shell.setFont), the cursor (Shell.setCursor), and other shell attributes. diff --git a/docs/FAQ/FAQ_How_do_I_show_a_given_perspective.md b/docs/FAQ/FAQ_How_do_I_show_a_given_perspective.md index cd92fcb9caa..1b5f05dbc53 100644 --- a/docs/FAQ/FAQ_How_do_I_show_a_given_perspective.md +++ b/docs/FAQ/FAQ_How_do_I_show_a_given_perspective.md @@ -5,9 +5,11 @@ FAQ How do I show a given perspective? Two APIs show a perspective: IWorkbench.showPerspective and IWorkbenchPage.setPerspective. You should generally use the first of these two because it will honor the user's preference on whether perspectives should be opened in the same window or in a separate window. Here's a quick sample snippet that opens the perspective with ID perspectiveID: +```java IWorkbench workbench = PlatformUI.getWorkbench(); - workbench.showPerspective(perspectiveID, + workbench.showPerspective(perspectiveID, workbench.getActiveWorkbenchWindow()); +``` Usually, the method getActiveWorkbenchWindow comes with the caveat that you must check for a null return value. In this case, null is acceptable: The showPerspective method uses the window parameter as a hint about what window to show the perspective in. If a null window is passed, it will pick an appropriate existing window or open a new one. diff --git a/docs/FAQ/FAQ_How_do_I_show_progress_on_the_workbench_status_line.md b/docs/FAQ/FAQ_How_do_I_show_progress_on_the_workbench_status_line.md index a87c05572dd..45182e4a5cd 100644 --- a/docs/FAQ/FAQ_How_do_I_show_progress_on_the_workbench_status_line.md +++ b/docs/FAQ/FAQ_How_do_I_show_progress_on_the_workbench_status_line.md @@ -5,6 +5,7 @@ FAQ How do I show progress on the workbench status line? The status line has two areas for showing progress. The status line manager has a progress monitor that can be used when you want to block the user from continuing to work during an operation. This progress bar is used as follows: +```java IActionBars bars = getViewSite().getActionBars(); IStatusLineManager statusLine = bars.getStatusLineManager(); IProgressMonitor pm = statusLine.getProgressMonitor(); @@ -12,6 +13,7 @@ The status line has two areas for showing progress. The status line manager has pm.worked(1); .... the actual work is done here... pm.done(); +``` If the amount of work to be done can be estimated ahead of time, a more intelligent value can be passed to beginTask, and calls to worked can be used to provide better progress feedback than a continuous animation. diff --git a/docs/FAQ/FAQ_How_do_I_specify_the_order_of_pages_in_a_wizard.md b/docs/FAQ/FAQ_How_do_I_specify_the_order_of_pages_in_a_wizard.md index 3899dcba654..a05502c81d9 100644 --- a/docs/FAQ/FAQ_How_do_I_specify_the_order_of_pages_in_a_wizard.md +++ b/docs/FAQ/FAQ_How_do_I_specify_the_order_of_pages_in_a_wizard.md @@ -5,18 +5,20 @@ FAQ How do I specify the order of pages in a wizard? In its simplest and most common form, a wizard is made up of a static, ordered list of pages. A wizard adds pages to the list by using the Wizard.addPage method, and the **Next** and **Back** buttons simply cycle through this ordered list. For a wizard with a static set of pages, you can simply override the addPages method and add all of your pages at once. This snippet is from AddingWizard in the FAQ Examples plug-in: +```java public class AddingWizard extends Wizard { private AddingWizardPage page1, page2; ... public void addPages() { - page1 = new AddingWizardPage("Page1", + page1 = new AddingWizardPage("Page1", "Please enter the first number"); addPage(page1); - page2 = new AddingWizardPage("Page2", + page2 = new AddingWizardPage("Page2", "Enter another number"); addPage(page2); } } +``` If you want to change the behavior of the wizard, depending on the values that are entered, you can dynamically create new pages or change the page order after the wizard is opened. Pages must still be added to the wizard by using the addPage method, but the progression of pages through the wizard can change, depending on the user's input. This ordering is changed by overriding the wizard methods getNextPage and getPreviousPage, which are called when the user clicks on **Next** or **Back** button. diff --git a/docs/FAQ/FAQ_How_do_I_specify_where_application_data_is_stored.md b/docs/FAQ/FAQ_How_do_I_specify_where_application_data_is_stored.md index 76b13a1f3cc..ae22971e742 100644 --- a/docs/FAQ/FAQ_How_do_I_specify_where_application_data_is_stored.md +++ b/docs/FAQ/FAQ_How_do_I_specify_where_application_data_is_stored.md @@ -3,11 +3,11 @@ FAQ How do I specify where application data is stored? ====================================================== - - - + + + Plug-in metadata, as well as other data associated with an Eclipse application, is usually stored inside the _platform instance location_. This location is also known as the _instance data area_ or the _workspace_. There are a number of ways that your application can specify this location: @@ -26,12 +26,14 @@ from your application's run method before you call PlatformUI.createAndRunWorkbe If you define a location programmatically (either by prompting the user or by other means), you must then set it as follows: +```java URL choice = ... pick a data location Location loc = Platform.getInstanceLocation(); if (loc.setURL(choice, true)) //success! else //location is in use, or is invalid +``` If your end-user is allowed to manipulate the command line directly, there are other things you need to keep in mind. For example, the user may have already picked a location using -data. In this case, Location.isSet() will return true, but you are still responsible for locking the location using Location.lock() to prevent other instances of your application from trying to use the same location concurrently. To see all of the cases that need to be considered take a look at how the Eclipse IDE application does it. Look at IDEApplication.checkInstanceLocation to see all the subtleties of checking and prompting for an instance location. diff --git a/docs/FAQ/FAQ_How_do_I_support_formatting_in_my_editor.md b/docs/FAQ/FAQ_How_do_I_support_formatting_in_my_editor.md index ac2acc51001..82e38cef54f 100644 --- a/docs/FAQ/FAQ_How_do_I_support_formatting_in_my_editor.md +++ b/docs/FAQ/FAQ_How_do_I_support_formatting_in_my_editor.md @@ -7,23 +7,26 @@ The JFace source viewer has infrastructure for supporting content formatters. A The following snippet from the Java source configuration installs a master strategy (JavaFormattingStrategy) that is used to format Java code and a slave formatting strategy for formatting comments: - MultiPassContentFormatter formatter= +```java + MultiPassContentFormatter formatter= new MultiPassContentFormatter( - getConfiguredDocumentPartitioning(viewer), + getConfiguredDocumentPartitioning(viewer), IDocument.DEFAULT_CONTENT_TYPE); formatter.setMasterStrategy( new JavaFormattingStrategy()); formatter.setSlaveStrategy( - new CommentFormattingStrategy(...), + new CommentFormattingStrategy(...), IJavaPartitions.JAVA_DOC); +``` - The work of formatting the characters in the document is performed by the formatting-strategy classes that are installed on the formatter. JFace doesn't provide much common infrastructure for doing this formatting as it is based largely on the syntax of the language you are formatting. - + Finally, you will need to create an action that invokes the formatter. No generic formatting action is defined by the text infrastructure, but it is quite easy to create one of your own. The action's run method can simply call the following on the source viewer to invoke the formatter: +```java sourceViewer.doOperation(ISourceViewer.FORMAT); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_support_multiple_natural_languages_in_my_plug-in_messages.md b/docs/FAQ/FAQ_How_do_I_support_multiple_natural_languages_in_my_plug-in_messages.md index 8885d6bc24f..3c779fab06a 100644 --- a/docs/FAQ/FAQ_How_do_I_support_multiple_natural_languages_in_my_plug-in_messages.md +++ b/docs/FAQ/FAQ_How_do_I_support_multiple_natural_languages_in_my_plug-in_messages.md @@ -3,9 +3,10 @@ FAQ How do I support multiple natural languages in my plug-in messages? Almost all plug-ins in Eclipse use java.util.ResourceBundle, a messages.properties file, and look up messages by using a key. The MessageFormat class can be used to insert parameters into the translated message. Here is an example: +```java String translate(String key, String[] parms) { try { - ResourceBundle bundle = + ResourceBundle bundle = ResourceBundle.getBundle("messages"); String msg = bundle.getString(key); return MessageFormat.format(msg, parms); @@ -13,6 +14,7 @@ Almost all plug-ins in Eclipse use java.util.ResourceBundle, a messages.properti return key; } } +``` Eclipse includes special support to replace constant strings in your plug-in source code by equivalent Java code that uses key-based lookup. Execute the context menu option **Source > Externalize Strings...** and follow the instructions. To save memory, we recommend choosing a short prefix for the generated keys. diff --git a/docs/FAQ/FAQ_How_do_I_switch_from_using_a_Progress_dialog_to_the_Progress_view.md b/docs/FAQ/FAQ_How_do_I_switch_from_using_a_Progress_dialog_to_the_Progress_view.md index 05bc37c5101..7efab9f426d 100644 --- a/docs/FAQ/FAQ_How_do_I_switch_from_using_a_Progress_dialog_to_the_Progress_view.md +++ b/docs/FAQ/FAQ_How_do_I_switch_from_using_a_Progress_dialog_to_the_Progress_view.md @@ -5,6 +5,7 @@ FAQ How do I switch from using a Progress dialog to the Progress view? If you have an existing plug-in that uses a ProgressMonitorDialog, you can easily switch to using the Progress view by rewriting your operation as a org.eclipse.core.runtime.Job. Assume that your original code looks like this: +```java IRunnableWithProgress op = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { runDecathlon(monitor); @@ -14,9 +15,11 @@ If you have an existing plug-in that uses a ProgressMonitorDialog, you can easil IWorkbenchWindow win = wb.getActiveWorkbenchWindow(); Shell shell = win != null ? win.getShell() : null; new ProgressMonitorDialog(shell).run(true, true, op); +``` The equivalent code using org.eclipse.core.runtime.Job would look like this: +```java class DecathlonJob extends Job { public DecathlonJob() { super("Athens decathlon 2004"); @@ -27,6 +30,7 @@ The equivalent code using org.eclipse.core.runtime.Job would look like this: } }; new DecathlonJob().schedule(); +``` Both use an IProgressMonitor to report progress to the user. The major difference is that the ProgressMonitorDialog is a modal dialog and blocks access to the entire UI during the execution of runDecathlon. When a Job is used, it will run in the background, and the user can continue working on something else. diff --git a/docs/FAQ/FAQ_How_do_I_turn_off_autobuilding_of_Java_code.md b/docs/FAQ/FAQ_How_do_I_turn_off_autobuilding_of_Java_code.md index afd839c2174..eeb4fadcdd2 100644 --- a/docs/FAQ/FAQ_How_do_I_turn_off_autobuilding_of_Java_code.md +++ b/docs/FAQ/FAQ_How_do_I_turn_off_autobuilding_of_Java_code.md @@ -5,6 +5,7 @@ FAQ How do I turn off autobuilding of Java code? JDT uses the autobuild facilities provided by the platform. If a resource changes, the platform checks the project description file (see .project in your projects). When the file contains a reference to the Java builder, the builder gets notified of the change and will then compile the Java source file and its dependents. The following project description file snippet shows that the Java builder is associated with the project: +```xml org.eclipse.jdt.core.javabuilder @@ -12,22 +13,23 @@ JDT uses the autobuild facilities provided by the platform. If a resource change +``` If a workspace gets large-say, tens of thousands of files-the process of checking each project, activating all registered builders, and discovering whether anything needs to be rebuilt owing to a single resource save may have a considerable impact on the responsiveness of the workbench. In these situations, autobuild can be turned off through **Window > Preferences > General > Workspace >** **Build automatically**. - + Even for smaller workspaces, turning off autobuilding may be a useful feature. For instance, when importing a large number of plug-ins from CVS, it may make sense to turn off autobuilding first. After all files are checked out, autobuilding is turned on again, and all pending builds are run in one swoop. - - + + See Also: --------- [FAQ\_Where\_can\_I\_find\_information\_about\_writing\_builders?](./FAQ_Where_can_I_find_information_about_writing_builders.md "FAQ Where can I find information about writing builders?") - + [FAQ\_How\_do\_I\_implement\_an\_Eclipse_builder?](./FAQ_How_do_I_implement_an_Eclipse_builder.md "FAQ How do I implement an Eclipse builder?") diff --git a/docs/FAQ/FAQ_How_do_I_use_IAdaptable_and_IAdapterFactory.md b/docs/FAQ/FAQ_How_do_I_use_IAdaptable_and_IAdapterFactory.md index dda4bf28a76..f366f2e52de 100644 --- a/docs/FAQ/FAQ_How_do_I_use_IAdaptable_and_IAdapterFactory.md +++ b/docs/FAQ/FAQ_How_do_I_use_IAdaptable_and_IAdapterFactory.md @@ -21,6 +21,7 @@ As another example, the DeleteResourceAction action deletes a selection of resou In all these cases, the code to perform the adaptation is similar. Here is a simplified version of the DeleteResourceAction code that obtains the selected resource for a given input: +```java Object input = ...; IResource resource = null; if (input instanceof IResource) { @@ -29,11 +30,14 @@ In all these cases, the code to perform the adaptation is similar. Here is a sim IAdaptable a = (IAdaptable)input; resource = (IResource)a.getAdapter(IResource.class); } +``` Note that it is not strictly necessary for the object being adapted to implement IAdaptable. For an object that does not implement this interface, you can request an adapter by directly calling the adapter manager: +```java IAdapterManager manager = Platform.getAdapterManager(); ... = manager.getAdapter(object, IResource.class); +``` For an excellent design story on why Eclipse uses adapters, see Chapter 31 of _Contributing to Eclipse_ by Erich Gamma and Kent Beck. diff --git a/docs/FAQ/FAQ_How_do_I_use_a_SubProgressMonitor.md b/docs/FAQ/FAQ_How_do_I_use_a_SubProgressMonitor.md index 6b1ce4682b8..cbaa012c239 100644 --- a/docs/FAQ/FAQ_How_do_I_use_a_SubProgressMonitor.md +++ b/docs/FAQ/FAQ_How_do_I_use_a_SubProgressMonitor.md @@ -11,11 +11,13 @@ But if every API method you call expects a fresh monitor, how do you implement a If you are lost at this point, it is probably best to look at a simple example. This fictional move method is implemented by calling a copy method, followed by a delete method. The move method estimates that the copying will take 80 percent of the total time, and that the deletion will take 20 percent of the time: +```java public void move(File a, File b, IProgressMonitor monitor) { SubMonitor subMonitor = SubMonitor.convert(monitor, 10); copy(a, b, subMonitor.split(8)); delete(a, subMonitor.split(2)); } +``` The copy and delete methods, in turn, will call beginTask on the SuMonitor that was allocated to it. The copy method might decide to report one unit of work for each 8KB chunk of the file. Regardless of the size of the file, the SubMonitor knows that it can report only eight units of work to the parent monitor and so it will scale reported work units accordingly. diff --git a/docs/FAQ/FAQ_How_do_I_use_image_and_font_registries.md b/docs/FAQ/FAQ_How_do_I_use_image_and_font_registries.md index c976e8dc135..ca97e364b4d 100644 --- a/docs/FAQ/FAQ_How_do_I_use_image_and_font_registries.md +++ b/docs/FAQ/FAQ_How_do_I_use_image_and_font_registries.md @@ -7,6 +7,7 @@ With SWT, you are responsible for managing the lifecycle of such operating syste Sometimes, a resource is used very frequently or must be shared among several widgets for unknown lengths of time. In these situations, the resources can be stored in a permanent registry. JFace provides three such registries: FontRegistry, ImageRegistry, and ColorRegistry. You can instantiate one of these registries yourself or use the global ones accessible from the JFaceResources class. The advantage to using a private instance is that you don't have to worry about your keys overlapping with the keys of another component. Here is an example of creating and accessing images in a private image registry: +```java static final String IMAGE_ID = "my.image"; ... //declaring the image @@ -18,6 +19,7 @@ Sometimes, a resource is used very frequently or must be shared among several wi Button button = new Button(...); Image image = registry.get(IMAGE_ID); button.setImage(image); +``` These registries create resources lazily as they are accessed, thus avoiding the expense of creating resources that may never be used. The resources are disposed of automatically when the display is disposed of. diff --git a/docs/FAQ/FAQ_How_do_I_use_images_defined_by_other_plug-ins.md b/docs/FAQ/FAQ_How_do_I_use_images_defined_by_other_plug-ins.md index f43dd5d2100..5446eefd2bc 100644 --- a/docs/FAQ/FAQ_How_do_I_use_images_defined_by_other_plug-ins.md +++ b/docs/FAQ/FAQ_How_do_I_use_images_defined_by_other_plug-ins.md @@ -5,9 +5,11 @@ FAQ How do I use images defined by other plug-ins? In general, you should not rely on images defined in other plug-ins as they could be changed or removed at any time. The exception to this rule is an image that has been declared by a plug-in as an API. The convention is to create an interface called ISharedImages that defines IDs for all images that you want to declare as API. Several plug-ins, including org.eclipse.ui.workbench, org.eclipse.jdt.ui, and org.eclipse.team.ui, declare such an ISharedImages class. Here is an example snippet that options the folder icon from the workbench's shared image API: +```java IWorkbench workbench = PlatformUI.getWorkbench(); ISharedImages images = workbench.getSharedImages(); Image image = images.getImage(ISharedImages.IMG_OBJ_FOLDER); +``` If you want to share images from your plug-in as API, you should define your own ISharedImages class with constants for all the images you want to make public. diff --git a/docs/FAQ/FAQ_How_do_I_use_progress_monitors.md b/docs/FAQ/FAQ_How_do_I_use_progress_monitors.md index 9b698f1e11b..d83f2bebfdd 100644 --- a/docs/FAQ/FAQ_How_do_I_use_progress_monitors.md +++ b/docs/FAQ/FAQ_How_do_I_use_progress_monitors.md @@ -13,12 +13,14 @@ After allocating the units of work, you should call SubMonitor.split as the task Here is a complete example of a long-running operation reporting progress: +```java SubMonitor subMonitor = SubMonitor.convert(monitor, 10); subMonitor.setTaskName("Performing decathlon: "); subMonitor.subTask("hammer throw"); //perform the hammer throw doHammerThrow(subMonitor.split(1)); //... repeat for remaining nine events +``` The monitor can also be used to respond to cancellation requests. Each call to SubMonitor.split checks if the monitor has been cancelled and will throw OperationCanceledException if so. diff --git a/docs/FAQ/FAQ_How_do_I_use_properties_to_optimize_a_viewer.md b/docs/FAQ/FAQ_How_do_I_use_properties_to_optimize_a_viewer.md index 3062cf047a6..695b6cebcb0 100644 --- a/docs/FAQ/FAQ_How_do_I_use_properties_to_optimize_a_viewer.md +++ b/docs/FAQ/FAQ_How_do_I_use_properties_to_optimize_a_viewer.md @@ -9,28 +9,34 @@ In the context of JFace viewers, _property_ means any aspect that has relevance The interface IBasicPropertyConstants defines some simple properties-parent, children, text, and image-but the set of possible properties is open ended. Let's say, for example, that you have a tree viewer that is showing a person's ancestral tree. The label of each tree item may contain different information, such as the person's name and year of birth. The viewer may have several filters for showing subsets of the family tree, such as gender or hair color. You could define a set of domain-specific properties for that viewer to enumerate all these values: +```java public interface IAncestralConstants { public static final String BIRTH_YEAR = "birth-year"; public static final String NAME = "name"; public static final String GENDER = "gender"; public static final String HAIR_COLOR= "hair-color"; } +``` Note that a property doesn't necessarily represent something that is directly visible but rather something that affects the presentation in some way. The label provider, filters, and sorters associated with the viewer define which properties affect them. In this case, the label provider cares only about the name and birth year, so it would override the isLabelProperty method on IBaseLabelProvider as follows: +```java public boolean isLabelProperty(Object el, String prop) { return IAncestralConstants.NAME.equals(prop) || IAncestralConstants.BIRTH_YEAR.equals(prop); } +``` Similarly, a sorter that sorts entries by name would override the method ViewerSorter.isSorterProperty to return true only for the NAME property. A filter that defines a subset based on hair color would override ViewerFilter.isFilterProperty to return true only for the HAIR_COLOR property. Still not seeing the point of all this? Well, here's the interesting bit. When changes are made to the domain objects, the viewer's update method, defined on StructuredViewer, can be passed a set of properties to help it optimize the update: +```java viewer.update(person, new String[] {NAME}); viewer.update(person, new String[] {GENDER, HAIR_COLOR}); +``` The viewer update algorithm will ask the label provider and any installed sorter and filters whether they are affected by the property being changed. This information can allow the update method to make some very significant optimizations. If the sorter and filters are not affected by the change, the update is very fast. If any sorter or filter is affected by the change, significant work has to be done to update the view. diff --git a/docs/FAQ/FAQ_How_do_I_use_property_pages.md b/docs/FAQ/FAQ_How_do_I_use_property_pages.md index 83ebec7213a..5b0f446298c 100644 --- a/docs/FAQ/FAQ_How_do_I_use_property_pages.md +++ b/docs/FAQ/FAQ_How_do_I_use_property_pages.md @@ -9,7 +9,9 @@ The Property dialog is invoked by selecting an object and pressing Alt+Enter or The Properties view, also known as the property sheet, is not populated using an extension point but is activated through API, by the PDE editors, or manually, through **Window > Show View**. This view, like the Outline view, asks the active workbench part to contribute its contents. When a part becomes active, the property sheet asks it to adapt to IPropertySheetPage, using the IAdaptable mechanism: +```java IWorkbenchPart.getAdapter(IPropertySheetPage.class); +``` If it wants a completely customized property page, the part can respond to this request and provide its own page. If the part does not provide a page, the property sheet presents a default page that solicits key/value pairs from the active part's selection. This again uses the IAdaptable mechanism to ask the selected element whether it wants to contribute properties. This time it asks the element for an implementation of IPropertySource. The property source is responsible for providing its keys and values, changing values, and restoring default values. diff --git a/docs/FAQ/FAQ_How_do_I_use_the_context_class_loader_in_Eclipse.md b/docs/FAQ/FAQ_How_do_I_use_the_context_class_loader_in_Eclipse.md index f16715bbf2b..a50cbcf67c1 100644 --- a/docs/FAQ/FAQ_How_do_I_use_the_context_class_loader_in_Eclipse.md +++ b/docs/FAQ/FAQ_How_do_I_use_the_context_class_loader_in_Eclipse.md @@ -5,11 +5,12 @@ FAQ How do I use the context class loader in Eclipse? In Java, each thread can optionally reference a _context class loader_. This loader can be set at any time by an application and is used for loading classes only when it is explicitly requested to do so. Many code libraries, in particular Java Database Connectivity (JDBC) and Xerces, use the context class loader in factory methods to allow clients of the library to specify what class loader to use. Although the context loader is not used by Eclipse itself, you may need to be aware of it when referencing third-party libraries from within Eclipse. - - + + By default, the context loader is set to be the application class loader, which is not used in Eclipse. Because Eclipse has a separate class loader for each installed plug-in, a default class loader generally does not make sense as the context loader for a given thread. If you are calling third-party libraries that rely on the context loader, you will need to set it yourself. The following code snippet sets the context class loader before calling a library. Note that the code politely cleans up afterward by resetting the context loader to its original value: +```java Thread current = Thread.currentThread(); ClassLoader oldLoader = current.getContextClassLoader(); try { @@ -18,12 +19,12 @@ By default, the context loader is set to be the application class loader, which } finally { current.setContextClassLoader(oldLoader); } +``` + + - - - See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_use_the_platform_debug_tracing_facility.md b/docs/FAQ/FAQ_How_do_I_use_the_platform_debug_tracing_facility.md index c1b94040834..d0f66d10241 100644 --- a/docs/FAQ/FAQ_How_do_I_use_the_platform_debug_tracing_facility.md +++ b/docs/FAQ/FAQ_How_do_I_use_the_platform_debug_tracing_facility.md @@ -8,37 +8,39 @@ Adding tracing to your code During development, it is common practice to print debugging messages to standard output. One common idiom for doing this is - +```java private static final boolean DEBUG = true; ... if (DEBUG) System.out.println("So far so good"); +``` The advantage of this approach is that you can flip the DEBUG field to false when it comes time to deploy your code. The Java compiler will then remove the entire if block from the class file as flow analysis reveals that it is unreachable. The downside of this approach is that all the hard work that went into writing useful debug statements is lost in the deployed product. If your user calls up with a problem, you will have to send a new version of your libraries with the debug switches turned on before you can get useful feedback. Eclipse provides a tracing facility that is turned off by default but can be turned on in the field with a few simple steps. To instrument your code, use Platform.getDebugOption to add conditions to your trace statements: - - private static final String DEBUG_ONE = +```java + private static final String DEBUG_ONE = "org.eclipse.faq.examples/debug/option1"; ... String debugOption = Platform.getDebugOption(DEBUG_ONE); if ("true".equalsIgnoreCase(debugOption)) System.out.println("Debug statement one."); +``` If you do not need dynamic trace enablement or if you are concerned about code clutter or performance, another tracing style yields cleaner and faster source: - +```java private static final boolean DEBUG_TWO = "true".equalsIgnoreCase(Platform.getDebugOption( "org.eclipse.faq.examples/debug/option2")); ... if (DEBUG_TWO) System.out.println("Debug statement two."); +``` - This tracing style is not quite as good as the standard approach outlined at the beginning of this FAQ. Because the debug flag cannot be computed statically, the compiler will not be able to completely optimize out the tracing code. You will still be left with the extra code bulk, but the performance will be good enough for all but the most extreme applications. **Note:** Some projects use Platform.getDebugOption("pluginID/debug") as their master switch. diff --git a/docs/FAQ/FAQ_How_do_I_use_the_platform_logging_facility.md b/docs/FAQ/FAQ_How_do_I_use_the_platform_logging_facility.md index a97f3572e52..f73b20c67d5 100644 --- a/docs/FAQ/FAQ_How_do_I_use_the_platform_logging_facility.md +++ b/docs/FAQ/FAQ_How_do_I_use_the_platform_logging_facility.md @@ -1,20 +1,21 @@ FAQ How do I use the platform logging facility? =============================================== -The Eclipse ILog class provides a simple set of APIs for logging exceptions, warnings, or other information useful in debugging or servicing a deployed Eclipse product. -The intent of the log is to record information that can be used later to diagnose problems in the field. -Because this information is not directed at users, you do not need to worry about translating messages or simplifying explanations into a form that users will understand. +The Eclipse ILog class provides a simple set of APIs for logging exceptions, warnings, or other information useful in debugging or servicing a deployed Eclipse product. +The intent of the log is to record information that can be used later to diagnose problems in the field. +Because this information is not directed at users, you do not need to worry about translating messages or simplifying explanations into a form that users will understand. The idea is that when things go wrong in the field, your users can send you the log file to help you figure out what happened. Each plug-in has its own log associated with it, but all logged information eventually makes its way into the platform log file (see the getLogFileLocation method on Platform). +```java import org.eclipse.core.runtime.ILog; ... public class MyLogger { ... private static final Bundle BUNDLE = FrameworkUtil.getBundle(MyLogger.class); - - + + ... public static void test(){ ILog.get().info("Starting"); @@ -26,16 +27,17 @@ Each plug-in has its own log associated with it, but all logged information even } ILog.get().warn("Creating a warning.."); } +``` -During development, you can browse and manipulate the platform log file using the Error Log view (**Window > Show View > General > Error Log**). +During development, you can browse and manipulate the platform log file using the Error Log view (**Window > Show View > General > Error Log**). You can also have the log file mirrored in the Java console by starting Eclipse with the -consoleLog command-line argument. eclipse -vm c:\\jre\\bin\\java.exe -consoleLog We explicitly pass the VM because on Windows you have to use java.exe instead of javaw.exe if you want the Java console window to appear. -You can also write any kind of IStatus object to the log file, including a MultiStatus if you have hierarchies of information to display. -If you create your own subclass of the utility class Status, you can override the getMessage method to return extra information to be displayed in the log file. +You can also write any kind of IStatus object to the log file, including a MultiStatus if you have hierarchies of information to display. +If you create your own subclass of the utility class Status, you can override the getMessage method to return extra information to be displayed in the log file. diff --git a/docs/FAQ/FAQ_How_do_I_use_the_text_document_model.md b/docs/FAQ/FAQ_How_do_I_use_the_text_document_model.md index bf1b203a71f..1c58cb1a0c7 100644 --- a/docs/FAQ/FAQ_How_do_I_use_the_text_document_model.md +++ b/docs/FAQ/FAQ_How_do_I_use_the_text_document_model.md @@ -5,7 +5,8 @@ FAQ How do I use the text document model? The underlying model behind text editors is represented by the interface IDocument and its default implementation, Document, both of which are declared in the org.eclipse.jface.text package. You can use documents to manipulate text inside and outside a text editor. Documents are created with a simple constructor that optionally takes a string representing the initial input. The document contents can be obtained and replaced by using get() and set(String). The document model has a powerful search method and several methods for querying or replacing portions of the document. The following example uses a document to implement search and replace: - String searchAndReplace(String input, String search, +```java + String searchAndReplace(String input, String search, String replace) throws BadLocationException { Document doc = new Document(input); int offset = 0; @@ -18,11 +19,11 @@ The underlying model behind text editors is represented by the interface IDocume } return doc.get(); } +``` - This example only scratches the surface of the capabilities of the IDocument model. Documents also provide change notification, mapping between line numbers and character offsets, partitions, and much more. Other FAQs in this chapter dig into some of these concepts in more detail. - + See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_I_write_a_message_to_the_workbench_status_line.md b/docs/FAQ/FAQ_How_do_I_write_a_message_to_the_workbench_status_line.md index b046e165906..8c4b34cd6bd 100644 --- a/docs/FAQ/FAQ_How_do_I_write_a_message_to_the_workbench_status_line.md +++ b/docs/FAQ/FAQ_How_do_I_write_a_message_to_the_workbench_status_line.md @@ -7,12 +7,16 @@ When pressing Ctrl+j in a text editor, the editor enters incremental find mode a This can be done from within any view as follows: +```java IActionBars bars = getViewSite().getActionBars(); bars.getStatusLineManager().setMessage("Hello"); +``` Editors can access the status line via IEditorActionBarContributor, which is given a reference to an IActionBars instance in its init method. The contributor is accessed from an editor by using +```java IEditorPart.getEditorSite().getActionBarContributor(); +``` Note that the status line is shared by all views and editors. When the active part changes, the status line updates to show the new active part's message. diff --git a/docs/FAQ/FAQ_How_do_I_write_an_editor_for_my_own_language.md b/docs/FAQ/FAQ_How_do_I_write_an_editor_for_my_own_language.md index deea6ab8d33..902da012c60 100644 --- a/docs/FAQ/FAQ_How_do_I_write_an_editor_for_my_own_language.md +++ b/docs/FAQ/FAQ_How_do_I_write_an_editor_for_my_own_language.md @@ -17,6 +17,7 @@ If you want to see what the minimalist editor looks like, we did the experiment Here is the structure of our minimalist eScript editor: +```java public class Editor extends TextEditor { ... public Editor() { @@ -28,11 +29,13 @@ Here is the structure of our minimalist eScript editor: } ... } +``` In the constructor, we set up a source viewer configuration, handling such issues as Content Assist, hover help, and instructing the editor what to do while the user types text. In the inherited createActions method the editor creates its Content Assist action, used when Ctrl+Space is pressed in the editor. Our configuration looks like this: +```java class Configuration extends SourceViewerConfiguration { public IPresentationReconciler getPresentationReconciler( ISourceViewer sourceViewer) { @@ -53,6 +56,7 @@ Our configuration looks like this: return '''new TextHover()'''; } } +``` We use the default presentation reconciler, and we do not distinguish between sections in our documents. In other words, reconciliation of layout will be the same all over the document, whether we are inside a feature, a plug-in, or a method. We declare a scanner, implemented by us, and rely on the text editor framework to parse the document using our parser when it suits it. @@ -62,14 +66,15 @@ Finally, we create a text-hover that will return a relevant string to be shown i For scanning the underlying document to draw it using different colors and fonts, we deploy RuleBasedScanner, one of the simplest scanners offered by the editor framework: +```java class Scanner extends RuleBasedScanner { public Scanner() { WordRule rule = new WordRule(new IWordDetector() { - public boolean isWordStart(char c) { - return Character.isJavaIdentifierStart(c); + public boolean isWordStart(char c) { + return Character.isJavaIdentifierStart(c); } - public boolean isWordPart(char c) { - return Character.isJavaIdentifierPart(c); + public boolean isWordPart(char c) { + return Character.isJavaIdentifierPart(c); } }); Token keyword = new Token(new TextAttribute(Editor.KEYWORD, null, SWT.BOLD)); @@ -92,6 +97,7 @@ For scanning the underlying document to draw it using different colors and fonts }); } } +``` For each of the keywords in our little language, we define a word entry in our WordRule. We pass our keyword detector, together with rules for recognizing comments, strings, and white spaces to the scanner. With this simple set of rules, the scanner can segment a stream of bytes into sections and then use the underlying rules to color the sections. diff --git a/docs/FAQ/FAQ_How_do_I_write_to_the_console_from_a_plug-in.md b/docs/FAQ/FAQ_How_do_I_write_to_the_console_from_a_plug-in.md index 1427699d233..b8696a4cd67 100644 --- a/docs/FAQ/FAQ_How_do_I_write_to_the_console_from_a_plug-in.md +++ b/docs/FAQ/FAQ_How_do_I_write_to_the_console_from_a_plug-in.md @@ -3,12 +3,13 @@ FAQ How do I write to the console from a plug-in? Many of the people asking this question are confused by the fact that two Eclipse instances are in use when you are developing plug-ins. One is the _development_ platform you are using as your IDE, and the other is the _target_ platform-also known as the runtime workbench-consisting of the plug-ins in the development workbench you are testing against. When a plug-in in the target platform writes a message to System.out or System.err, the message appears in the Console view of the development platform. This view emulates the Java console that appears when Eclipse runs under Windows with java.exe. You should be writing to the console only in this manner when in debug mode (see [FAQ\_How\_do\_I\_use\_the\_platform\_debug\_tracing_facility?](./FAQ_How_do_I_use_the_platform_debug_tracing_facility.md "FAQ How do I use the platform debug tracing facility?")). - + In some situations however, a plug-in in the development platform has a legitimate reason to write to the development platform Console view. Some tools originally designed for the command line, such as Ant and CVS, traditionally use console output as a way of communicating results to the tool user. When these tools are ported for use with an IDE, this console output is typically replaced with richer forms of feedback, such as views, markers, and decorations. However, users accustomed to the old command-line output may still want to see this raw output as an alternative to other visual forms of feedback. Tools in this category can use the Console view to write this output. - + Prior to Eclipse 3.0, each plug-in that wanted console-like output created its own Console view. Eclipse 3.0 provides a single generic Console view that all plug-ins can write to. The view can host several console documents at once and allows the user to switch between different console pages. Each page in the console is represented by an org.eclipse.ui.console.IConsole object. To write to the console, you need to create your own IConsole instance and connect it to the Console view. To do this, you have to add a new dependency to org.eclipse.ui.console in the plugin.xml of your plugin. For a console containing a simple text document, you can instantiate a MessageConsole instance. Here is a method that locates a console with a given name and creates a new one if it cannot be found: +```java private MessageConsole findConsole(String name) { ConsolePlugin plugin = ConsolePlugin.getDefault(); IConsoleManager conMan = plugin.getConsoleManager(); @@ -21,24 +22,26 @@ Prior to Eclipse 3.0, each plug-in that wanted console-like output created its o conMan.addConsoles(new IConsole[]{myConsole}); return myConsole; } +``` - Once a console is created, you can write to it either by directly modifying its IDocument or by opening an output stream on the console. This snippet opens a stream and writes some text to a console: +```java MessageConsole myConsole = findConsole(CONSOLE_NAME); MessageConsoleStream out = myConsole.newMessageStream(); out.println("Hello from Generic console sample action"); +``` - Creating a console and writing to it do not create or reveal the Console view. If you want to make that sure the Console view is visible, you need to reveal it using the usual workbench API. Even once the Console view is revealed, keep in mind that it may contain several pages, each representing a different IConsole provided by a plug-in. Additional API asks the Console view to display your console. This snippet reveals the Console view and asks it to display a particular console instance: +```java IConsole myConsole = ...;// your console instance IWorkbenchPage page = ...;// [obtain the active page](./FAQ_How_do_I_find_the_active_workbench_page.md "FAQ How do I find the active workbench page?") String id = IConsoleConstants.ID_CONSOLE_VIEW; IConsoleView view = (IConsoleView) page.showView(id); view.display(myConsole); +``` - See Also: --------- diff --git a/docs/FAQ/FAQ_How_do_activities_get_enabled.md b/docs/FAQ/FAQ_How_do_activities_get_enabled.md index 3db886193d9..bf37ca5c31f 100644 --- a/docs/FAQ/FAQ_How_do_activities_get_enabled.md +++ b/docs/FAQ/FAQ_How_do_activities_get_enabled.md @@ -13,9 +13,10 @@ There are two kinds of activities When a user starts a new workspace, all activities will typically be disabled. As the user explores the application and starts to use new features, more activities can become enabled as they are needed. This enablement typically happens automatically when the workbench determines that a user is starting to use features defined in a disabled activity. The workbench defines a number of _trigger points_, UI interactions that signal the introduction of a new activity. For example, the Eclipse IDE workbench considers creation of a project to be a trigger point. When a project is created, the workbench looks at the natures on that project and enables any activities that have pattern bindings matching any of the nature IDs. - + You can define your own trigger points for any logical place where new plug-in functionality will be introduced. The trigger point itself doesn't need to know about any particular activities; it simply needs to define an identifier that represents the new functionality. The identifier should be in the form either ``/`` or simply ``. Using that ID, you can enable any matching activities as follows: +```java String id = ... IWorkbench wb = PlatformUI.getWorkbench(); IWorkbenchActivitySupport as = wb.getActivitySupport(); @@ -25,17 +26,18 @@ You can define your own trigger points for any logical place where new plug-in f if (activities.addAll(identifier.getActivityIds())) { as.setEnabledActivityIds(activities); } +``` The exact format of the ID used for your trigger point should be well documented so that activity writers will be able to write appropriate pattern bindings for activating their activities using your trigger points. - + Activities can also be enabled or disabled explicitly by an end user. Again, this is something only the advanced user will do. The success of activities as a mechanism for scalability and progressive disclosure relies on carefully chosen trigger points in the user interface for seamlessly enabling activities. 2\. Expression-enabled activities --------------------------------- -For a description of expression-enabled activities look at [FAQ What is the purpose of activities?](./FAQ_What_is_the_purpose_of_activities.md "FAQ What is the purpose of activities?"). +For a description of expression-enabled activities look at [FAQ What is the purpose of activities?](./FAQ_What_is_the_purpose_of_activities.md "FAQ What is the purpose of activities?"). Expression-enabled activities can, of course, only be enabled through an enablement of their expressions. - + diff --git a/docs/FAQ/FAQ_How_does_OSGi_and_the_new_runtime_affect_me.md b/docs/FAQ/FAQ_How_does_OSGi_and_the_new_runtime_affect_me.md index 45b7d2fde2b..be7cfae7c40 100644 --- a/docs/FAQ/FAQ_How_does_OSGi_and_the_new_runtime_affect_me.md +++ b/docs/FAQ/FAQ_How_does_OSGi_and_the_new_runtime_affect_me.md @@ -9,9 +9,11 @@ By bringing the two together, Eclipse gained the infrastructure for many new fea Now, to the question of how plug-ins are affected: The new runtime is 100 percent backward compatible with the runtime that existed in all versions before Eclipse 3.0. Plug-ins written prior to 3.0 will continue to run without requiring any modification. When you port a plug-in to 3.0, you can still make use of the old runtime API by explicitly importing the backward-compatibility layer, which is found in a separate plug-in. Although the boot and runtime plug-ins were imported automatically prior to Eclipse 3.0, the runtime must now be imported explicitly. The new runtime compatibility plug-in contains the deprecated portions of the API from the boot and runtime plug-ins and also exports the new runtime plug-in. In short, all you now have to import is the new runtime compatibility plug-in, and you will get access to both the new runtime API and the old. The following example from a plugin.xml file imports both the old and new runtimes: +```xml - + +``` Apart from that one change, you can continue using runtime facilities as you did prior to Eclipse 3.0. Over time, more elements of the old runtime will likely become deprecated, and plug-ins will begin to use the equivalent OSGi APIs instead. However, for release 3.0, the focus is on getting the technology in place with minimal disruption to the rest of the platform. For now, the fact that Eclipse is running on OSGi is an implementation detail that will not significantly affect you. diff --git a/docs/FAQ/FAQ_How_does_a_view_persist_its_state_between_sessions.md b/docs/FAQ/FAQ_How_does_a_view_persist_its_state_between_sessions.md index 2c21dd61fa0..c5eba332b24 100644 --- a/docs/FAQ/FAQ_How_does_a_view_persist_its_state_between_sessions.md +++ b/docs/FAQ/FAQ_How_does_a_view_persist_its_state_between_sessions.md @@ -5,6 +5,7 @@ FAQ How does a view persist its state between sessions? Storing view state is done in two commons ways, depending on whether you want to store settings between workbench sessions or across invocations of your view. The first of these facilities is found directly on IViewPart. When the workbench is shut down, the method saveState is called on all open views. The parameter to this method is an IMemento, a simple data structure that stores hierarchies of nodes containing numbers and strings. Here is an example from the recipe application in the FAQ examples, where a view is persisting the current selection of a list viewer in a memento: +```java private static final String STORE_SELECTION = "ShoppingList.SELECTION"; public void saveState(IMemento memento) { super.saveState(memento); @@ -17,9 +18,11 @@ Storing view state is done in two commons ways, depending on whether you want to } memento.putString(STORE_SELECTION, buf.toString()); } +``` When the workbench is reopened, the method init(IViewSite, IMemento) is called the first time each view becomes visible. The IMemento will contain all the information that was added to it when the workbench was shut down. Note that init is called before the createPartControl method, so you will not be able to restore widget state directly from the init method. You can store the IMemento instance in a field and restore state later on when your widgets have been created. Continuing this example, here is the code for restoring the viewer selection when the view is reopened: +```java private IMemento memento; ... public void init(IViewSite site, IMemento memento) @@ -35,6 +38,7 @@ When the workbench is reopened, the method init(IViewSite, IMemento) is called t IStructuredSelection ss = new StructuredSelection(value.split(",")); viewer.setSelection(ss); } +``` Note that the IMemento instance can be null if the view state was not saved from a previous session: for example, when the view is first created. diff --git a/docs/FAQ/FAQ_How_to_create_a_context_menu_and_add_actions_to_the_same.md b/docs/FAQ/FAQ_How_to_create_a_context_menu_and_add_actions_to_the_same.md index 5d49fcd4dbe..a24b776234e 100644 --- a/docs/FAQ/FAQ_How_to_create_a_context_menu_and_add_actions_to_the_same.md +++ b/docs/FAQ/FAQ_How_to_create_a_context_menu_and_add_actions_to_the_same.md @@ -5,13 +5,14 @@ FAQ How to create a context menu and add actions to the same? **To create a Context Menu for your View or Editor do the following :** - + Step 1. Use popupMenus Extension point as explained in the Help of Eclipse. [Creating Popup Menus](https://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/guide/workbench_basicext_popupMenus.htm) Step 2. You need to also register the context menu to the ViewSite or to the EditorSite which will contain the context menu. This is done using the registerContextMenu function available with ISite. The following code snippet explains how to register the context menu to your View. +```java private void hookContextMenu() { MenuManager menuMgr = new MenuManager("#PopupMenu"); menuMgr.setRemoveAllWhenShown(true); @@ -19,7 +20,7 @@ The following code snippet explains how to register the context menu to your Vie .getControl().setMenu(menu); getSite().registerContextMenu(menuMgr, ); } - +``` This function needs to be implemented and then called from createPartControl(). diff --git a/docs/FAQ/FAQ_How_to_decorate_a_TableViewer_or_TreeViewer_with_Columns.md b/docs/FAQ/FAQ_How_to_decorate_a_TableViewer_or_TreeViewer_with_Columns.md index 464e09bfd11..e087ec07be7 100644 --- a/docs/FAQ/FAQ_How_to_decorate_a_TableViewer_or_TreeViewer_with_Columns.md +++ b/docs/FAQ/FAQ_How_to_decorate_a_TableViewer_or_TreeViewer_with_Columns.md @@ -7,9 +7,10 @@ Eclipse does not support decorating TableViewers and TreeViewers with TreeColumn This can be achieved by extending the DecoratingLabelProvider class and creating your own class called as for e.g.TableDecoratingLabelProvider and implement ITableLabelProvider in that class. - + It would look something like this +```java /** * Class that supports Decoration of TableViewer and TreeViewer with TreeColumns */ @@ -67,18 +68,23 @@ It would look something like this } return text; } +``` This class can now handle Trees which have Columns and TableViewers. How you use it is specified below While attaching the LabelProvider to your viewer use this Code +```java ILabelDecorator decorator = PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator(); .setLabelProvider(new TableDecoratingLabelProvider(, decorator)); +``` instead of +```java ILabelDecorator decorator = PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator(); .setLabelProvider(new DecoratingLabelProvider(, decorator)); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_What_is_a_JDOM.md b/docs/FAQ/FAQ_What_is_a_JDOM.md index 48a623ab375..bb66aebebb5 100644 --- a/docs/FAQ/FAQ_What_is_a_JDOM.md +++ b/docs/FAQ/FAQ_What_is_a_JDOM.md @@ -3,9 +3,9 @@ FAQ What is a JDOM? ![Warning2.png](images/Warning2.png) -**JDT's JDOM has been superseded by the [DOM/AST](https://help.eclipse.org/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/AST.html), and should no longer be used.** +**JDT's JDOM has been superseded by the [DOM/AST](https://help.eclipse.org/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/AST.html), and should no longer be used.** + - A JDOM is a Java document object model. DOM is a commonly used term for an object-oriented representation of the structure of a file. A Google definition search turned up this Web definition: _Document Object Model: DOM is a platform- and language-neutral interface, that provides a standard model of how the objects in an XML object are put together, and a standard interface for accessing and manipulating these objects and their interrelationships._ -[Google search for define:Document Object Model](http://www.google.com/search?q=define:Document+Object+Model) @@ -14,6 +14,7 @@ In the context of JDT, the JDOM represents a hierarchical, in-memory representat The class ChangeReturnTypeAction in the FAQ Example plug-in uses the JDOM to change the return type of a selected method. Here is the portion of the action that creates and manipulates the JDOM: +```java String oldContents = ...;//original file contents IMethod method = ...;//the method to change String returnType = ...;//the new return type @@ -26,6 +27,7 @@ The class ChangeReturnTypeAction in the FAQ Example plug-in uses the JDOM to cha IDOMType type = (IDOMType) unit.getChild(typeName); IDOMMethod domMethod = (IDOMMethod) type.getChild(mName); domMethod.setReturnType(returnType); +``` Note that modifications to the DOM occur on a copy of the file contents in memory. If the DOM is modified and then discarded, any changes will also be discarded. The current string representation of the in-memory DOM can be obtained by calling IDOMCompilationUnit.getContents(). To save modifications to disk, you should use a working copy. diff --git a/docs/FAQ/FAQ_What_is_a_document_partition.md b/docs/FAQ/FAQ_What_is_a_document_partition.md index c9874e0f254..7d8ccb36e2c 100644 --- a/docs/FAQ/FAQ_What_is_a_document_partition.md +++ b/docs/FAQ/FAQ_What_is_a_document_partition.md @@ -5,12 +5,13 @@ FAQ What is a document partition? Each document is divided into one or more nonoverlapping _partitions_. Many of the text-framework features can be configured to operate differently for each partition. Thus, an editor can have different syntax highlighting, formatting, or Content Assist for each partition. For example, the Java editor in Eclipse has different partitions for strings, characters, and comments. - + If no partitions are explicitly defined, the single default partition is of type IDocument.DEFAULT\_CONTENT\_TYPE. If the explicitly defined partitions do not span the entire document, all remaining portions of the document implicitly belong to this default partition. In other words, every character in the document belongs to exactly one partition. Most editors define explicit partitions for small portions of the document that need custom behavior, and the bulk of the document remains in the default partition. - + Documents are partitioned by connecting them to an instance of org.eclipse.jface.text.IDocumentPartitioner. In the case of editors, this is usually added by the document provider as soon as the document is created. You can implement the partitioner interface directly if you want complete control, but in most cases you can simply use the default implementation, DefaultPartitioner. This example from the HTML editor defines a partitioner and connects it to a document: +```java IDocumentPartitioner partitioner = new DefaultPartitioner( createScanner(), @@ -19,27 +20,29 @@ Documents are partitioned by connecting them to an instance of org.eclipse.jface HTMLConfiguration.HTML_COMMENT }); partitioner.connect(document); document.setDocumentPartitioner(partitioner); +``` The default partitioner's constructor takes as arguments a scanner and an array of partition types for the document. The _partition scanner_ is responsible for computing the partitions. It is given a _region_ of the document and must produce a set of tokens describing each of the partitions in that region. When a document is created, the scanner is asked to create tokens for the entire document. When a document is changed, the scanner is asked to repartition only the region of the document that changed. Figure 15.2 shows the relationships among editor, document, partitioner, and scanner. - - + + The text framework provides a powerful rule-based scanner infrastructure for creating a scanner based on a set of predicate rules. You simply create an instance of the scanner and plug in the rules that define the regions in your document. Each rule is given a stream of characters and must return a token representing the characters if they match the rule. Browse through the type hierarchy of IPredicateRule to see what default rules are available. The following snippet shows the creation of the scanner for the HTML editor example: +```java IPartitionTokenScanner createScanner() { IToken cmt = new Token(HTMLConfiguration.HTML_COMMENT); IToken tag = new Token(HTMLConfiguration.HTML_TAG); IPredicateRule[] rules = new IPredicateRule[2]; rules[0] = new MultiLineRule("", cmt); rules[1] = new TagRule(tag); - RuleBasedPartitionScanner scanner = + RuleBasedPartitionScanner scanner = new RuleBasedPartitionScanner(); scanner.setPredicateRules(rules); return sc; } +``` - See Also: --------- diff --git a/docs/FAQ/FAQ_What_is_a_label_decorator.md b/docs/FAQ/FAQ_What_is_a_label_decorator.md index 2b9488d81ff..5224d26dcab 100644 --- a/docs/FAQ/FAQ_What_is_a_label_decorator.md +++ b/docs/FAQ/FAQ_What_is_a_label_decorator.md @@ -7,6 +7,7 @@ A DecoratingLabelProvider can be used when an element's text and image need to b Lightweight label decorators were introduced in Eclipse 2.1. These decorators abstract away the details of performing the image overlay. An implementation of ILightWeightLabelDecorator is provided with an IDecoration object, which it calls in order to add the decorations. The following simple example decorates a viewer containing java.io.File objects to indicate whether they are read-only: +```java ImageDescriptor readOnlyOverlay = ...; public void decorate(Object element, IDecoration decoration) { if (!(element instanceof java.io.File)) @@ -17,12 +18,15 @@ Lightweight label decorators were introduced in Eclipse 2.1. These decorators ab decoration.addOverlay(readOnlyOverlay); decoration.addSuffix(" (read only)"); } +``` A decorating label provider is installed on a viewer in the same way as any other label provider: +```java ILabelProvider lp = ... the basic label provider ILabelDecorator decorator = ... the decorator viewer.setLabelProvider(new DecoratingLabelProvider(lp, decorator)); +``` See Also: --------- diff --git a/docs/FAQ/FAQ_What_is_a_viewer.md b/docs/FAQ/FAQ_What_is_a_viewer.md index 9881c07dfd5..e3878a64390 100644 --- a/docs/FAQ/FAQ_What_is_a_viewer.md +++ b/docs/FAQ/FAQ_What_is_a_viewer.md @@ -7,12 +7,14 @@ The purpose of a viewer is to simplify the interaction between an underlying mod A viewer is created by first creating an SWT widget, constructing the viewer on that widget, and then setting its content provider, label provider, and input. This snippet is from the BooksView class in the FAQ Examples plug-in, which creates a table viewer to display a library of books: +```java int style = SWT.MULTI | SWT.H\_SCROLL | SWT.V\_SCROLL; Table table = new Table(parent, style); TableViewer viewer = new TableViewer(table); viewer.setContentProvider(new BookshelfContentProvider()); viewer.setLabelProvider(new BookshelfLabelProvider()); viewer.setInput(createBookshelf()); +``` In general, JFace viewers allow you to create a model-view-controller (MVC) architecture. The view is the underlying SWT widget, the model is specified by the framework user, and the JFace viewer and its associated components form the controller. The viewer input is a model element that seeds the population of the viewer. diff --git a/docs/FAQ/FAQ_What_is_a_working_copy.md b/docs/FAQ/FAQ_What_is_a_working_copy.md index c87425f1f83..9f4bc48c0a6 100644 --- a/docs/FAQ/FAQ_What_is_a_working_copy.md +++ b/docs/FAQ/FAQ_What_is_a_working_copy.md @@ -7,6 +7,7 @@ The Java model supports the creation of so-called working copies of compilation Working copies should generally be used whenever you modify a compilation unit. This ensures that you are modifying the most up-to-date contents of that file, even if they have not yet been written to disk. If you do not use working copies, and a dirty Java editor is open on that file already, the user will be forced to reconcile your changes manually. The following example of using a working copy to replace a compilation unit's contents is from the implementation of ChangeReturnTypeAction included in this book's FAQ Examples plug-in: +```java ICompilationUnit unit = ...; //get compilation unit handle unit.becomeWorkingCopy(null, null); try { @@ -18,6 +19,7 @@ Working copies should generally be used whenever you modify a compilation unit. } finally { unit.discardWorkingCopy(); } +``` You should always put discardWorkingCopy in a finally block to ensure that the working copy opened by becomeWorkingCopy is discarded even in the case of an exception. Although in this example, we simply replaced the old file contents with new contents, the IBuffer API can be used to perform modifications on smaller parts of the buffer, to replace a region, or to append contents to the end of the file. diff --git a/docs/FAQ/FAQ_What_is_an_action_set.md b/docs/FAQ/FAQ_What_is_an_action_set.md index 345b541fb29..cbc3e66b423 100644 --- a/docs/FAQ/FAQ_What_is_an_action_set.md +++ b/docs/FAQ/FAQ_What_is_an_action_set.md @@ -7,6 +7,7 @@ An action set is a logical group of menus and actions that should appear togethe You can create your own action sets, thus contributing to the main menu and toolbar, using the org.eclipse.ui.actionSets extension point. Here is an action set definition from the FAQ examples plug-in: +```xml +``` The action set declaration itself is followed by a series of menu and action attributes, which are discussed in more detail in the FAQs that follow this one. Action sets are an entirely declarative concept. They cannot be defined, customized, or manipulated programmatically. diff --git a/docs/FAQ/FAQ_What_is_the_Java_model.md b/docs/FAQ/FAQ_What_is_the_Java_model.md index 9a505dd2697..bea23503787 100644 --- a/docs/FAQ/FAQ_What_is_the_Java_model.md +++ b/docs/FAQ/FAQ_What_is_the_Java_model.md @@ -5,6 +5,7 @@ The Java model is a hierarchical representation of the Java projects in your wor Using a utility method provided by JavaCore, a Java model is obtained for the workspace. Using the IJavaModel, the Java projects can be inspected. Each project contains a classpath, consisting of multiple package fragment roots, such as source directories in the project or referenced JARs from required plug-ins. Each fragment contains a number of class files. An example of its use is given in the following piece of code: +```java IWorkspace workspace = ResourcesPlugin.getWorkspace(); IJavaModel javaModel = JavaCore.create(workspace.getRoot()); IJavaProject projects[] = javaModel.getJavaProjects(); @@ -29,6 +30,7 @@ Using a utility method provided by JavaCore, a Java model is obtained for the wo String projectName = projects[n].getElementName(); System.out.println("Classpath for project "+ projectName +" contains "+nClasses+" classes."); } +``` The output of this code for a workspace with a single empty Java project is diff --git a/docs/FAQ/FAQ_What_is_the_difference_between_a_path_and_a_location.md b/docs/FAQ/FAQ_What_is_the_difference_between_a_path_and_a_location.md index b4c6343ed56..ba2e0422a05 100644 --- a/docs/FAQ/FAQ_What_is_the_difference_between_a_path_and_a_location.md +++ b/docs/FAQ/FAQ_What_is_the_difference_between_a_path_and_a_location.md @@ -9,6 +9,7 @@ In fact, IPath objects are used in a variety of contexts for locating an object The file-system location of a resource, on the other hand, is returned by the method IResource.getLocation. Methods on IContainer and IWorkspaceRoot can help you convert from one to the other. The following code converts from a path to a location: +```java IPath path = ...; IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceRoot root = workspace.getRoot(); @@ -16,11 +17,13 @@ The file-system location of a resource, on the other hand, is returned by the me if (resource != null) { location = resource.getLocation(); } +``` Note that in some situations, a resource can have a null location. In particular, resources whose project doesn't exist and linked resources that are relative to a nonexistent path variable will have a null location. Here is the converse code to convert from a location to the workspace paths that correspond to it: +```java IPath location = ...; IFile[] files = root.findFilesForLocation(location); IFolder[] folders = root.findContainersForLocation(location); @@ -31,6 +34,7 @@ Here is the converse code to convert from a location to the workspace paths that for (int i = 0; i < folders.length; i++) path = folders[i].getLocation(); } +``` As this snippet shows, a single file-system location can correspond to multiple resources. This is true because linked resources can point to locations inside other projects. Of course, the same file-system location can't correspond to both files and folders at the same time. diff --git a/docs/FAQ/FAQ_What_is_the_difference_between_highlight_range_and_selection.md b/docs/FAQ/FAQ_What_is_the_difference_between_highlight_range_and_selection.md index 545dc913e77..a86919710f8 100644 --- a/docs/FAQ/FAQ_What_is_the_difference_between_highlight_range_and_selection.md +++ b/docs/FAQ/FAQ_What_is_the_difference_between_highlight_range_and_selection.md @@ -5,16 +5,19 @@ FAQ What is the difference between highlight range and selection? ITextEditor has two similar concepts for singling out a portion of the editor contents: _selection_ and _highlight range_. The selection is the highlighted segment of text typically set by the user when dragging the mouse or moving the caret around while holding the shift key. The selection can be obtained programmatically via the editor's selection provider: +```java ITextEditor editor = ...;//the text editor instance ISelectionProvider sp = editor.getSelectionProvider(); ISelection selection = sp.getSelection(); ITextSelection text = (ITextSelection)selection; +``` The selection can also be changed using the selection provider, but ITextEditor provides a convenience method, selectAndReveal, that will change the selection and also scroll the editor so that the new selection is visible. Highlight range also defines a subset of the editor contents, but it cannot be directly manipulated by the user. Its most useful feature is that the editor can be toggled to show only the current highlight range. This is used in the Java editor to support the Show source of selected element only mode. The default implementation of ITextEditor also links the highlight range to the ISourceViewer concept of _range indication_. The source viewer in turn creates an annotation in the vertical ruler bar that shades the portion of the editor corresponding to the highlight range. To use the Java editor as an example again, you'll notice this shading indicates the range of the method currently being edited. The following snippet sets the highlight range of a text editor and then instructs the editor to display only the highlighted portion: +```java ITextEditor editor = ...; editor.setHighlightRange(offset, length, true); editor.showHighlightRangeOnly(true); - +``` diff --git a/docs/FAQ/FAQ_What_is_the_plug-in_manifest_file_plugin_xml.md b/docs/FAQ/FAQ_What_is_the_plug-in_manifest_file_plugin_xml.md index 51c6be648cb..7972e8bcc07 100644 --- a/docs/FAQ/FAQ_What_is_the_plug-in_manifest_file_plugin_xml.md +++ b/docs/FAQ/FAQ_What_is_the_plug-in_manifest_file_plugin_xml.md @@ -5,6 +5,7 @@ FAQ What is the plug-in manifest file (plugin.xml)? The plug-in manifest file, plugin.xml, describes how the plug-in extends the platform, what extensions it publishes itself, and how it implements its functionality. The manifest file is written in XML and is parsed by the platform when the plug-in is loaded into the platform. All the information needed to display the plug-in in the UI, such as icons, menu items, and so on, is contained in the manifest file. The implementation code, found in a separate Java JAR file, is loaded when, and only when, the plug-in has to be run. This concept is referred to as _lazy loading_. Here is the manifest file for a simple plug-in: +```xml @@ -15,10 +16,11 @@ The plug-in manifest file, plugin.xml, describes how the plug-in extends the pla +``` The processing instructions at the beginning specify the XML version and character encoding and that this plug-in was built for version 3.0 of the Eclipse Platform. The plugin element specifies the basic information about the plug-in, including, in this case, the optional class attribute to specify an instance of the Plugin class associated with this plug-in. Because it contains a subclass of Plugin, this plug-in must include a runtime element that specifies the JAR file that contains the code and a requires element to import the org.eclipse.core.runtime plug-in where the superclass resides. The manifest may also specify _extensions_ and _extension points_ associated with the plug-in. Of all this, only the plugin element with the id, name, and version attributes are required. - + It is possible to internationalize the strings within a plugin by moving some of the xml attribute values into .properties files. The PDE will assist you in this as follows: 1. Right click on the plugin.xml or MANIFEST.MF in the project view. @@ -31,11 +33,13 @@ Helpful property names can make a translator's job much easier. These externalized strings will appear in your plugin.xml as, for example: +```java +``` For more information on launch delegates, see the documentation for the org.eclipse.debug.core.launchDelegates extension point and the javadoc for ILaunchConfigurationDelegate in the debug core plug-in. diff --git a/docs/FAQ/FAQ_When_does_my_language_need_its_own_nature.md b/docs/FAQ/FAQ_When_does_my_language_need_its_own_nature.md index 92ef20782f4..acb7db5f26a 100644 --- a/docs/FAQ/FAQ_When_does_my_language_need_its_own_nature.md +++ b/docs/FAQ/FAQ_When_does_my_language_need_its_own_nature.md @@ -19,6 +19,7 @@ Adding a project nature Project natures act as tags on a project to indicate that a certain tool is used to operate on that project. They can also be used to distinguish projects that your plug-in is interested in from the rest of the projects in the workspace. For example, natures can be used to filter declarative extensions that operate only on projects of a particular type. The propertyPages and popupMenus extension points allow you to filter enablement of an extension, based on various properties of the selected resource. One of the properties that this mechanism understands is the nature of a project. Here is an example of an actionSet declaration that operates only on files in projects with the PDE nature: +```xml ... +``` Another reason for using natures is to make use of the nature lifecycle methods when your plug-in is connected to or disconnected from a project. When a nature is added to a project for the first time, the nature's configure method is called. When the nature is removed from the project, the deconfigure method is called. This is an opportunity to initialize metadata on the project and to associate additional attributes, such as builders, with the project. diff --git a/docs/FAQ/FAQ_When_does_my_language_need_its_own_perspective.md b/docs/FAQ/FAQ_When_does_my_language_need_its_own_perspective.md index b0c905d52f3..f6532bd5427 100644 --- a/docs/FAQ/FAQ_When_does_my_language_need_its_own_perspective.md +++ b/docs/FAQ/FAQ_When_does_my_language_need_its_own_perspective.md @@ -9,6 +9,7 @@ Think of perspectives as one of the windows in a virtual desktop manager. When y Perspectives are created by using the org.eclipse.ui.perspectives extension point: +```xml +``` - See Also: --------- diff --git a/docs/FAQ/FAQ_When_should_I_use_refreshLocal.md b/docs/FAQ/FAQ_When_should_I_use_refreshLocal.md index 86b6597f112..95125a9b80b 100644 --- a/docs/FAQ/FAQ_When_should_I_use_refreshLocal.md +++ b/docs/FAQ/FAQ_When_should_I_use_refreshLocal.md @@ -10,23 +10,25 @@ Resources become out of sync with the workspace if they are changed directly in * When you do file I/O using your own natives. * When you launch external builders, tools, or Ant scripts that modify files in the workspace. - + Here is an example snippet that sets the contents of a file using a FileOutputStream, and then uses refreshLocal to synchronize the workspace. This example is a bit contrived, because you could easily use the workspace API in this case. Imagine that the actual file manipulation is buried in some third-party library that you can't change, and this code makes more sense. +```java private void externalModify(IFile iFile) throws ... { java.io.File file = iFile.getLocation().toFile(); FileOutputStream fOut = new FileOutputStream(file); fOut.write("Written by FileOutputStream".getBytes()); iFile.refreshLocal(IResource.DEPTH_ZERO, null); } +``` You might reasonably ask why the workspace does not refresh out of sync files automatically. The answer in Eclipse 3.0 is that it can, with some caveats. The problem is that there is no way to do this efficiently in a platform-neutral way. Some operating systems have callback mechanisms that send notifications when there are changes to particular sections of the file system, but this support doesn't exist on all operating systems that Eclipse runs on. The only way to perform automatic refresh across all platforms is to have a background thread that periodically polls the file system for changes. This clearly can have a steep performance cost, especially since workspaces might easily contain tens of thousands of files. - + The solution in Eclipse 3.0 is to have an auto-refresh capability that is turned off by default. On platforms that have efficient native support for change notification, this can be quite fast. On other platforms, change notification can be very slow. Users who have a need to modify files externally on a regular basis may gladly pay the performance cost to get automatic workspace refresh. Users who do not make external modifications to files, can leave auto-refresh off and avoiding paying a performance penalty for a feature they do not need. This follows the general performance rule of only introducing a performance hit if and when it is actually needed. Auto-refresh can be turned on by checking **Refresh workspace automatically** on the **Workbench** preference page. - + The down side of auto-refresh is that programmatic clients of the workspace API still need to check for and defend against out of sync resources. Resources can be out of sync if auto-refresh is turned off, and they can even be out of sync when auto-refresh is turned on. If you are programmatically modifying files in the workspace externally, you should still perform a refreshLocal to make sure files come back in sync as quickly as possible. - + diff --git a/docs/FAQ/FAQ_Where_are_project_build_specifications_stored.md b/docs/FAQ/FAQ_Where_are_project_build_specifications_stored.md index ef746aebc60..d7bb7ce703f 100644 --- a/docs/FAQ/FAQ_Where_are_project_build_specifications_stored.md +++ b/docs/FAQ/FAQ_Where_are_project_build_specifications_stored.md @@ -5,6 +5,7 @@ FAQ Where are project build specifications stored? A project is built according to the specifications defined in its .project file. To see the .project file for a given project, click on the **Menu** toggle in the Package Explorer's toolbar, select **Filters...**, and deselect **.\* files**. Open the .project file. The .project file for a plug-in should look similar to this: +```xml org.eclipse.escript.builder @@ -13,15 +14,15 @@ A project is built according to the specifications defined in its .project file. - org.eclipse.jdt.core.javabuilder + org.eclipse.jdt.core.javabuilder - org.eclipse.pde.ManifestBuilder + org.eclipse.pde.ManifestBuilder - org.eclipse.pde.SchemaBuilder + org.eclipse.pde.SchemaBuilder @@ -30,8 +31,8 @@ A project is built according to the specifications defined in its .project file. org.eclipse.jdt.core.javanature +``` - See Also: --------- diff --git a/docs/FAQ/FAQ_Where_do_plug-ins_store_their_state.md b/docs/FAQ/FAQ_Where_do_plug-ins_store_their_state.md index b4f19c49828..de955cdef24 100644 --- a/docs/FAQ/FAQ_Where_do_plug-ins_store_their_state.md +++ b/docs/FAQ/FAQ_Where_do_plug-ins_store_their_state.md @@ -11,12 +11,14 @@ Plug-ins can store data that may be shared among several workspaces in two locat Here is an example of obtaining a lock on the user location: +```java Location user = Platform.getUserLocation(); if (user.lock()) { // read and write files } else { // wait until lock is available or fail } +``` Note that these locations are accessible to all plug-ins, so make sure that any data stored here is in a unique subdirectory based on your plug-in's unique ID. Even then, keep in mind that a single user may open multiple workspaces simultaneously that have access to these areas. If you are writing files in these shared locations, you must make sure that you protect read-and-write access by locking the location. diff --git a/docs/FAQ/FAQ_Why_are_some_actions_activated_without_a_target.md b/docs/FAQ/FAQ_Why_are_some_actions_activated_without_a_target.md index 4fd40fe31ec..eefadb0cb52 100644 --- a/docs/FAQ/FAQ_Why_are_some_actions_activated_without_a_target.md +++ b/docs/FAQ/FAQ_Why_are_some_actions_activated_without_a_target.md @@ -11,13 +11,15 @@ Luckily, the workbench added an interface called IActionDelegate2 in version 2.0 This alternative solution allows clients to write more compact code with control flow localized to the execution of the action. A typical action would declare itself as follows: - class Handler extends ActionDelegate +```java + class Handler extends ActionDelegate implements IActionDelegate2 { public void runWithEvent(IAction action, Event event) { - MessageDialog.openInformation(new Shell(), + MessageDialog.openInformation(new Shell(), "Demo", "Handling: "+action+" on "+event); } } +``` Interfaces like IActionDelegate2 are an indication of how a platform like Eclipse struggles with the tension between adoption and innovation. Because too many client plug-ins already depended on the implementation of the old interface IActionDelegate, it could not be easily changed without breaking the existing Eclipse API. Instead, a parallel replacement was added, which is less elegant but comes back in multiple places in Eclipse. The existence of the IActionDelegateWithEvent interface shows how even naming mistakes have to persist for a while as some clients may rely on it. diff --git a/docs/FAQ/FAQ_Why_cant_my_Ant_build_find_javac.md b/docs/FAQ/FAQ_Why_cant_my_Ant_build_find_javac.md index fff761d5bfd..671b747466a 100644 --- a/docs/FAQ/FAQ_Why_cant_my_Ant_build_find_javac.md +++ b/docs/FAQ/FAQ_Why_cant_my_Ant_build_find_javac.md @@ -11,14 +11,15 @@ Ant tasks that include the javac task for compiling Java source will fail if a J This simply means that Ant could not find a Java compiler. The easiest solution is to make sure that tools.jar, which is included with any JDK-as opposed to a JRE-is on Ant's classpath. You can add items to Ant's classpath from the **Ant > Runtime** preference page. If you launch Eclipse by using a full JDK instead of a JRE, tools.jar should appear on the Ant classpath automatically. - + Alternatively, Ant supports the notion of a _compiler adapter_, allowing you to plug in your own Java compiler, such as the Java compiler that is built into Eclipse. The Eclipse compiler adapter is found in the org.eclipse.jdt.core in jdtCompilerAdapter.jar. Again, you need to make sure that this JAR is on Ant's classpath from the Ant preference page. Then, simply add the following line to your build file to specify the compiler: - - +``` + - See Also: --------- diff --git a/docs/FAQ/FAQ_Why_do_I_get_an_invalid_thread_access_exception.md b/docs/FAQ/FAQ_Why_do_I_get_an_invalid_thread_access_exception.md index c9e93acbafc..384cfb3ecdb 100644 --- a/docs/FAQ/FAQ_Why_do_I_get_an_invalid_thread_access_exception.md +++ b/docs/FAQ/FAQ_Why_do_I_get_an_invalid_thread_access_exception.md @@ -9,6 +9,7 @@ When the end user of your application activates a menu or clicks a button, the O Therefore, when an application decides that it needs to live a life on its own, one option is for it to create another Java thread. A typical sample is the following: +```java new Thread(new Runnable() { public void run() { while (true) { @@ -21,6 +22,7 @@ Therefore, when an application decides that it needs to live a life on its own, } } }).start(); +``` This starts a timer that goes off every second and does some work. Because the work will be done in an unsafe thread, we need to request that SWT performs the task in a safe manner. We do this by requesting that the default SWT display runs our runnable when it can using asyncExec. In practice, this request is served as soon as possible. Execution is performed asynchronously. In other words, the request is placed in a queue with all other asyncExec requests and dealt with in a first-come first-served manner. diff --git a/docs/FAQ/FAQ_Why_do_the_names_of_some_interfaces_end_with_the_digit_2.md b/docs/FAQ/FAQ_Why_do_the_names_of_some_interfaces_end_with_the_digit_2.md index c8222333a8e..e4d20f526a4 100644 --- a/docs/FAQ/FAQ_Why_do_the_names_of_some_interfaces_end_with_the_digit_2.md +++ b/docs/FAQ/FAQ_Why_do_the_names_of_some_interfaces_end_with_the_digit_2.md @@ -7,6 +7,7 @@ This evolutionary side effect posed a big dilemma: cause all plug-ins to break a Note that additional overhead can occur. For instance, in class org.eclipse.ui.internal.PluginAction, special code needs to verify that the target implements the interface: +```java public void runWithEvent(Event event) { ... if (delegate instanceof IActionDelegate2) { @@ -21,6 +22,7 @@ Note that additional overhead can occur. For instance, in class org.eclipse.ui.i } ... } +``` The code gets messy owing to an early decision to name the interface differently. Although interfaces were added to Java to separate _types_ from their _implementations_, in the case of a successfully adopted platform such as Eclipse, they are not resilient to evolution. Changing them breaks too much existing code. If subclassing is used, the contract can easily be enhanced with a default implementation in the base class. The subclasses would not have to be changed or even recompiled. diff --git a/docs/FAQ/FAQ_Why_does_the_Eclipse_compiler_create_a_different_serialVersionUID_from_javac.md b/docs/FAQ/FAQ_Why_does_the_Eclipse_compiler_create_a_different_serialVersionUID_from_javac.md index 9e3e11eb262..c701ef049ea 100644 --- a/docs/FAQ/FAQ_Why_does_the_Eclipse_compiler_create_a_different_serialVersionUID_from_javac.md +++ b/docs/FAQ/FAQ_Why_does_the_Eclipse_compiler_create_a_different_serialVersionUID_from_javac.md @@ -7,16 +7,17 @@ You may discover that serializable classes compiled with Eclipse are not compati If you need object serialization, the _only_ way to be safe is to explicitly define the serialVersionUID in your code: +```java class MyClass implements Serializable { public static final long serialVersionUID = 1; } +``` - Then, whenever your class changes shape in a way that will be incompatible with previously serialized versions, simply increment this number. - - + + If you don't explicitly define a serialVersionUID, the language requires that the VM generate one, using some function of all field and method names in the class. The problem is, the compiler generates some _synthetic_ methods that you never see in your source file, and there is no clear specification for how these synthetic method names are generated. Any two compilers are likely to generate different method names, and so the serialVersionUID will be different. Bottom line: Always define the serialVersionUID explicitly in your source files. diff --git a/docs/FAQ/FAQ_Why_dont_my_markers_appear_in_the_editors_vertical_ruler.md b/docs/FAQ/FAQ_Why_dont_my_markers_appear_in_the_editors_vertical_ruler.md index 75564820cb3..00af61aa4e9 100644 --- a/docs/FAQ/FAQ_Why_dont_my_markers_appear_in_the_editors_vertical_ruler.md +++ b/docs/FAQ/FAQ_Why_dont_my_markers_appear_in_the_editors_vertical_ruler.md @@ -5,12 +5,13 @@ FAQ Why don't my markers appear in the editor's vertical ruler? Text editors in Eclipse can display markers in a number of ways. Most commonly, they appear as icons in the vertical ruler on the left-hand side of the editor pane. Markers can also optionally be displayed as squiggly underlines in the text and in the overview ruler on the right-hand side of the editor. How each type of marker is displayed is chosen by the user on the editor preference pages (**Workbench > Editors > Text Editor > Annotations** and **Java > Editor > Annotations**). The IMarker interface declares a number of frequently used marker types. Any created marker that has either the LINE_NUMBER or CHAR_START and CHAR_END attributes set will be displayed by editors. These attributes must exist when the marker is created for the marker to appear in an editor. The most common mistake is to create the marker and then add the attributes in a separate operation. The text framework provides a utility class called MarkerUtilities to make this easier for you. Here is a sample snippet that adds a marker correctly: +```java int lineNumber = ...; HashMap map = new HashMap(); MarkerUtilities.setLineNumber(map, lineNumber); MarkerUtilities.createMarker(resource, map, IMarker.TEXT); +``` - See Also: --------- diff --git a/docs/FAQ/FAQ_Why_is_the_interface_for_my_new_extension_point_not_visible.md b/docs/FAQ/FAQ_Why_is_the_interface_for_my_new_extension_point_not_visible.md index 6e34451c3e6..47cc0341569 100644 --- a/docs/FAQ/FAQ_Why_is_the_interface_for_my_new_extension_point_not_visible.md +++ b/docs/FAQ/FAQ_Why_is_the_interface_for_my_new_extension_point_not_visible.md @@ -5,11 +5,13 @@ FAQ Why is the interface for my new extension point not visible? When you declare a new extension point and a corresponding interface to implement, plug-ins that contribute to your extension point sometimes cannot see your interface. The reason is that your interface may not match the export tag' regular expression in your plug-in's runtime library tag. If your interface is called com.xyz.MyInterface, your plugin.xml should look like this: +```xml name="sample.jar"> +``` Multiple export tags can be used, in addition to wildcards. The default tag set by the PDE is *, indicating that all types in the JAR should be exported. diff --git a/docs/FAQ/FAQ_Why_should_I_add_my_own_project_nature.md b/docs/FAQ/FAQ_Why_should_I_add_my_own_project_nature.md index f04eea78df5..5c8d6c778db 100644 --- a/docs/FAQ/FAQ_Why_should_I_add_my_own_project_nature.md +++ b/docs/FAQ/FAQ_Why_should_I_add_my_own_project_nature.md @@ -17,6 +17,7 @@ Adding a project nature Project natures act as tags on a project to indicate that a certain tool is used to operate on that project. They can also be used to distinguish projects that your plug-in is interested in from the rest of the projects in the workspace. For example, natures can be used to filter declarative extensions that operate only on projects of a particular type. The propertyPages and popupMenus extension points allow you to filter enablement of an extension, based on various properties of the selected resource. One of the properties that this mechanism understands is the nature of a project. Here is an example of an actionSet declaration that operates only on files in projects with the PDE nature: +```xml ... +``` Another reason for using natures is to make use of the nature lifecycle methods when your plug-in is connected to or disconnected from a project. When a nature is added to a project for the first time, the nature's configure method is called. When the nature is removed from the project, the deconfigure method is called. This is an opportunity to initialize metadata on the project and to associate additional attributes, such as builders, with the project. diff --git a/docs/FAQ/FAQ_Why_should_I_use_the_new_progress_service.md b/docs/FAQ/FAQ_Why_should_I_use_the_new_progress_service.md index 168dd280ff2..6f2ead01578 100644 --- a/docs/FAQ/FAQ_Why_should_I_use_the_new_progress_service.md +++ b/docs/FAQ/FAQ_Why_should_I_use_the_new_progress_service.md @@ -7,6 +7,7 @@ Eclipse 3.0 introduced a central new workbench _progress service_. This service The service is used much like the SWT BusyIndicator. Simply pass an IRunnableWithProgress instance to the busyCursorWhile method. The UI will prevent further user input and report progress feedback until the runnable completes. Note that the runnable executes in a non-UI thread, so you will have to use asyncExec or syncExec to execute any code within the runnable that requires access to UI widgets: +```java IWorkbench wb = PlatformUI.getWorkbench(); IProgressService ps = wb.getProgressService(); ps.busyCursorWhile(new IRunnableWithProgress() { @@ -14,6 +15,7 @@ The service is used much like the SWT BusyIndicator. Simply pass an IRunnableWit ... do some long running task } }); +``` This progress service was introduced to unify a number of progress-reporting mechanisms in Eclipse 2.1. JFace provides a Progress Monitor dialog, SWT provides a busy indicator, and the workbench provides a progress indicator on the status line. Each of these mechanisms has its own advantages and disadvantages. The busy cursor is the least obtrusive and works well for tasks that typically take a second or less. The Progress dialog provides much more information and allows the user to cancel but is visually distracting, especially on short tasks as it pops up over the user's work. The status line progress monitor is a bit less obtrusive but doesn't give an obvious indication that the UI is not accepting further input, and the space for presenting progress indication is very constrained. The new progress service tries to achieve a balance by automatically adapting between a busy cursor and a dialog, depending on the situation. diff --git a/docs/Javadoc.md b/docs/Javadoc.md index 2e7268bed88..23e8cdb6944 100644 --- a/docs/Javadoc.md +++ b/docs/Javadoc.md @@ -17,7 +17,9 @@ All HTML tags must be explicitly terminated All HTML tags appearing in Javadoc comments must be explicitly terminated, even the ones that are considered optional in older versions of HTML such as +```html

...

+``` Various internal tools that post-process the extracted HTML documentation into other forms (e.g., Windows help file) need these tags. diff --git a/docs/Progress_Reporting.md b/docs/Progress_Reporting.md index 041b8977743..e25241ec6fd 100644 --- a/docs/Progress_Reporting.md +++ b/docs/Progress_Reporting.md @@ -12,11 +12,13 @@ I recently got to investigate issues in p2 why the progress bar did not move whi The problem is how to handle a case where you need to do something like this: +```java for (int i = 0; i < candidates.length; i++) { if (loadCandidate1(i)) { break; } } +``` Where a call to `loadCandidate(int)` is potentially a long running task. The first loaded candidate means we are done. @@ -25,7 +27,7 @@ Antipattern Here is an implementation of the above example using the antipattern - i.e. "don't do this":   - +```java public void antiPattern(IProgressMonitor monitor) { SubMonitor sub = SubMonitor.convert(monitor, candidates.length); for (int i = 0; i < candidates.length; i++) { @@ -48,6 +50,7 @@ Here is an implementation of the above example using the antipattern - i.e. "don } return false; } +``` Well, what is wrong with this, you may ask...Well, the length of the progress bar will be divided into as many slots as there are candidates, and if the first candidate succeeds and uses its 1000 ticks, and the remaining candidates are never considered, we will end up reporting the 1000 ticks on a fraction of the overall progress bar. This means that for 10 candidates, you will see the progress-bar slowly go to about 10% of the overall length, to suddenly jump to 100%. @@ -56,6 +59,7 @@ Good pattern Here is the good pattern that makes use of the full progress bar: +```java public void goodPattern(IProgressMonitor monitor) { SubMonitor sub = SubMonitor.convert(monitor, 1000); for (int i = 0; i < candidates.length; i++) { @@ -82,6 +86,7 @@ Here is the good pattern that makes use of the full progress bar: } return false; } +``` Notice how [`setWorkRemaining(int)`](http://help.eclipse.org/stable/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/runtime/SubMonitor.html#setWorkRemaining(int)) is called each time in the loop. This reallocates the remaining ticks, but there is no need to compute how many that actually remains, the child allocation of 1000 ticks will always give the child 1000 ticks to report, even if there were not enough ticks left in the parent. All the scaling is performed by the SubMonitor, so you don’t have to worry about it. @@ -92,6 +97,7 @@ Good pattern - regular loop Here is the good pattern for a regular loop where each iteration does consume ticks. +```java public void goodLoopPattern(IProgressMonitor monitor) { SubMonitor sub = SubMonitor.convert(monitor, candidates.length*100); for (int i = 0; i < candidates.length; i++) { @@ -116,6 +122,7 @@ Here is the good pattern for a regular loop where each iteration does consume ti } return false; } +``` Here I simply use SubMonitor’s [`newChild(int)`](http://help.eclipse.org/stable/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/runtime/SubMonitor.html#newChild(int)), this works without calling “done” because the next call to newChild (or “done” for that matter) will consume the ticks allocated for the child. diff --git a/docs/Provisional_API_Guidelines.md b/docs/Provisional_API_Guidelines.md index 51f63779797..d8b645059ca 100644 --- a/docs/Provisional_API_Guidelines.md +++ b/docs/Provisional_API_Guidelines.md @@ -7,10 +7,10 @@ Overview Eclipse APIs undergo a development process, passing through many phases from initial forms to real APIs with guarantees of long term support. It is important that API clients understand the state of the APIs in any given build of Eclipse. -This document sets out API guidelines for the Eclipse Project committers on how to indicate APIs that are still under development and subject to change. +This document sets out API guidelines for the Eclipse Project committers on how to indicate APIs that are still under development and subject to change. These guidelines are also useful for API clients who want to know about the state of a given API they are using. -The development cycle for each major and minor Eclipse project release has a release designated as the API freeze. +The development cycle for each major and minor Eclipse project release has a release designated as the API freeze. The rules for development and treatment of APIs are different for the periods before and after this point, so this document outlines guidelines for both phases of the development cycle. Definition of terms used in this document: @@ -18,7 +18,7 @@ Definition of terms used in this document: **API package**  A package must be exported via the MANIFEST.MF to be considered API. -However, any package that does contain the segment "internal" and which has not set the x-internal or the x-friends directive in the MANIFEST.MF is not API. +However, any package that does contain the segment "internal" and which has not set the x-internal or the x-friends directive in the MANIFEST.MF is not API. See [Naming Conventions](Naming_Conventions.md) for details) **Internal API** @@ -31,15 +31,15 @@ A public Java class or interface in an API package, or a public or protected met **Provisional API** -An API element that has not existed in any release of the Eclipse project. -All provisional API is subject to arbitrary change or removal without any notice. -This document refers to all non-final APIs as provisional APIs. +An API element that has not existed in any release of the Eclipse project. +All provisional API is subject to arbitrary change or removal without any notice. +This document refers to all non-final APIs as provisional APIs. Provisional API has set the x-internal or the x-friends directive for the package in the MANIFEST.MF Before the API freeze --------------------- -Prior to the API freeze, any API element that did not exist in the previous release is provisional by definition. This is true regardless of the package name, bundle manifest, or javadoc of the types involved. +Prior to the API freeze, any API element that did not exist in the previous release is provisional by definition. This is true regardless of the package name, bundle manifest, or javadoc of the types involved. However, the conventions below should be used to indicate where API is provisional. ### Package naming @@ -50,13 +50,13 @@ New code that are not intended to become API in time for one of the upcoming rel ### Bundle manifest -All API packages should be exported unconditionally by the bundle manifest. +All API packages should be exported unconditionally by the bundle manifest. If internal packages are exported, they should be marked via the x-internal or the x-friends directive in the MANIFEST.MF. ### Javadoc -The primary indicator of provisional API is the @since tag, indicating that it was introduced during the current development period. -For example, during development leading up to the 3.4 release of Eclipse, a tag of @since 3.4 designates provisional API. +The primary indicator of provisional API is the @since tag, indicating that it was introduced during the current development period. +For example, during development leading up to the 3.4 release of Eclipse, a tag of @since 3.4 designates provisional API. If the API is particularly volatile, experimental, or at risk of removal, a further comment in the javadoc can be used to clarify the state of the API: *

@@ -64,53 +64,53 @@ If the API is particularly volatile, experimental, or at risk of removal, a furt * part of a work in progress. There is no guarantee that this API will * work or that it will remain the same. Please do not use this API without * consulting with the team. - *

` + *

` + - Though not required, inserting this paragraph in your class or interface javadoc makes the state of the API very clear to potential clients. By indicating the name of the responsible team in the comment, you allow for interaction with prospective clients. If a prospective API client contacts the developer of the provisional API, they can agree on a certain level of stability and advanced warning before changes are made in the API. Also note that while you don't need to use the exact template described above, a consistent template does make it easier to find and remove these comments when finalizing the API. After the API freeze -------------------- -From the perspective of code maintenance, there is really no such thing as "provisional API". -Either it is complete and committed platform API, or it is internal code. -API that is new in the current release cycle is still subject to change, but changes after this point are rare and require approval from the Eclipse project [PMC](https://eclipse.dev/eclipse/team-leaders.php). +From the perspective of code maintenance, there is really no such thing as "provisional API". +Either it is complete and committed platform API, or it is internal code. +API that is new in the current release cycle is still subject to change, but changes after this point are rare and require approval from the Eclipse project [PMC](https://eclipse.dev/eclipse/team-leaders.php). -Note that there are no guarantees about the existence or shape of internal code, even if the package name or comments suggest that it may become API in the next release. -In particular, the API contract (binary upwards compatibility) does not apply. -Clients who think they must use internal code may do so at their own risk, or with slightly less risk if they can reach an agreement with the team that developed the internal code. +Note that there are no guarantees about the existence or shape of internal code, even if the package name or comments suggest that it may become API in the next release. +In particular, the API contract (binary upwards compatibility) does not apply. +Clients who think they must use internal code may do so at their own risk, or with slightly less risk if they can reach an agreement with the team that developed the internal code. Note also that in such cases, the required versions for plug-in dependencies need to be specified with great care. ### Package naming -All internal code that is not intended to become API at some point must be in a package whose name contains the segment "internal". +All internal code that is not intended to become API at some point must be in a package whose name contains the segment "internal". Internal code that is planned to become API in a future release must be marked as internal via the x-internal or x-friends directive in the MANIFEST.MF. ### Bundle manifest -All API packages should be exported unconditionally by the bundle manifest. +All API packages should be exported unconditionally by the bundle manifest. Internal packages may also exported, they must be marked as x-internal in this case. ### Javadoc -No special javadoc treatment for internal code is needed. -Note that @since tags also have little significance for internal code at this point. -If internal code is added in the 3.4 development period, but promoted to real API in the 3.5 development period, the correct tag for that API will be @since 3.5. +No special javadoc treatment for internal code is needed. +Note that @since tags also have little significance for internal code at this point. +If internal code is added in the 3.4 development period, but promoted to real API in the 3.5 development period, the correct tag for that API will be @since 3.5. The experimental javadoc paragraph can be left in the class or interface comment, but is not required. Changing provisional APIs ------------------------- -Technically, a provisional API can change arbitrarily or be removed at any time without notice. -Clients in the greater community who are consuming Eclipse milestone and integration builds cannot make any assumptions about the state of any provisional API between any two non-release builds. -However, committers have a shared responsibility to ensure that integration builds are not broken due to changes in provisional APIs. -Known clients of the provisional API within the SDK should be given fair warning and a chance to react before breaking changes are made. +Technically, a provisional API can change arbitrarily or be removed at any time without notice. +Clients in the greater community who are consuming Eclipse milestone and integration builds cannot make any assumptions about the state of any provisional API between any two non-release builds. +However, committers have a shared responsibility to ensure that integration builds are not broken due to changes in provisional APIs. +Known clients of the provisional API within the SDK should be given fair warning and a chance to react before breaking changes are made. As a courtesy to the community, and to minimize the risk of build failures, it is useful to deprecate provisional APIs slated for change or removal in at least one integration build before making the change. Although not required, adding such a temporary tag can ease the transition for early adopters of the API: - * @deprecated This API will be removed in I20380119. Method {@link #blort()} should be used instead.` + * @deprecated This API will be removed in I20380119. Method {@link #blort()} should be used instead.` + - Note that there are no restrictions on changing internal code before or after the API freeze. Since all such code is in internal packages after this point, it can change arbitrarily without notice up to and including the final build of the release. diff --git a/docs/Status_Handling_Best_Practices.md b/docs/Status_Handling_Best_Practices.md index 679885283d4..47b831368c4 100644 --- a/docs/Status_Handling_Best_Practices.md +++ b/docs/Status_Handling_Best_Practices.md @@ -10,10 +10,10 @@ Introduction In software engineering serviceability is also known as supportability, and refers to the ability to debug or perform root cause analysis in pursuit of solving a problem with a product. Serviceability includes the logging of state and the notification of the user. -Eclipse provides a framework to manage the Log file as well as Dialog to notify the user. +Eclipse provides a framework to manage the Log file as well as Dialog to notify the user. This framework allows provider to plug-in their diagnosis tools, providing extra value to the user. -This paper explains the best practices of using the IStatus class. +This paper explains the best practices of using the IStatus class. The second part explains to plug-in provider how to exploit the new ‘StatusHandler’ model, allowing them to contribute to the user interface as well as managing the IStatus we are about to show or log. Before we investigate IStatus, we need to agree on a couple basic principle about logging and error message rendering. @@ -25,14 +25,14 @@ Messages A message is the principal information the user will see in the log or in the User Interface. A message that is logged is supposed to be user consumable and thus follow the same readability and globalization rules as a String rendered in a menu. - + Message content --------------- There are tons of information on how to create a usable message. We rely on your Software Engineering experience to avoid messages like: ‘internal error, please see log’. - + Provide additional information in your message ---------------------------------------------- @@ -42,7 +42,7 @@ We recommend you provide two other pieces of information when you create a messa 1. An explanation of the message. This is a String that will provide more information to the user than a one line message. The explanation should not be too technical, yet provide more value than the message text itself. Once again, information is available on the web. 2. A recommendation of the message. This is a String that will tell the user what he/she should do. When you write this part, put yourself in the shoes of the user and answer the following question: “ok, now what do I do ?” - + Attempt to use a unique identifier ---------------------------------- @@ -52,7 +52,7 @@ Unique identifier could be an int or a String that uniquely tag the message. The 1. It is easier to search a knowledge base with a unique int than the full text of the message. 2. Because messages are translated, a user in a foreign country may send your support team a translated message. If you do not have a unique identifier, it will be difficult for your team to translate it back into the original language. - + Developing messages in eclipse: using the NLS.bind method --------------------------------------------------------- @@ -103,29 +103,31 @@ Most of the framework related to Logging and Error rendering uses an IStatus: * ILog.log(IStatus status) * IProgressMonitorWithBlocking.setBlocked(IStatus reason) * ErrorDialog.openError(Shell parent, String dialogTitle, String message, IStatus status) - - + + Calling the Status API ---------------------- -You should investigate the Status and MultiStatus classes. +You should investigate the Status and MultiStatus classes. We recommend you use the following constructor: +```java public Status(int severity, String pluginId, int code, String message, Throwable exception) - +``` Implementing your own Status ---------------------------- You should consider the following when creating an IStatus instance. -1. Try to create a subclass of IStatus that will carry your specific payload. -An Example in Eclipse 3.3 is the class CVSStatus. +1. Try to create a subclass of IStatus that will carry your specific payload. +An Example in Eclipse 3.3 is the class CVSStatus. The class carries information that diagnostic tool can use to validate CVS. 2. Do not use IStatus.ERROR as a code. Try to use your own code. As an example, look at the Class CVSSTatus. +```java public class CVSStatus extends TeamStatus {   /*** Status codes ***/ @@ -140,6 +142,7 @@ The class carries information that diagnostic tool can use to validate CVS. super(severity, CVSProviderPlugin.ID, code, message, t,null); this.cvsLocation = cvsLocation; } +``` The Eclipse 3.3 Status handler framework ======================================== @@ -164,6 +167,7 @@ Calling the new framework is straight forward. Once your IStatus is created, you Remember the Handler has the last decision about showing and logging. Consider the previous information as a hint to the handler, but do not rely on them for your execution. +```java public void run(IAction action) { // Throw an error to be handled File aConfigurationFile = obtainConfigurationFileFor(authenticatedUser); @@ -183,8 +187,9 @@ Remember the Handler has the last decision about showing and logging. Consider t if (aStream!=null){ try {aStream.close();} catch (Exception e){}; } - } + } } +``` Developing a StatusHandler ========================== @@ -196,22 +201,23 @@ A StatusHandler is the counterpart of StatusManager. As a developer, you will ca Implementing the handle method ------------------------------ +```java public void handle(StatusAdapter statusAdapter, int style) {   // Retrieve IStatus and message - IStatus oldStatus = statusAdapter.getStatus(); + IStatus oldStatus = statusAdapter.getStatus();   // Verify we do not have a CompanyStatusWithID if (!(oldStatus instanceof CompanyStatusWithID)){ String message = oldStatus.getMessage();   //All our ID start with DYNA - if (null!=message && message.startsWith("DYNA")){ + if (null!=message && message.startsWith("DYNA")){   //Remove any unique identifier to not show it to the user int lengthOfUniqueId = message.indexOf(' ');   - String uniqueID = message.substring(0,lengthOfUniqueId); + String uniqueID = message.substring(0,lengthOfUniqueId); message = message.substring(lengthOfUniqueId); message = message + getExplanation(oldStatus); // Retrieve the explanation for this status   @@ -228,6 +234,7 @@ Implementing the handle method   super.handle(statusAdapter, style); } +``` Developing an ErrorSupportProvider ================================== @@ -240,9 +247,9 @@ To Register your SupportArea, you must call the following code Policy.setErrorSupportProvider(); Policy.setErrorSupportProvider(); - - + + We recommend you do it in the Activator class of your bundle, in the start method. Of course you can change it later, for instance in your handle method. In that case, there is no contract that the ErrorSupportProvider you set will be the one receiving the IStatus your are processing. @@ -251,6 +258,7 @@ Implementing the createSupportArea method Implement the createSupportArea method, returning the control you want to show the user. +```java public Control createSupportArea(Composite parent, IStatus status) { parent.addDisposeListener(this); // get notified so we can clean our SWT widgets   @@ -262,15 +270,18 @@ Implement the createSupportArea method, returning the control you want to show t toolkit.getColors().initializeSectionToolBarColors(); ... } +``` Here is a simple example that will open a web page. +```java public Control createSupportArea(Composite parent, IStatus status) { viewer = new Browser(parent, SWT.NONE); viewer.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true)); viewer.setUrl(); return viewer; } +``` We highly recommend you implement an IDisposeListener to clean up after yourself, when the ErrorDialog is closed. diff --git a/docs/VersionNumbering.md b/docs/VersionNumbering.md index 1bdeb0e6b6a..44751fa4c2d 100644 --- a/docs/VersionNumbering.md +++ b/docs/VersionNumbering.md @@ -18,15 +18,15 @@ Each segment captures a different intent: ### When to change the major segment -The major segment number must be increased when a plug-in makes breaking changes to its API. -When the major segment is changed the minor and service segments are reset to 0. +The major segment number must be increased when a plug-in makes breaking changes to its API. +When the major segment is changed the minor and service segments are reset to 0. See [Evolving Java-based APIs](Evolving-Java-based-APIs.md) for details on what constitutes a breaking change. **Example**: From the version 2.2.7, an incompatible change would lead to 3.0.0. By definition, such changes should not be made when working in a maintenance stream. ### When to change the minor segment -The minor segment number must be incremented when a plug-in changes in an "externally visible" way. +The minor segment number must be incremented when a plug-in changes in an "externally visible" way. Examples of externally visible changes include [binary compatible API changes](Evolving-Java-based-APIs-2.md) or an increased minimum Java version via the Bundle-RequiredExecutionEnvironment header in the MANIFEST.MF, significant performance changes, major code rework, adding a new extension point, changing files with a somewhat unclear API status (e.g. changing icons from gif to png), etc. Another way to know when this version number should be changed is by exclusion: it should indicate changes that are neither bug fixes (indicated by the service segment) nor breaking API changes (indicated by the major segment). When the minor segment is changed, the service segment is reset to 0. **Example**: From the version 2.2.7, a minor change would lead to 2.3.0. @@ -45,17 +45,17 @@ This example shows how the version of a plug-in reacts to changes (indicated in First development stream - 1.0.0 - + Second development stream - 1.0.100 (indicates a bug fix) - 1.1.0 (a new API has been introduced) The plug-in ships as 1.1.0 - + Third development stream - 1.1.100 (indicates a bug fix) - 2.0.0 (indicates a breaking change) The plug-in ships as 2.0.0 - + Maintenance stream after 1.1.0 - 1.1.1 The plug-in ships as 1.1.1 @@ -127,16 +127,17 @@ Exported packages being used as service APIs must have a version number. The gui In the Javadoc, @since tags are used to indicate the version of a **plug-in** in which a specific API has been added. Because Javadoc describes API, only the first two segment of the plug-in version number should be used. This represents a change from the previous practice where @since indicated the development stream. In addition to using the plug-in version, we recommend to prefix the version number by the plug-in id. This allows tracking of APIs moving from one plug-in to another (this can happen when a plug-in is split into multiple plug-ins but the package names are kept). **Example**: In the 3.2 development stream, the API of the new plug-in org.eclipse.core.filesystem should be tagged as follows: - +```java /** * This class is the main entry point for clients of the Eclipse file system API. This * class has factory methods for obtaining instances of file systems and file * stores, and provides constants for option values and error codes. - * + * * @noextend This class is not intended to be subclassed by clients. * @noinstantiate This class is not intended to be instantiated by clients. * @since org.eclipse.core.filesystem 1.0 */ +``` Versioning features ------------------- @@ -153,8 +154,8 @@ A branding plug-in should keep its version in sync with its feature. ### To require features or to require bundles -A feature can express its external dependencies as required features, required plug-ins, or a combination of the two. -How dependencies are expressed has consequences on the install-time behavior of your feature, so it is important to understand the different approaches. +A feature can express its external dependencies as required features, required plug-ins, or a combination of the two. +How dependencies are expressed has consequences on the install-time behavior of your feature, so it is important to understand the different approaches. These approaches are described below along with a discussion of their effect. Feature dependencies do not have to express dependencies that are already expressed at the plug-in level. Such duplication or further refinement of dependency information between features and plug-ins may unnecessarily restrict the ability to install the feature. With the classic Eclipse Update Manager that was the default install/update technology prior to Eclipse 3.4, dependency information was required at the feature level because the provisioning technology only reasoned at the level of features. @@ -173,21 +174,21 @@ Expressing dependencies directly at the plug-in level has the benefit of isolati contains plugins: org.eclipse.draw2d 3.1.0 org.eclipse.gef 3.1.0 - + Case 2: It is better to express this as: contains plugins: org.eclipse.draw2d 3.1.0 - org.eclipse.gef 3.1.0 + org.eclipse.gef 3.1.0 requires plugins: org.eclipse.core.runtime 3.1.0 match="compatible" org.eclipse.ui.views 3.1.0 match="compatible" org.eclipse.ui.workbench 3.1.0 match="compatible" org.eclipse.jface 3.1.0 match="compatible" org.eclipse.swt 3.1.0 match="compatible" - - - + + + In case 1, if the version of the org.eclipse.platform feature changes to 4.0.0 (because org.eclipse.core.resources changes its major version number), org.eclipse.gef is required to deliver a new version of its features. In case 2, such changes are transparent to the author of GEF. @@ -198,7 +199,7 @@ In case 1, if the version of the org.eclipse.platform feature changes to 4.0.0 ( #### Require features Use required features when you want another entire feature to be present when your feature is installed. This typically results in a user-level awareness of the required feature, rather than a hidden implementation detail of your feature. -For example, users installing Java EE tools from the [Web Tools Platform](http://www.eclipse.org/webtools/) project also require [Java development tools](https://github.com/eclipse-jdt). +For example, users installing Java EE tools from the [Web Tools Platform](http://www.eclipse.org/webtools/) project also require [Java development tools](https://github.com/eclipse-jdt). This is not just because their plug-ins depend on plug-ins in JDT, but because users of the Java EE tools really expect the full JDT to be there, including documentation, help content, and possibly source. In this case the dependency should be expressed at the feature level to ensure the entire required feature is installed. Feature-level dependencies are also required if you are targeting a platform using the classic Eclipse Update Manager, which operated purely at the level of feature dependencies. ### Feature includes