1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional Eclipse 3 for Java Developers 2006 phần 8 pot

61 318 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 61
Dung lượng 682,95 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

These are defined in the string literals in the properties file, inthe following way: Editor.save.SVG.error=Error saving SVG file {0} in folder {1} If you use such parameters, it is a go

Trang 1

When the root node Eclipse Platform is selected, you will see some additional functions listed on theright side of the window By clicking the Revert to Previous hyperlink you can return to the state of theplatform before you applied the last change to the configuration If you have previously added features

by simply unpacking them into the \eclipse\ root folder, the Process Detected Changes hyperlinkappears By clicking this hyperlink you can perform the missing installation steps for such a feature

Install Handlers

The Eclipse Update Manager can be extended via so-called install handlers These are Java classes that

implement the interface IInstallHandler from the package org.eclipse.update.core (usuallythey extend the standard implementation BaseInstallHandler) The methods of such a class arecalled at specific points of the installation or update process and can perform specific actions

You can predefine an install handler as a global install handler This is done in the manifest file plugin.xmlof a suitable plug-in at the extension point org.eclipse.update.core.installHandlers Alternatively, you can include an install handler in the installation archive.However, in this case, they can be used only within the current installation (a local install handler)

If you want to use an install handler during the installation of a feature, you must declare it on theAdvanced page of the feature manifest feature.xml (see the section “Creating and Editing Features”).There you specify, in the Library field, the name of the archive containing the install handler In theHandler field, you specify the name of the IInstallHandler class If you use a global instead of alocal install handler, the Library field remains empty and the Handler field specifies the identificationunder which the global install handler was installed

A typical application of install handlers is for the installation of resources outside the Eclipse platform,for example, if you want to deploy a specific Java Runtime Environment

Internationalizing Products

I am wary of writing anything about this topic, because there is an excellent article about ization by Dan Kehn, Scott Fairbrother, and Cam-Thu Le on www.eclipse.org A short overviewshould therefore be sufficient A practical example is given in the section “Internationalizing the SpellChecker” of Chapter 13

international-Internationalization is often understood as merely translating texts presented to the end user into anational language This is certainly an important aspect of internationalization, but it is not the only one.For example, the meaning of images may differ from culture to culture and so the images should also beadapted to the target culture You probably are aware of the confusion that date formats (European vs.U.S.) can cause But the placement of GUI elements may also differ from culture to culture Countriessuch as the Arabic nations and Israel, for example, read from right to left, and many Asiatic countriesread from top to bottom A good example of how things can go wrong was an advertisement for a newdetergent in Arabic countries It read: “Big effect in very little time” and displayed the dirty laundry onthe left and the clean laundry on the right!

Trang 2

Similarly, people may have different expectations of where important form elements should be

positioned The various lengths of text constants in different languages may also influence the

layout of screen masks

Despite these layout problems, I will concentrate here on text elements in different languages

Internationalizing other items such as images and icons as well as currency and date formats can often

be achieved by mapping them onto text strings (image name, format string)

Text Constants in Programs

The simplest case is the internationalization of text constants in programs In the Java source editor,Eclipse offers excellent support for this with the context function Source > Externalize Strings This wiz-ard creates a list with all string constants used in a compilation unit Afterward, you can sort these stringconstants into three different categories:

string constant is replaced with a call to an access method This method fetches the string stant at runtime from the properties file with the help of a specified key In addition, the sourceline is suffixed with a comment that looks like this:

Messages.getString("SpellCorrectionView.Replace_5")); //$NON-NLS-1$

is not analyzed in future invocations of the function Externalize Strings For examplemanager.add(new Separator("Additions"));

is translated intomanager.add(new Separator("Additions")); //$NON-NLS-1$

of the function Externalize Strings

The wizard performs all the selected replacements in the source file It also creates a properties filewithin the current package that contains the externalized string constants It also creates a Messagesclass that organizes access to the file via the getString() method

Trang 3

All that remains to do is to translate the properties file into the target language If you use the Java ing convention basename_lang_region_variant.properties for the properties file, the Messageclass will automatically use the correct properties file, depending on the national language of the targethost platform You can then add new languages in the form of new properties files without recompiling

nam-a single Jnam-avnam-a clnam-ass

