搜索
英文字典
分类
存档
{#archives}
最新文章
最新回复
链接
|
分页共3页 1 2 3 下一页 最后一页
|
|
Java team want to improve support for dynamically typed languages
|
Java team are looking to improve support
for dynamically typed languages on the Java platform, Gilad Bracha post
a blog to talk about it.More details, please to see Invokedynamic and Tim Bray's Blog
|
|
|
|
|
Who is the best-SD's Readers' Choice Awards Finalists (提名名单)
|
|
Who is the best Language? Who is the best Tool?and so on.
|
|
|
|
|
MIT to launch $100 laptop prototype in November
|
|
Notebook is intended for school children around the world.(MIT的100美元笔记本原型机11月发布。)
|
|
|
|
|
Ruby or Python, that is the question(Ruby与Python的对比)
|
|
Python-Ruby Comparison
|
|
|
|
|
Dan Box也谈SICP了(Dan Box also recommends SICP)
|
|
|
|
|
|
|
2005 Google Code Jam Winner-Marek Cygan
|
|
|
|
|
|
|
这回Dan Box说的是真话-"Scheme Is Love"
|
|
|
|
|
|
|
如何参与TopCoder比赛简介
|
|
初步介绍如何参与TopCoder比赛
|
|
|
|
|
Apache Harmony的投票结果
|
|
开源Java的投票结果
|
|
|
|
|
进入世界顶级IT公司的捷径:TopCoder锦标赛的冠军
|
|
获得TopCoder锦标赛的冠军意味着什么?
|
|
|
|
|
WTP Tutorials - Developing the WTP with Eclipse
|
|
This tutorial shows you how to set up your Eclipse
environment to develop or modify the Web Tools Platform (WTP) project plug-ins. First
we will discuss how to connect to the CVS repository to check
out the WTP source code. We will then set up our target platform.
Next we will make a modification to the WTP source and run
our eclipse application. Finally, we will create a patch
for our change, which we could submit to the WTP project.
|
|
|
|
|
|
“友邦惊诧”论①*鲁迅
|
|
只要略有知觉的人就都知道:这回学生的请愿②,是因为日本占据了辽吉,南京政府束手无策,单会去哀求国联,③而国联却正和日本是一伙。读书呀,读书呀,不
错,学生是应该读书的,但一面也要大人老爷们不至于葬送土地,这才能够安心读书。报上不是说过,东北大学逃散,冯庸大学④逃散,日本兵看见学生模样的就枪
毙吗?放下书包来请愿,真是已经可怜之至。不道国民党政府却在十二月十八日通电各地军政当局文里,又加上他们“捣毁机关,阻断交通,殴伤中委,拦劫汽车,
横击路人及公务人员,私逮刑讯,社会秩序,悉被破坏”的罪名,而且指出结果,说是“友邦人士,莫名惊诧,长此以往,国将不国”了!
|
|
|
|
|
SWT - Virtual Tables Tutorial
|
|
Virtual Tables are a new selling point of the SWT framework. Being new to SWT myself,
I tried to hunt down information on the topic with minimal success. The SWT JavaDocs
are as weak for this feature as every other feature. The SWT books at the local
Chapters don't even mention Virtual Tables. Pages upon pages of Google hits link to
casual mention about how virtual tables are good, great, and/or fast. Either that or
comments by people like myself, who like most developers, really just want an example
to clarify things. Then the clouds parted and the light shone on a random SWT book
errata website. Where there's an Errata, there's sample code. So in an attempt to
save others some time and effort, I've decided to author a very brief tutorial on the
subject.
|
|
|
|
|
Gathering performance statistics
|
Introduction
The modular nature of Eclipse makes for a highly dynamic execution environment.
What happens when a context menu is opened in a view, or when the user switches
to a different perspective, depends on the set of plug-ins that are installed and
the set of plug-ins that are loaded at the time of the event. While this execution
model has powerful advantages, it makes it difficult to track down performance
problems in an Eclipse-based application. For example, a user may report that
it takes five seconds to open a view's context menu. The long pause may be
caused by:
|
|
|
|
|
Eclipse,Visual Studio,NetBeans趋势分析
|
笔者用BlogPulse就Eclipse、Visual Studio,NetBeans三个IDE在Blog世界的热门程度做了个趋势分析,在 Trend Term一项中分别输入Eclipse、Visual Studio,NetBeans用来比较三者的发展趋势,比较结果如下:

上图是一个月的趋势分析,Eclipse获得胜利,排名第一。
|
|
|
|
|
Eclipse Plugins Exposed, Part 2: Simple GUI Elements
|
by Emmanuel Proulx
03/30/2005
The way to write American music is simple. All you have to do is be an American and then write any kind of music you wish. -- Virgil Thompson
|
|
|
|
|
Eclipse Plugins Exposed, Part 2: Simple GUI Elements
|
by Emmanuel Proulx
03/30/2005
The way to write American music is simple. All you have to do is be an American and then write any kind of music you wish. -- Virgil Thompson
|
|
|
|
|
Contributing Actions to the Eclipse Workbench
|
Summary
The Eclipse Platform is an open and extensible platform. This article explains
in detail how the Workbench can be extended to add new actions and provides
guidance to the plug-in developers on how they can design for extensibility.
By Simon Arsenault, OTI
October 18, 2001
|
|
|
|
|
愿微软的灵魂安息与盖茨必须走人
|
|
"R.I.P.
Microsoft"一文已经发表有一段时间了,笔者本来也不想提它,但既然国内又有人开始肉麻的吹捧微软了,哪无妨让大家看看一部分美国精英是如何看待
微软的。
|
|
|
|
|
走上开放之路: Windows 开发人员的 Java Web 支持基础
|
将 Windows 客户机-服务器应用程序迁移到 Java 技术和 J2EE 的路标图
Mark Weber
(weberm@us.ibm.com),
高级软件工程师,IBM
David Carew
(carew@us.ibm.com),
高级电子商务体系结构师,IBM
2004 年 3 月
本文是走上开放之路系列文章的第二部分。这个系列一共包括三部分,目的是帮助 .NET、Windows 客户机-服务器以及 ASP 开发人员快速转换到 Java 平台上。在走上开放之路系列文章中,作者将帮助您充分利用现有的开发知识,简化您通往基于开放标准的编程之路。对于那些使用
Visual Basic 6 或 C++,而对 Java 语言或 J2EE 技术并不熟悉,但却对在基于 Java 和 J2EE 的 Web 应用程序中支持
Web 的 Windows 客户机-服务器的应用程序非常感兴趣的 Windows 开发人员来说,高级软件工程师 Mark Weber 和高级电子商务体系结构师
David Carew 为他们指出了一条道路,并帮助他们了解由 IBM 或其他地方提供的最有用的一些工具、技术以及在线资料。您可以在相应的论坛中与作者或其他读者分享您对这些文章的想法。(您也可以单击本文开头或末尾的
讨论
来访问论坛。)
|
|
|
|
|
231个 SWT-JFace-Eclipse小程序代码以及部分截图
|
Java2s上放了约有231个 SWT-JFace-Eclipse小程序代码,以及部分相关的屏幕截图,此外,这个网站上还有其他一些与Java有关的内容,
感兴趣的朋友可以看一看。网址是 SWT-JFace-Eclipse
|
|
|
|
|
Modeling Rule-Based Systems with EMF
|
Summary
There are examples of meta-models defined in ECore for modeling objects and
relational data. However, not much has been said about how to model rules. This
article will define a meta-model in ECore for modeling rule-based systems. We
will then use the meta-model to model the solution of a logical problem. Then
we will compose some JET templates and generate code from the model, run the
generated code through a rule engine and see that the logical problem is
correctly solved.
By Chaur G. Wu, Independent Consultant (cha_urwu@hotmail.com)
November 30, 2004
Before we look at this article’s example, let’s set the stage by going through
some background information and make clear some terms that we will use
throughout the article. In this part, we will give very brief introduction
of rule-based systems and meta-modeling.
Rule-Based Systems
So what do we mean by rule-based? In the evolution course of computing, a field
called artificial intelligence was developed in the 70s and 80s with an
aim to make computers reason like human beings. Rule-based programming paradigm
emerged at that time as ways to implement systems that appear to think and
reason like human beings. Examples of rule-based systems are expert systems
that have the knowledge of a doctor or a tax advisor and can answer complex
questions people would normally ask those professionals.
The idea of rule-based programming is to represent a domain expert’s knowledge
in a form called rules. That’s why it’s called rule-based. Besides rules,
another important ingredient in a rule-based system is facts. Here’s an
example. Say John is a weather reporter who gives advice to people on TV
channels based on weather conditions. Here’s John’s knowledge about weather:
-
If it’s a rainy day, advise people to bring umbrellas when they go out.
-
If it’s a rainy day, the road would be slippery because of the rain and hence
warn people to drive more carefully.
How do we represent the knowledge in a rule-based system? We represent it as
rules and facts like this:
Rule 1: If it’s a rainy day, advise people to bring umbrellas when they go out. Rule 2: If the road is slippery, warn people to drive more carefully. Rule 3: If it’s a rainy day, road is slippery.
Fact 1: It’s a rainy day. Fact 2: Road is slippery.
Here’s how our imaginary expert system mimics the reasoning capability of
weather reporter John. If by looking out of the window, we see it’s raining, we
tell our expert system that it’s raining by asserting fact number 1.
Immediately the expert system tries to match the asserted fact with its three
rules. Rules 1 and 3 are fired because the asserted fact satisfies their
conditions (the if clause). When rule one is fired (a more accurate
term is activated), the system advises people to bring umbrella as if it were a
real weather reporter. Firing rule 3 asserts fact 2. And because fact 2
satisfies the conditions of rule 2, rule 2 is fired and the system advises
people to drive more carefully. All these chain reactions happen in sequence as
the result of asserting fact number 1.
Although the example is nowhere close to the complexity of a practical
rule-based system, it shows the following key points:
-
A rule-based system consists mainly of three things: facts, rules and an
engine that acts on them.
-
Rules represent knowledge and facts represent data. A rule-based system solves
problems by applying rules on facts (i.e. matching facts with rules’ if
clauses).
-
A rule consists of two parts: conditions (if
clauses) and actions.
-
The action part of a rule might assert new facts that fire other rules.
Among the most popular rule engines, JESS (Java Expert System Shell)
is probably of the most interest to Java developers. It is the reference
implementation of JSR 094 Java Rule Engine API and it has plug-ins to
support development of rule systems in Eclipse. Therefore, the rule code we
will see in this article will be in JESS's syntax. Before we
leave this section, it’s helpful to introduce JESS and take a glimpse of
its programming syntax. JESS is software that interprets rules and facts
expressed in its programming language. Just as Java is a language for
expressing objects and Java compiler is software that interprets Java code,
JESS has a language for expressing rules and facts and a compiler to interpret
the code. JESS is developed in Java by Ernest Friedman-Hill at Sandia National
Laboratories. Here’s what the rules and facts in our weather example look like
in JESS code.
(defrule rule-1 (rainy-day) = > (advise-people bring-umbrella)) (defrule rule-2 (road-slippery) => (advise-people drive-carefully)) (defrule rule-3 (rainy-day) => (assert road-slippery)) (road-slippery) (rainy-day)
The last two lines in the list above are the two facts. The first three lines
are the three rules. Rules in JESS take this form: (defrule
rule-name conditions => actions) Rules are defined using
the defrule construct. rule-1, rule-2,
and rule-3 are the names of the rules respectively. rule-1
has a condition: (rainy-day). In this case, (rainy-day)
is also called a pattern. It is so called because the
rule engine treats it as a pattern for matching facts. The pattern (rainy-day)
in rule-1 will match only one fact: the (rainy-day) fact
in the last line of the code list. When it's matched, the action (advise-people
bring-umbrella) of rule-1 will be executed.
There are a lot more to the syntax of a rule language like JESS. We
will only explain those necessary for following along this article. For
more details, you can refer to the documentation that comes with JESS.
Model, Meta-model, Meta-metamodel
Sometimes it’s helpful to the discussion if we categorize models into different
levels. We call a model a meta-model if it is used to define models. We
call a model a meta-metamodel if it is used to define meta-models.
For example, ECore is a model. It can be a meta-model or a meta-metamodel
depending on how we use it. When we use ECore to define models of a purchase
order system, it plays the role of a meta-model. The Rule Meta Model we will
develop later in this article is another example of meta-model. It is a
meta-model because we will use it to define a model for a logical problem.
The Rule Meta Model we will develop later is defined in ECore. In this sense,
ECore is a meta-metamodel because it is used to define a meta-model. Another
example of ECore as a meta-metamodel is EMF’s Gen Model. EMF’s Gen Model is a
meta-model that defines models concerning how code is generated. ECore is the
meta-metamodel that defines Gen Model.
When we say model A defines model B, in a practical sense, we mean that all
model elements in B are instances of model elements in A. We will see this in
effect later when we reach the article’s example. For the purpose of this
article, the important facts to note are:
-
Categorization of meta levels is not absolute.
-
We will use ECore as a meta-metamodel to define the Rule Meta Model.
-
Model elements in the Rule Meta Model will be instances of model elements in
ECore.
-
We will use the Rule Meta Model to define a model for a logical problem.
Elements in the model will be instances of model elements in the Rule Meta
Model.
-
Meta-metamodels are also referred to as M3 models; meta-models as M2 models;
models like a bank application model as M1 models.
Problem Statement
The logical problem we will solve with this article’s Rule Meta Model is
this:
There are four boxes, labeled from 1 to 4. We have four balls in four colors:
red, blue, green and yellow. Our task is to put one ball in each box according
to the following three constraints.
-
If red ball is in box 1, blue ball must be in box 3.
-
If yellow ball is not in box 2, green ball must be in box 3.
-
Green ball cannot be in box 4 and Red ball cannot be in box 2.
Set up Environment and Run the Example Code
The solution to the problem is in RuleMetaModel.zip
and BallPlacementRuleModel.zip that come
with this article. The code in the zip files requires the following software.
Java Runtime or SDK (The one I use is Java SDK 1.4.2 from Sun Microsystems) Eclipse (The version I use is Eclipse SDK 3.0) EMF (The version I use is EMF SDK 2.0.1 RC2) JESS 7.0a1
Installing JESS is simple. You can download JESS from
http://herzberg.ca.sandia.gov/jess/download.shtml. Then unzip the downloaded file
to a folder, add jess.jar to your java classpath and you are ready to go. JESS
is not free software. After clicking the link above, you’ll be asked to enter
your name, company and email. After that, you’ll be taken to the page where
you can download various versions of JESS. The one to download for this article
is trial version 7.01a1. This version of JESS comes with some Eclipse plug-ins
for editing JESS code in the Eclipse IDE. Those plug-ins are not needed for
running the code of this article. Installing them is optional.
To install and run the example for this article, unzip RuleMetaModel.zip
into your plugins/ subdirectory. This zip file contains three plug-ins.
They are the model, edit, editor plug-ins EMF generates for our Rule Meta Model.
The other zip file, BallPlacementRuleModel.zip,
contains two files: BallPlacement.rulemetamodel and BallPlacement.clp.
BallPlacement.rulemetamodel is the model that models our logical
problem. It is defined using Rule Meta Model. The other file BallPlacement.clp
is JESS code generated from BallPlacement.rulemetamodel. Below
is a pictorial view of all the components in the two zip files and how they
relate to EMF and rule engine.
Figure 1. Overall picture of the example code.

