Package open.dolphin.client

Source Code of open.dolphin.client.StampTreeTransferHandler

package open.dolphin.client;

import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;

import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.InputEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import open.dolphin.infomodel.IInfoModel;
import open.dolphin.infomodel.InfoModelTransferable;
import open.dolphin.infomodel.ModuleModel;
import open.dolphin.infomodel.RegisteredDiagnosisModel;
import open.dolphin.ui.PatchedTransferHandler;

/**
* StampTreeTransferHandler
*
* @author Minagawa,Kazushi
* @author pns
*
*/
public class StampTreeTransferHandler extends PatchedTransferHandler {
    private static final long serialVersionUID = 1205897976539749194L;

    // StampTreeNode Flavor
    private DataFlavor stampTreeNodeFlavor = LocalStampTreeNodeTransferable.localStampTreeNodeFlavor;

    // KartePaneからDropされるオーダのFlavor
    private DataFlavor orderFlavor = OrderListTransferable.orderListFlavor;

    // KartePaneからDropされるテキストFlavor
    private DataFlavor stringFlavor = DataFlavor.stringFlavor;

    // 病名エディタからDropされるRegisteredDiagnosis Flavor
    private DataFlavor infoModelFlavor = InfoModelTransferable.infoModelFlavor;

    // Drop する target の path
    private TreePath targetPath;

    // target の中に入れるか,前に挿入するか,後ろに挿入するかの情報(StampTreeDropTargetListener でセットする)
    public enum Insert { AFTER, BEFORE, INTO_FOLDER };
    private Insert insertPosition;
   
    // 半透明ドラッグのために保存する
    private JComponent draggedComp = null;

    public void setTargetPath(TreePath t) {
        targetPath = t;
    }
    public void setPosition(Insert p) {
        insertPosition = p;
    }
    public Insert getInsertPosition() {
        return insertPosition;
    }
   
    /**
     * 半透明 drag の為に,draggedComp と mousePosition を保存する
     * @param comp
     * @param e
     * @param action
     */
    @Override
    public void exportAsDrag(JComponent comp, InputEvent e, int action) {
        insertPosition = null;
       
        JTree tree = (JTree)comp;
        TreePath path = tree.getSelectionPath();
        if (path == null) return; // 1回ヌルポがでた
       
        TreeNode node = (TreeNode) path.getLastPathComponent();           
        StampTreeRenderer r = (StampTreeRenderer) tree.getCellRenderer();

        boolean selected = false;
        boolean expanded = tree.isExpanded(path);
        boolean isLeaf = node.isLeaf();
        int row = tree.getRowForPath(path);
        boolean hasFocus = true;

        draggedComp = (JComponent) r.getTreeCellRendererComponent(tree, node, selected, expanded, isLeaf, row, hasFocus);
        draggedComp.setSize(draggedComp.getPreferredSize());
        // calculate MousePosition
        Rectangle pathBounds = tree.getPathBounds(path);
        mousePosition = tree.getMousePosition();
        // mousePosition may be null
        if (mousePosition != null) {
            mousePosition.x -= pathBounds.x;
            mousePosition.y -= pathBounds.y;
        }
        super.exportAsDrag(comp, e, action);
    }
    /**
     * 選択されたノードでDragを開始する。
     */
    @Override
    protected Transferable createTransferable(JComponent c) {
        StampTree sourceTree = (StampTree) c;
        StampTreeNode dragNode = (StampTreeNode) sourceTree.getLastSelectedPathComponent();
        return new LocalStampTreeNodeTransferable(dragNode);
    }

    @Override
    public int getSourceActions(JComponent c) {
        return COPY_OR_MOVE;
    }