In some cases, it may be necessary to embed program-generated values into the string constants Thiscan be done with the help of parameters These are defined in the string literals in the properties file, inthe following way:

Editor.save.SVG.error=Error saving SVG file {0} in folder {1}

If you use such parameters, it is a good idea to extend the Messages class with a parameterized variant

of the method getString():

public static String getString(String key, Object[] params) {

if (params == null) return getString(key);

try {return java.text.MessageFormat.format(getString(key), params);

} catch (Exception e) {return "!"+key+"!";

}}

Text Constants in Manifest Files

To internationalize the various manifest files such as plugin.xml, feature.xml, fragment.xml,site.xml, about.ini, etc requires a bit more work, because there is no tool support for this task.Here, you need to create a corresponding properties file for each of these files: plugin.properties,feature.properties, site.properties, about.properties, etc The exception is

fragment.xml Instead of fragment.properties, the file plugin.properties is used

In the original file, replace the translatable string constants with key strings that are identified via a fixed % character In the corresponding properties file, specify the key definition You can translate thesefiles into the target language afterward, as discussed in the previous section

pre-Here is an example of the definition of an Action Set in the manifest file plugin.xml:

Trang 4

Help Texts and Cheat Sheets

In the case of help pages and Cheat Sheets this approach is not suitable Instead, you need to

translate the whole page You must create a separate folder for each language in which to store the translated pages

At runtime, the correct folder is selected by evaluating substitution variables Eclipse understands fourdifferent substitution variables that can modify library paths:

os This variable is replaced by a token representing the current operation

system (linux, macosx, qnx, solaris, win32)

ws This variable is replaced by a token representing the current windowing

system (carbon, gtk, motif, photon, win32)

nl This variable is replaced by the current Java locale

arch This variable is replaced by a token representing the current processor

architecture (PA_RISC, ppc, sparc, x86)

When you want to test a plug-in that uses these variables, you can set the variables under Window >Preference > Plug-in Development > Target Environment

For example, if you specify a Cheat Sheet (see the section “The Help System” in Chapter 11) in plugin.xml, you can use a substitution variable for the folder name:

Unfortunately, this approach has a severe disadvantage: if a specific language package is not available,Eclipse will simply show nothing instead of the standard English version Fortunately, there is an alter-native, which works without substitution variables This alternative approach relies solely on namingconventions If you want, for example, to create help pages and Cheat Sheets in the German language,you would store them under the directory nl/de (for all German language areas) and nl/de/DE (forGermany only) At runtime, Eclipse evaluates the Locale information of the JVM and tries to find anappropriate folder under the nl/ directory If such a folder is not found, the standard help pages andCheat Sheets (usually in English) are used These pages are not stored under the nl/ directory

Trang 5

Deploying National Language Resource Bundles

The best method is to deploy language bundles as separate fragments (see “Plug-ins and Fragments”)

To do so, just create a package structure within the new fragment that mirrors the package structure ofthe corresponding plug-in However, the fragment packages contain only the properties files that havebeen translated into the target language The translated nl/ folders are also included in the fragment.You must mark these folders on the Build page of the manifest editor for inclusion into the deployment

archive (see the section “Deploying a Feature”) An exception to the rule is the plugin_locale.xml files,

which must be stored in the src/ directory instead of the project folder

Patches

When a product is deployed and then bugs are later discovered, it is often unacceptable for the customer

to reinstall the whole product, especially if the product is large Download times are lengthy in suchcases, and sometimes an online update is impossible Fixing bugs by sending CDs to customers isexpensive Fortunately, Eclipse-based applications have a modular structure that enables a partialupdate

The Eclipse Feature Patch allows exactly that Instead of redeploying the entire updated feature, you can create a feature patch that contains only the modified plug-ins The Eclipse Update Manager is intel-ligent enough to merge the patch into the installed feature

To create a Feature Patch, create a new project by choosing File > New > Other > Plug-in Development >Feature Patch In the wizard enter a project name, and continue to the next page There define a patch ID,

a patch name, and the patch provider Then select the feature to be patched On the Included Plug-insand Fragments page, select the plug-ins and fragments that go into the patch Then press Finish TheFeature Patch project is now ready for deployment It can be deployed like any other feature project

Summar y

In this chapter I have discussed additional concepts required for creating Eclipse-based products Youshould now know what fragments and features are and how they relate to plug-ins You should be able