We will explain each component as we go along. For now, since we already have
JESS rule engine set up, let's run BallPlacement.clp through the
JESS rule engine (the yellow part in Figure 1). Assume that you unzipped the
two files in BallPlacementRuleModel.zip to C:\ and
that jess.jar is in your java classpath. Here is the command to
run BallPlacement.clp through the JESS rule engine:
java jess.Main
C:\BallPlacement.clp
The result you will see in the command console will look like the screenshot
below. Dumping the result to a console window like this is not pretty but it
serves our purpose just fine. The last four facts listed in the screenshot
are solutions to the logical problem. That is, out of the 24 possible
placements of the balls in the boxes, only four placements satisfy the
three constraints posed by our problem.

BallPlacement.clp
Before we look more closely at the Rule Meta Model and Ball Placement Model,
let’s see what constitutes a rule language by taking a look at BallPlacement.clp
first. This knowledge will help us make sense of the meta-model and model
later. BallPlacement.clp defines two fact templates: placement
and ball.
(deftemplate placement (slot box_one) (slot box_two) (slot box_three) (slot box_four))
(deftemplate ball (slot color))
A fact template as its name suggests is a template of facts and is
defined by the deftemplate construct in JESS. Earlier we wrote the
weather fact like this: (rainy-day). If we want to specify
temperature in addition to weather, we’ll probably write a fact like this: (rainy-day
50F). Facts like these are called ordered facts because they
require their elements to be in a specific order. (rainy-day 50F) is
a different fact from (50F rainy-day) because the elements are in
a different order. Sometimes it’s desirable to have some structure in the way
we state facts so that we can express elements in a fact regardless of their
positions. This is where fact templates come into play. With fact templates, we
can state facts like this: (weather-report (weather rainy-day) (temperature
50F)). We say that the weather-report fact has two slots:
weather and temperature. Slot weather has
a value of rainy-day and slot temperature has a value
of 50F. It doesn’t matter if you put the temperature slot
before or after the weather slot. Facts like this are called unordered
facts because the order of their elements is not relevant.
In our example, the placement fact template defines four slots, one
for each box. The ball fact template defines one slot: color.
With these two fact templates, we can state the fact that "green ball is in box
one" in JESS language like this: (placement (box_one Green)).
Besides fact templates, BallPlacement.clp has a
few rules. Here's the rule that describes the first constraint about ball
placement.
(defrule placement_constraint1
?placement <- (placement (box_one ?box_one) (box_two ?box_two) (box_three ?box_three) (box_four ?box_four))
(and (placement (box_one ?box_one&Red) (box_two ?box_two) (box_three ?box_three) (box_four ?box_four)) (placement (box_one ?box_one) (box_two ?box_two) (box_three ?box_three&~Blue) (box_four ?box_four))) =>
(retract ?placement))
We have seen rules in the weather report metaphor. We know placement_constraint1
is the name of the rule. are
the conditions of the rule and is
the action. Condition assigns what
looks like a pattern to the ?placement variable. In fact,
what actually gets assigned to the ?placement variable is a fact
that matches the pattern. In JESS, variable names start with ? . ?box_one,
?box_two in the code list above are all variables. Variables
are not typed. You can assign strings, integers, facts and values of other data
types to them. Assigning a value to a variable is usually done through the bind
function like this:
(bind ?variable "some string value")
However, using bind function to assign a value to a variable is an
action not a condition. That's why in , instead
of using the bind function in the condition part of a rule, we
use a special form called pattern binding <- to
assign a fact to the ?placement variable.
Condition has
two fact matching patterns enclosed in a logical and. The logical
and is called a conditional element in a rule
language. Don't worry if the two conditions still look cryptic. Let's
mimic the reasoning process of a rule engine and you will see how the
conditions function. Let's see what happens if we put the
following fact in the rule engine:
(placement (box_one Red) (box_two Blue) (box_three Green) (box_four Yellow))
The rule engine tries to see if the fact satisfies the two conditions of placement_constraint1.
It first tries to match the fact with the pattern in . The
pattern in has
one variable in each of the four slots of the placement fact. That
means the pattern matches any value in those four slots. So the fact
satisfies the first condition and Red is assigned to ?box_one,
Blue to ?box_two, Green to ?box_three
and Yellow to ?box_four.
But this is not enough to trigger the execution of placement_constraint1's
action. The rule engine sees that there's a second condition in the rule. So it
tries to see if the same fact matches the second condition's patterns. The
first pattern in says
that box_one must be ?box_one and Red
(?box_one&Red) and the other three slots can have any values
that are assigned to the three variables ?box_two, ?box_three
and ?box_four respectively. The rule engine already knows from the
first condition that ?box_one is Red. So (?box_one&Red)
is no contradiction (Red is Red). The fact satisfies the first pattern of .
Because of the and conditional element, the second pattern
in needs
to match the fact too for the whole condition to be considered
satisfied. The second pattern in says
that box_three must be ?box_three and not Blue
(?box_three&~Blue) and the other three slots can have any
values that are assigned to the three variables ?box_one, ?box_two
and ?box_four respectively. The rule engine already know from the
first condition that ?box_three is Green. So (?box_three&~Blue)
is no contradiction (Green is not Blue). The fact satisfies the second
pattern of as
well.
So all conditions are satisfied. The action of placement_constraint1
will execute because of the assertion of the fact. What the action does is
remove the matching fact from the rule engine. Why? Because all placement facts
that satisfy the conditions of any one of the three constraint rules in BallPlacement.clp
are not solutions to our logical problem. We remove them from the rule engine's
fact list so that the ones remaining will be our solutions.
Rule Meta Model
Now that we know the basic constructs such as patterns, actions,
rules, facts of a rule language, it's time to see how we
model them in a meta-model; that is, the blue part in Figure 1. Our Rule Meta
Model consists of a package, a few data types, enumerations and classes. As we
said earlier, Rule Meta Model is defined in ECore and by that we mean all
model elements in Rule Meta Model are instances of model elements in
ECore. The one and only package in the Rule Meta Model is an instance of
ECore’s EPackage; the data types instances of ECore’s EDataType;
the enumerations instances of ECore’s EEnum and the classes
instances of ECore’s EClass.
Below is a screenshot of how Rule Meta Model looks like in Eclipse. In the
following sections, we'll go through the data types, enumerations and classes
one by one.
Figure 2. Rule Meta Model.

Data Types
Unlike Java, a rule language is untyped. In the code excerpt of BallPlacement.clp
in previous section, we don’t see the types of ball, color,
and placement. Although the language itself is untyped, underneath
the language in the rule engine, things are still typed. For example, ball,
color, placement are of a type called Symbol.
Values like "something" are of type String and values
like 2.3 are of type Float. Types like Symbol,
String, and Float are called primitive types or
data types. Most rule languages support a common set of primitive types.
However, there are types available in one language but you don’t see them in
others. It's important not to confuse data types like String
and Float in a rule language with similar data types java.lang.String
and java.lang.Float in java. They are totally different types used
in different languages interpreted by different virtual machines. Types in a
rule language are interpreted by a rule engine whereas java types are
interpreted by a Java virtual machine. This is why when we model these data
types in the Rule Meta model, we cannot simply use java.lang.String
or java.lang.Float but need to implement our own types.
There are six data types in Rule Meta Model. Each of them corresponds to a java
class. You can tell which java class a data type corresponds to by
looking at the screenshot in Figure 2 or at the Instance Class Name
property of the EDataType instance that defines the data type. The
table below summarizes the correspondences.
| data type |
implementing java class |
| RSymbol |
com.example.rule.ecore.rulemetamodel.RSymbol |
| RFactAddress |
com.example.rule.ecore.rulemetamodel.RFactAddress |
| RInteger |
com.example.rule.ecore.rulemetamodel.RInteger |
| RFloat |
com.example.rule.ecore.rulemetamodel.RFloat |
| RDataType |
com.example.rule.ecore.rulemetamodel.RDataType |
| RMultiField |
com.example.rule.ecore.rulemetamodel.RMultiField |
When defining data types, besides implementing corresponding java classes,
it's often appropriate and necessary to overwrite the generated code
for converting strings to and from instances of the data types.
In our example, we overwrite createRSymbolFromString() in com.example.rule.ecore.rulemetamodel.impl.RulemetamodelFactoryImpl.java
for RSymbol and other five similar methods in the same file for
the other five data types.
A meta model like ours should be as platform independent as possible. We don't
want to tailor Rule Meta Model too much to a rule language that
models conforming to the Rule Meta Model can only generate code for that
specific language. A complete Rule Meta Model should model data
types common to most popular rule languages. Data types proprietary to a
specific rule language can be modeled at M1 level. Because the example code for
this article is more a demonstration than a full-fledged product, the set of
data types we model here is by no means complete for a rule language,
nor are the java classes implementing those data types.
Enumerations, Classes
There are three enumerations in the Rule Meta Model: RRuleType, RFunctionType,
RCondElemEnum. The three enumerations and six data types are
used in the definition of classes in Rule Meta Model. For example, the
following diagram shows that class RFactTemplate has one attribute
factName whose type is RSymbol, one of the data types
we just defined. Besides attribute factName, RFactTemplate
also has a containment reference to zero or multiple instances of RFactSlot.
RFactTemplate models fact templates in a rule language. The class
definition we see here is in line with our previous knowledge of fact
templates: a fact template has a name and defines zero or multiple slots.
As to RFactSlot, it models slots in fact templates. It has an
attribute slotName of type RSymbol and an attribute
slotValueRange of type RMultiField. We know from
previous section that a slot has a name. What we didn't mention is that some
rule languages allow you to specify the legitimate values of a slot, which
is what slotValueRange is for.

