zoukankan      html  css  js  c++  java
  • GEF常见问题2:具有转折点的连接线

    从直线连接转换到可以任意增减转折点的折线连接,因为模型里要增加新的元素,所以模型、editpart和图形部分都要有所修改,显得稍微有些烦琐,但其实很多代码是通用的。这个过程主要分为以下几个部分:

    1、在模型里增加转折点对应的类(这些转折点在GEF里称作Bendpoint),在类里要具有两个Dimension类型用来记录Bendpoint相对连接线起止点的位置。在连接类里要维护一个Bendpoint列表,并提供访问方法,由于篇幅关系这里只列出连接类中的这几个方法。

    public void addBendpoint(int index, ConnectionBendpoint point) {
        getBendpoints().add(index, point);
        firePropertyChange(PROP_BENDPOINT, 
    nullnull);
    }

    /**
     * zhanghao: 为了在更新两个dimension后能发送事件,在MoveBendpointCommand要在用这个方法设置新坐标,
     * 而不是直接用BendPoint里的方法。
     
    */
    public void setBendpointRelativeDimensions(int index, Dimension d1, Dimension d2){
        ConnectionBendpoint cbp
    =(ConnectionBendpoint)getBendpoints().get(index);
        cbp.setRelativeDimensions(d1,d2);
        firePropertyChange(PROP_BENDPOINT, 
    nullnull);
    }

    public void removeBendpoint(int index) {
        getBendpoints().remove(index);
        firePropertyChange(PROP_BENDPOINT, 
    nullnull);
    }

    2、在原来的连接方式里,由于连接线本身不需要刷新,所以现在要确保这个editpart实现了PropertyChangeListener接口,并像其他editpart一样覆盖了activate()和deactivate()这两个方法,以便接收Bendpoint发生改变的事件。

    public void activate() {
        
    super.activate();
        ((Connection)getModel()).addPropertyChangeListener(
    this);
    }

    public void deactivate() {
        
    super.deactivate();
        ((Connection)getModel()).removePropertyChangeListener(
    this);
    }

    public void propertyChange(PropertyChangeEvent event) {
        String property 
    = event.getPropertyName();
        
    if(Connection.PROP_BENDPOINT.equals(property)){
            refreshBendpoints();
        }
    }

    为模型连接类对应的editpart里增加一个继承自BendpointEditPolicy的子类ConnectionBendPointEditPolicy,这个类的内容后面会说到。

    protected void createEditPolicies() {
        
        installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE, 
    new ConnectionBendPointEditPolicy());
    }

    直线连接的情况下,连接的刷新不需要我们负责,但增加了Bendpoint以后,必须在Bendpoint发生改变时刷新连接线的显示。所以在上面这个editpart的refreshVisuals()方法里需要增加一些代码,以便把模型里的Bendpoint转换为图形上的relativeBendpoint。

    protected void refreshVisuals() {
        Connection conn 
    = (Connection) getModel();
        List modelConstraint 
    = conn.getBendpoints();
        List figureConstraint 
    = new ArrayList();
        
    for (int i = 0; i < modelConstraint.size(); i++) {
            ConnectionBendpoint cbp 
    = (ConnectionBendpoint) modelConstraint
                    .get(i);
            RelativeBendpoint rbp 
    = new RelativeBendpoint(getConnectionFigure());
            rbp.setRelativeDimensions(cbp.getFirstRelativeDimension(), cbp
                    .getSecondRelativeDimension());
            rbp.setWeight((i 
    + 1/ ((float) modelConstraint.size() + 1));
            figureConstraint.add(rbp);
        }
        getConnectionFigure().setRoutingConstraint(figureConstraint);
    }

    3、创建CreateBendpointCommand、MoveBendpointCommand和DeleteBendpointCommand这三个类,可以像Logic例子那样创建一个基类BendPointCommand让它们来继承。作为例子,BendpointCommand的内容如下。

    public class BendpointCommand extends Command {

        
    protected int index;
        
    protected Connection connection;
        
    protected Dimension d1, d2;

        
    public void setConnection(Connection connection) {
            
    this.connection = connection;
        }

        
    public void redo() {
            execute();
        }

        
    public void setRelativeDimensions(Dimension dim1, Dimension dim2) {
            d1 
    = dim1;
            d2 
    = dim2;
        }

        
    public void setIndex(int i) {
            index 
    = i;
        }

    }

    4、在ConnectionBendPointEditPolicy里实现BendpointEditPolicy定义的创建、移动和删除Bendpoint的三个方法。

    public class ConnectionBendPointEditPolicy extends BendpointEditPolicy {

        
    protected Command getCreateBendpointCommand(BendpointRequest request) {
            CreateBendpointCommand cmd 
    = new CreateBendpointCommand();
            Point p 
    = request.getLocation();
            Connection conn 
    = getConnection();

            conn.translateToRelative(p);

            Point ref1 
    = getConnection().getSourceAnchor().getReferencePoint();
            Point ref2 
    = getConnection().getTargetAnchor().getReferencePoint();

            conn.translateToRelative(ref1);
            conn.translateToRelative(ref2);

            cmd.setRelativeDimensions(p.getDifference(ref1), p.getDifference(ref2));
            cmd.setConnection((com.example.model.Connection) request.getSource()
                    .getModel());
            cmd.setIndex(request.getIndex());
            
    return cmd;
        }

        
    protected Command getDeleteBendpointCommand(BendpointRequest request) {
            BendpointCommand cmd 
    = new DeleteBendpointCommand();
            Point p 
    = request.getLocation();
            cmd.setConnection((com.example.model.Connection) request.getSource().getModel());
            cmd.setIndex(request.getIndex());
            
    return cmd;
        }

        
    protected Command getMoveBendpointCommand(BendpointRequest request) {
            MoveBendpointCommand cmd 
    = new MoveBendpointCommand();
            Point p 
    = request.getLocation();
            Connection conn 
    = getConnection();

            conn.translateToRelative(p);

            Point ref1 
    = getConnection().getSourceAnchor().getReferencePoint();
            Point ref2 
    = getConnection().getTargetAnchor().getReferencePoint();

            conn.translateToRelative(ref1);
            conn.translateToRelative(ref2);

            cmd.setRelativeDimensions(p.getDifference(ref1), p.getDifference(ref2));
            cmd.setConnection((com.example.model.Connection) request.getSource()
                    .getModel());
            cmd.setIndex(request.getIndex());
            
    return cmd;
        }
    }

    修改完成后的编辑器如下图所示。


    编辑器中的转折连接线

    点此下载工程,此工程修改自GEF应用实例中的GefPractice,目标文件的扩展名改为.gefpracticebp。

    如果觉得本文内容有帮助:试试我开发的Android应用 应用计时折扣君推荐+1(需登录)

  • 相关阅读:
    VS Code 的常用快捷键
    oj教程--坑
    oj教程--学习顺序
    oj教程--链表
    oj教程--队列
    oj教程--栈
    【MySQL】汇总数据
    【MySQL】使用WHERE子句
    【MySQL】SELECT语句
    【MySQL】使用MySQL(连接、选择数据库、显示数据库和表信息)
  • 原文地址:https://www.cnblogs.com/bjzhanghao/p/432227.html
Copyright © 2011-2022 走看看