to internationalize and customize your application and to deploy such an application

In the next chapter you will apply the knowledge gained in Chapter 11 and this chapter in a larger example

Trang 7

Project Three: A Spell Checker as an Eclipse Plug-in

The third example application is a fully functional spell checker for the Eclipse SDK An early

ver-sion of this example was published in my book Eclipse 2 for Java Developsers, and the (enhanced)

plug-in that was offered as a separate download became quite popular—so popular that in Eclipse 3 the Java editor was equipped with an integrated spell checker

The spell checker presented here, however, is more versatile It can perform spell checking notonly in Java sources but in any editor and text widget And it can be extended with plug-ins sothat it can intelligently spell-check text formats such as Java, C++, JavaScript, HTML, PHP, JSP,and so on For the purpose of this book, I present a stripped-down version (no checking while typing, no overriding of preferences on the project level) due to space limitations The full version,including source code, is available at www.wrox.com (see also Appendix C)

During the implementation of this spell checker I demonstrate the following plug-in developmenttechniques:

❑ Definition of a plug-in manifest

❑ Integration of third-party JARs into your own plug-ins

❑ Use of the API for the ITextEditor interface and the MultiEditor class

❑ Addition of menu items to the menu structure of the Eclipse workbench

❑ Addition of menu items to the context menu of editors

❑ Addition of tool buttons to the toolbar of the Eclipse workbench

❑ Association of actions with keyboard shortcuts

❑ Implementation of a workbench view (for correction proposals)

13

13

Trang 8

❑ Creation of a view toolbar and a view menu

❑ Location and opening of view instances

❑ Creation of new preference pages

❑ Creation of a help system, including table of contents, context-sensitive help (InfoPops), andactive help

❑ Internationalization of a plug-in

I also show how to write a plug-in that can be extended by others The spell-checking functionality willnot be implemented in the form of a single plug-in but as a group of cooperating plug-ins Differentspell-checking strategies for different document types can be implemented as required and installed separately To do this, the spell checker base plug-in defines its own extension points These points allowthe addition of file type–specific plug-ins As an example I will show the implementation of an extensionplug-in for spell checking in JavaScript source files This gives the end user the optional ability to perform spell checking in Javadoc comments, non-Javadoc comments, and string literals When I implement this plug-in, I will demonstrate the following techniques:

❑ Definition of an extension point, including a schema

❑ Definition of dependencies between plug-ins

❑ Integration of help systems from several plug-ins

The Spell Checker Core Classes

The core classes of the spell checker consist of the a spell checking engine (which we take from an ing Open Source project), and classes that construct a framework in which later add-ons may plug in.This framework is, in particular, responsible for implementing a GUI (Spell Correction View, actions,preference pages), for controlling the spell-checking engine, and for managing additional plug-ins

exist-The Engine

I don’t implement the core spell checking classes myself but instead use the engine of the jazzy spellchecker This engine is completely implemented in Java and is available as an Open Source project atsourceforge.net/projects/jazzy The algorithms used in this engine belong to the most effectivecurrent spell-checking algorithms

I use version 0.5 of jazzy here The archive jazzy-0.5-bin.zip also contains the source code In

addition, the dictionary english.0.zip is required, which is also available on the SourceForge Web site.The jazzy archive also contains the JAR file jazzy-core.jar This is the archive that you will need for yourproject It contains the packages com.swabunga.spell.engine and com.swabunga.spell.event

Trang 9

Figure 13.1 shows the most important classes in the spell checker and how they interact (the numbers

in parentheses indicate the sequence of method calls) In addition, there are the Plugin class, the classesfor managing the preferences, and the classes for configuring the spell-checking engine The spell-checking process is initiated by the CheckSpellingActionDelegate class The

SpellCheckManagerclass acts as a central controller The SpellCheckCorrectionView class plays spelling errors and interacts with the end user The DocumentWordTokenizer class is used bythe jazzy engine to tokenize a document into single words The SpellCheckingTarget class acts as acommon view on editors and text widgets It provides the text content of these objects in the form ofIDocumentinstances to the other classes and is concerned with text selection and text replacement

dis-CheckSpellingActionDelegate

SpellCheckManager

SpellCorrectionView

