`
sunway
  • 浏览: 114753 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

第二章 主类和主界面类的实现(2)

阅读更多
From:http://www.blog.edu.cn/user1/19180/archives/2005/372857.shtml,kid 发表于 2005-11-11

3 Palette的设置
    如果你的主界面的继承自GraphicalEditorWithPalette抽象类,那么在初始化主界面的时候,我们必须实现接口getPaletteRoot函数,向系统返回Palette的根。

    之前曾经说过,Palette是一个树形结构,在这个结构中有四种主要的节点类型:PaletteRoot、PaletteGroup、PaletteDrawer、ToolEntry,其中,PaletteRoot、PaletteGroup、PaletteDrawer都继承自PaletteContainer,PaletteContainer和ToolEntry则都继承自PaletteEntry,这是Palette树结构的基类。getPaletteRoot就是要向系统返回PaletteRoot对象。

    PaletteRoot对象是Palette树结构的树根,可以通过add函数向其中插入PaletteEntry对象。PaletteRoot继承自PaletteContainer,它对PaletteContainer的扩展主要是getDefaultEntry和setDefaultEntry函数,这两个函数分别用来获得和设置缺省操作。注意setDefaultEntry函数的参数是一个ToolEntry类型。

    PaletteGroup继承自PaletteContainer类,和PaletteRoot类似,它也可以包含其它的PaletteEntry对象。它没有增加新的操作,只是重设了PaletteContainer中的一些属性。和PaletteDrawer对象不同,PaletteGroup对象不能折叠它的子女,也没有标签。

    PaletteDrawer是一个抽屉类型,同样继承自PaletteContainer类,它可以用来归类一组ToolEntry,它们有一个标签,点击这个标签的时候,这组ToolEntry就会被折叠起来。PaletteDrawer对象和PaletteGroup最大的不同就是,PaletteDrawer不能包括container,但是PaletteGroup可以包括别的container,亦即PaletteDrawer不能拥有子树。

    ToolEntry是直接继承自PaletteEntry,它描述一个单独的工具,它是一个叶子节点。我们不能向它插入子女,它只能作为上述三个类的子女。ToolEntry是工具入口的父类,其下还有一些子类,常用的比如SelectionToolEntry、MarqueeToolEntry、CreationToolEntry、CombinedTemplateCreationEntry、ConnectionCreationToolEntry。

    SelectionToolEntry用于创建选择工具,MarqueeToolEntry则用于创建区域选择工具,你可以直接使用没有参数的构造函数,也可以在构造函数中加入String参数指明工具的名称(默认情况下会有英文工具名)。

    CreationToolEntry用于创建一个元素,它是CombinedTemplateCreationEntry和ConnectionCreationToolEntry的基类,它的构造函数是:


CreationToolEntry
    (
    String label,
    String shortDesc,
    CreationFactory factory,
    ImageDescriptor iconSmall,
    ImageDescriptor iconLarge
    )

其中,label是工具的标签,shortDesc是简短的描述,iconSmall和iconLarge是图标,可以设为null。factory是你要创建的元素的创建工厂,这里由于GEF使用了Abstract Factory模式。你可以使用SimpleFactory的实例生成这个工厂,SimpleFactory的构造方法是SimpleFactory(Class aClass),注意它的参数是一个Class对象,你可以使用[类名].class来得到这个对象。现在还有一个问题就是,我应该使用哪个元素的.class呢?换句话说,这个工具创建的哪个对象呢?这里应该注意的是,你创建的对象应该是一个模型元素。原来说过,GEF采用MVC框架,而GEF首先创建M,然后根据M创建C,并在创建C的时候创建V。而根据模型创建EditPart的映射,是在GraphicalEditorWithPalette->configureGraphicalViewer中使用setEditPartFactory来完成的,这又是一个使用Abstract Factory的例子。关于EditPartFactory的问题,我们在后面会有说明。下面举一个例子,比如我要创建一个矩形绘制工具,那么我应该这么写new CreationToolEntry("矩形", "创建一个矩形",  new SimpleFactory(RectangleModel.class), null, null),注意RectangleModel是矩形的模型,里面存储了有关这个矩形对象的信息,当然至于是什么信息,就根据你的应用自行定夺了。

    CombinedTemplateCreationEntry用于创建可以拖拽的创建工具,它和CreateToolEntry类似,只是它可以进行拖拽。但是要想这个工具支持拖拽,还要给界面增加响应拖拽的消息,所以一般情况下可以用CreationToolEntry代替。它的构造函数和CreationToolEntry类似:


CombinedTemplateCreationEntry
    (
    String label,
    String shortDesc,
    Object template,
    CreationFactory factory,
    ImageDescriptor iconSmall,
    ImageDescriptor iconLarge
    )

第三个参数template就可以设置为factory中的Class对象。

    ConnectionCreationToolEntry用于描述创建线形元素的工具,它的构造方法和CreationToolEntry相同。仔细研究ConnectionCreationToolEntry的构造函数,发现其中有一条语句是setToolClass(ConnectionCreationTool.class),这好像是指明了该工具使用的创建工具,这和JBOO的思想很像,将来有时间可以研究一下。

    现在再让我们回到NotationBuilderEditor的那个代码中,我们发现在getPaletteRoot函数中,我们是这么写的:


protected PaletteRoot getPaletteRoot() {
    if (this.paletteRoot == null) {
        this.paletteRoot = PaletteFactory.createPalette();
    }
    return this.paletteRoot;
}

这段代码中首先使用单键模式,然后使用PaletteFactory.createPalette()函数构造PaletteRoot对象。这个PaletteFactory也是我们编写的用于创建PaletteRoot的类,当然你也可以在getPaletteRoot函数中直接进行创建。下面就给出PaletteFactory的源代码:


package pku.oo.util;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.gef.palette.CombinedTemplateCreationEntry;
import org.eclipse.gef.palette.ConnectionCreationToolEntry;
import org.eclipse.gef.palette.CreationToolEntry;
import org.eclipse.gef.palette.MarqueeToolEntry;
import org.eclipse.gef.palette.PaletteContainer;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.palette.PaletteGroup;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.palette.SelectionToolEntry;
import org.eclipse.gef.palette.ToolEntry;
import org.eclipse.gef.requests.SimpleFactory;

import pku.oo.model.RectangleModel;


public class PaletteFactory {
    public static PaletteRoot createPalette() {
        PaletteRoot paletteRoot = new PaletteRoot();
        paletteRoot.addAll(createCategories(paletteRoot));
        return paletteRoot;
    }

    private static List createCategories(PaletteRoot root) {
        List<PaletteContainer> categories = new ArrayList<PaletteContainer>();

        categories.add(createGeneralControlGroup(root));
        categories.add(createGraphicsDrawer());
        categories.add(createLayoutDrawer());
        categories.add(createDecoratorDrawer());      

        return categories;
    }

    private static PaletteContainer createGeneralControlGroup(PaletteRoot root) {
        PaletteGroup controlGroup = new PaletteGroup("工具栏");

        List<ToolEntry> entries = new ArrayList<ToolEntry>();
        ToolEntry tool =null;
        tool = new SelectionToolEntry("选择工具");
        entries.add(tool);
        root.setDefaultEntry(tool);
       
        tool=new MarqueeToolEntry("区域选择工具");
        entries.add(tool);

        controlGroup.addAll(entries);
        return controlGroup;
    }
    private static PaletteContainer createGraphicsDrawer() {
        PaletteDrawer drawer = new PaletteDrawer("基本图元");
        List<ToolEntry> entries = new ArrayList<ToolEntry>();
        ToolEntry tool = new CreationToolEntry("矩形", "创建一个矩形",  new SimpleFactory(
                RectangleModel.class), null, null);
        entries.add(tool);
        drawer.addAll(entries);
        return drawer;

    }

    private static PaletteContainer createLayoutDrawer() {

        PaletteDrawer drawer = new PaletteDrawer("布局");
        List<ToolEntry> entries = new ArrayList<ToolEntry>();
        drawer.addAll(entries);
        return drawer;
    }
    private static PaletteContainer createDecoratorDrawer() {

        PaletteDrawer drawer = new PaletteDrawer("修饰");
        List<ToolEntry> entries = new ArrayList<ToolEntry>();
        drawer.addAll(entries);
        return drawer;
    }
}

4 Outline Page的设置
    这里只是介绍如何配置Outline Page,由于Outline Page的原理和主编辑器框架十分类似,因此其结构也比较复杂,关于如何编写Outline Page,将在后面说明。

    在上面的NotationBuilderEditor例子中,getAdapter函数是这样写的:


public Object getAdapter(Class type) {
    if (type == IContentOutlinePage.class)
        return new OutlinePage();
    return super.getAdapter(type);
}

我们说过,这个getAdapter不仅可以创建大纲视图,还可以创建其它的附属视图,那么你需要根据这个type来进行创建。对于大纲视图来说,我们创建了一个OutlinPage对象,这个对象的代码也在上面给出了,它是作为NotationBuilderEditor的内嵌类出现的,我们再重放一下它的代码:


class OutlinePage extends ContentOutlinePage {
    public OutlinePage() {
        super(new TreeViewer());
    }

    public void init(IPageSite pageSite) {
        super.init(pageSite);
    }

    public void createControl(Composite parent) {
        super.createControl(parent);
        getSelectionSynchronizer().addViewer(getViewer());
        getViewer().setEditDomain(getEditDomain());
        getViewer().setEditPartFactory(new TreePartFactory());
        getViewer().setContents(getDiagram());
    }

    public void dispose() {
    getSelectionSynchronizer().removeViewer(getViewer());
    super.dispose();
    }
}

    仔细看OutlinePage的createControl函数中的语句是否感觉似曾相识呢?不错,它和NotationBuilderEditor中的很多语句都很像,这就表明Outline Page的工作原理和主界面(具体说就是GraphicalEditorWithPalette)的原理是相似的,下面简单说明一下:首先,这个Outline Page设置了自己的同步的视图(getSelectionSynchronizer),那就是我们的主界面视图,然后它设置自己的编辑区域和EditPartFactory,最后设置自己的编辑内容,这和主编辑区域的内容是一样的,因为它们都是对同一文档进行编辑,只不过是不同的表现形式。大纲一旦设置了自己的EditPartFactory,当它发现自己的同步视图发生了变化(注意,它监测的是同步视图的模型部分),就会调用自己的EditPartFactory来更新自己的视图,其过程同样先是创建模型对应的EditPart,由EditPart创建Figure。



5 EditPartFactory
    EditPartFactory的作用,抽象地讲,是要建立模型和EditPart之间的映射,使得系统可以根据模型创建对应的EditPart。EditPartFactory并不难写,只是模型、EditPart的概念和关系现在还不能解释,等到下一个章节会有说明。下面的一个例子给出了一个简单的EditPartFactory:


package pku.oo.part;

import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;

import pku.oo.model.Diagram;
import pku.oo.model.RectangleModel;


public class PartFactory implements EditPartFactory {

    public EditPart createEditPart(EditPart context, Object model) {
        EditPart part = null;
        if (model instanceof Diagram)
            part = new DiagramPart();
        else if(model instanceof RectangleModel) {
            part = new RectanglePart();
        }
              
        part.setModel(model);
        return part;
    }
}


其中只有一个函数createEditPart,context是上下文,model是模型。这里需要注意的是,不要忘记为主编辑区域创建EditPart。
分享到:
评论

相关推荐

    Kotlin 1.3 案例集锦第三章 通讯录主类初始化

    Kotlin 1.3 案例集锦第三章 通讯录主类初始化

    Kotlin 1.3 案例集锦第三章 通讯录主类搜索及数据

    Kotlin 1.3 案例集锦第三章 通讯录主类搜索及数据处理

    JAVA课程设计(做界面)

    本程序选择了JTextField、JRadioButton、JComboBox、JButton等组件来实现界面。JTextField用于输入文本信息,JRadioButton用于选择性别,JComboBox用于选择省份、城市、年级,JButton用于添加学生信息。 知识点六:...

    微信分享 不修改主类

    2. **意图(Intent)处理**:通过广播接收器或者静态内部类,监听特定的分享意图。当接收到分享请求时,不直接启动主Activity,而是通过其他方式处理分享逻辑。 3. **Fragment或Dialog**:在不改变主Activity的情况...

    javafx实现好看的界面

    - 主类:启动应用程序的Java类,通常包含`start()`方法来加载和显示Scene。 通过研究这个压缩包中的内容,开发者可以深入理解JavaFX的工作原理,学习如何利用其特性创建出具有专业外观和用户体验的应用程序。无论是...

    界面设计源代码

    "TestDemo.java"可能是主程序文件,通常包含主类和主方法,它是程序的入口点,通过`public static void main(String[] args)`函数启动。这个文件可能包含了Swing的一些基本组件和布局管理器,如JFrame(窗口)、...

    Visual C++界面编程技术代码(1--7章)随书光盘

    2. **第二章:MFC基础** - MFC概述:解释MFC(Microsoft Foundation Classes)的作用,它是如何简化Windows应用程序开发的。 - CWinApp类:理解应用程序主类CWinApp,它作为程序的入口点。 - CFrameWnd类:学习...

    VC界面类编程\源代码\用c++做的qq界面

    在VC++环境中,界面类编程是一项重要的技能,尤其是在开发桌面应用程序时。本示例中的"VC界面类编程\源代码\用c++做的qq界面"是关于如何使用C++和Visual C++(VC)库来创建一个类似QQ的用户界面。这个项目提供了实践...

    java实现了系统托盘的主类

    实现了java的系统托盘等等之类的。要看的可以see see 额

    简述Java程序的构成如何判断主类.doc

    Java Application 程序的主类是包含 main() 方法的类,Java Applet 程序的主类是系统类 Applet 的派生子类。主类的类名就是这个 Java 源程序的文件名。 判断主类的方法是查看该类是否包含 main() 方法。如果该类...

    错误:找不到或者无法加载主类

    在 Java 开发中,遇到“找不到或无法加载主类”的错误是一个常见的问题。这是因为 Java 虚拟机(JVM)无法找到要执行的类文件。究其原因,通常是因为环境变量配置不正确或 Classpath 配置不当。本文将详细讲解 Java ...

    银行家算法JAVA代码实现,附带图形化界面

    2. **Process.java**:表示进程的类,包含进程ID、最大需求、当前需求、已分配资源等属性,以及相应的方法用于设置和获取这些属性。 3. **Resource.java**:表示资源的类,定义资源的类型和数量。 4. **GUI.java**:...

    简单JAVA语言编写的万年历系统源码(图形界面)

    首先,源码中可能会包含一个主类,它是整个程序的入口点,继承自JFrame或者实现了Runnable接口。在这个主类中,开发者会初始化GUI组件,如创建一个JFrame窗口,并在其中添加显示日期的JLabel,以及可能的按钮或菜单...

    在CMD下用java命令出现“找不到或无法加载主类”问题

    当在命令行界面(如Windows的CMD)执行`java`命令时,如果出现“找不到或无法加载主类”的错误提示,通常意味着Java运行时环境(JRE)无法找到并加载指定的主类。这可能是由以下几个原因造成的: 1. **类路径设置不...

    抛出无法找到主类:org.apache.axis.wsdl.WSDL2Java

    抛出无法找到主类:org.apache.axis.wsdl.WSDL2Java(Throws Could not find main class: org.apache.axis.wsdl.WSDL2Java)。 添加本文的jar包压缩包解压出来的所有jar包到当前使用的java.exe 命令的lib目录下的ext...

    用java写的多线程聊天程序GUI界面socket实现

    2. `ChatClient`: 客户端的主类,创建Socket连接到服务器,并设置GUI界面。 3. `ChatThread`: 服务器端的子线程类,处理单个客户端的通信。 4. `ChatWindow`: GUI界面类,包含输入框、发送按钮和文本区域,处理用户...

    错误:找不到或无法加载主类com.xxx.xxx.Application(完美解决)

    1. **检查并修复类路径**:确保所有相关的库和类文件都在类路径中,包括你的主类。 2. **更新Maven配置**:在`pom.xml`中正确设置`&lt;mainClass&gt;`标签,例如: ```xml &lt;groupId&gt;org.apache.maven.plugins ...

    基于YOLOV5实现的一个识别照片中人们是否戴口罩的基础应用源码+模型+数据集,带用QT实现的人机界面

    基于YOLOV5实现的一个识别照片中人们是否戴口罩的基础应用源码+模型+数据集,带用QT实现的人机界面 训练过程: 在models文件夹下建立一个mask_yolov5s.yaml的模型配置文件,设定nc =2 表示这次训练的分类有两类:...

    Java包与文件操作

    文件操作在Java中主要通过`java.io`包实现,例如使用`File`类来表示文件对象,`FileInputStream`和`FileOutputStream`进行读写操作。不过,描述中没有具体说明如何测试文件操作,这可能是通过在类中使用文件I/O功能...

    班级通信录java代码

    3. Java 中的类和对象:资源中定义了两个类:STU 和 Frm_Main,分别用于处理主类和主框架的逻辑。 Swing 组件库 1. JFrame 和 Container:资源中使用了 JFrame 和 Container components 来创建图形用户界面。 2. ...

Global site tag (gtag.js) - Google Analytics