The diagram below shows some more classes and their relations to each
other. Class RRule models rules. It has an attribute ruleName
that represents the name of a rule; a containment reference condition
that represents conditional elements in a rule's condition part; a containment
reference ceMatchPattern that represents patterns in a rule's
condition part but not enclosed in conditional elements; and a reference actions
that represents a rule's action part.
Class RCondElem models conditional elements. A conditional element
can contain match patterns or more conditional elements. That's why our
definition of RCondElem has one containment reference to itself
and one containment reference to RPattern. The ceName
attribute of RCondElem denotes what conditional element (and,
or, not, etc) an instance of RCondElem is.
If you look at RCondElemEnum, the type of the ceName attribute,
you will see that there are three enumeration literals there: and,
or, not. For the same reason we don't define a complete
set of data types, the list of conditional elements in RCondElemEnum
is not complete and in a more complete meta-model, RCondElemEnum
should include conditional elements common in most popular rule languages.
Class RFunction models functions. A function like (retract
(?placement)) we saw earlier has a name and takes zero or
multiple instances of primitive data types as parameters. In this case, retract
is the name of the function and ?placement is a parameter.
Although not visible, the retract function returns a value. In
JESS, it returns the symbol TRUE if it successfully removes a
fact. In our definition of RFunction, we have an attribute functionName
to represent the name of a function; an attribute returnValue of
type RDataType to represent a function's return value; a reference
to instances of RDataType to represent a function's parameters.
The functionType attribute in RFunction denotes
whether the function is provided by the rule engine or defined by users.

Ball Placement Rule Model
With the three plug-ins of Rule Meta Model in place, we can now use
it to model our logical problem. Let's launch Eclipse and create a new
project. Select File -> New -> Project and in the popup
dialog, select Simple -> Project Click Next button
and name the project Test or anything you like. With a project in
place, we can now create a rule model or import BallPlacement.rulemetamodel
that comes with this article's example code.
To creat the model from scratch, right click on the project we just created and
in the popup context menu, select New -> Other. And then in the
popup window, select Example EMF Model Creation Wizards -> Rulemetamodel
Model and click the Next button. In the next screen,
name the model whatever you like but keep the file extension as
.rulemetamodel. Click the Next button to go to the
next screen, and select RModule from the top dropdown box. Then
click the Finish button.
To import BallPlacement.rulemetamodel, right click on the
project we just created and in the popup context menu, select Import.
In the popup dialog window, select File System and click Next
button. The Import dialog window will show up. Use the browse
button in the dialog window to select the folder where
you unzipped the files in BallPlacementRuleModel.zip. A
list of files in that folder will show up in the Import dialog
window. Check BallPlacement.rulemetamodel in the list and click
the Finish button.
If you create the model from scratch, you can refer to BallPlacement.rulemetamodel
for details of the model's elements. Below is a screenshot of how the
model looks like in Eclipse. It has two fact templates: placement and
ball. It has three rules for the three constraints posed
in the logical problem. It has two other rules for putting initial
facts into rule engine. Without facts, the rule engine will have nothing
to apply the three constraint rules to. The model also has some functions.
They are used in the action part of the rules.

