天天看點

GEF常見問題4:非矩形圖元

現在假設要把原來GefPractice例子裡的矩形圖元節點換成用橢圓形表示,都需要做哪些改動呢?很顯然,首先要把原來繼承RectangleFigure的NodeFigure類改為繼承Ellipse:

public class NodeFigure extends Ellipse /*RectangleFigure*/{

GEF常見問題4:非矩形圖元

}

這樣修改後可以看到編輯器中的圖元已經變成橢圓形了。但如果使用者點選一個圖元,表示選中的邊框(選擇框)仍然是矩形的,如圖1所示:

圖1 橢圓形的節點和矩形選擇框

如果覺得矩形的選擇框不太協調,可以通過覆寫DiagramLayoutEditPolicy的createChildEditPolicy()方法修改。預設情況下這個方法傳回一個ResizableEditPolicy,我們要定義自己的子類(EllipseResizableEditPolicy)來替代它作為傳回值。

EllipseResizableEditPolicy裡需要覆寫ResizableEditPolicy的兩個方法,createSelectionHandles()方法決定“控制柄”(ResizeHandle)和“選擇框”(MoveHandle)的相關情況,我們的實作如下:

protected List createSelectionHandles() {

    List list = new ArrayList();

    //添加選擇框

    //ResizableHandleKit.addMoveHandle((GraphicalEditPart) getHost(), list);

    list.add(new MoveHandle((GraphicalEditPart) getHost()) {

        protected void initialize() {

            super.initialize();

            setBorder(new LineBorder(1) {

                public void paint(IFigure figure, Graphics graphics, Insets insets) {

                    tempRect.setBounds(getPaintRectangle(figure, insets));

                    if (getWidth() % 2 == 1) {

                        tempRect.width--;

                        tempRect.height--;

                    }

                    tempRect.shrink(getWidth() / 2, getWidth() / 2);

                    graphics.setLineWidth(getWidth());

                    if (getColor() != null)

                        graphics.setForegroundColor(getColor());

                    //用橢圓形替代矩形

                    //graphics.drawRectangle(tempRect);

                    graphics.drawOval(tempRect);

                }

            });

        }

    });

    //添加控制柄

    ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.EAST);

    ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.SOUTH);

    ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.WEST);

    ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.NORTH);

    return list;

createDragSourceFeedbackFigure()方法決定使用者拖動圖形時,随滑鼠移動的半透明圖形(即“鬼影”)的形狀和顔色,是以我們覆寫這個方法以顯示橢圓形的鬼影。

protected IFigure createDragSourceFeedbackFigure() {

    //用橢圓替代矩形

    //RectangleFigure r = new RectangleFigure();

    Ellipse r = new Ellipse();

    FigureUtilities.makeGhostShape(r);

    r.setLineStyle(Graphics.LINE_DOT);

    r.setForegroundColor(ColorConstants.white);

    r.setBounds(getInitialFeedbackBounds());

    addFeedback(r);

    return r;

經過以上這些修改,可以看到選擇框和鬼影都是橢圓的了,如圖2所示。

圖2 與節點形狀相同的選擇框和鬼影

繼續閱讀