DocumentWordTokenizer jazzy-Engine

SpellCheckingTarget

checkDocument (1)

getSelection(2)getDocument(3)

checkSpelling(5)

setInput(9)(wait)

spellingError(7)

setSelection(8)init(4)

Trang 10

Setting Up the Project

First, you want to make sure that the functions for plug-in development are enabled in your Eclipse platform Go to Window > Configure Activities and mark Plug-in Development

Next, you must set up the target platform Testing and debugging a plug-in does not happen in thedevelopment platform but in a separate Eclipse session The configuration of this platform can differconsiderably from the configuration of the development platform For example, you may want to runthe new plug-in in the minimal Eclipse runtime environment, that is, in a platform that does not have aJava IDE or a PDE So you must first determine with which plug-ins your target platform is equipped.You can do this with the function Window > Preferences > Plug-in Development > Target Platform(Figure 13.2) You can exclude certain plug-ins during the configuration of the target platform, and you can include other plug-ins that are not in the Eclipse workspace by clicking the Not In Workspacebutton

Figure 13.2

In this case, you may want to test the spell checker plug-in in an environment that is equipped with aJava IDE and a PDE, since you want to use the spell-checking facility in the editors of those features.Therefore, you need to checkmark all plug-ins of the target platform with the exception of the exampleplug-ins and the source code plug-ins

If you have already installed the spell checker plug-in into your development platform, you should alsodisable all of the plug-ins that start with com.bdaum.SpellChecker in order to avoid conflicts.Instead of modifying the global preferences for the target platform, another possibility is to later create aspecial Run configuration for the new plug-in To do so, invoke Run > Run and press the New button

to create a new configuration for a runtime workbench On the Plug-ins page, you may select from ous options When you mark the Choose Plug-ins and Fragments to Launch option from the list, you

Trang 11

vari-may select individual plug-ins for inclusion into the test platform If you want to use the minimum ber of plug-ins for running your plug-in, proceed as follows:

num-1. Press the Deselect All button.

2. Now mark the Workspace Plug-ins check box (or only the plug-ins that you want to test)

3. Press the Add Required Plug-ins button This will mark all plug-ins that are required for ning the plug-ins selected in the previous step

run-But now let’s return from this excursion and create the project In contrast to the first two example applications, you don’t create a Java project for this example Instead, you need to switch to the Plug-inDevelopment perspective and select File > New > Plug-in Project This wizard leads you step-by-stepthrough the creation of a plug-in project:

1. On the second wizard page, enter the project’s name This will also be the identification of theplug-in You should therefore choose a name that is not being used by the manufacturers ofother plug-ins Common practice is to prefix the plug-in with the identification of the authoringorganization I have named the plug-in com.bdaum.SpellChecker in this case

2. On the next page, select Java Project and leave all other controls at their default values

3. On the next page, enter a provider name Make sure that the options Generate the Java Class

That Controls the Plug-in’s Life Cycle and This Plug-in Will Make Contributions to the UI arechecked

4. On the next page, checkmark the option Create a Plug-in Using One of the Templates and selectCustom Plug-in Wizard This will allow you to generate large parts of the new plug-in fromexisting templates

5. On the next page, checkmark the options Hello World Action Set, Help Table of Contents,

Preference Page, and View Remove the check marks from all other options

Now you need to configure the generators for these templates On the following pages, enter the details:

❑ On the Sample Action Set page, change Action Class Name to CheckSpellingActionDelegate

❑ On the Sample Help Table of Contents page, change Label of Table of Contents to SpellChecker Checkmark the Primary option because this is the main table of contents for the spellchecker feature Remove the check marks of all categories because you want to create only a sin-gle table of contents with no nested tocs

❑ On the Sample Preference Page page, change Page Class Name toDefaultSpellCheckerPreferencePage Under Page Name enter %Spelling The % charac-ter indicates that this is not display text but a key that still needs to be resolved into display textwhen the project is internationalized (see “Text Constants in Manifest Files” later in this chapter)

❑ On the Main View Settings page, change View Class Name to SpellCorrectionView UnderView Name, enter %Spell Under View Category Id, enter com.bdaum.SpellChecker.views, and under View Category Name, enter %Spell_Checker (The view category identi-fies the group under which the new view appears when the function Window > Show View isinvoked.) Select Table Viewer as the viewer type (this table will later contain the correction pro-posals) In addition, uncheck the option Add the View to the Resource Perspective The viewtherefore remains invisible initially—it will appear only when the spell checker is in use

