停止



XML


上车
乘客名:
车  票:
           

Google

英文字典
Answers, not links


>>More




{#archives}














    分页共3页 1 2 3 下一页 最后一页


    Java team want to improve support for dynamically typed languages
    -  [Java ]

      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


    由 isaacxu 发表于 09:00:52 | 评论 (1) | 引用 (1) | 编 辑 




    Who is the best-SD's Readers' Choice Awards Finalists (提名名单)
    -  [news ]

      Who is the best Language? Who is the best Tool?and so on.


    由 isaacxu 发表于 00:41:00 | 评论 (1) | 引用 (1) | 编 辑 




    MIT to launch $100 laptop prototype in November
    -  [Linux ]

      Notebook is intended for school children around the world.(MIT的100美元笔记本原型机11月发布。)


    由 isaacxu 发表于 12:17:46 | 评论 (1) | 引用 (1) | 编 辑 




    Ruby or Python, that is the question(Ruby与Python的对比)
    -  [Ruby ]

      Python-Ruby Comparison


    由 isaacxu 发表于 01:01:57 | 评论 (0) | 引用 (1) | 编 辑 




    Dan Box也谈SICP了(Dan Box also recommends SICP)
    -  [lisp ]

      


    由 isaacxu 发表于 01:42:19 | 评论 (0) | 引用 (0) | 编 辑 




    2005 Google Code Jam Winner-Marek Cygan
    -  [TopCoder ]

      


    由 isaacxu 发表于 18:13:00 | 评论 (0) | 引用 (1) | 编 辑 




    这回Dan Box说的是真话-"Scheme Is Love"
    -  [lisp ]

      


    由 isaacxu 发表于 23:15:54 | 评论 (0) | 引用 (1) | 编 辑 




    This is Java(一):Java平台
    -  [Java ]

      


    由 isaacxu 发表于 01:43:23 | 评论 (1) | 引用 (1) | 编 辑 




    Java 开发环境的过去、现在和将来(初稿)
    -  [Java ]

      


    由 isaacxu 发表于 09:58:00 | 评论 (1) | 引用 (1) | 编 辑 




    Eclipse3.1下载量达到61万
    -  [eclipse ]

      


    由 isaacxu 发表于 00:47:54 | 评论 (0) | 引用 (1) | 编 辑 




    TopCoder上又有11,100美金的开发项目
    -  [TopCoder ]

      TopCoder上又有新的项目了,总价值11,100美金,详细内容见链接

    http://www.topcoder.com/?t=development&c=comp_projects



    由 isaacxu 发表于 12:31:28 | 评论 (1) | 引用 (2) | 编 辑 




    如何参与TopCoder比赛简介
    -  [TopCoder ]

      初步介绍如何参与TopCoder比赛


    由 isaacxu 发表于 22:52:51 | 评论 (5) | 引用 (2) | 编 辑 




    Apache Harmony的投票结果
    -  [Java ]

      开源Java的投票结果


    由 isaacxu 发表于 19:23:25 | 评论 (0) | 引用 (2) | 编 辑 




    进入世界顶级IT公司的捷径:TopCoder锦标赛的冠军

      获得TopCoder锦标赛的冠军意味着什么?


    由 isaacxu 发表于 18:30:00 | 评论 (0) | 引用 (2) | 编 辑 




    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.



    由 isaacxu 发表于 18:43:55 | 评论 (0) | 引用 (0) | 编 辑 




    “友邦惊诧”论①*鲁迅
    -  [新闻消息 ]

      只要略有知觉的人就都知道:这回学生的请愿②,是因为日本占据了辽吉,南京政府束手无策,单会去哀求国联,③而国联却正和日本是一伙。读书呀,读书呀,不 错,学生是应该读书的,但一面也要大人老爷们不至于葬送土地,这才能够安心读书。报上不是说过,东北大学逃散,冯庸大学④逃散,日本兵看见学生模样的就枪 毙吗?放下书包来请愿,真是已经可怜之至。不道国民党政府却在十二月十八日通电各地军政当局文里,又加上他们“捣毁机关,阻断交通,殴伤中委,拦劫汽车, 横击路人及公务人员,私逮刑讯,社会秩序,悉被破坏”的罪名,而且指出结果,说是“友邦人士,莫名惊诧,长此以往,国将不国”了!


    由 isaacxu 发表于 00:29:03 | 评论 (0) | 引用 (0) | 编 辑 




    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.


    由 isaacxu 发表于 04:29:57 | 评论 (0) | 引用 (0) | 编 辑 




    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:



    由 isaacxu 发表于 04:25:55 | 评论 (0) | 引用 (0) | 编 辑 




    Eclipse,Visual Studio,NetBeans趋势分析
    -  [新闻消息 ]

      笔者用BlogPulse就Eclipse、Visual Studio,NetBeans三个IDE在Blog世界的热门程度做了个趋势分析,在Trend Term一项中分别输入Eclipse、Visual Studio,NetBeans用来比较三者的发展趋势,比较结果如下:
    1 month
    上图是一个月的趋势分析,Eclipse获得胜利,排名第一。


    由 isaacxu 发表于 00:36:24 | 评论 (0) | 引用 (0) | 编 辑 




    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



    由 isaacxu 发表于 15:11:55 | 评论 (0) | 引用 (1) | 编 辑 




    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



    由 isaacxu 发表于 15:11:21 | 评论 (0) | 引用 (1) | 编 辑 




    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



    由 isaacxu 发表于 13:17:38 | 评论 (0) | 引用 (1) | 编 辑 




    愿微软的灵魂安息与盖茨必须走人
    -  [新闻消息 ]

       "R.I.P. Microsoft"一文已经发表有一段时间了,笔者本来也不想提它,但既然国内又有人开始肉麻的吹捧微软了,哪无妨让大家看看一部分美国精英是如何看待 微软的。


    由 isaacxu 发表于 05:32:10 | 评论 (0) | 引用 (1) | 编 辑 




    走上开放之路: 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 或其他地方提供的最有用的一些工具、技术以及在线资料。您可以在相应的论坛中与作者或其他读者分享您对这些文章的想法。(您也可以单击本文开头或末尾的 讨论 来访问论坛。)


    由 isaacxu 发表于 23:03:54 | 评论 (0) | 引用 (1) | 编 辑 




    231个 SWT-JFace-Eclipse小程序代码以及部分截图
    -  [程序设计 ]

      Java2s上放了约有231个SWT-JFace-Eclipse小程序代码,以及部分相关的屏幕截图,此外,这个网站上还有其他一些与Java有关的内容,
    感兴趣的朋友可以看一看。网址是SWT-JFace-Eclipse
    SWT-JFace-Eclipse   Click here for ScreenShots

    2D (31) ApplicationWindow (3) Browser (5) BusyIndicator (1) Button (6)

    Canvas (3) ClipBoard (1) Combo (4) ControlEditor (2) CoolBar (2)

    Dialog (12) DragDrop (2) Editor (3) Event (9) FileChooser (2)

    Focus (1) Font (3) Form (4) Group (2) JFace-Dialog (6)

    JFace-Registry (2) Label (13) Layout (25) List (4) ListViewer (1)

    MVC (1) Menu (3) Password (1) PopupList (1) Print (5)

    ProgressBar (3) RadioButton (1) Sash (5) SashForm (3) Scale (2)

    Scroll (1) ScrollBar (1) Shell (4) Slider (2) StyledText (6)

    Tab (4) Table (16) TableTree (1) Text (7) Thread (2)

    ToolBar (4) Tree (6) ViewForm (2) WIN32 (2) Wizard (1)


    由 isaacxu 发表于 14:03:19 | 评论 (1) | 引用 (1) | 编 辑 




    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:

    1. If it’s a rainy day, advise people to bring umbrellas when they go out.
    2. 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:

    1. A rule-based system consists mainly of three things: facts, rules and an engine that acts on them.
    2. 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). 
    3. A rule consists of two parts: conditions (if clauses) and actions. 
    4. 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:

    1. Categorization of meta levels is not absolute.
    2. We will use ECore as a meta-metamodel to define the Rule Meta Model.
    3. Model elements in the Rule Meta Model will be instances of model elements in ECore.
    4. 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.
    5. 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.

    1. If red ball is in box 1, blue ball must be in box 3.
    2. If yellow ball is not in box 2, green ball must be in box 3.
    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



    由 isaacxu 发表于 02:22:51 | 评论 (1) | 引用 (0) | 编 辑 




    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.

    Screen shot of the diagram editor
    Fig 1. The shape diagram editor running under Linux

    Try it! 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 tag the java.io.Serializable interface together with tag 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 tag register and tag unregister as receivers of property change notifications. Those are posted by calling tag the firePropertyChange method. Finally, in order to aid integration with the Properties view of the workbench, tag the IPropertySource interface is implemented (details of which are omitted in Figure 2).

    public abstract class ModelElement implements tag IPropertySource, tag Serializable {

    private transient PropertyChangeSupport pcsDelegate =
    new PropertyChangeSupport(this);

    tag public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
    if (l == null) {
    throw new IllegalArgumentException();
    }

    pcsDelegate.addPropertyChangeListener(l);
    }

    tag protected void firePropertyChange(String property,
    Object oldValue,
    Object newValue) {
    if (pcsDelegate.hasListeners(property)) {
    pcsDelegate.firePropertyChange(property, oldValue, newValue);
    }
    }

    tag private void readObject(ObjectInputStream in) throws IOException,
    ClassNotFoundException {
    in.defaultReadObject();
    pcsDelegate = new PropertyChangeSupport(this);
    }

    tag public synchronized void removePropertyChangeListener(PropertyChangeListener l) {
    if (l != null) {
    pcsDelegate.removePropertyChangeListener(l);
    }
    }

    ...
    }
    Fig 2. The base class of all model objects

    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 tag source and tag 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 (tag, tag), with package level visibility, are added that allow shapes and connections to communicate about their mutual relationship. In addition, two public methods (tag, tag) 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.

    public abstract class Shape extends ModelElement {

    private Point location = new Point(0, 0);
    private Dimension size = new Dimension(50, 50);
    tag private List sourceConnections = new ArrayList();
    tag private List targetConnections = new ArrayList();

    public Point getLocation() {
    return location.getCopy();
    }

    public void setLocation(Point newLocation) {
    if (newLocation == null) {
    throw new IllegalArgumentException();
    }
    location.setLocation(newLocation);
    firePropertyChange(LOCATION_PROP, null, location);
    }

    tag void addConnection(Connection conn) {
    if (conn == null || conn.getSource() == conn.getTarget()) {
    throw new IllegalArgumentException();
    }
    if (conn.getSource() == this) {
    sourceConnections.add(conn);
    firePropertyChange(SOURCE_CONNECTIONS_PROP, null, conn);
    } else if (conn.getTarget() == this) {
    targetConnections.add(conn);
    firePropertyChange(TARGET_CONNECTIONS_PROP, null, conn);
    }
    }

    tag void removeConnection(Connection conn) {
    if (conn == null) {
    throw new IllegalArgumentException();
    }
    if (conn.getSource() == this) {
    sourceConnections.remove(conn);
    firePropertyChange(SOURCE_CONNECTIONS_PROP, null, conn);
    } else if (conn.getTarget() == this) {
    targetConnections.remove(conn);
    firePropertyChange(TARGET_CONNECTIONS_PROP, null, conn);
    }
    }

    tag public List getSourceConnections() {
    return new ArrayList(sourceConnections);
    }

    tag public List getTargetConnections() {
    return new ArrayList(targetConnections);
    }

    ...
    }
    Fig 3 Shape functionality

    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 tag the addChild and tag removeChild methods are used by commands to perform validation of their operations. Public access to all shapes in a diagram is tag provided for the benefit of the controller class.

    public class ShapesDiagram extends ModelElement {

    ...
    private Collection shapes = new Vector();

    tag public boolean addChild(Shape s) {
    if (s != null && shapes.add(s)) {
    firePropertyChange(CHILD_ADDED_PROP, null, s);
    return true;
    }
    return false;
    }

    tag public List getChildren() {
    return new Vector(shapes);
    }

    tag public boolean removeChild(Shape s) {
    if (s != null && shapes.remove(s)) {
    firePropertyChange(CHILD_REMOVED_PROP, null, s);
    return true;
    }
    return false;
    }
    }
    Fig 4. ShapeDiagram - a container of shapes

    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 tag implements the PropertyChangeListener interface. When tag activated, it registers with the model as the receiver of the property change events. Upon tag deactivation, it removes itself from the list of listeners. Finally, when it tag 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.

    public abstract class SpecificPart extends AbstractGraphicalEditPart
    tag implements PropertyChangeListener {

    tag public void activate() {
    if (!isActive()) {
    super.activate();
    ((PropertyAwareModel) this.getModel()).addPropertyChangeListener(this);
    }
    }

    tag public void deactivate() {
    if (isActive()) {
    ((PropertyAwareModel) this.getModel()).removePropertyChangeListener(this);
    super.deactivate();
    }
    }

    tag public void propertyChage(PropertyChangeEvent evt) {
    String prop = evt.getPropertyName();
    ...
    }
    }
    Fig 5. Property aware part

    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 tag 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 tag 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 tag 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.

    protected void createEditPolicies() {
    tag installEditPolicy(EditPolicy.COMPONENT_ROLE, new RootComponentEditPolicy());
    XYLayout layout = (XYLayout) getContentPane().getLayoutManager();
    tag installEditPolicy(EditPolicy.LAYOUT_ROLE, new ShapesXYLayoutEditPolicy(layout));
    tag installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, null);
    }
    Fig 6. Policies installed by the diagram edit part.

    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 tag 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.

    class ShapeEditPart extends AbstractGraphicalEditPart 
    tag implements PropertyChangeListener, NodeEditPart {

    tag protected List getModelSourceConnections() {
    return getCastedModel().getSourceConnections();
    }

    tag protected List getModelTargetConnections() {
    return getCastedModel().getTargetConnections();
    }

    tag public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection) {
    return new ChopboxAnchor(getFigure());
    }

    tag public ConnectionAnchor getSourceConnectionAnchor(Request request) {
    return new ChopboxAnchor(getFigure());
    }

    public void propertyChange(PropertyChangeEvent evt) {
    String prop = evt.getPropertyName();

    if (Shape.SIZE_PROP.equals(prop) || Shape.LOCATION_PROP.equals(prop)) {
    refreshVisuals();
    }
    if (Shape.SOURCE_CONNECTIONS_PROP.equals(prop)) {
    refreshSourceConnections();
    }
    if (Shape.TARGET_CONNECTIONS_PROP.equals(prop)) {
    refreshTargetConnections();
    }
    }

    tag protected void refreshVisuals() {
    Rectangle bounds = new Rectangle(getCastedModel().getLocation(),
    getCastedModel().getSize());
    figure.setBounds(bounds);
    ((GraphicalEditPart) getParent()).setLayoutConstraint(this, figure, bounds);
    }
    }
    Fig 7. Controller of shapes

    As shapes may be connected to other shapes, the shape edit part overrides the tag getModelSourceConnections and the tag 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 tag 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 tag second method is invoked to provide a user with feedback while a new connection is being created. The tag 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 tag 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 tag 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.

    new GraphicalNodeEditPolicy() {
    tag protected Command getConnectionCreateCommand(CreateConnectionRequest request) {
    Shape source = (Shape) getHost().getModel();
    int style = ((Integer) request.getNewObjectType()).intValue();
    ConnectionCreateCommand cmd = new ConnectionCreateCommand(source, style);
    request.setStartCommand(cmd);
    return cmd;
    }

    tag protected Command getConnectionCompleteCommand(CreateConnectionRequest request) {
    ConnectionCreateCommand cmd =
    (ConnectionCreateCommand) request.getStartCommand();
    cmd.setTarget((Shape) getHost().getModel());
    return cmd;
    }

    ...
    }
    Fig 8. Graphical node edit policy

    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 tag PropertyChangeListener interface and registers the part for the events with the model on activation. The connection part tag returns a polyline decorated with an arrow as the figure. It installs two edit policies. The first one, the tag ConnectionComponentPolicy, supplies a delete command needed by the action associated with the Delete menu item. The tag 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 tag changes in the line style property and adjusts the polyline figure appropriately.

    class ConnectionEditPart extends AbstractConnectionEditPart 
    tag implements PropertyChangeListener {

    protected IFigure createFigure() {
    tag PolylineConnection connection = (PolylineConnection) super.createFigure();
    connection.setTargetDecoration(new PolygonDecoration());
    connection.setLineStyle(getCastedModel().getLineStyle());
    return connection;
    }

    protected void createEditPolicies() {
    tag installEditPolicy(EditPolicy.CONNECTION_ROLE, new ConnectionEditPolicy() {
    protected Command getDeleteCommand(GroupRequest request) {
    return new ConnectionDeleteCommand(getCastedModel());
    }
    });
    tag installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE,
    new ConnectionEndpointEditPolicy());
    }

    public void propertyChange(PropertyChangeEvent event) {
    String property = event.getPropertyName();
    tag if (Connection.LINESTYLE_PROP.equals(property)) {
    ((PolylineConnection) getFigure()).
    setLineStyle(getCastedModel().getLineStyle());
    }
    }
    ...
    }
    Fig 9. Controller of connections

    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 tag 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.

    protected void configureGraphicalViewer() {
    super.configureGraphicalViewer();

    GraphicalViewer viewer = getGraphicalViewer();
    viewer.setRootEditPart(new ScalableRootEditPart());
    tag viewer.setEditPartFactory(new ShapesEditPartFactory());
    viewer.setKeyHandler(
    new GraphicalViewerKeyHandler(viewer).setParent(getCommonKeyHandler()));
    ContextMenuProvider cmProvider =
    new ShapesEditorContextMenuProvider(viewer, getActionRegistry());
    viewer.setContextMenu(cmProvider);
    getSite().registerContextMenu(cmProvider, viewer);
    }

    protected void initializeGraphicalViewer() {
    super.initializeGraphicalViewer();
    GraphicalViewer graphicalViewer = getGraphicalViewer();
    tag graphicalViewer.setContents(getModel());
    tag graphicalViewer.addDropTargetListener(createTransferDropTargetListener());
    }
    Fig 10. Configuring and initializing a graphic viewer

    Once the factory is set, you should tag 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 tag 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, tag 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 tag add a global action key for the selected action in the second method, declareGlobalActionKeys.

    public class ShapesEditorActionBarContributor extends ActionBarContributor {
    tag protected void buildActions() {
    this.addRetargetAction(new UndoRetargetAction());
    this.addRetargetAction(new RedoRetargetAction());
    this.addRetargetAction(new DeleteRetargetAction());
    }

    public void contributeToToolBar(IToolBarManager toolBarManager) {
    super.contributeToToolBar(toolBarManager);
    toolBarManager.add(getAction(ActionFactory.UNDO.getId()));
    toolBarManager.add(getAction(ActionFactory.REDO.getId()));
    }

    protected void declareGlobalActionKeys() {
    tag this.addGlobalActionKey(ActionFactory.SELECT_ALL.getId());
    }
    }
    Fig 11. Connecting menu actions

    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.

    Delete action call sequence
    Fig 12. Delete action call sequence

    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 tag 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.

    public Object getAdapter(Class type) {
    // returns the content outline page for this editor
    tag if (type == IContentOutlinePage.class) {
    if (outlinePage == null) {
    outlinePage = new ShapesEditorOutlinePage(this, new TreeViewer());
    }
    return outlinePage;
    }
    return super.getAdapter(type);
    }
    Fig 13. Providing an overview

    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


    由 isaacxu 发表于 02:21:26 | 评论 (0) | 引用 (0) | 编 辑 




    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 ProjectionDocument
    • ProjectionDocumentManager: 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.

    1. Override createPartControl method of TextEditor to configure and install ProjectionSupport
    2. Override createSourceViewer method of AbstractTextEditor to return a ProjectionViewer
    3. 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



    由 isaacxu 发表于 02:20:06 | 评论 (0) | 引用 (0) | 编 辑 




    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

    由 isaacxu 发表于 02:17:00 | 评论 (0) | 引用 (0) | 编 辑 




    FAQS 35-如何在Eclipse的扩展目录上安装插件?
    -  [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中的样子,如下图
    step1
    图1 生成目录结构
    这其中.eclipseextension文件是告诉Eclipse插件管 理工具,此文件目录这是 一个插件扩展目录,一般称此文件为Marker file,如下图所示
    step2
    图2 生成Mark file
    一旦建立好相应的目录结构后,将需要安装的插件装入此准备好的目录中,如下图所示
    step3
    图3 装入插件
    扩展目录装入插件以后的最终目录结构间下图
    step4
    图4 最终目录结构
    接下来,就可以启动Eclipse插件管理工具进行安装了。在Eclipse3.0中打开Help > Software Updates > Manage Configuration...,选择Add an Extension Location,选择上述的目录结构就完成了插件的安装。其实,语言包的安装也可以按照上述办法实现,你把语言包当成一个 插件就好理解了。上述操作过程见下面各图,使用的是经过汉化的Eclipse3.0。
    step5
    图5 启动管理配置工具
    step6
    图6 启动后的界面
    step7
    图7 点击添加扩展位置後的界面
    step8
    图8 选择准备好的扩展目录
    step9
    图9 安装成功后的界面
    step10
    图10 扩展安装完成
    step11
    图11 扩展目录安装语言包示例


    由 isaacxu 发表于 22:19:00 | 评论 (0) | 引用 (0) | 编 辑 




    分页共3页 1 2 3 下一页 最后一页