    /**
     * DropされたFlavorをStampTreeにインポートする。
     */
    @Override
    public boolean importData(JComponent c, Transferable tr) {

        if (targetPath == null) {
            System.out.println("StampTreeTransferHandler: targetPath is null");
            return false;
        }
        if (insertPosition == null) {
            System.out.println("StampTreeTransferHandler: insertPosition is null");
            return false;
        }

        if (canImport(c, tr.getTransferDataFlavors())) {

            try {
                // Dropを受けるStampTreeを取得する
                StampTree tree = (StampTree) c;
                String targetEntity = tree.getEntity();

                // Drop位置のノードを取得する
                StampTreeNode targetNode = (StampTreeNode) targetPath.getLastPathComponent();

                // StampTree 内の DnD
                if (tr.isDataFlavorSupported(stampTreeNodeFlavor)) {

                    // ソースのノードを取得する
                    StampTreeNode sourceNode = (StampTreeNode) tr.getTransferData(stampTreeNodeFlavor);

                    // Drop 位置の親
                    StampTreeNode newParent = (StampTreeNode) targetNode.getParent();

                    // root までの親のパスのなかに自分がいるかどうかを判定する
                    // Drop先が DragNode の子である時は DnD できない i.e 親が自分の子になることはできない
                    DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
                    TreeNode[] parents = model.getPathToRoot(targetNode);
                    boolean exist = false;
                    for (TreeNode parent : parents) {
                        if (parent == (TreeNode) sourceNode) {
                            exist = true;
                            Toolkit.getDefaultToolkit().beep();
                            //System.out.println("new Child is ancestor");
                            break;
                        }
                    }

                    // 親が自分の子になろうとしているわけではない場合,処理開始
                    if (!exist) {
                        int index = newParent.getIndex(targetNode);
                        if (index == -1) {
                            System.out.println("StampTreeTransferHandler: index is -1");
                            return false;
                        }

                        // 同じ親の場合,下に移動した場合 index が変わる
                        if (sourceNode.getParent() == newParent && insertPosition != Insert.INTO_FOLDER) {
                            int sourceRow = tree.getRowForPath(new TreePath(sourceNode.getPath()));
                            int targetRow = tree.getRowForPath(targetPath);
                            if (sourceRow < targetRow) index--;
                        }

                        switch(insertPosition) {
                            case BEFORE:
                                model.removeNodeFromParent(sourceNode);
                                model.insertNodeInto(sourceNode, newParent, index);
                                break;
                            case AFTER:
                                model.removeNodeFromParent(sourceNode);
                                model.insertNodeInto(sourceNode, newParent, index+1);
                                break;
                            case INTO_FOLDER: //最後の子として挿入
                                model.removeNodeFromParent(sourceNode);
                                model.insertNodeInto(sourceNode, targetNode, targetNode.getChildCount());
                        }
                        TreeNode[] path = model.getPathToRoot(sourceNode);
                        ((JTree) tree).setSelectionPath(new TreePath(path));
                    }
                    return true;

                // KartePaneからDropされたオーダをインポートする
                } else if (tr.isDataFlavorSupported(orderFlavor)) {

                    OrderList list = (OrderList) tr.getTransferData(OrderListTransferable.orderListFlavor);
                    ModuleModel droppedStamp = list.orderList[0];

                    // 同一エンティティの場合、選択は必ず起っている
                    if (droppedStamp.getModuleInfo().getEntity().equals(targetEntity)) {
                        return tree.addStamp(droppedStamp, targetNode);

                    // パス Tree の場合
                    } else if (targetEntity.equals(IInfoModel.ENTITY_PATH)) {
                        if (targetNode == null) {
                            targetNode = (StampTreeNode) tree.getModel().getRoot();
                        }
                        return tree.addStamp(droppedStamp, targetNode);

                    } else {
                        // Rootの最後に追加する
                        return tree.addStamp(droppedStamp, null);
                    }

                // KartePaneからDropされたテキストをインポートする
                } else if (tr.isDataFlavorSupported(stringFlavor)) {

                    String text = (String) tr.getTransferData(DataFlavor.stringFlavor);
                    if (targetEntity.equals(IInfoModel.ENTITY_TEXT)) {
                        return tree.addTextStamp(text, targetNode);
                    } else {
                        return tree.addTextStamp(text, null);
                    }

                // DiagnosisEditorからDropされた病名をインポートする
                } else if (tr.isDataFlavorSupported(infoModelFlavor)) {

                    RegisteredDiagnosisModel rd = (RegisteredDiagnosisModel) tr.getTransferData(InfoModelTransferable.infoModelFlavor);
                    if (targetEntity.equals(IInfoModel.ENTITY_DIAGNOSIS)) {
                        return tree.addDiagnosis(rd, targetNode);
                    } else {
                        return tree.addDiagnosis(rd, null);
                    }
                } else {
                    return false;
                }

            } catch (IOException ex) {
                System.out.println("StampTreeTransferHandler.java: "+ ex);
                ex.printStackTrace();
            } catch (UnsupportedFlavorException ex) {
                System.out.println("StampTreeTransferHandler.java: "+ ex);
            }
        }
        return false;
    }

    /**
     * DnD後、Dragしたノードを元のStamptreeから削除する。
     */
    @Override
    protected void exportDone(JComponent c, Transferable data, int action) {
    }

    /**
     * インポート可能かどうかを返す。
     */
    @Override
    public boolean canImport(JComponent c, DataFlavor[] flavors) {

        boolean isLocked = ((StampTree)c).getStampBox().isLocked();
        return isFlavorMatched(flavors) && !isLocked && targetPath != null;
    }

    private boolean isFlavorMatched(DataFlavor[] flavors) {
        for (DataFlavor flavor : flavors) {
            if (stampTreeNodeFlavor.equals(flavor)) return true;
            if (orderFlavor.equals(flavor)) return true;
            if (stringFlavor.equals(flavor)) return true;
            if (infoModelFlavor.equals(flavor)) return true;
        }
        return false;
    }
       
    /**
     * 半透明のフィードバックを返す
     * @param t
     * @return
     */
    @Override
    public Icon getVisualRepresentation(Transferable t) {
        if (draggedComp == null) return null;
       
        int width = draggedComp.getWidth();
        int height = draggedComp.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
        draggedComp.paint(image.getGraphics());
        return new ImageIcon(image);
    }
}
TOP

Related Classes of open.dolphin.client.StampTreeTransferHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.