❑ On the View Features page, uncheck the option Add Support for Sorting

Trang 12

When you press the Finish button, Eclipse opens the new plug-in the plugin.xml manifest in the PDE editor Eclipse has also generated the packages com.bdaum.SpellChecker, com.bdaum

.SpellChecker.actions, com.bdaum.SpellChecker.preferences, and

com.bdaum.SpellChecker.viewswith the classes SpellCheckerPlugin,

CheckSpellingActionDelegate, DefaultSpellCheckerPreferencePage, and

SpellCorrectionView You now have the base classes for the new plug-in, and you may

now modify and complete these classes

The Plug-in Configuration

Next you need to describe some more details of the new plug-in in the manifest file plugin.xml If thisfile is not yet open, you can double-click it to open it Figure 13.3 shows the Overview page of the plug-

in manifest Since you are going to define your own extension point for this plug-in, you will also need

to define a schema (see the section “The Schema documentTokenizer.exsd”)

Figure 13.3

Trang 13

The Manifest plugin.xml

The following source code shows the manifest in its nearly final state All changes and additions appliedmanually are printed in bold Now, what do you need to change?

<?xml version="1.0" encoding="UTF-8"?>

<?eclipse version="3.0"?>

<pluginid="com.bdaum.SpellChecker"

For the plug-ins org.eclipse.core.runtime, org.eclipse.ui, org.eclipse.jface.text,and org.eclipse.help mark the option Re-export the Dependency This will make these plug-insavailable to all plug-ins that specify com.bdaum.SpellChecker as a required plug-in

Trang 14

On the Extension Points page, you need to define a new extension point, documentTokenizer Thisextension point will allow you and others to add extensions for specific text formats later, such as a plug-

in for Java source code spell checking (see the section “A Plug-in for Java Properties”) The name of thisextension point is chosen on the basis that later extensions will consist more or less of specific tokenizersthat break the text into single words following file type–specific rules

“Managing Images”) Also, the Action Set gets a new name

❑ Define a new toolbarPath com.bdaum.SpellChecker.spell_checker, so that the actionwill appear in a separate group in the workbench’s toolbar

❑ For menubarPath specify the value edit/spelling Consequently, the action will appearunder the Edit menu

❑ By not specifying a value for the enablesFor attribute, you ensure that the action’s enablingdoes not depend on the number of selected resources but is controlled programmatically

❑ Specify a definitionId to establish a reference to the following command extension

❑ Under helpContextId define the anchor point for context-sensitive help (InfoPop)

Trang 15

First, define a command and associate it with the org.eclipse.ui.category.textEditorcategory Thus, the command will later be listed under the Text Editing category when the functionWindow > Preferences > Workbench > Keys is invoked Note that the ID of the command must matchthe definitionId of the action defined previously.

Second, define two key bindings: one for the global context and one for the text editor context This willassign the F9 function key to the spell-checking action both in generic windows and during text editing

If you want, you may define additional key bindings for other configurations such as the emacs ration (org.eclipse.ui.emacsAcceleratorConfiguration)

The spell-checking function should also be accessible via the context menu of the editors You can do this

by defining an extension for the extension point org.eclipse.ui.popupMenus and addingviewerContributionsto this extension Unfortunately, there is no way to add a function to any edi-tor type that may later be installed into the platform by other plug-ins The only thing you can do is todefine viewer contributions to the most common editor types You associate viewer contributions to edi-tors by specifying a targetId When an editor is initialized, it sets this menu ID with the methodsetEditorContextMenuId() The mother of all text editors, the AbstractTextEditor class, setsthe menu ID #EditorContext The subclass TextEditor overrides this with

#TextEditorContext, and the subclass CompilationUnitEditor, which acts as an ancestor ofsource code editors such as the Java editor, overrides this menu ID with

#CompilationUnitEditorContext By specifying these three IDs, you should cover a wide range ofeditors, indeed

Trang 16

Of course, the spell-checking action should appear in the Resource perspective as soon as the

spell-checking feature is installed into an Eclipse platform You can achieve this by defining a

