1
14
15 package demo.view.advanced;
16
17 import y.util.D;
18 import y.view.NodeRealizer;
19 import y.view.ShapeNodeRealizer;
20 import y.view.Graph2DView;
21 import y.view.Graph2D;
22 import y.view.Drawable;
23
24 import javax.swing.Icon;
25 import javax.swing.JLabel;
26 import javax.swing.JList;
27 import javax.swing.JScrollPane;
28 import javax.swing.ListCellRenderer;
29 import javax.swing.DefaultListCellRenderer;
30 import javax.swing.ListSelectionModel;
31 import javax.swing.event.ListSelectionListener;
32 import javax.swing.event.ListSelectionEvent;
33 import java.awt.BorderLayout;
34 import java.awt.Color;
35 import java.awt.Component;
36 import java.awt.Graphics;
37 import java.awt.Graphics2D;
38 import java.awt.Point;
39 import java.awt.RenderingHints;
40 import java.awt.datatransfer.DataFlavor;
41 import java.awt.datatransfer.StringSelection;
42 import java.awt.datatransfer.Transferable;
43 import java.awt.datatransfer.UnsupportedFlavorException;
44 import java.awt.dnd.DnDConstants;
45 import java.awt.dnd.DragGestureEvent;
46 import java.awt.dnd.DragGestureListener;
47 import java.awt.dnd.DragSource;
48 import java.awt.dnd.DropTarget;
49 import java.awt.dnd.DropTargetDragEvent;
50 import java.awt.dnd.DropTargetDropEvent;
51 import java.awt.dnd.DropTargetListener;
52 import java.awt.dnd.DropTargetEvent;
53 import java.io.IOException;
54 import java.util.HashMap;
55 import java.util.Iterator;
56 import java.util.Map;
57 import java.util.Collection;
58
59 import demo.view.DemoBase;
60
61
67 public class DragAndDropDemo extends DemoBase
68 {
69
70 public DragAndDropDemo()
71 {
72 final Map stringToNodeRealizerMap = createStringToRealizerMap();
74 final Map inverse = new HashMap();
75 for(Iterator it = stringToNodeRealizerMap.entrySet().iterator();it.hasNext();){
76 Map.Entry entry = (Map.Entry) it.next();
77 inverse.put(entry.getValue(), entry.getKey());
78 }
79
80
81 final DragAndDropSupport dndSupport = new DragAndDropSupport(inverse.keySet(), view) {
83 protected String getTextValue(NodeRealizer selected) {
84 return (String) inverse.get(selected);
85 }
86
87 protected NodeRealizer createNodeRealizerFromTextValue(String s) {
88 return (NodeRealizer) stringToNodeRealizerMap.get(s);
89 }
90 };
91
92 final JList realizerList = dndSupport.getList();
94 realizerList.setBackground(Color.lightGray);
95
96 contentPane.add(new JScrollPane(realizerList),BorderLayout.WEST);
98 }
99
100
105 protected Map createStringToRealizerMap()
106 {
107 Map result = new HashMap();
108
109 Map shapeTypeToStringMap = ShapeNodeRealizer.shapeTypeToStringMap();
110 float hueIncrease = 1.0f/shapeTypeToStringMap.size();
111 float hue = 0.0f;
112 for(Iterator iter = shapeTypeToStringMap.keySet().iterator(); iter.hasNext(); hue += hueIncrease)
113 {
114 Byte shapeType = (Byte)iter.next();
115 ShapeNodeRealizer r = new ShapeNodeRealizer(shapeType.byteValue());
116 r.setWidth(100);
117 r.setLabelText( (String)shapeTypeToStringMap.get(shapeType) );
118 r.setFillColor(new Color(Color.HSBtoRGB(hue, 1.0f, 1.0f)));
119 result.put(r.getLabelText(), r);
120 }
121 return result;
122 }
123
124
128 public abstract static class DragAndDropSupport {
129 private final JList realizerList;
130
131 protected DragAndDropSupport(Collection nodeRealizerList, final Graph2DView view) {
132 this( nodeRealizerList.toArray(), view );
133 }
134
135 protected DragAndDropSupport(Object[] nodeRealizers, final Graph2DView view) {
136 realizerList = new JList(nodeRealizers );
138 realizerList.setCellRenderer(new NodeRealizerCellRenderer());
139
140 realizerList.addListSelectionListener(new ListSelectionListener() {
142 public void valueChanged(ListSelectionEvent e) {
143 if (realizerList.getSelectedValue() instanceof NodeRealizer) {
144 nodeRealizerSelected(view);
145 }
146 }
147 });
148
149 realizerList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
150 realizerList.setSelectedIndex(0);
151
152 final DragSource dragSource = new DragSource();
155 dragSource.createDefaultDragGestureRecognizer(realizerList, DnDConstants.ACTION_MOVE,
156 new DragGestureListener() {
157 public void dragGestureRecognized(DragGestureEvent event) {
158 Object selected = realizerList.getSelectedValue();
159 final String textValue = getTextValue((NodeRealizer) selected);
160 if (textValue != null) {
161 StringSelection text = new StringSelection(textValue);
162 dragSource.startDrag(event, DragSource.DefaultMoveDrop, text, null);
164 }
165 }
166 });
167
168 new DropTarget(view.getCanvasComponent(), new DropTargetListener() {
171
172 public void dragEnter(DropTargetDragEvent event) {
174 if (checkStringFlavor(event)) {
175 event.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
176 } else {
177 event.rejectDrag();
178 }
179 }
180
181 private boolean checkStringFlavor(DropTargetDragEvent event) {
183 DataFlavor[] flavors = event.getCurrentDataFlavors();
185 for (int i = 0; i < flavors.length; i++) {
186 if (flavors[i] == DataFlavor.stringFlavor) {
187 return true;
188 }
189 }
190 return false;
191 }
192
193 public void drop(DropTargetDropEvent event) {
195 try {
196 boolean foundStringFlavor = false;
198 DataFlavor[] flavors = event.getCurrentDataFlavors();
199 for (int i = 0; i < flavors.length; i++) {
200 if (flavors[i] == DataFlavor.stringFlavor) {
201 foundStringFlavor = true;
202 break;
203 }
204 }
205 if (foundStringFlavor) {
206 event.acceptDrop(event.getDropAction());
207 } else {
208 event.rejectDrop();
209 return;
210 }
211 } catch (RuntimeException rex) {
212 event.rejectDrop();
213 D.show(rex);
214 }
215 try {
216 Transferable transferable = event.getTransferable();
217 String s = (String) transferable.getTransferData(DataFlavor.stringFlavor);
218 Point p = event.getLocation();
219 NodeRealizer r = createNodeRealizerFromTextValue(s);
220 if (r != null) {
221 final double worldCoordX = view.toWorldCoordX(p.x);
223 final double worldCoordY = view.toWorldCoordY(p.y);
224 event.dropComplete(dropRealizer(view, r, worldCoordX, worldCoordY));
225 } else {
226 event.dropComplete(false);
228 }
229 } catch (IOException ioe) {
230 event.dropComplete(false);
232 D.show(ioe);
233 } catch (UnsupportedFlavorException ufe) {
234 event.dropComplete(false);
236 D.show(ufe);
237 } catch (RuntimeException x) {
238 event.dropComplete(false);
239 throw x;
240 }
241 }
242
243 public void dragExit(DropTargetEvent dte) {
245 }
246
247 public void dropActionChanged(DropTargetDragEvent dtde) {
249 dragEnter(dtde);
250 }
251
252 public void dragOver(DropTargetDragEvent dtde) {
254 dragEnter(dtde);
255 }
256 });
257 }
258
259
265 protected abstract String getTextValue(NodeRealizer selected);
266
267
273 protected abstract NodeRealizer createNodeRealizerFromTextValue(String s);
274
275
280 protected boolean dropRealizer( Graph2DView view, NodeRealizer r, double worldCoordX, double worldCoordY ) {
281 final Graph2D graph = view.getGraph2D();
282 r = r.createCopy();
283
284 if ( view.getGridMode() ) {
285 double gridSize = view.getGridResolution();
286 double x = Math.floor( worldCoordX / gridSize + 0.5 ) * gridSize;
287 double y = Math.floor( worldCoordY / gridSize + 0.5 ) * gridSize;
288
289 r.setCenter( x, y );
290 } else {
291 r.setCenter( worldCoordX, worldCoordY );
292 }
293 graph.createNode( r );
294 view.updateView();
295 return true;
296 }
297
298
302 protected void nodeRealizerSelected(Graph2DView view) {
303 view.getGraph2D().setDefaultNodeRealizer((NodeRealizer) realizerList.getSelectedValue());
304 }
305
306
309 public JList getList() {
310 return realizerList;
311 }
312 }
313
314
318 public static final class NodeRealizerCellRenderer implements ListCellRenderer {
319
320 private DefaultListCellRenderer renderer = new DefaultListCellRenderer();
321 private NodeRealizerIcon icon = new NodeRealizerIcon();
322
323 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
324 JLabel label = (JLabel) renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
325 icon.setRealizer((NodeRealizer) value);
326 label.setText("");
327 label.setIcon(icon);
328 return label;
329 }
330
331
334 public static final class NodeRealizerIcon implements Icon {
335 private static final int inset = 10;
336 private NodeRealizer realizer;
337
338 public void setRealizer(NodeRealizer realizer) {
339 this.realizer = realizer;
340 }
341
342 public int getIconWidth() {
343 return (int) (realizer.getWidth() + inset);
344 }
345
346 public int getIconHeight() {
347 return (int) (realizer.getHeight() + inset);
348 }
349
350 public void paintIcon(Component c, Graphics g, int x, int y) {
351 realizer.setLocation(x + inset * 0.5d, y + inset * 0.5d);
352 g = g.create();
353 try {
354 final Graphics2D gfx = (Graphics2D) g;
355 gfx.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
356 realizer.paint(gfx);
357 } finally {
358 g.dispose();
359 }
360 }
361 }
362 }
363
364
367 public static void main(String[] args)
368 {
369 initLnF();
370 DragAndDropDemo demo = new DragAndDropDemo();
371 demo.start("Drag and Drop Demo");
372 }
373 }
374