Code Generation with JET Template
If you select the RModule node in BallPlacement.rulemetamodel and
see its property view, you'll see that there's property called Output File
Path. The value of this property is where the model puts the
generated code. Please change its value to an appropriate location on your
computer and then right click on the RModule node. In the popup
context menu, select Generate and check your file system to see if
a file by the name you specified in the Output File Path property
is generated. The generated file should be the same as BallPlacement.clp
in BallPlacementRuleModel.zip.
The logic for generating rule language code from a rule model is in a JET (Java
Emitter Templates) template and a java helper class. The JET template file is
Module.clpjet in the templates folder of com.example.rule.ecore
project, which can be unzipped from RuleMetaModel.zip. The
java helper class is com.example.rule.ecore.templates.ModuleHelper.java.
Readers unfamiliar with JET can refer to
JET Tutorial Part 1 (Introduction to JET) and
JET Tutorial Part 2 (Write Code that Writes Code) for an excellent and
very readable guide.
Practically, a generation model might be necessary for storing complex settings
that govern the generation of rule language code from a rule model just like
EMF's Gen Model for generating code from ECore models. For simplicity, we
modified the editor plug-in EMF generated from our Rule Meta Model and provide
a menu option in the context menu that pops up when you right click the RModule
node.
Conclusion
We have demonstrated how to define a meta-model with EMF, use the meta-model to
define a model for a logical problem and use JET to generate rule language code
from the model. We have also seen that the generated code correctly solves the
non-trivial logical problem. The flexibility of EMF as well as Eclipse makes
all the work a breeze. The EMF framework has all modeling foundation there and
thanks to that, most of our time is spent in understanding rule languages
and how rule engine works.
The example code for this article is a demonstration. There are many things to
improve. Modeling rule-based systems is still a field in progress. There are
standards bodies working on specifications. In the Reference section at the end
of this article, we provide some pointers to relevant OMG standards in
progress such as Production Rule Representation RFP and Sridhar Iyengar's
response to OMG's Business Rules in Models RFI. Also listed in the Reference
section is a very popular rule engine called CLIPS, of which JESS and many
other rule engines are variations.
Reference
Frank
Budinsky, David Steinberg, Ed Merks, Raymond Ellersick, Timothy J.
Grose, "Eclipse Modeling Framework", Addison Wesley, ISBN 0-1314-2542-0
Production Rule Representation RFP
http://www.omg.org/cgi-bin/doc?br/2003-9-3
Business Semantics of Business Rules RFP
http://www.omg.org/cgi-bin/doc?br/2003-6-3
Business Rules Management RFI http://www.omg.org/cgi-bin/doc?bei/2004-6-3
Java Specification Request 94, Java Rule Engine API
http://www.jcp.org/jsr/detail/94.jsp
Business Rules in Models
http://www.omg.org/technology/documents/Business_Rules_in_Models_RFI.htm
Sridhar Iyengar's response to OMG's Business Rules in Models RFI
http://www.omg.org/cgi-bin/doc?ad/03-01-25
CLIPS 6.2 http://www.ghg.net/clips/CLIPS.html
|
|
|
|
|
A Shape Diagram Editor
|
Summary
Graphical Editing Framework (GEF) provides a powerful foundation for creating
editors for visual editing of arbitrary models. Its effectiveness lies in
a modular build, fitting use of design patterns, and decoupling of components
that comprise a full, working editor. To a newcomer, the sheer number and
variety of concepts and techniques present in GEF may feel intimidating. However,
once learned and correctly used, they help to develop highly scalable and
easy to maintain software. This article aims to provide a gentle yet comprehensive
introduction to GEF. It describes a shape diagram editor - a small, fully
functional test case of core concepts.
By Bo Majewski, Cisco Systems, Inc.
December 8, 2004
Introduction
Graphical Editing Framework (GEF)
has been designed to allow editing of user data, generally referred to as the
model, using graphical rather than textual format. It becomes an invaluable
tool when dealing with entities that contain many-to-many, one-to-many and other
complex relationships. With the popularity of the Eclipse Rich
Client Platform, which leads to development of editors for more than just
code, the importance of GEF is certain to increase. A few existing examples,
such as database schema editor [7], logical
circuits editor, and a task flow manager nicely illustrate both the power and
flexibility of the framework that may be applied to such varied and disparate
domains.
Yet the trouble with any generic framework, and GEF is no exception, is that
its comprehensive design makes it hard to learn. Until recently, the smallest
available example came with over 75 classes. Trying to understand nuances of
GEF from interaction of that many user defined types and hundreds more native
to GEF is certain to test the patience and acumen of even the most diligent
developers. To rectify this issue, a new, much smaller example editor has been
added and will appear in the upcoming 3.1 release. The shape diagram editor
(see Figure 1) allows you to create and edit simple
diagrams. It manipulates two types of objects, represented by rectangles and
ellipses. You may connect any two objects with one of the two connection types.
The two connection types are represented by solid and dashed lines. Each connection
is directed, in the sense that it starts at a source object and terminates in
the target object. The direction of each connection is indicated by an arrow.
A connection may be reattached by dragging its source or target to a new object.
Objects in the editor may be selected either by clicking on them or by dragging
a rubber band around them. Selected objects can be deleted. All model manipulations,
such as adding or deleting objects, moving them, resizing them, etc., may be
undone or redone. Finally, the editor integrates with the Properties
and Outline standard views of Eclipse. The editor's virtue comes not
from its usefulness, but rather from the fact its limited number of user defined
types serve as examples of a large percentage of concepts and techniques that
one could encounter in a mature GEF editor.
Download and unzip
the latest 3.1 GEF Examples from the
GEF Project
Downloads
into your main Eclipse directory. To create
a new diagram, launch the wizard by pressing Ctrl-N. Expand the
Examples folder and select Shapes Diagram. The following
sections give a detailed overview of the shape diagram inner workings. Before
we dive into code, let us start with a big picture tour of the main
GEF ideas.
Core GEF concepts
GEF assists you in building a visual editor of your data. The data may be
as simple as a thermostat with a single temperature knob, or as complex as a
virtual private network with hundreds of routers, connections, and quality of
service policies. To the credit of the GEF designers, they managed to create
a framework that works with any data, or in GEF terminology, with any model.
This is achieved by strictly following the Model-View-Controller pattern. The
model is your data. To GEF, a model is any plain old Java object. The model
should not know anything about either the controller or the view. The view
is the visual representation of the model or one of its parts on the screen.
It may be as simple as a rectangle, line or ellipse, or as complex as a nested
logical circuit. Again, the view should remain ignorant about both the model
and the controller. GEF uses Draw2D figures as views, although anything that
implements the IFigure interface will do. The controller, known
as an edit part, is the one that brings the two together. A top level
controller is created when you start editing your model. If the model consists
of many fragments, the top level controller informs GEF about that fact. In
turn, child controllers for each fragment are created. If those again consists
of subparts, the process is repeated until all objects that comprise a model
have their controllers built. The other task of the controller is to create
a figure representing the model. Once the model has been set on a particular
controller, the GEF asks it for the congruous IFigure object. Since
neither the model nor the view know about each other, it is the task of the
controller to listen to changes in the model and update the visual representation
of it. As a result, a common pattern in many GEF editors is a model that posts
PropertyChangeEvent notifications. When an edit part receives an
event notification it reacts appropriately by adjusting visual or structural
representation of the model.
Another aspect of visual editing is reacting to user actions and mouse
or keyboard events. The challenge here is to provide a mechanism that
comes with sensible defaults, yet at the same time is flexible enough to
allow those defaults to be replaced by interactions appropriate for
the edited model. Take a mouse drag event as an example. If we were
to assume every time a mouse drag event is detected that all selected
objects are moved, we'd limit the freedom of the editor developer. It
is quite likely that somebody might wish to provide zoom in or out
operations on a mouse being dragged. GEF solves this issue by using
tools, requests, and policies.
A tool is a stateful object that translates low level events,
such as mouse pressed, mouse dragged, and so on, into high level
requests, represented by a Request object.
Which request is posted depends on which tool is active. For example,
the connection tool, upon receiving a mouse pressed event, posts a
connection start or connection end request. If it was a create tool,
we'd receive a create request. GEF comes with a number
of predefined tools and means of creating application specific
tools. Tools may be activated programmatically or as a response to a
user action. Most of the time, tools post requests to the EditPart
whose figure was underneath the mouse. For example, if you click on a rectangle
representing a widget, the edit part associated with it receives a
selection or direct edit request. Sometimes, like the MarqueeSelectionTool
does, the request
is posted to all parts whose figures are contained within a given area. Regardless of
how one or more edit parts are chosen as the target of requests,
they do not handle requests themselves. Instead, they delegate this
task to registered edit policies. Each policy is asked for a command
for a given request. A policy not wishing to handle the request may
return a null. The mechanism of having policies
rather than an edit part respond
to requests allows to keep both of them small
and highly specialized. This, in turn, means easy to debug and more
maintainable code.
The final piece of the puzzle is commands. Rather than
modifying the model directly, GEF requires that you do it with the help of
commands. Each command should implement applying and undoing
changes to the model or its part. This way GEF editors automatically
support the undo/redo of model alterations.
A significant benefit of using GEF, in addition to being able to boast about
your skills and design pattern knowledge, is the fact that it fully
integrates with the Eclipse platform. Objects selected in the editor
may provide properties for the standard Properties view. Eclipse wizards
may be used to create and initialize models edited by GEF editors. Undo
and Redo items of the Edit menu may trigger undoing or redoing of
GEF editing changes. Simply put, GEF editors are first class citizens
of the regular Eclipse platform, with the same level of integration as
a text editor or any other workbench editor, implementing IEditorPart
interface.
The Model
The first step when building a GEF editor is to create a model. In our case
the model consists of four types of objects: a shape diagram, which holds shapes,
two shape types, and shape connections.
Before we start writing code for those classes, we prepare some
basic infrastructure.
Core model classes
When creating a model use the following guidelines:
-
The model stores all data that may be edited or viewed by
the user. In particular, this also means data pertinent to the
visual representation, such as bounds. You may not rely on either
edit parts or figures to keep such data, as they may be created and
discarded at will. If you dislike storing visual data together with
your business data, consider the suggestion made in
[3].
-
Provide ways of persisting the model. Ensure that when an
editor is closed your model is persisted. When the same editor is
opened, implement a method for the model to restore its state from
permanent storage.
-
The model must remain ignorant of the view or the
controller. Never store any references to either the view or
the controller. GEF may discard a view or a controller under certain
circumstances. If you keep references to them, you are left with
an inactive figure or an edit part.
- Provide a way for others to listen to changes in your
model. This allows the
controller to react to changes and appropriately adjust the
view. Since you are not allowed to keep a reference to the controller,
the only way to deal with it is to provide a way for a controller to
register (and unregister!) with your model as a receiver of events. A
good choice is a property change event notification defined in the
java.beans package.
As the above outlined rules are common for all models, it is beneficial
to create a hierarchy of base classes that enforces them. The
ModelElement extends Java's Object class, adding
three features: persistence, property change, and property source support.
Simple model persistence is guaranteed by implementing
the
java.io.Serializable interface together with
the
readObject method. This solution permits one to save the
editor's model in a binary
format. While it may work for certain applications, it does not provide
format portability. In more complex cases, one may implement
saving the model in XML or similar format. Model changes are communicated
using property change events. The base class allows edit parts to
register and
unregister as receivers of property change notifications.
Those are posted by calling
the firePropertyChange method.
Finally, in order to aid integration with the Properties view of the workbench,
the IPropertySource interface is implemented (details of which
are omitted in Figure 2).
Two types of objects, ellipse and rectangle shapes, share further common
functionality that may be factored out into a common class. In particular,
both represent objects that occupy certain locations and have a non-zero
size. Both may have connections ending or originating at them. Any changes
to these properties need to be communicated to all listeners. Furthermore,
the location and size property are also exposed through the
IPropertySource interface, allowing the user to inspect and
modify them via the Properties view.
Management of connections between objects is worth a more detailed look.
There is no concept of a global store of all connections. Instead, GEF
requires model parts to report any connections that start
or terminate in them. These must be reported as Lists
of objects. The Shape class maintains two array lists
of
source and
target connections. The source connections are those
which have the given shape as the source, and target connections
are those in which the given shape is recorded as the target. Two
methods
( ,
),
with package level visibility, are added that allow shapes
and connections to communicate about their mutual relationship. In
addition, two public methods
( ,
)
are defined that allow classes external
to the model package learn about connectivity of a shape.
These are used by shape controllers, explained in the subsequent part
of this article.
Top level model classes
With the above preparation we may start coding top level model classes.
The Connection class represents a connection between two
shapes. It stores the source and target of a connection. Changes in
connectivity are effected by invoking disconnect or
reconnect methods. Connections maintain a boolean
flag indicating if they are currently connected or disconnected.
The flag is used by commands to verify legitimacy of certain
operations. Both source and target retain
references to the original shapes allowing disconnected connections
to be easily reconnected. Connections maintain one attribute,
the line style. The EllipticalShape and
RectangularShape classes
provide an extension to the above described Shape
class, with a minimum of functionality added.
The ShapeDiagram class extends the ModelElement
class with the container functionality. It maintains a collection of
shapes and notifies listeners about collection changes. The boolean values
returned by
the addChild and
removeChild methods
are used by commands to perform validation of their operations. Public access to all
shapes in a diagram is
provided for the benefit of the controller class.
A note on implementation
A careful reader is certain to recognize that the model effectively
created a specific implementation
of a directed graph, with shapes acting as vertices, connections
representing edges, and shape diagrams playing the role of the graph. The
representation built here is known as adjacency list representation
and is suitable for sparse graphs. With minimal effort, one could
transform the model's code into a generic graph representation. The only additions to
the implementation regularly presented in books on algorithms is the
fact that the graph, its nodes, and its edges post events when their
states change. Also nodes, unlike in mathematical graphs, rather than
being zero-dimensional points, have rectangular bounds. Finally, while
regular graphs act as a central global storage of edges, a diagram does not
hold connections, as GEF does not require it.
It is worth noting that the solutions employed by the above presented classes
are not the only ones possible. Those who developed computer representations
of graphs may prefer alternative ways of storing connections
or arranging communications between nodes and edges. However, such
details are not important. Designers are free to choose their own more
generic, faster, or otherwise enhanced model representation. The vital part is
event based notification of model changes, maintenance of all, including
visual attributes of the model, and support for model persistence.
Depending on your experience and needs, the rest are traits which you should
feel free to alter.
The Views
Due to the simplicity of the shape diagram editor, we do not have to create figures
representing our model, but use predefined figures instead. A
diagram is represented by the Figure class equipped with the
FreeformLayout manager. This gives
us the freedom to drag and drop objects at any location. Objects
are represented either by the RectangleFigure or
by Ellipse. Relying on predefined figures to represent parts of
the model is uncustomary. Even though your view may not have any
references to either the model or the controller, it must have a
visual attribute for every important aspect of the model that the
user may wish to inspect or change. It is thus much more common
to define intricate figures with the number of visual attributes,
such as color, text, nested figures, etc., matching the number
of attributes of the model they represent. For a more
thorough treatment about creating complex figures please see
[4].
The Parts
For each independent piece of the model we must define a controller. By
"independent" we mean an element that may be subject to user
manipulations. A good rule of thumb to follow is that anything that
may be selected or deleted should have its own edit part.
The role of edit parts is to understand the model, listen to events about
its changes, and update views, correspondingly. Due to the choices made
at the model level, all edit parts follow the pattern shown in
Figure 5. Each part
implements the PropertyChangeListener
interface. When
activated, it registers with the model as the receiver of
the property change events. Upon
deactivation, it removes itself from the
list of listeners. Finally, when it
receives a property change event, based
on the name of the property and the new and old values it refreshes one
or more visual aspects of the figure representing the model. In fact, this
pattern is so common that in a larger application it would justify creating
a base class factoring out this behavior.
The DiagramEditPart class
When the editor successfully loads and sets a shape diagram object on a
graphical viewer, the ShapesEditPartFactory is asked to
create a part controlling the diagram. It creates a new DiagramEditPart
and sets the diagram as its model. The newly created part is activated,
registers itself with the model, and creates a figure, with a free form layout
manager that allows positioning of diagram figures based on their constraints
(bounds). The DiagramEditPart reports all shapes contained
in the diagram via the getModelChildren. As mentioned before,
GEF repeats the process of generating parts and figures for all returned
model children.
The DiagramEditPart class installs three policies. All policies
should be installed in the createEditPolicies method that
is declared by the AbstractEditPart class, and must be implemented
by all concrete classes extending the AbstractGraphicalEditPart.
Policies are delegates used by edit parts to handle requests posted by
tools. In the simplest cases, policies take care of generating
commands. A policy is registered with the String key, referred
to as the policy's role.
The key has no meaning to edit parts. However, it should have meaning to a software
developer, as it allows others, specifically those who extend your
controller, to disable or remove the policy by specifying its key. As far
as GEF is concerned, your key could be "foobar". However,
you'd better tell your fellow developers that in order to, say, set a new
layout policy when the layout manager is changed, they need to
install a new "foobar" policy. As this might be amusing, but not
obvious, it is recommended that you use keys defined in
the EditPolicy interface, whose names
try to convey the role the given policy plays in an edit part.
The
first policy installed using the EditPolicy.COMPONENT_ROLE key
has the task of preventing the root of the model from being deleted. It overrides
the createDeleteCommand method to return an unexecutable
command. The
second policy, installed with the LAYOUT_ROLE
key, handles create and constraint change requests. The first request is
posted when a new shape is dropped into a diagram. The layout policy
returns a command that adds a new shape to the diagram editor and places
it at the drop location. The constraint change request is posted whenever
the user resizes or moves shapes already present in the diagram. The
third call to the installEditPolicy removes rather than
installs a policy. This prevents the root part from providing selection
feedback when the user clicks on the area of the diagram corresponding
to the root of the model. This call also illustrates the importance of
meaningful keys used to register part's policies.
The diagram edit part monitors child added and child removed property events.
These are posted by the ShapesDiagam class whenever new
shapes are added or removed. Upon detecting either type of a property
change event, the diagram edit part invokes the refreshChildren
method, defined in the AbstractEditPart. This method traverses
all model children and creates, removes, or re-orders edit part children
appropriately.
The ShapeEditPart class
Diagram shapes are managed by the ShapeEditPart. The part itself
is created by the ShapesEditPartFactory in response to
DiagramEditPart returning a list of model children. Each
part created by the factory is given the child model which it controls.
Once the model is set, the part is asked to create a figure representing it.
Depending on the type of the model, it returns either an ellipse or a
rectangle.
Shape edit parts monitor four types of property change events: size,
location, source, and target connections. If the shape changes size or location,
the
refreshVisual method is called. This method is automatically
invoked by GEF the first time a figure is created. In it, the visual
attributes of the figure should be adjusted based on the state of the
model. Reusing the same method for model updates is another frequently
encountered pattern in GEF editors. In the case of the shape editor part,
the new location and size are fetched and stored with the figure representing
the shape. In addition, the new bounds are passed as the constraint to the
layout manager of the parent controller. When source or target connections
change, the source or target connection edit parts are refreshed by a call
to the methods defined in the AbstractGraphicalEditPart.
Similarly to the refreshChildren method, these methods go
through the list of connections and add, remove, or reposition edit parts
corresponding to them.
As shapes may be connected to other shapes, the shape edit part overrides the
getModelSourceConnections and the
getModelTargetConnections methods. The role of these methods
is to inform GEF about connections that originate or terminate at the
given shape. In addition, the ShapeEditPart implements
the
NodeEditPart interface. By implementing it, the edit part is
able to define source and target anchors, i.e., points to which connections
attach. The logic circuit editor example uses this feature to indicate
where a wire would attach to a logical gate. Since shapes do not have
any specific connection points, we use a chop box anchor which clips the
connection against the rectangular bounds of the figure. If you wish,
you can return the EllipseAnchor for ellipse shapes, which
returns a point on the ellipse's boundary. For more complex shapes, you should
extend the AbstractConnectionAnchor class and implement the
getLocation method. Notice that two types of methods are
implemented: one taking a ConnectionEditPart, and one
taking a Request as the parameter. The
second method is invoked to provide a user with feedback while a new
connection is being created. The
first one is used for
established connections.
Shape edit part installs two policies. The ShapeComponentEditPolicy
supplies a command for removing a shape from the diagram. The second policy,
installed with the GRAPHICAL_NODE_ROLE key, handles the task of
creating and reattaching connections between shapes. A new connection is
created in two steps by the connection creation tool. When a user clicks on a
figure corresponding to an element of the model, the policy is requested to
create a connection command. Returning null from this method
indicates that the connection may not originate from the given element of
the model. If the connection is possible, a new command should be created and
stored in the request as the start command. When another figure is
clicked, the policy is required to supply a
connection complete command. This
could be a new command built from the start command, or the start command tag
supplied with the information about the terminating point of the connection.
The other task of the graphical node edit policy is to provide connection
reattachment commands. Connection reattachment may change the source or the
target of the connection. The same rules apply to these commands as to the
connection creation command. In particular, if a given connection should not
be reattached, the policy must return null. It is also possible for the policy
to return a command that refuses to be executed, by returning false from the
canExecute method. Due to space limitation, details of these
commands are left out and the reader is referred to the source code.
The ConnectionEditPart class
As connections are user editable parts of the model, they
must have their own controller. It is implemented
by the ConnectionEditPart class, which extends
the AbstractConnectionEditPart
class. Similar to other controllers, it implements the
PropertyChangeListener interface
and registers the part for the events with the model on activation.
The connection part
returns a polyline decorated with an arrow as the figure.
It installs two edit policies. The
first one, the
ConnectionComponentPolicy, supplies
a delete command needed by the action associated with the Delete
menu item. The
second one is of greater interest. It equips
a selected connection with handles, placed at the start and the
end. Without this policy, reattaching connections
is impossible, as the GEF has no handles to grab onto when the
end of the connection is being dragged. The authors of the GEF
recommend that all ConnectionEditParts should have
this policy, even if their ends are not draggable. At minimum this
policy provides a visual selection feedback. The
propertyChange method watches for
changes in the line
style property and adjusts the polyline figure appropriately.
Shape Editor
The shape editor extends the GraphicalEditorWithFlyoutPalette
class. This class is a specialized form of a graphical editor, a type
of an editor part, equipped with a palette hosting tool entries. The
extending class must implement two methods, getPaletteRoot
and getPalettePreferences. The first method must return a
palette root populated with tool entries. Tool entries are specialized
types of palette entries capable of installing tools on the edit
domain of the editor. They may be hosted in palette drawers, which
provide convenient way of grouping them. It is recommended that
one tool entry is set as the default entry of the palette root. A typical
solution is to use an instance of the SelectionToolEntry
class in that role. Palette preferences, returned by the second method,
specify whether the palette is visible or collapsed, the location where it
is docked, and the palette width. A commonly found solution is to save them
to and restore them from the plug-in's preference store.
The already mentioned edit domain plays the role of a central controller. It
holds a palette of tools, loads the default tool, maintains the active tool
to which it forwards mouse and key events, and deals with the command stack.
GEF provides the default implementation, the DefaultEditDomain,
which you should set on your editor in the constructor.
Part of the job that a graphical editor must perform is to create and
initialize a graphical viewer. A graphical viewer is a specialized
EditPartViewer capable of performing hit testing. Again, we may
rely on the default viewer supplied by the
GraphicalEditor class. There are, however, a few things that
need to be done. In the configureGraphicalViewer method
set a factory of edit parts. The factory must implement
the sole method of the EditPartFactory interface,
createEditPart(EditPart, Object). The first argument is the
edit part that returned the second argument, a (part of your) model, through
the getModelChildren method. Other things to do here
may include setting up a key handler, context menus, etc.
Once the factory is set, you should
set the contents on the graphical viewer.
The contents naturally should be the object restored from the
IEditorInput passed to the editor in the setInput
method. The shape example also adds
a drop target listener to the graphical
viewer. This allows one to use the drag and drop gesture rather than select and
click when adding new shapes to the diagram. The drop target listener
uses a subclassed TemplateTransferDropTargetListener that
uses a CreateRequest to fetch a command for adding an
object to the model owned by the edit part above which the drag and
drop gesture was finalized.
In addition to the described tasks, the editor takes care of reporting
the dirty flag by monitoring a command stack. This is a preferred
solution, as this keeps the flag in synch with any undo or redo
actions that the user may perform. Notice that the command stack
has the save location marked in both doSave and
doSaveAs methods. Other details of the editor, such
as actual saving and restoring of the model, are not discussed here
as they tend to be very application specific. The editor's functionality
that deals with exposing editor content to other views, connecting
menu items to editor actions, and other workbench cooperation techniques
is described next.
Integrating with the workbench
The editor, as presented so far, would be fully operational. However,
it would not integrate well with the workbench. For example, the
Edit menu actions, such as Delete, Undo, and
Redo could not be used. Other views could not show alternative
presentations of the editor content. In other words, the editor would
not get the benefits of being part of the Eclipse workbench. The task
of transforming an isolated editor into a proper participant of the
workbench is explained in the following three sections.
Editor Actions
The ShapesEditor class creates a number of default
actions in the createActions method invoked during editor
initialization. These are undo, redo, select all, delete, save, and print
actions. In order to
connect standard menu items to them, you should define an action bar
contributor and list it, in the plugin.xml file, as
the editor contributor. In the action bar contributor you need to
implement two methods. The first one,
the buildActions method,
should create retargetable actions for undo, redo, and delete. If you
wish to enable keyboard selection of all widgets, you need
to add a global
action key for the selected action in the second method,
declareGlobalActionKeys.
It may be illustrative to trace what happens when the user selects
the Delete item in the Edit menu (see Figure 12). The
delete action, which is added to the action registry by the
parent class of the ShapesEditor class, traces the
current selection. When the delete action is executed, it checks
if any of the currently selected objects are instances of the
EditPart class. For each such object it requests a command
from the edit part. In turn, each edit part checks if any of the
edit policies created on it understand and are willing to handle
the delete request. For shapes, the ShapeComponentEditPolicy
claims it can handle the delete request, and when asked for a command
it returns a ShapeDeleteCommand instance. The
action executes the command, which removes the shape from
the diagram. The diagram fires a property change event that is
handled by the DiagramEditPart and ultimately leads to
a rectangle or ellipse representing the deleted shape to be removed from the
display.
Exposing properties
Every graphical editor is a source of selection events. You can test this
by creating a view that registers with the workbench site's page as a selection listener.
Every time you select an object in your graphical editor, your view
receives a notification in the selectionChanged method. One
of Eclipse's standard views, Properties view, listens to
selection events, and for every selection checks if its objects implement
the IPropertySource interface. If so, it uses the methods of
the interface to interrogate the selected object or objects about their
properties and displays them in a tabular format.
Thanks to the above described infrastructure, exposing properties of objects
edited in graphical editor is a matter of implementing methods of the
IPropertySource interface. By inspecting the Shape
class you can view how position and size of objects are made
available to the Properties view.
Providing an Outline
The Outline view is used to provide an alternative and often more
succinct view of edited data. In Java editors it is used to show
imports, variables, and methods of the edited class, without going into
code details. Graphical editors can also benefit from such a high level
view. The shape diagram editor, similarly to the logic circuit editor,
exposes the edited contents in the form of a tree (see
Figure 1). The database schema editor
[7] provides a view of the entire editor window
with a thumb for panning.
In order to expose edited content to the Outline view, you need to
override the getAdapter method and
return an outline
implementation when the adapter class is the IContentOutlinePage
interface. The easiest way to implement an outline is to extend
the ContentOutlinePage class by supplying it with an
appropriate configured EditPartViewer.
In the case of the shape diagram editor, the edit part view is implemented by
a tree viewer. You should supply it with the same edit domain as your
main editor. A tree viewer, just like any other EditPartViewer,
requires a method for creating child edit parts. The editor uses the same
mechanism as that employed with the DiagramEditPart, by
setting an edit part factory on it. In addition, the selection of the
overview and the main editor window is synchronized using a
selection synchronizer, a GEF utility class that reconciles the selection
state of two edit parts. The ShapesTreeEditPartFactory
returns either a ShapeTreeEditPart or a
DiagramTreeEditPart instance, depending on the model type. By
inspecting those classes, the reader should have no difficulty recognizing
already familiar patterns. Both edit parts implement the
PropertyChangeListener interface and react to property changes
by adjusting visual representation of the model. Both install edit policies
to control types of interactions exposed through them.
Design patterns used by GEF
GEF attains its flexibility through an extensive use of design patterns. Provided
here is a brief summary of those most commonly encountered. For a more
detailed treatment on patterns please see [2].
- Model-View-Controller
-
The MVC pattern is used by GEF to decouple user interface, behavior,
and presentation. The model is represented by any Java
Object.
The view must implement the IFigure interface. The controller
is a type of an EditPart.
- Command
-
Commands encapsulate model changes, therefore providing support for undoable
operations.
- Chain of Responsibility
-
Decouples senders of requests (tools) from receivers by giving more than
one object a chance to handle the request. In the case of GEF, multiple edit
policies may respond to a request with
Commands which then
are chained together.
- State
-
Allows editor to alter its behavior when its internal state changes. With
GEF editors, this change is implemented by switching too
|
|
|
|
|
Folding in Eclipse Text Editors
|
Summary
Starting with release 3.0, Eclipse allows folding in its text editor. In this
article, I explain the new projection infrastructure introduced in
the JFace Text framework
and show how to extend the XML Editor example provided
with Eclipse to allow folding of text.
By Prashant Deva (prashant.deva@gmail.com)
March 11, 2005
Starting with Eclipse 3.0 the JFace Text framework has been extended with a
feature to allow for collapsing and expanding of text. This can be noticed in
the JDT text editor, which allows you to fold individual methods and classes.
You can implement folding in your plug-in too, to allow the users to fold text
according the structure of your plug-in's documents.
You will notice that 2 new packages have been added to the framework:
- org.eclipse.jface.text.projection
Implements the infrastructure for folding in a UI independent manner.
This package resides in the plug-in org.eclipse.text. - org.eclipse.jface.text.source.projection
Uses the class in org.eclipse.jface.text.projection to implement
folding in a UI dependent manner.
This package resides in the plug-in org.eclipse.jface.text.
Basic Concept
Now let's look at the basic idea in the framework that allows it to just show portions
of the actual text. Although these concepts have been in the framework
since 2.1, a whole new implementation was added in 3.0 to support the additional
requirements of text folding.