perspective extension (org.eclipse.ui.perspectiveExtensions) for the Resource perspective,

as shown in the following code

In addition, the code defines the position and the size of the Spell Correction View relative to the Tasks View

Trang 17

For the Spell Correction View itself, you need only add an icon definition.

The Schema documentTokenizer.exsd

The schema documentTokenizer.exsd describes the extension point documentTokenizer, whichwas created in the previous section It was generated by the manifest editor; now you need only

Trang 18

complete it The completed schema is shown in Listing 13.1 (I shortened it a bit by removing the mentation sections).

docu-First, the schema consists of the usual extension root element Besides the attributes point, id, andname, such an extension may—in this case—contain an unlimited number of tokenizer elements.These tokenizer elements are equipped with the following attributes:

id Identification of the tokenizer

class A class that must extend the class

AbstractDocumentWordTokenizer.preferences The class implementing the tokenizer’s preferences This class must

extend the class SpellCheckerPreferences If this attribute isomitted, the default spell-checking preferences will be used for thistokenizer

extensions A list of file extensions for which this tokenizer should be activated

Trang 19

<attribute name="id" type="string" use="required">

jazzy-In addition, you need a dictionary Directly under the project, create a new folder called dict Thenunpack the english.0.zip file that you downloaded from the SourceForge site and import theenglish.0file into the new folder You can do this with a drag-and-drop mouse action

The Plugin Class

The generated SpellCheckerPlugin class serves as the Java representation of the plug-in On ization of the plug-in, a single instance of this class is created This instance can be obtained via the staticmethod getDefault() This class is therefore well suited to be a central registry that can be accessedfrom anywhere in the plug-in It also provides methods for obtaining information about the plug-in

Trang 20

* This class cares for the initialization of preferences and

* acts as a central registry for core components such as

* SpellCheckManager and CheckSpellingActionDelegate

*/

public class SpellCheckerPlugin extends AbstractUIPlugin {

The DEFAULTDICT and USERDICT constants describe the storage location of the English default nary and the user dictionary relative to the storage location of the plug-in Then you need a few fields tohold instances of SpellCheckerPreferences, SpellCheckerManager, and

dictio-CheckSpellingActionDelegate Also, the field spThread is used to hold an instance of the checking thread By registering the spell-checking thread in a central location, you can later easily con-trol the proper serialization of competing spell-checking actions

spell-// Default dictionaries

private static final String DEFAULTDICT = "dict/english.0";

private static final String USERDICT = "dict/user.dict";

private CheckSpellingActionDelegate spellCheckingActionDelegate;

// Spell checking thread

private Thread spThread;

The constructor of this class, SpellCheckerPlugin(), must set the system property jazzy.config

to the value com.bdaum.SpellChecker.SpellCheckConfiguration This tells the configurationmodel of the jazzy engine to fetch the configuration data not from the jazzy.properties files butinstead from the class SpellCheckConfiguration, which you will implement later

Trang 21

// Set configuration for jazzy engine We make jazzy fetch// the configuration from our own configuration

// implementation

System.setProperty("jazzy.config",

"com.bdaum.SpellChecker.SpellCheckConfiguration");

}/**

* Returns the plug-in singleton

*/

public static SpellCheckerPlugin getDefault() {return plugin;

}The utility method getId() fetches the plug-in identification string from the plug-in descriptor as itwas defined in the manifest file plugin.xml

To retrieve the location of these files, you must first fetch the OSGi bundle This bundle contains generalinformation about the plug-in, as well as the URLs of its various components However, this URL isgiven in a format that only Eclipse can interpret correctly: it starts with the protocol specification platform: To resolve this URL into a conventional file URL (a URL beginning with file:), you mustfirst apply the resolve() method

Dictionary URL

The getPreferences() method returns the one and only instance of theSpellCheckerPreferencesclass If it does not exist yet, a new instance is created

