// http://www.javaworld.com/javaworld/jw-03-1999/jw-03-dragndrop-p1.html package main; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceDragEvent; import java.awt.dnd.DragSourceDropEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DragSourceListener; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.Serializable; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JLayeredPane; public class Connection extends JLabel implements DragGestureListener, DragSourceListener, DropTargetListener, Transferable, Serializable { private int index, type; private String name; private boolean input; private int conX, conY; private boolean open; // Of er een kabel in zit... private Module module; private ImageIcon icon; private Connection _this = null; public final static int imageWidth = 13/2; // DE HELFT ERVAN!!! Cables cables = null; private static boolean moving = false; //--- drag private DragSource dragSource = null; private int dragAction = DnDConstants.ACTION_COPY_OR_MOVE; //--- drop private DropTarget dropTarget = null; private int dropAction = DnDConstants.ACTION_COPY_OR_MOVE; //--- data public static final DataFlavor inConnectionFlavor = new DataFlavor("jmod/inConnection", "jMod In Connection"); public static final DataFlavor outConnectionFlavor = new DataFlavor("jmod/outConnection", "jMod Out Connection"); private static final DataFlavor[] inFlavors = {inConnectionFlavor, outConnectionFlavor}; private static final DataFlavor[] outFlavors = {outConnectionFlavor, inConnectionFlavor}; private DataFlavor[] flavors = null; private int oldDragX = -1, oldDragY = -1; // endDrag zorgt ervoor dat de kabel die zojuist gedropt is, opnieuw getekend wordt met een curve. // Volgens mij worden alle kabels opnieuw getekend na een drop... ach ja... private boolean endDrag = true; Connection(Module newModule, boolean bInput, int newIndex, String newName, int newType, int newX, int newY) { _this = this; index = newIndex; type = newType; input = bInput; name = newName; conX = newX; conY = newY; open = true; module = newModule; if (input){ if (type == 0) icon = new ImageIcon("./grafix/_con_in_red.gif"); if (type == 1) icon = new ImageIcon("./grafix/_con_in_blue.gif"); if (type == 2) icon = new ImageIcon("./grafix/_con_in_yellow.gif"); if (type == 3) icon = new ImageIcon("./grafix/_con_in.gif"); flavors = inFlavors; } else { if (type == 0) icon = new ImageIcon("./grafix/_con_out_red.gif"); if (type == 1) icon = new ImageIcon("./grafix/_con_out_blue.gif"); if (type == 2) icon = new ImageIcon("./grafix/_con_out_yellow.gif"); if (type == 3) icon = new ImageIcon("./grafix/_con_out.gif"); flavors = outFlavors; } this.setIcon(icon); this.setLocation(conX, conY); this.setSize(icon.getIconWidth(), icon.getIconHeight()); this.setToolTipText(name); module.add(this); dragSource = DragSource.getDefaultDragSource(); dragSource.createDefaultDragGestureRecognizer(this, dragAction, this); dropTarget = new DropTarget(this, dropAction, this, true); this.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { moving = false; // TODO ?Replace lgic to Cables Cable cab = null; int modIndex = module.getModuleData().getModIndex(); int conIndex = _this.getConnectionIndex(); int inpIndex = _this.input?0:1; boolean poly = module.getModuleData().getPoly(); int loopSize = poly?module.getModules().getCables().getPolySize():module.getModules().getCables().getCommonSize(); if (loopSize > 0) { for (int i=0; i < loopSize; i++) { cab = module.getModules().getCables().getCable(poly, i); if (((cab.getBeginModule() == modIndex) && (cab.getBeginConnector() == conIndex) && (cab.getBeginConnectorType() == inpIndex)) || ((cab.getEndModule() == modIndex) && (cab.getEndConnector() == conIndex) && (cab.getEndConnectorType() == inpIndex))) { Cables.setDragCable(cab); Cables.getDragCable().setSelectColor1(); break; } } } if (e.isAltDown()) { module.getModules().getCables().selectChain(cab, poly); } if (e.getClickCount() > 1 || e.isControlDown()) { moving = true; Cables.determBeginWindowDrag(module.getX() + conX, module.getY() + conY); Cables.determBeginCableDrag(modIndex, conIndex, inpIndex); Cables.getDragCable().setSelectColor2(); } } public void mouseReleased(MouseEvent e) { if (e.isAltDown()) { Cable cab = Cables.getDragCable(); module.getModules().getCables().unSelectChain(cab, module.getModuleData().getPoly()); } if (!e.isAltDown()) { if (Cables.getDragCable() != null) Cables.getDragCable().restoreColor(); } } }); } // Getters public Module getModule() { return module; } public String getConnectionName() { return name; } public int getConnectionType() { return type; } public int getConnectionIndex() { return index; } public int getConnectionLocationX() { return conX; } public int getConnectionLocationY() { return conY; } public String getConnectionTypeName() { String returnType; switch (type) { case 0: returnType = "Audio"; break; // 24bit, min = -64, max = +64 - 96kHz. case 1: returnType = "Control"; break; // 24bit, min = -64, max = +64 - 24kHz. case 2: returnType = "Logic"; break; // 1bit, low = 0, high = +64. case 3: returnType = "Slave"; break; // frequentie referentie tussen master en slave modulen default: returnType = "Wrong type..."; break; } return returnType; } //--- drag public void setEndDrag(boolean newEndDrag) { endDrag = newEndDrag; } public void dragGestureRecognized(DragGestureEvent e) { endDrag = false; if (Cables.getDragCable() != null) Cables.getDragCable().restoreColor(); if (Cables.getDragCable() != null) module.getModules().getCables().unSelectChain(Cables.getDragCable(), module.getModuleData().getPoly()); // Het ligt aan de Action (shift/control) wat we gaan doen... if (e.getDragAction() == 2 && !moving) { // new moving = false; e.startDrag(DragSource.DefaultCopyDrop, this, this); Cables.newDragCable(module.getX() + conX, module.getY() + conY, Cable.SELECTCOLOR1, input?0:1); module.getDesktopPane().add(Cables.getDragCable()); } else { // dan is de kabel die in de mousePressed gevonden is de juiste. moving = true; e.startDrag(DragSource.DefaultMoveDrop, this, this); Cables.setTempCable(Cables.getDragCable()); Cables.getDragCable().setSelectColor2(); } module.getDesktopPane().setLayer(Cables.getDragCable(), JLayeredPane.DEFAULT_LAYER.intValue() + 10); // Ietskes hoger // Debug.println("Connection dragGestureRecognized(source)"); } public void dragEnter(DragSourceDragEvent e) { // Debug.println("dragEnter(source)?"); } public void dragOver(DragSourceDragEvent e) { // Debug.println("dragOver(source)?"); } public void dragExit(DragSourceEvent e) { // Debug.println("Connection dragExit(source)"); } public void dragDropEnd(DragSourceDropEvent e) { if (e.getDropSuccess() == false) { if (moving) { if (e.getDropAction() == 2) { // rejected by wron connection module.getModules().getCables().addCable(module.getModuleData().getPoly(), Cables.getTempCable(Cables.getDragCable())); module.getModules().getCables().redrawCables(module.getModules(), module.getModuleData().getPoly()); } else { // rejected by 'module' -> delete module.getModules().getCables().removeCable(Cables.getDragCable(), module.getModuleData().getPoly()); } } else { module.getModules().getCables().removeCable(Cables.getDragCable(), module.getModuleData().getPoly()); } return; } int dropAction = e.getDropAction(); if (dropAction == DnDConstants.ACTION_MOVE) { // wat te doen als het een move was... etc } this.open = false; // dit moet ook in de target gebeuren } public void dropActionChanged(DragSourceDragEvent e) { //Bij het indrukken van Shift en Ctrl //Debug.println("dropActionChanged(source)"); // DragSourceContext context = e.getDragSourceContext(); // context.setCursor(DragSource.DefaultCopyNoDrop); } // --- drop private boolean isDragOk(DropTargetDragEvent e) { DataFlavor chosen = null; // do we need this anymore? for (int i = 0; i < flavors.length; i++) { if (e.isDataFlavorSupported(flavors[i])) { chosen = flavors[i]; break; } } /* if the src does not support any of the Connection flavors */ if (chosen == null) { return false; } // the actions specified when the source // created the DragGestureRecognizer int sa = e.getSourceActions(); // Copy or Move // we're saying that these actions are necessary if ((sa & dragAction) == 0) return false; return true; } public void dragEnter(DropTargetDragEvent e) { // Debug.println("dragEnter(target)"); } public void dragOver(DropTargetDragEvent e) { if(!isDragOk(e)) { e.rejectDrag(); return; } int newDragX = e.getLocation().x - Connection.imageWidth; int newDragY = e.getLocation().y - Connection.imageWidth; if ((newDragX != oldDragX) || (newDragY != oldDragY)) { if (Cables.getDragCable() != null) { Cables.getDragCable().setNewDragWindowLayout((module.getX() + conX) + (newDragX), (module.getY() + conY) + (newDragY)); Cables.getDragCable().repaint(); oldDragX = newDragX; oldDragY = newDragY; } } e.acceptDrag(dragAction); } public void dragExit(DropTargetEvent e) { // Debug.println("dragExit(target)"); } public void dropActionChanged(DropTargetDragEvent e) { // Debug.println(new Integer(e.getDropAction()).toString()); } public void drop(DropTargetDropEvent e) { DataFlavor chosen = null; if (e.isLocalTransfer() == false) { // chosen = StringTransferable.plainTextFlavor; } else { for (int i = 0; i < flavors.length; i++) if (e.isDataFlavorSupported(flavors[i])) { chosen = flavors[i]; break; } } if (chosen == null) { e.rejectDrop(); return; } // the actions that the source has specified with DragGestureRecognizer int sa = e.getSourceActions(); if ((sa & dropAction) == 0 ) { // Als een Move op Copy niet mag... e.rejectDrop(); return; } Object data = null; try { e.acceptDrop(dropAction); data = e.getTransferable().getTransferData(chosen); if (data == null) throw new NullPointerException(); } catch (Throwable t) { t.printStackTrace(); e.dropComplete(false); return; } if (data instanceof Connection) { Connection con = (Connection) data; int newColour = 6; con.endDrag = true; if (_this.equals(con)) { e.dropComplete(false); return; } int modIndex = module.getModuleData().getModIndex(); int conModIndex = con.getModule().getModuleData().getModIndex(); if (!moving) { if (con.input) Cables.getDragCable().setCableData(conModIndex, con.index, 0, modIndex, index, input?0:1, newColour); else Cables.getDragCable().setCableData(modIndex, index, this.input?0:1, conModIndex, con.index, con.input?0:1, newColour); } else { if (Cables.getDragBeginCable()) // if (input) { // Debug.println("a"); Cables.getDragCable().setCableData(modIndex, index, input?0:1, -1, 0, 0, newColour); // } // else { // Debug.println("b"); // Cables.getDragCable().setCableData(modIndex, index, input?0:1, -1, 0, 0, newColour); // } else { // if (con.input) { // Debug.println("c"); Cables.getDragCable().setCableData(-1, 0, 0, modIndex, index, input?0:1, newColour); // } // else { // Debug.println("d"); // Cables.getDragCable().setCableData(-1, 0, 0, modIndex, index, input?0:1, newColour); // } } } // Dragged to other end of cable if ((Cables.getDragCable().getBeginModule() == Cables.getDragCable().getEndModule()) && (Cables.getDragCable().getBeginConnector() == Cables.getDragCable().getEndConnector()) && (Cables.getDragCable().getBeginConnectorType() == Cables.getDragCable().getEndConnectorType())) { e.dropComplete(false); return; } newColour = module.getModules().getCables().checkChain(Cables.getDragCable(), module.getModuleData().getPoly()); if (newColour < 0) // reject cable; { e.dropComplete(false); return; } Cables.getDragCable().setColor(newColour); if (!moving) module.getModules().getCables().addCable(module.getModuleData().getPoly(), Cables.getDragCable()); module.getModules().getCables().redrawCables(module.getModules(), module.getModuleData().getPoly()); } else { e.dropComplete(false); return; } e.dropComplete(true); } //--- data public DataFlavor[] getTransferDataFlavors() { return flavors; } public boolean isDataFlavorSupported(DataFlavor targetFlavor) { // het dataobject (nu zichzelf) krijgt flavours mee van de source. return true; } public synchronized Object getTransferData(DataFlavor flavor) { // afhankelijk van welke flavour de target(?) graag wil, geven we het juiste terug // if (flavor.equals(inConnectionFlavor)) // return this; // if (flavor.equals(outConnectionFlavor)) // return this; // throw new UnsupportedFlavorException(flavor); // we vinden alles goed return this; } public String toString() { return (input?"input ":"output ") + index + " " + getConnectionTypeName() + "(" + type + ") " + name; } }