As you can see in the figure (a) above, without folding things were very simple.
We had a document to hold the text and a corresponding view to provide the UI
for the text. Now things are a little bit more complicated. We have a Master
Document, which is like the document we used to use previously.
It contains the entire text. However, there is also an additional Projection
Document attached to a Master Document. The contents of a projection
document are a subset of the contents of the Master Document. In other words,
the content of a projection document consists of portions of the Master Document.
As you probabably guessed, when you collapse the text in the editor you see
the contents of a projection document containing only the expanded sections.
Behind the scenes
UI Independent Infrastructure
Now let’s take a look at the org.eclipse.jface.text.projection package.
Keep in mind that you don't actually have to use this package in order to implement
folding in your text editor. The following description is just
to help you understand the concepts behind the folding infrastructure.
The classes we need to concentrate on are:
ProjectionDocument: Represents
a portion of the content of a Master Document.ProjectionDocumentEvent: The event object
sent out by ProjectionDocumentProjectionDocumentManager: Maintains the association between
a Master Document and its Projection Documents.
The rest of the classes in the package are for internal use only and we need
not bother with them.
The class ProjectionDocumentManager acts as glue between the master
document and its child projection documents, connecting them together. Thus
any change made to the projection document causes a corresponding change
to the master document and vice versa.
Here is an example of using ProjectionDocumentManager:
Document masterDocument = new Document(); ProjectionDocumentManager manager = new ProjectionDocumentManager();
ProjectionDocument projectionDocument = (ProjectionDocument) manager.createSlaveDocument(masterDocument);
In the above example we first create a Master Document and
then create a Projection Document off of it by using the ProjectionDocumentManager.
Instances of the class ProjectionDocument
( )
should be created only
by using the ‘factory method’ createSlaveDocument() of ProjectionDocumentManager
and not instantiated through its constructor.
A Projection Document has two methods to define its content from the master
document:
public void addMasterDocumentRange(int
offsetInMasterDocument,int lengthInMasterDocument)
Adds a range of text from the Master Document to the Projection Document.
-
public void removeMasterDocumentRange(int
offsetInMasterDocument,int lengthInMasterDocument)
Removes a range of text corresponding to the Master Document from the Projection
Document.
Adding more to the previous lines of code:
masterDocument.set("one two");
//removes "one t" from projection document projectionDocument.removeMasterDocumentRange(0,5);
//adds "ne " to projection document projectionDocument.addMasterDocumentRange(1,3);
System.out.println(masterDocument.get()); //prints 'one two' System.out.println(projectionDocument.get());//prints 'ne wo'
Above, we set the contents of the master document to a string.
Doing so
automatically sets the contents of the projection document to the same value. Then
we modify the projection document to contain only certain portions of the master
document. Finally we output the contents of both the documents and see that
the portion of master document which we removed from the projection document
is not printed out but the contents of the master document remain the same.
The Stage
UI Dependent Infrastructure
To actually implement folding in your editor, you don't really need to be concerned
with the details above.
The Eclipse developers have provided a nice package
named org.eclipse.jface.text.source.projection
that takes care of all the details and makes your job far easier.
The centerpiece of this package is the ProjectionViewer class,
which you must use in your plug-in instead of the usual TextViewer
class, to implement folding. A ProjectionViewer internally uses
a ProjectionDocumentManager to manage the display of Projection
Documents, so we don't have to worry about that. It implements the ITextViewerExtension5
interface which is a central part of the UI dependent infrastructure.
ITextViewerExtension5 introduces the concept of
widget coordinates and model coordinates.
A widget coordinate corresponds
to a position on the text viewer while a model coordinate corresponds to a position
on the document. A widget range always has a corresponding model range which
maps to the viewer’s document, while on the other hand a model range can be
either ‘exposed’ or ‘unexposed’. An exposed model range is visible on the viewer
and can thus be mapped to a widget range. Thus when you expand the text in the
viewer, that model range is ‘exposed’ and vice versa. ITextViewerExtension5
contains methods to do the conversion from widget to model coordinates and vice
versa, and to expose model ranges.
Projection Support
Another important class in this package is ProjectionSupport.
This class controls the display and configuration of all the UI elements related
to folding, for example, the painting of those elipsis icons when
you collapse a region, and the vertical column that contains the triangle icons
to expand/collapse text. A ProjectionSupport instance needs to be installed
on a viewer. The XML Editor example shown below demonstrates how to do this
in code.
ProjectionSupport
allows you to specify summarizable annotation types. Basically,
these are the annotations that will appear in the vertical column on the left
when you fold the text that contains them. For example, JDT specifies the ‘error’
and ‘warning’ annotation types as summarizable, so that when you fold the text
that contains a warning or an error, its icon appears on the vertical column
besides the folding arrow, as shown below.

