GEF原理及实现系列(二、模型)

GEF的模型只与控制器打交道,而不知道任何与视图有关的东西。
1.模型的功能
    在GEF框架中,模型(Model)是非常简单的一部分,用户可把模型理解成一个简单的可持久化的实体。但为了能让控制器知道模型的变化,应该把控制器作为事件监听者注册在模型中,当模型发生变化时,就触发相应的事件给控制器,后者负责通知各个视图进行更新。
2.模型的实现
    典型的模型对象会包含PropertyChangeSupport类型的成员变量,用来触发事件,通知监听器即控制器。一般来说,模型会实现一个基类,用来封装事件机制,主要包括添加监听器、删除监听器,以及模型属性改变触发的相应事件,代码如下:
java 代码
 
package com.example.model;      import java.beans.PropertyChangeListener;   import java.beans.PropertyChangeSupport;   import java.io.Serializable;      public abstract class Element implements Cloneable, Serializable {          PropertyChangeSupport listeners = new PropertyChangeSupport(this);       //添加监听器       public void addPropertyChangeListener(PropertyChangeListener l) {           listeners.addPropertyChangeListener(l);       }       //触发属性改变的事件       protected void firePropertyChange(String prop, Object old, Object newValue) {           listeners.firePropertyChange(prop, old, newValue);       }       //触发结构改变的事件       protected void fireStructureChange(String prop, Object child) {           listeners.firePropertyChange(prop, null, child);       }      //    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {   //        in.defaultReadObject();   //        listeners = new PropertyChangeSupport(this);   //    }       //删除监听器       public void removePropertyChangeListener(PropertyChangeListener l) {           listeners.removePropertyChangeListener(l);       }      }  

    另外,当用户希望通过属性视图编辑模型属性时,模型要实现IPropertySource接口,该接口的方法解释如下:
   
package org.eclipse.ui.views.properties;

public interface IPropertySource {

    public Object getEditableValue();//得到在属性页中能编辑的值,可以返回this表示当前模型

    public IPropertyDescriptor[] getPropertyDescriptors();//得到IPropertyDescriptor类型的数组,其中每一项为属性页中能编辑的项
   
    public Object getPropertyValue(Object id);//通过id值得到某个属性,在添加每一项IPropertyDescriptor时都会指定id值

    public boolean isPropertySet(Object id);//表示特定属性id值是否改变

    public void resetPropertyValue(Object id);//通过id重置属性

    public void setPropertyValue(Object id, Object value);//通过id和值设置某一项属性的值
}
    如果模型和其它模型有关系(在视图上为连线),模型要维护这些关系,并适当的持久化,当模型的属性修改后,模型要触发相应的事件通知监听器。
java 代码
 
package com.example.model;      import java.util.ArrayList;   import java.util.List;      import org.eclipse.draw2d.geometry.Point;   import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;   import org.eclipse.ui.views.properties.IPropertyDescriptor;   import org.eclipse.ui.views.properties.IPropertySource;   import org.eclipse.ui.views.properties.TextPropertyDescriptor;      public class Node extends Element implements IPropertySource {       //定义属性的常量ID        final public static String PROP_LOCATION = "LOCATION";          final public static String PROP_NAME = "NAME";          final public static String PROP_VISIBLE = "VISIBLE";          final public static String PROP_INPUTS = "INPUTS";          final public static String PROP_OUTPUTS = "OUTPUTS";          protected Point location = new Point(00);          protected String name = "Node";          protected boolean visible = true;       //定义属性的编辑项       protected IPropertyDescriptor[] descriptors = new IPropertyDescriptor[] {               new TextPropertyDescriptor(PROP_NAME, "Name"),               new ComboBoxPropertyDescriptor(PROP_VISIBLE, "Visible"new String[] { "true""false" }) };       //定义模型连线的列表       protected List outputs = new ArrayList(5);          protected List inputs = new ArrayList(5);          public void addInput(Connection connection) {           this.inputs.add(connection);           //当输入的连线改变后,触发结构改变的事件           fireStructureChange(PROP_INPUTS, connection);       }          public void addOutput(Connection connection) {           this.outputs.add(connection);         //当输出的连线改变后,触发结构改变的事件           fireStructureChange(PROP_OUTPUTS, connection);       }          public List getIncomingConnections() {           return this.inputs;       }          public List getOutgoingConnections() {           return this.outputs;       }          public void removeInput(Connection connection) {           this.inputs.remove(connection);           fireStructureChange(PROP_INPUTS, connection);       }          public void removeOutput(Connection connection) {           this.outputs.remove(connection);           fireStructureChange(PROP_OUTPUTS, connection);       }          public boolean isVisible() {           return visible;       }          public void setVisible(boolean visible) {           if (this.visible == visible) {               return;           }           this.visible = visible;           firePropertyChange(PROP_VISIBLE, null, Boolean.valueOf(visible));       }          public String getName() {           return name;       }          public void setName(String name) {           if (this.name.equals(name)) {               return;           }           this.name = name;           //当模型的名字改变后,通知监听器更新名字的显示           firePropertyChange(PROP_NAME, null, name);       }          public void setLocation(Point p) {           if (this.location.equals(p)) {               return;           }           this.location = p;         //当模型的位置改变后,通知监听器更新模型的位置           firePropertyChange(PROP_LOCATION, null, p);       }          public Point getLocation() {           return location;       }          //------------------------------------------------------------------------       // Abstract methods from IPropertySource          public Object getEditableValue() {           return this;       }       //得到属性编辑项       public IPropertyDescriptor[] getPropertyDescriptors() {           return descriptors;       }       //得到属性编辑项的值       public Object getPropertyValue(Object id) {           if (PROP_NAME.equals(id))               return getName();           if (PROP_VISIBLE.equals(id))               return isVisible() ? new Integer(0) : new Integer(1);           return null;       }          public boolean isPropertySet(Object id) {           return true;       }          public void resetPropertyValue(Object id) {          }       //设置属性的值       public void setPropertyValue(Object id, Object value) {           if (PROP_NAME.equals(id))               setName((String) value);           if (PROP_VISIBLE.equals(id))               setVisible(((Integer) value).intValue() == 0);       }   }  

    上例中实现了模型对应的属性视图,当属性被修改后,模型将会调用“fire...”方法触发相应的模型改变事件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值