/**

* Returns the absolute

* path of the default dictionary file

Trang 22

* Returns the absolute

* path of the default user dictionary file

URL pluginURL = getDefault().getBundle().getEntry(filename);

// This URL starts with the pseudo protocol "plugin:"

// Therefore resolve this URL into a real URLtry {

URL resolvedURL = Platform.resolve(pluginURL);

// Extract the path informationreturn resolvedURL.getPath();

} catch (IOException e) {

logError(4, Messages.getString(

"SpellCheckerPlugin.Error_resolving_dictionary_URL"),e);

}return null;

}

You must also provide some code to initialize the default values of the preferences Remember that whenthe Eclipse platform is started, only the manifest files of the various plug-ins are interpreted, but noplug-in–specific code is executed The preference store is therefore not initialized at that time

However, the Plugin class invokes initializeDefaultPreferences() during the very first call

of the getPluginPreferences() method You can override this method to apply the necessary initializations It delegates the initialization of the preference values to the

return plugin.preferences;

}

/**

Trang 23

* Initialization of the PreferenceStore

}

The Manager

The manager mediates the communication between the user interface and the spell-checking engine

To be able to access this manager from all classes, an instance of the manager is stored here in the plug-ininstance During its very first call, getManager() creates an instance of the SpellCheckManagerclass This lazy creation ensures that this component is created only when it is actually needed

return plugin.manager;

}The spellCheckingActionDelegate field with its get…() and set…() access methods acts as aregistry for the ActionDelegate instance created by the workbench You will need these methods later

in the context of active help (see the section “Active Help”)

}/**

* Returns the currently active SpellCheckingActionDelegate

Trang 24

The static methods isPending() and startThread() are used to determine whether the checking thread is currently active and to start a new thread.

public static boolean isPending() {

return (plugin.spThread != null && plugin.spThread.isAlive());

/**

* Writes internal errors to log file

*

* @param code - Plug-in specific error code

* @param message - message text

* @param ex - Throwable that caused the error or null

*/

public static void logError(

int code, String message, Throwable ex) {getDefault().getLog().log(

new Status(IStatus.ERROR, getId(), code, message, ex));

}

}

The Check Spelling Action

The Check Spelling action can be applied to editor text areas as well as to other editable text widgets ofthe type Text or StyledText This chapter discusses the CheckSpellingActionDelegate classthat acts as a proxy for the Check Spelling action and the SpellCheckingTarget class that acts as anumbrella class for the various concrete targets of the action

Trang 25

The SpellCheckingTarget Class

The Eclipse platform hosts a wide variety of editors such as simple text editors and the Java editor butalso more complex editors such as the PDE manifest editor and the PDE schema editor In Chapter 11,the section “The Architecture of the Eclipse Workbench” shows the hierarchy of editor types used inEclipse The common root type, IEditorPart, has only a tiny API that does not offer enough function-ality for spell-checking purposes, while the various concrete editor implementations have differing APIsfor accessing the editor contents For this reason, I opted to introduce the umbrella class

SpellCheckingTarget, which implements a consistent API for the editor functions required for checking purposes An additional benefit is that this class can even represent editor-less spell-checkingtargets such as text fields in dialog boxes

private static final Object[] NOARGS = new Object[0];

private static final Point NOSELECTION = new Point(0, 0);

A SpellCheckerTarget instance maintains references to the target editor (which may be null), to thetarget widget, and to the tokenizer used to analyze the text For editor spell-checking targets, it deter-mines the selection provider and the document provider from the target editor For spell-checking tar-gets without a document provider, an auxiliary document instance is created

// The target editor or nullpublic IEditorPart editor;

// The target widget or nullpublic Control textArea;

// Indicated if target is editablepublic boolean isEditable = true;

// The document tokenizer associated with this targetpublic AbstractDocumentWordTokenizer tokenizer;

Trang 26

// The targets selection provider

private ISelectionProvider selectionProvider;

// The target document provider

private IDocumentProvider documentProvider;

// If we have no document provider we create an auxiliary document

private IDocument auxDocument;

Factory Method

SpellCheckingTargetinstances are not created via a public constructor but by the factory methodgetInstance() This method differentiates between three cases In the case of a target editor of typeITextEditor, the methods defined in this interface are used to derive the necessary information, such

as the selection provider and the document provider In case of the more general type IEditorPart,Java reflection is used to determine the selection provider A document provider is not set in this case.Finally, if there is no target editor, information is retrieved directly from the widget

* @param part - currently active workbench part or null

* @param control - Text or StyledText control that currently has the

* focus or null

*/