Here is how it is implemented:
fProjectionSupport.addSummarizableAnnotationType( "org.eclipse.ui.workbench.texteditor.error"); fProjectionSupport.addSummarizableAnnotationType( "org.eclipse.ui.workbench.texteditor.warning");
The setHoverControlCreator() method
allows you to set up a hover control to display the collapsed text
in a tooltip style box when the use moves the cursor over the arrow.
For example:

The constructor takes an IInformationControlCreator as the argument. You usually
create an anonymous class here. Here is how JDT does it:
fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() { public IInformationControl createInformationControl(Shell shell) { return new CustomSourceInformationControl(shell, IDocument.DEFAULT_CONTENT_TYPE); } });
Projection Annotations
To enable folding, we have to specify which regions of the text are collapsible.
We do this by
calling addAnnotation()
adding ProjectionAnnotations to the ProjectionViewer's
ProjectionAnnotationModel. The position allows the annotation to
be attached to certain text in the editor.
The methods of ProjectionAnnotationModel are pretty self-explanatory:
class ProjectionAnnotationModel{
public void collapse(Annotation annotation) public void expand(Annotation annotation) public boolean expandAll(int offset,int length)
public void toggleExpansionState(Annotation annotation)
public void modifyAnnotations(Annotation[] deletions,Map additions, Annotation[] modifications) }
These methods toggle the annotations to expand/collapse states.
The only method which may be confusing is: modifyAnnotations().
This basically does several deletions, additions, and modifications at once.
The additions
parameter is a Map with Annotation as the key and Position as the value. Executing
the method generates a single change event rather than a series of them when
you would add and remove annotations one after the other.
A ProjectionAnnotation has the following methods to collapse/expands
the text region it is associated with:
public void markCollapsed() //marks the annotation as collapsed public void markExpanded() //marks the annotation as expanded public boolean isCollapsed() //tells whether the annotation is collapsed or expanded
Thus, when you are working in JDT and you click the arrow on the left side
column of the text to collapse it, the method isCollapsed() is
called to check whether the text is collapsed or not and then
markCollapsed() is called
if isCollapsed() returns false. For example,
if(!annotation.isCollapsed()) annotation.markCollapsed();
Manipulating ProjectionAnnotations is the only
supported way to control folding. Even if you were to get a hold of a Projection
Document, its projection behavior should never be manipulated directly.
Painting the Annotations...
Folding in the editor would be quite useless without the user interface
that allowed us to collapse and expand the text.
Here's what it looks like in the editor:

ProjectionAnnotation has a method which actually paints those triangles you see
on the left.
public void paint(GC gc, Canvas canvas,
Rectangle rectangle)
You can override this method in your plug-in if you want to draw something other
than an triangle on the left side, for example a plus/minus sign.
There is one more method you should know about:
public void setRangeIndication(boolean
rangeIndication)
A range indication
is that line you see when you move your cursor to an triangle indicating
that the text is expanded. The line signifies the range of
text that will be collapsed when you click the triangle, and thus the name.
Passing true or false to this method controls whether
that line is drawn or not.
The Show
XML Editor plug-in
I can hear you saying “Yeah, all this is fine, but how do I actually use this
stuff in my plug-in?” Well to show you how to do that I will walk you through
a little example. We will extend the XML editor plug-in example provided with
Eclipse to allow folding of XML elements. My aim is just to demonstrate the
basics of implementing folding here, so I have tried to keep the code as simple
as possible. If you want to add any advanced functionality you should be able
to do so yourself by now (hopefully) ;-)
Let's look at the steps involved in supporting folding.
Note that all the methods shown below are defined in the class
XMLEditor which extends the TextEditor class.
- Override
createPartControl method of TextEditor
to configure and install ProjectionSupport - Override
createSourceViewer method of AbstractTextEditor
to return a ProjectionViewer - Provide some functionality to define collapsible regions
Now lets see how to implement this in our plug-in.
Create a new Plug-in project.
At the end of the Project Wizard there will be an option to Create a
plug-in using one of the templates. Check it and select Plug-in with an editor.
This will create a plug-in with an editor for XML files. Now we will extend
this editor to allow the folding of XML elements.
1) First, we override the createPartControl
method of the TextEditor class. To keep things simple
I haven't provided any code for summarizable annotation types or hover controls,
but you are free to do so in your own plug-in.
public void createPartControl(Composite parent) { super.createPartControl(parent); ProjectionViewer viewer =(ProjectionViewer)getSourceViewer();
projectionSupport = new ProjectionSupport(viewer,getAnnotationAccess(),getSharedColors()); projectionSupport.install();
//turn projection mode on viewer.doOperation(ProjectionViewer.TOGGLE);
annotationModel = viewer.getProjectionAnnotationModel();
}
2) Next, we tell createSourceViewer to return
a ProjectionViewer instead of a SourceViewer.
protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { ISourceViewer viewer = new ProjectionViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles);
// ensure decoration support has been created and configured. getSourceViewerDecorationSupport(viewer);
return viewer; }
3) Finally, we need some mechanism to tell the editor which
regions are collapsible. For that I have written a (very) small parser for XML
(which is very buggy and doesn't support nested elements). The parser runs as
a reconciling strategy and parses the entire document every time it is modified.
The parser then passes the range of every XML element to the editor, which then
in turn adds Projection Annotations to define collapsible regions.
The source code for my simple parser is too large to show here, however, those
interested can take a look at the XmlReconcilingStrategy.java
file in the provided source code.
Below is the code that does all this:
private Annotation[] oldAnnotations; public void updateFoldingStructure(ArrayList positions) { Annotation[] annotations = new Annotation[positions.size()];
//this will hold the new annotations along //with their corresponding positions HashMap newAnnotations = new HashMap();
for(int i = 0; i < positions.size();i++) { ProjectionAnnotation annotation = new ProjectionAnnotation();
newAnnotations.put(annotation, positions.get(i));
annotations[i] = annotation; }
annotationModel.modifyAnnotations(oldAnnotations, newAnnotations,null);
oldAnnotations = annotations; }
Here is our completed editor with folding:

Source Code
All the source code that accompanies this article
may be found in the xmlEditorPlugin.zip file.
Conclusion
By now, you should have understood the UI independent and dependent infrastructure
used in JFace Text to implement the folding capability. You should also have
understood how to implement folding in the text editor of your eclipse plug-in.
Plus you even got a free XML editor for Eclipse with folding support ;-).
References
|
|
|
|
|
Eclipse Corner Articles
|
| Eclipse
Corner Articles |
|
The following articles
have been written by members of the development team and other members
of the eclipse community. You too can contribute! Eclipse Corner depends
on contributions from people like you.
(Besides these, a number of other web sites carry technical articles about
Eclipse. You'll find pointers to these on the Eclipse
Community page.) |
| Eclipse
White Paper |
 |
Eclipse
Platform Technical Overview July 2001 (updated for Eclipse
2.1 in Feb. 2003)
The Eclipse Platform is designed for building integrated development environments
(IDEs) that can be used to create applications as diverse as web sites,
embedded JavaTM programs, C++ programs, and Enterprise JavaBeansTM. This
paper is a general technical introduction to the Eclipse Platform. Part
I presents a technical overview of its architecture. Part II is a case study
of how the Eclipse Platform was used to build a full-featured Java development
environment. |
| New
Articles |
 |
Folding
in Eclipse Text Editors Prashant Deva March 11, 2005
Starting with release 3.0, Eclipse allows folding in its text
editor. In this article, I explain the new projection infrastructure
introduced in the JFace Text framework and show how to extend the XML
Editor example provided with Eclipse to allow folding of text. |
 |
A Shape Diagram Editor Bo Majewski (Cisco) December 8, 2004
Graphical Editing Framework (GEF) provides a powerful foundation for creating
editors for visual editing of arbitrary models. Its effectiveness lies in
a modular build, fitting use of design patterns, and decoupling of components
that comprise a full, working editor. To a newcomer, the sheer number and
variety of concepts and techniques present in GEF may feel intimidating. However,
once learned and correctly used, they help to develop highly scalable and
easy to maintain software. This article aims to provide a gentle yet comprehensive
introduction to GEF. It describes a shape diagram editor - a small, fully
functional test case of core concepts. |
 |
Modeling Rule-Based Systems with EMF Chaur G. Wu
November 30, 2004
There are examples of meta-models defined in ECore for modeling objects and
relational data. However, not much has been said about how to model rules. This
article will define a meta-model in ECore for modeling rule-based systems. We
will then use the meta-model to model the solution of a logical problem. Then
we will compose some JET templates and generate code from the model, run the
generated code through a rule engine and see that the logical problem is
correctly solved. |
 |
Building
administrative applications in Eclipse Doina Klinger and Chris
Markes (IBM) November 12, 2004
Eclipse is most commonly used as a platform for tools that allow the
user to construct or assemble an end product out of development resources.
It is less usual to use Eclipse as an administrative tool for monitoring
existing runtime systems or applications. This article will describe some
of the issues that arise in this case and illustrate possible solutions.
It will show you can build an Eclipse perspective dedicated to the monitoring
task. Running processes are shown in a dedicated view which always reflects
their current state. You can start/stop the process, manage connections,
invoke operations that the server exposes, examine server output and view
events generated by the running applications. |
 |
EMF goes RCP Marcelo Paternostro (IBM) October 12, 2004
This article explains how you can use EMF to generate RCP applications. It assumes
that you have already used EMF, or have at least read the articles and references
available on the documentation section of the EMF web site. |
 |
Building a Database Schema Diagram Editor with GEF Phil Zoio
(Realsolve Solutions) September 27, 2004
GEF is a very powerful framework for visually creating and editing models. With a small initial investment,
even the relative Eclipse novice can be quickly up and running, building applications with graphical editing capabilities.
To illustrate, this article uses a relational database schema diagram editor with a deliberately
simplified underlying model, but with enough bells and whistles to show some of the interesting features of GEF at work. |
 |
On the Job: The Eclipse Jobs API Michael Valenta (IBM) September
20, 2004
This article looks at the new Jobs API available as part of Eclipse 3.0.
It describes the main portions of the Jobs API and the use of scheduling
rules. It also describes some changes to Eclipse resource management including
how the Resources plug-in integrates with the new API. Finally, it describes
some new UI functionality that has been added to provide feedback to users
about jobs that are run in the background. |
 |
Branding Your Application Andrew Eidsness and Pascal Rapicault
(IBM) September 16, 2004
In this article we look at how to create branding for your Eclipse-based
application. Branding is how you change the high level visual elements of your
product. This includes items such as the splash screen, the about dialog, and
the program executable. |
| General |
 |
Rich
Client Tutorial Part 1 Ed Burnette (SAS) July 28,
2004
The Rich Client Platform (RCP) is an exciting new way to build Java
applications that can compete with native applications on any platform.
This tutorial is designed to get you started building RCP applications
quickly. |
 |
Rich
Client Tutorial Part 2 Ed Burnette (SAS) August 9,
2004
The Rich Client Platform (RCP) allows you to build Java applications
that can compete with native applications on any platform. Part 1 of
the tutorial introduced you to the platform and the steps used to build
the smallest possible RCP program. In part 2 we'll look at what we did
in more detail and introduce some of the configuration classes that let
you take control of much of the layout and functionality of an RCP
application. |
 |
Rich
Client Tutorial Part 3 Ed Burnette (SAS) July 28,
2004
The Rich Client Platform (RCP) lets you pick and choose functionality
from Eclipse for use in your own applications. Parts 1 and 2 of this
tutorial introduced you to the platform and some of the configuration
classes it provides. Part 3 discusses how to add functionality such as
menus, views, and help files. |
 |
PDE
Does Plug-ins Wassim Melhem (IBM) and Dejan Glozic (IBM) September
8, 2003
The Plug-in Development Environment (PDE) provides a set of tools that assist
the developer in every stage of plug-in development from genesis to deployment.
This article chronicles the creation, development, testing, building, and
deployment of a simple "Hello World" plug-in using a subset of
these tools. |
 |
How
to Internationalize your Eclipse Plug-In Dan Kehn (IBM), Scott
Fairbrother (IBM), and Cam-Thu Le (IBM) August 23, 2002
This article is a roadmap for writing Eclipse plug-ins destined for the
international market. We'll begin with a brief review of the motivations
and technical challenges of internationalization, followed by step-by-step
instructions of how to internationalize your Eclipse plug-in. |
 |
