KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > oddjob > designer > actions > DCTransferHandler


1 /*
2  * (c) Rob Gordon 2005
3  */

4 package org.oddjob.designer.actions;
5
6 import java.awt.datatransfer.DataFlavor JavaDoc;
7 import java.awt.datatransfer.StringSelection JavaDoc;
8 import java.awt.datatransfer.Transferable JavaDoc;
9 import java.io.Reader JavaDoc;
10 import java.util.ArrayList JavaDoc;
11 import java.util.Arrays JavaDoc;
12 import java.util.List JavaDoc;
13
14 import javax.swing.JComponent JavaDoc;
15 import javax.swing.JOptionPane JavaDoc;
16 import javax.swing.TransferHandler JavaDoc;
17
18 import org.apache.log4j.Logger;
19 import org.oddjob.OddjobException;
20 import org.oddjob.designer.DesignerXMLParser;
21 import org.oddjob.designer.model.ComponentAction;
22 import org.oddjob.designer.model.DesignComponent;
23 import org.oddjob.designer.model.DesignTreeNode;
24 import org.oddjob.designer.model.DesignerModel;
25 import org.oddjob.designer.model.InsertableDesignComponent;
26 import org.oddjob.designer.model.StructuralDesignComponent;
27 import org.oddjob.designer.view.RadioActions;
28 import org.oddjob.designer.view.ViewHelper;
29
30 /**
31  * A TransferHandler for transfering component data as XML to and from the
32  * DesignPanel.
33  */

34 public class DCTransferHandler extends TransferHandler JavaDoc {
35     private static final Logger logger = Logger.getLogger(DCTransferHandler.class);
36
37     /** The model */
38     private final DesignerModel model;
39
40     /** The source of a transfer, so it can be deleted on move. */
41     private DesignTreeNode sourceNode;
42
43     /**
44      * Constructor.
45      *
46      * @param model The DesignerModel.
47      */

48     public DCTransferHandler(DesignerModel model) {
49         this.model = model;
50     }
51         
52     /* (non-Javadoc)
53      * @see javax.swing.TransferHandler#canImport(javax.swing.JComponent, java.awt.datatransfer.DataFlavor[])
54      */

55     public boolean canImport(JComponent JavaDoc comp, DataFlavor JavaDoc[] transferFlavors) {
56         return selectBestFlavor(transferFlavors) != null;
57     }
58     
59     /* (non-Javadoc)
60      * @see javax.swing.TransferHandler#importData(javax.swing.JComponent, java.awt.datatransfer.Transferable)
61      */

62     public boolean importData(JComponent JavaDoc comp, Transferable JavaDoc t) {
63         DataFlavor JavaDoc[] dfs = t.getTransferDataFlavors();
64         DataFlavor JavaDoc df = selectBestFlavor(dfs);
65         String JavaDoc xml = null;
66         try {
67             Reader JavaDoc reader = df.getReaderForText(t);
68             StringBuffer JavaDoc b = new StringBuffer JavaDoc();
69             char[] ca = new char[1024];
70             while (true) {
71                 int i = reader.read(ca);
72                 if (i < 0) {
73                     break;
74                 }
75                 b.append(ca, 0, i);
76             }
77             xml = b.toString();
78         }catch (Exception JavaDoc e) {
79             logger.error("Failed data transfer.", e);
80             return false;
81         }
82         logger.debug(xml);
83         
84         if (model.getCurrentComponent() == null) {
85             return false;
86         }
87         ComponentAction[] actions = getActions(model.getCurrentSelection(), xml);
88         if (actions.length == 0) {
89             JOptionPane.showMessageDialog(comp,
90                     "Sorry - can't insert/add child at selected node.",
91                     "Information",
92                     JOptionPane.INFORMATION_MESSAGE);
93             return false;
94         }
95
96         return RadioActions.showDialog(comp,
97                 ViewHelper.convertAll(actions));
98     }
99
100     /* (non-Javadoc)
101      * @see javax.swing.TransferHandler#getSourceActions(javax.swing.JComponent)
102      */

103     public int getSourceActions(JComponent JavaDoc c) {
104         if (model.getCurrentSelection() == null) {
105             return NONE;
106         }
107         return COPY_OR_MOVE;
108     }
109     
110     /* (non-Javadoc)
111      * @see javax.swing.TransferHandler#createTransferable(javax.swing.JComponent)
112      */

113     protected Transferable JavaDoc createTransferable(JComponent JavaDoc c) {
114         String JavaDoc xml = model.getCurrentXML();
115         if (xml == null) {
116             return null;
117         }
118         sourceNode = model.getCurrentSelection();
119         logger.debug("Exporting:\n" + xml);
120         return new StringSelection JavaDoc(xml);
121     }
122     
123     /* (non-Javadoc)
124      * @see javax.swing.TransferHandler#exportDone(javax.swing.JComponent, java.awt.datatransfer.Transferable, int)
125      */

126     protected void exportDone(JComponent JavaDoc source, Transferable JavaDoc data, int action) {
127         if (action == MOVE) {
128             model.delete(sourceNode);
129         }
130     }
131
132     /**
133      * Get the best DataFlavor for transfers. At the moment we only support
134      * plain text.
135      *
136      * @param dataFlavors The available DataFlavors.
137      * @return The selected DataFlavor or null if none match what we can handle.
138      */

139     static DataFlavor JavaDoc selectBestFlavor(DataFlavor JavaDoc[] dataFlavors) {
140         for (int i = 0; i < dataFlavors.length; ++i) {
141             DataFlavor JavaDoc df = dataFlavors[i];
142             if ("text".equals(df.getPrimaryType()) &&
143                     "plain".equals(df.getSubType())) {
144                 return df;
145             }
146         }
147         return null;
148     }
149     
150     /**
151      * Get transfer actions when dropping/pasting data onto a node.
152      *
153      * @param node The sink node.
154      * @param xml The xml text.
155      *
156      * @return Available actions. Might be an empty array but
157      * it will never be null.
158      */

159     static ComponentAction[] getActions(final DesignTreeNode node, final String JavaDoc xml) {
160         List JavaDoc actions = new ArrayList JavaDoc();
161         final DesignComponent parentComponent = DesignerModel.getParentComponent(node);
162         if ( parentComponent != null && parentComponent instanceof InsertableDesignComponent) {
163             actions.add(new ComponentAction() {
164                 public String JavaDoc getName() {
165                     return "Insert";
166                 }
167                 /* (non-Javadoc)
168                  * @see org.oddjob.designer.model.ComponentAction#perform()
169                  */

170                 public void perform() {
171                     DesignComponent child = null;
172                     try {
173                         child = DesignerXMLParser.buildComponent(xml);
174                     } catch (Exception JavaDoc e) {
175                         throw new OddjobException("Failed to transfer data [" + xml
176                                 + "] (" + e.getMessage() + ")", e);
177                     }
178                     InsertableDesignComponent idc = (InsertableDesignComponent)
179                             parentComponent;
180                     idc.insertChild(DesignerModel.getIndex(node), child);
181                     
182                 }
183             });
184         }
185         if (node.getDesignComponent() instanceof StructuralDesignComponent) {
186             StructuralDesignComponent sdc = (StructuralDesignComponent)node.getDesignComponent();
187             ComponentAction[] tas = sdc.transferActions(xml);
188             actions.addAll(Arrays.asList(tas));
189         }
190         return (ComponentAction[]) actions.toArray(new ComponentAction[0]);
191     }
192 }
193
Popular Tags