public static SpellCheckingTarget getInstance(IWorkbenchPart part,

Control control) {

SpellCheckingTarget instance = null;

if (part instanceof ITextEditor) {// Special treatment for text editorinstance = new SpellCheckingTarget();

ITextEditor textEditor = (ITextEditor) part;

instance.textArea = control;

instance.isEditable = control.isEnabled();

if (part instanceof IEditorPart) {// Find selection provider for generic editorsinstance.editor = (IEditorPart) part;

if (part instanceof ISelectionProvider)// The editor is an selection provider itselfinstance.selectionProvider = (ISelectionProvider) part;

else {// Find the editors selection provider by using reflection

Trang 27

try {Method getSelectionProvider = part.getClass()

}

Selections

To perform spell-checking only within a selected text block, the SpellCheckingTarget class ments the getSelection() method If a selection provider was set, the selection is retrieved from thisselection provider Otherwise, the selection is retrieved directly from the widget The selection providermethod is preferred because it is more reliable For some editors, the length of the text in the widget differs from the length of the text in the document This is the case, for example, for HTML and XMLeditors Character entities such as &quot; are represented as a single character in the widget but appear

imple-in the document imple-in their serialized form

if (sel instanceof ITextSelection) {int pos = ((ITextSelection) sel).getOffset();

return new Point(pos, pos

+ ((ITextSelection) sel).getLength());

}}// otherwise retrieve selection from text control

if (textArea instanceof Text)return ((Text) textArea).getSelection();

if (textArea instanceof StyledText)return ((StyledText) textArea).getSelection();

Trang 28

the widget method is preferred over the selection provider method is that some selection providers don’tsupport the setting of a selection.

/**

* Set the targets text selection

*

* @param start - start of selection

* @param end - end of selection

*/

public void setSelection(int start, int end) {

// Special treatment for ITextEditor

if (editor instanceof ITextEditor)((ITextEditor) editor).selectAndReveal(start, end - start);

// if we have a text control set selection directly in controlelse if (textArea instanceof Text)

((Text) textArea).setSelection(start, end);

else if (textArea instanceof StyledText)((StyledText) textArea).setSelection(start, end);

// for other editors use standard wayelse if (selectionProvider != null)selectionProvider.setSelection(new TextSelection(start,

is returned If there is no document provider, an auxiliary document is created and the

SpellCheckingTargetinstance is registered as a ModifyListener with the text widget When thiswidget is modified, the auxiliary document is updated accordingly in the modifyText() method.Because the getDocument() method can be called from the spell-checking thread, all SWT accessesmust be encapsulated into a syncExec() block

// Create auxiliary document and store it for further use

if (textArea != null && auxDocument == null) {textArea.getDisplay().syncExec(new Runnable() {public void run() {

if (textArea instanceof Text)((Text) textArea)

.addModifyListener(SpellCheckingTarget.this);

else((StyledText) textArea)

.addModifyListener(SpellCheckingTarget.this);

Trang 29

auxDocument = new Document(getWidgetText());

}});

}return auxDocument;

}/**

* Tests if the underlying document is not auxiliary

* Get the targets editor input

* Reacts to text widget modifications

}/**

* Retrieves the text from the text widget

}

Text Replacement

When a spelling error is corrected, the misspelled word must be replaced in the spell-checking targetwith the corrected word Before this is done, the corrected word is serialized with the help of the tokenizer For a plain text editor this is a null operation; however, for other text types the text representa-tion in the document may differ from the text representation in the user interface (and the dictionary)

Trang 30

If the document is auxiliary, the change in the document is not reflected automatically by the

corresponding text widget In such a case, the widget must be updated explicitly

/**

* Replace text in the target

*

* @param pos - the replacement position

* @param len - the length of the text part to be replaced

* @param replacement - the replacement string

* @return - length change of document

*/

public int replaceText(int pos, int len, String replacement) {

try {IDocument document = getDocument();

String oldWord = document.get(pos, len);

if (!oldWord.equals(replacement)) {// True change - replace word in documentString rawString = (tokenizer != null) ?

tokenizer.serializeWord(replacement) : replacement;

document.replace(pos, len, rawString);

// In case of auxiliary document apply change to// Text or StyleText widget, too

}} catch (BadLocationException ex) {}

if (textArea instanceof Text)

Ngày đăng: 12/08/2014, 23:22

TỪ KHÓA LIÊN QUAN