How
to Test Your Internationalized Eclipse Plug-In Dan Kehn (IBM)
August 23, 2002
This article shows you how to validate your internationalized product and
prepares you for the types of common problems you can expect during translation
testing. It includes an Eclipse plug-in that defines a Properties File
Compare view that can help your translation testers find errors more
quickly. |
 |
Branding Your Application Andrew Eidsness and Pascal Rapicault
(IBM) September 16, 2004
In this article we look at how to create branding for your Eclipse-based
application. Branding is how you change the high level visual elements of your
product. This includes items such as the splash screen, the about dialog, and
the program executable. |
 |
How to Use the Eclipse API Jim des Rivieres (OTI) April
24, 2001
The Eclipse Platform offers a comprehensive API (Application Programmer
Interface) to developers writing plug-ins. This article discusses the general
ground rules for using the Eclipse Platform API, including how to tell API
from non-API, and how to stay in the API "sweet spot" to avoid the risk
of being broken as the platform and its APIs evolve. These general ground
rules are also recommended practice for plug-ins that must declare API elements
of their own. |
 |
Levels of Integration Jim Amsden (OTI) March 25, 2001
The types of problems web application developers face today require the
use of a diverse set of tools that operate in many domains. In order to
provide flexible tool integration, a tool integration platform must allow
tool developers to target different levels or integration based on the desired
level of investment, time to market, and specific tool needs. Each integration
level determines how a tool must behave, and what end users can expect as
a result. This article defines the different levels of tool integration
supported by Eclipse, and gives an overview of how they work.
|
 |
Designing
Accessible Plug-ins in Eclipse Tod Creasey (IBM) May 20, 2003
Accessibility for the disabled is now a priority in application development
as advances in techniques and support within operating systems have now
made this possible. This article covers the Eclipse accessibility support,
general tips for creating accessible plug-ins, and the types of disabilities
that the Eclipse accessibility support assists. This is all illustrated
using an example of making a view accessible. |
 |
Building
administrative applications in Eclipse Doina Klinger and Chris
Markes (IBM) November 12, 2004
Eclipse is most commonly used as a platform for tools that allow the
user to construct or assemble an end product out of development resources.
It is less usual to use Eclipse as an administrative tool for monitoring
existing runtime systems or applications. This article will describe some
of the issues that arise in this case and illustrate possible solutions.
It will show you can build an Eclipse perspective dedicated to the monitoring
task. Running processes are shown in a dedicated view which always reflects
their current state. You can start/stop the process, manage connections,
invoke operations that the server exposes, examine server output and view
events generated by the running applications. |
| Core |
 |
How
You've Changed! Responding to resource changes in the Eclipse workspace
(Revised for 3.0)
John Arthorne (OTI) November 23, 2004
Many tools and user interface elements are interested in processing resource
changes as they happen. For example, the task list wants to update new or
changed markers, the navigator wants to reflect added and deleted resources,
and the Java compiler wants to recompile modified Java files. Such notifications
are potentially costly to compute, manage and broadcast. The Eclipse Platform
resource model includes a series of mechanisms for efficiently notifying
clients of resource changes. This article outlines these facilities and
gives some examples of their use. |
 |
Project
Natures and Builders (Revised for 3.0) John Arthorne (IBM)
November 23, 2004
This article discusses two central mechanisms that are associated with projects
in an Eclipse workspace. The first of these is incremental project builders,
which create some built state based on the project contents, and then keep
that built state synchronized as the project contents change. The second
is project natures, which define and manage the association between a given
project and a particular plug-in or feature. The purpose and uses of builders
and natures will be described in detail, and working examples will be provided
to highlight the finer details of implementing them for your own plug-in.
|
 |
Notes
on the Eclipse Plug-in Architecture Azad Bolour (Bolour Computing)
July 3, 2003
Eclipse plug-ins embody an architectural pattern for building an application
from constituent parts. This article presents an in-depth view of the participant
roles and collaborations of this architectural pattern, as they exist in
an instance of the Eclipse workbench. The goal is to provide an understanding
of plug-ins, and of how plug-in extensions are defined and processed, independently
of the mechanics of using the Eclipse workbench to produce plug-ins. |
| Debug |
 |
We Have Lift-off: The Launching Framework in Eclipse Joe Szurszewski
(IBM) January 8, 2003
The ability to launch (run or debug) code under development is fundamental
to an IDE. But because Eclipse is more of a tools platform than a tool itself,
Eclipse's launching capabilities depend entirely on the current set of installed
plug-ins. This article describes the API available to build launching plug-ins
and works through developing an example launcher using this API. |
 |
Launching Java Applications Programmatically Darin Wright (IBM)
August 26, 2003
Application developers require the ability to run and debug code in order to
test it. Tool developers require the ability to launch Java applications that
assist in application development - for example, starting and stopping a web
server on which servlets, JSPs, and HTML pages can be tested; or launching a
VM on which scrapbook evaluations can be performed. This article focuses on
the high level API provided by the Java launching plug-in that tool developers
can leverage for the programmatic launching of local Java applications. |
 |
How to write an Eclipse debugger Darin Wright (IBM) and Bjorn
Freeman-Benson (Predictable Software) August 27, 2004
One of the major tasks of adding a new language to an Eclipse-based IDE
is debugging support. A debugger needs to start and stop the
program being debugged, suspend and resume, single-step, manage
breakpoints and watch points,
and so on. This article explains the Eclipse Platform debug framework
and steps through a
simple, yet illustrative, example of adding debug support for a new
language. |
| Help |
 |
Help - Part 1: Contributing a Little Help (Revised for 2.0) Greg
Adams (OTI) and Dorian Birsan (IBM) August 9, 2002
The Eclipse Platform’s help system defines two extension points ("toc"
and "contexts") that allow individual plug-ins to contribute
online help and context-sensitive help for their components. In this article
we will investigate the "toc" extension point and how you can
use it to contribute documentation for your plug-in. |
| SWT |
 |
Understanding
Layouts in SWT (Revised for 2.0)
Carolyn MacLeod (OTI), Shantha Ramachandran (OTI) April 24, 2002
When writing applications in SWT, you may need to use layouts to give your windows a specific look. A layout controls the
position and size of children in a Composite.
Layout classes are subclasses of the abstract class Layout. This article shows you how to work with standard layouts,
and write your own custom layout class. |
 |
SWT:
The Standard Widget Toolkit - Part 2 Carolyn MacLeod (OTI)
and Steve Northover (OTI) November 27, 2001
SWT uses operating system resources to deliver its native graphics and widget
functionality. Allocating and freeing operating system resources is traditionally
an area of programming that is error prone. Languages that include garbage
collection, such as the Java™ language, relieve the programmer from the
burden of managing memory, but not from the allocation and freeing of operating
system resources. This article discusses the simple strategy used by SWT
to help application designers manage operating system resources. |
 |
Getting Your Feet Wet with the SWT StyledText Widget (Revised for 3.0) Lynne
Kues (OTI) and Knut Radloff (OTI) July 19, 2004
The StyledText widget is a customizable widget that can be used to display
and edit text with different colors and font styles. This article presents
an overview of the concepts, issues, and rules that you should be aware
of when using the StyledText widget. |
 |
Into
the Deep End of SWT StyledText Widget (Revised for 2.0) Lynne
Kues (OTI) and Knut Radloff (OTI) September 18, 2002
This is the second
of two articles on the SWT StyledText widget. This article dives into
some of the more advanced concepts of StyledText and builds on the previous
article "Getting
Your Feet Wet With the SWT StyledText Widget".
|
 |
SWT Color Model James Moody (OTI) and Carolyn MacLeod (OTI)
April 24, 2001
The combination of platforms, display devices and color depth makes providing
an easy to use yet powerful and portable color model an interesting challenge.
In this article we will examine the color management models of Windows and
X/Motif and then dig into the makings of the SWT color model and its implications
for client code. |
 |
SWT: The Standard Widget Toolkit - Part 1 Steve Northover
(OTI) March 22, 2001
SWT is the software component that delivers native widget functionality
for the Eclipse platform in an operating system independent manner. It is
analogous to AWT/Swing in Java with a difference - SWT uses native widgets.
This article is the first in series of articles that discuss the SWT widget
toolkit. This article discusses the low level implementation techniques
used to implement SWT on different platforms. Examples are drawn from the
windows and Motif implementations. |
 |
ActiveX Support in SWT Veronika Irvine (OTI) March 22,
2001 OLE
Documents, such as Word, Excel or PowerPoint, and ActiveX Controls such
as Internet Explorer are COM objects that can be embedded into other applications
running on a Microsoft Windows platform. This article provides an overview
of OLE and how to integrate OLE Documents and ActiveX Controls into an application
using SWT. |
 |
Creating Your Own Widgets using SWT Steve Northover (OTI) &
Carolyn MacLeod (OTI) March 22, 2001
When writing applications, you typically use the standard widgets provided
by SWT. On occasion, you will need to extend the set of base widgets by
creating your own custom widgets. For example, you might want to add a new
type of widget not provided by the standard widgets, or extend the functionality
of an existing widget. This article explains the different SWT extension
strategies and shows you how to use them. |
 |
Graphics
Context - Quick on the draw Joe Winchester (IBM) July 3, 2003
The package org.eclipse.swt.graphics contains classes that
allows management of graphics resources. Graphics can be drawn on anything
that implements org.eclipse.swt.graphics.Drawable, which includes
org.eclipse.swt.widgets.Control and org.eclipse.swt.graphics.Image.
The class org.eclipse.swt.graphics.GC encapsulates all of the
drawing API, including how to draw lines and shapes, draw text and images
and fill shapes. This article shows how to use a GC to draw onto an Image,
or onto a control through its paintEvent callback. The Canvas control, specifically
designed for drawing operations, has a number of constructor style bits
that allow you to determine when and how painting occurs, and the article
shows how to use these. |
 |
Drag and Drop - Adding Drag and Drop to an SWT Application Veronika Irvine (IBM) August 25, 2003
Drag and drop provides a quick and easy mechanism for users to re-order and transfer
data within an application and between applications. This article is an overview of how
to implement Drag and Drop and Clipboard data transfers within an SWT
application. |
 |
Taking
a look at SWT Images Joe Winchester (IBM) September 10, 2003
SWT's Image class can be used to display images in a GUI. The most common
source of images is to load from a standard file format such as GIF, JPEG,
PNG, or BMP. Some controls, including Buttons and TreeItems, are able to
display an Image directly through the setImage(Image) method, but any control's
paint event allows images to be drawn through the callback's graphic context.
SWT's ImageData class represents the raw data making up an SWT Image and
determines the color for each pixel coordinate. This article shows the correct
uses of ImageData and Image, shows how to load images from files, and how
to achieve graphic effects such as transparency, alpha blending, animation,
scaling, and custom cursors. |
 |
A
small cup of SWT Christophe Cornu (IBM) September 19, 2003
Are you interested in developing applications for the Microsoft Pocket PC?
Are you a desktop developer curious about embedded user interfaces? A well-built
embedded application is both user and resource friendly. User expectations
are high, but resources are very limited. This article contains a bag of
hints, tricks, and recipes for developing SWT apps on the Pocket PC. |
 |
A
Basic Image Viewer Chengdong Li (University of Kentucky) March
15, 2004
This article shows how to extend SWT Canvas to implement a mini image viewer plug-in using Java2D
transforms. The
extended image canvas can be used to scroll and zoom large images, and can also
be extended to apply other transforms. The implementation is based on SWT and
the non-UI portions of AWT. The plug-in has been tested on Windows, Linux GTK, and Mac
OS X Carbon with Eclipse 2.1 or better. |
 |
Viewing
HTML pages with SWT Browser widget Christophe Cornu (IBM) August
26, 2004
This article explains how to add HTML viewing capability to an SWT
application. The Browser widget provides an easy way to integrate rich
HTML content into your application. |
| Workbench
& JFace |
 |
Eclipse
User Interface Guidelines, Version 2.1 Nick Edgar, Kevin Haaland,
Jin Li, and Kimberley Peter (IBM) February 2004
User Interface Guidelines "best practices"
document intended for use by designers and implementors of an Eclipse user
interface extension. (Earlier
version of the guidelines.) |
 |
Simplifying
Preference Pages with Field Editors Ryan Cooper (OTI) August
21, 2002 Even
though preference pages can be simple to program, you can spend a lot of
time getting them "just right." Field editors make this task faster
and easier by providing the behavior for storing, loading, and validating
preferences. Field editors also define some of the behavior for grouping
and laying out widgets on a preference page. |
 |
How
to use the JFace Tree Viewer
Chris Grindstaff (Applied Reasoning) May 2, 2002
The goal of this article is to teach you how
to use TreeViewers in your Eclipse plug-ins or stand-alone JFace/SWT applications.
We’ll start with a simple example and progressively add functionality.
|
 |
