JGraph是基于Java swing、Java 2D开发的纯Java图形库,很像Eclipse的EMF、JMF,可以很方便地帮助开发人员在Swing框架中实现组件的呈现、布局、拖拽、group等图形化操作。JGraph也是基于MVC模式实现,将整个框架分为cell(M层)、cell view(C层)和renderer(V层)。有一些设计思想很有趣,比如它的GraphConstants,将所有属性存在传入的map里,通过方法签名实现属性的意义化和类型限制,很有趣的思想

下面进入正题,如何判断一个cell view被deselect。JGraph现在已半商业化,文档很稀少,JavaDoc更是不堪入目,最好的研究方法还是读源代码,比如前两天为了正确设置cell view的虚线边框颜色就看了一晚上源代码
JGraph的事件监听写得很诡异,在cell view中需要通过以下方法添加监听器:

class MyCellView extends VertexView {
    public CellHandle getHandle(GraphContext context) {
        return new CellHandle(){
            void paint(Graphics g);

            void overlay(Graphics g);

            void mouseMoved(MouseEvent event);

            void mousePressed(MouseEvent event);

            void mouseDragged(MouseEvent event);

            void mouseReleased(MouseEvent event);
        };
    }
}

你可以通过JGraph对象的getSelectionCell()getSelectionCells()获得被选中的cell,但是有一个问题,就是当你单击空白区域以取消选择一个cell view时,该方法依然返回非空的最后选择的对象。于是尝试从MouseEvent获得点击时鼠标的X、Y坐标,并调用getFirstCellForLocation(double x, double y)获得鼠标位置的cell(没有则返回null)。但这样还是有问题,当你通过框选选择一个(或若干个)cell时,getFirstCellForLocation(double x, double y)返回的对象取决于你实现的方法(是press、drag还是release)。最后,在通读了一下JGraph的JavaDoc后,发现可以使用如下方法解决这个问题:

graph.getSelectionModel().addGraphSelectionListener(new GraphSelectionListener() {
    public void valueChanged(GraphSelectionEvent e) {
        MachineCell[] cell = null;

        if (e.isAddedCell()) { // selected
            cell = new MachineCell[]{(MachineCell) e.getCell()};
        } else {
            cell = new MachineCell[0];
        }

        for (ActionListener l : listeners) {
            l.actionPerformed(new ActionEvent(cell, 0, ""));
        }
    }
});

其中第五行的isAddedCell()方法签名如下:

isAddedCell

public boolean isAddedCell()
Returns true if the first cell has been added to the selection, a return value of false means the first cell has been removed from the selection.

 

Returns:
whether or not the first cell has been added or removed