Preferences
in the Eclipse Workbench UI (Revised for 2.0) Tod Creasey (OTI)
August 15, 2002
In the Eclipse Platform
plug-in developers define preference pages for their plug-ins for use in
the Workbench Preferences Dialog. This article explains when to use a preference
and some of the features the Eclipse Platform provides to support preferences.
|
 |
Creating an Eclipse View Dave Springgay (OTI) November 2, 2001
In the Eclipse Platform
a view is typically used to navigate a hierarchy of information, open an
editor, or display properties for the active editor. In this article
the design and implementation of a view will be examined in detail.
You'll learn how to create a simple view based on SWT, and a more advanced
view using the JFace viewer hierarchy. We'll also look at ways to
achieve good integration with many of the existing features in the workbench,
such as the window menu and toolbar, view linking, workbench persistence
and action extension. |
 |
Creating JFace Wizards Doina Klinger (IBM) December 16, 2002
This article shows you how to implement a wizard using the JFace toolkit
and how to contribute your wizard to the Eclipse workbench. A wizard whose
page structure changes according to user input is implemented to demonstrate
the flexibility of wizard support. |
 |
Contributing
Actions to the Eclipse Workbench Simon Arsenault
(OTI) October 18, 2001
The Eclipse Platform
is an open and extensible platform. This article explains in detail how
the Workbench can be extended to add new actions and provides guidance to
the plug-in developers on how they can design for extensibility. |
 |
Using Perspectives in the Eclipse UI Dave Springgay (OTI) August
27, 2001
In the Eclipse Platform
a Perspective determines the visible actions and views within a window.
Perspectives also go well beyond this by providing mechanisms for task oriented
interaction with resources in the Eclipse Platform, multi-tasking and information
filtering. In this article the concepts behind perspectives are examined.
The process for perspective definition, extension and instantiation will
also be covered in detail with coding examples and sample scenarios.
|
 |
Using Images in the Eclipse UI (Revised for 2.0) John Arthorne (OTI)
September 12, 2002
Managing images in a large graphical application can be a daunting task.
Since modern operating systems such as Windows only support a small number
of images in memory at once, an application’s icons and background images
must be carefully managed and sometimes shared between widgets. This article
describes the image management facilities provided by the Eclipse Platform,
along with some best practice guidelines to keep in mind when writing your
own Eclipse UI plug-ins. We assume the reader already has a basic understanding
of Eclipse, the UI extension points defined by the Eclipse Platform, and
the Standard Widget Toolkit (SWT). |
 |
Mark My Words Dejan Glozic (IBM) and Jeff McAffer (OTI) April
1, 2001
Eclipse workbench has
a central mechanism for managing resource annotations. They are called markers.
In this article, you will learn how to use markers to mark-up resources
as well as how to define your own marker types and enhance the Tasks view
to handle them in a special way. |
 |
Understanding Decorators in Eclipse Balaji Krish-Sampath (IBM) January
16, 2003
Decorators, as the name suggests, are used for adorning/annotating resources
with useful information. Decorators can be used by plug-ins to convey more
information about a resource and other objects displayed in different workbench
views. This article, with the help of a simple plug-in example, will
illustrate the steps involved in decorating resources, along with some best
practice approaches for decorating resources. Finally, we will discuss performance
issues that may arise when enabling decorators, and briefly go over the
new Lightweight decorators found in Eclipse 2.1. |
 |
Take
control of your properties Dicky Johan (Broadvision) May 20,
2003
The Eclipse workbench provides a properties view which is used to view (and/or
edit) properties of a selected item. In this article, you will learn how
to use the properties view to dynamically modify the properties of a GUI
button. |
 |
Building
and delivering a table editor with SWT/JFace Laurent Gauthier
(Mirasol Op'nWorks) July 3, 2003
The JFace API provides several classes that can be used to build editable
table views. In this article, we present a fairly extensive example that
exercises the JFace and SWT classes needed to implement a table with cell
editors for check-boxes, free text and combo-boxes. We also show how to
package and deliver the classes into a stand-alone (non-Eclipse) Java application. |
 |
Drag
and Drop in the Eclipse UI John Arthorne (IBM) August
25, 2003
In this article, we discuss the drag and drop facilities provided by JFace and
the Eclipse platform UI. After reading this, you will know how to add drag and
drop support to your own Eclipse views, and how that support will interact with
the standard views in the Eclipse platform. Along the way, we'll also discuss
that keyboard relative of drag and drop: cut and paste. You'll learn that putting
your own custom objects on the clipboard is easy once you've figured out the
basics of drag and drop. This article is intended to be read as a companion
to the SWT
drag and drop article. |
 |
Mutatis
mutandis - Using Preference Pages as Property Pages Berthold
Daum (bdaum industrial communications) October 24, 2003
A common problem in the implementation of applications is the implementation of
project-specific properties that override workbench-wide preferences on project or file level. The
naive approach is to implement these pages from scratch. However, writing the
same code twice is a boring task and leads to increased maintenance efforts. In
this article we show how existing preferences pages (with or without field
editors) can be easily converted into pages that can act as both preference and
property pages. We demonstrate this by implementing the abstract class FieldEditorOverlayPage
providing the necessary functionality. |
 |
On the Job: The Eclipse Jobs API Michael Valenta (IBM) September
20, 2004
This article looks at the new Jobs API available as part of Eclipse 3.0.
It describes the main portions of the Jobs API and the use of scheduling
rules. It also describes some changes to Eclipse resource management including
how the Resources plug-in integrates with the new API. Finally, it describes
some new UI functionality that has been added to provide feedback to users
about jobs that are run in the background. |
| Team |
 |
Branching
with Eclipse and CVS Paul Glezen (IBM)
July 3, 2003
This article presents a brief branch and merge scenario designed to quickly
illustrate some branch and merge features of Eclipse's CVS integration.
I assume the reader already appreciates the value of branching and merging
in a source control environment. Little is said to justify it here. Rather,
a step-by-step scenario illustrates the common branch and merge operations
using Eclipse-based IDEs with CVS as the source control mechanism. |
| Update |
 |
How
To Keep Up To Date Dejan Glozic (IBM) and Dorian Birsan (IBM)
August 27, 2003
This article shows you how to create and publish bundles of plug-ins (called
features) to an update site so that customers can download and install them
directly into Eclipse using the Eclipse update manager. This has many advantages
over the low tech way of delivering new or updated plug-ins in a zip file that
someone manually unzips into the directory where Eclipse is installed. |
| Beyond
the Eclipse Platform |
 |
Using EMF Catherine Griffin (IBM) December 9, 2002 (updated
May 2003 for EMF 1.1)
This article introduces EMF, the Eclipse Modelling Framework, and will help
you get started using EMF in your own Eclipse plug-ins. |
 |
JET Tutorial Part 1 (Introduction to JET) Remko Popma (Azzurri
Ltd.) July 30, 2003 (updated May 2004 for EMF 2.0)
Generating source code can save you time in your projects and can reduce
the amount of tedious redundant programming. Generating source code can
be powerful, but the program that writes the code can quickly become very
complex and hard to understand. One way to reduce complexity and increase
readability is to use templates. The Eclipse Modeling Framework (EMF) project
contains two very powerful tools for generating source code: JET (Java Emitter
Templates) and JMerge (Java Merge). With JET you can use a JSP-like syntax
(actually a subset of the JSP syntax) that makes it easy to write templates
that express the code you want to generate. JET is a generic template engine
that can be used to generate SQL, XML, Java source code and other output
from templates. In this article you will learn how to create JET
templates, how to use the JET Nature and JET Builder to automatically translate
templates into Java classes, and how to use these classes to generate source
code. This article also provides a short reference to the JET syntax. |
 |
JET Tutorial Part 2 (Write Code that Writes Code) Remko Popma
(Azzurri Ltd.) August 26, 2003 (updated May 2004 for EMF 2.0)
In Part 2 of this JET (Java Emitter Templates) tutorial, we will take a
look at the JET engine API. You will learn how to write plug-ins that use
the classes in the JET package to generate Java source code. As a real-world
example, we will create a plug-in that takes user input and generates a
Typesafe Enumeration class. The generated source code is based on a JET
template that can be distributed with the plug-in, allowing users of the
plug-in to customize the generated code by editing the template. This article
also provides a short reference to the JET API. |
 |
Display a UML Diagram using Draw2D Daniel Lee (IBM) August
25, 2003
The Graphical Editing Framework (GEF) ships with a painting and layout plug-in
called Draw2D. Draw2D provides figures and layout managers which form the
graphical layer of a GEF application. This article focuses only on the use
of Draw2D to render a simple UML class diagram. While Draw2D can be used
for standalone purposes, it is not an editing framework. Most applications
will use the GEF plug-in as the editing layer. |
 |
Using
Native Drag and Drop with GEF Eric Bordeau (IBM) August
25, 2003
Native drag and drop provides the ability to drag data from one GUI
object to another GUI object, which could potentially be in another
application. GEF allows access to the operating system's underlying
drag and drop infrastructure through SWT. This article will provide an
in-depth look at GEF's drag and drop functionality and show some simple
examples of how to take advantage of this API. |
 |
Building a Database Schema Diagram Editor with GEF Phil Zoio
(Realsolve Solutions) September 27, 2004
GEF is a very powerful framework for visually creating and editing models. With a small initial investment,
even the relative Eclipse novice can be quickly up and running, building applications with graphical editing capabilities.
To illustrate, this article uses a relational database schema diagram editor with a deliberately
simplified underlying model, but with enough bells and whistles to show some of the interesting features of GEF at work. |
 |
EMF goes RCP Marcelo Paternostro (IBM) October 12, 2004
This article explains how you can use EMF to generate RCP applications. It assumes
that you have already used EMF, or have at least read the articles and references
available on the documentation section of the EMF web site. |
 |
Modeling Rule-Based Systems with EMF Chaur G. Wu
November 30, 2004
There are examples of meta-models defined in ECore for modeling objects and
relational data. However, not much has been said about how to model rules. This
article will define a meta-model in ECore for modeling rule-based systems. We
will then use the meta-model to model the solution of a logical problem. Then
we will compose some JET templates and generate code from the model, run the
generated code through a rule engine and see that the logical problem is
correctly solved. |
 |
A Shape Diagram Editor Bo Majewski (Cisco) December 8, 2004
Graphical Editing Framework (GEF) provides a powerful foundation for creating
editors for visual editing of arbitrary models. Its effectiveness lies in
|
|
|
|
|
FAQS 35-如何在Eclipse的扩展目录上安装插件?
|
对于喜欢与Eclipse开发进度同步的用户来讲,每次使用最新的Eclipse所面临的问题是,重新安装需要的插件。特别是有些插件未提供在线升级功
能,每次一个一个的手工安装插件,确实是一件烦人的事情。我们可以利用Eclipse的Product
extensions机制将插件安装在Eclipse的安装目录之外,即将插件安装在扩展目录上。这样当Eclipse升级时只需升级Eclipse本
身,而插件依然可以利用无需重新安装。一般而言,Product
extensions机制主要是扩展Eclipse相关产品的功能而建立的,要实现扩展使Eclipse插件管理工具能够识别安装的新插件,需要一种特殊
的目录结构,此目录结构如下:
samplePlugin/ eclipse/ .eclipseextension features/ com.example.betterwebs.betterfeature_1.0.0/ feature.xml plugins/ com.example.betterwebs.betterfeature_1.0.0/ plugin.xml about.html com.example.betterwebs.betterwebsupport_1.0.0/
如上所示的目录结构就可以满足安装Eclipse插件的要求。准备好的目录结构在W2K中的样子,如下图

图1 生成目录结构
这其中.eclipseextension文件是告诉Eclipse插件管
理工具,此文件目录这是
一个插件扩展目录,一般称此文件为Marker
file,如下图所示

图2 生成Mark file
一旦建立好相应的目录结构后,将需要安装的插件装入此准备好的目录中,如下图所示

图3 装入插件
扩展目录装入插件以后的最终目录结构间下图

图4 最终目录结构
接下来,就可以启动Eclipse插件管理工具进行安装了。在Eclipse3.0中打开 Help
> Software Updates > Manage Configuration...,选择 Add an
Extension Location,选择上述的目录结构就完成了插件的安装。其实,语言包的安装也可以按照上述办法实现,你把语言包当成一个
插件就好理解了。上述操作过程见下面各图,使用的是经过汉化的Eclipse3.0。

图5 启动管理配置工具

图6 启动后的界面

图7 点击添加扩展位置後的界面

图8 选择准备好的扩展目录

图9 安装成功后的界面

图10 扩展安装完成

图11 扩展目录安装语言包示例
|
|
|
分页共3页 1 2 3 下一页 最后一页
|
|