View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans.
5    *
6    * CosyBeans is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.util;
21  
22  import java.awt.Component;
23  import java.awt.datatransfer.DataFlavor;
24  import java.awt.datatransfer.Transferable;
25  import java.awt.datatransfer.UnsupportedFlavorException;
26  import java.beans.PropertyChangeEvent;
27  import java.beans.PropertyVetoException;
28  import java.io.IOException;
29  
30  import javax.swing.JComponent;
31  
32  import com.cosylab.gui.components.util.CosyTransferHandler;
33  import com.cosylab.gui.displayers.DisplayerParameters;
34  import com.cosylab.introspection.BeanIntrospector;
35  
36  /**
37   * <code>AbstractDisplayerParametersTransferHandler</code> is a TransferHandler
38   * for all DisplayerParameters-type-displayer. 
39   * 
40   * @author tkusterle
41   *
42   */
43  public abstract class AbstractDisplayerParametersTransferHandler extends CosyTransferHandler {
44  	
45  	private static final long serialVersionUID = -4223198013311762602L;
46  	protected DisplayerParametersSelectorDialog dialog;
47  	protected JComponent displayer;
48  	protected DataFlavor[] flavors= {DisplayerParametersFlavor.FLAVOR,DataFlavor.stringFlavor};
49  
50  	public AbstractDisplayerParametersTransferHandler(JComponent comp, boolean reciveEnabled, boolean exportEnabled) {
51  		super(reciveEnabled, exportEnabled);
52  		displayer= comp;
53  		hookTransferHandler((JComponent)comp);
54  	}
55  
56  	/**
57  	 * Creates new DnD transfer handler with modified flavors. 
58  	 * @param comp the component for which this handler si created
59  	 * @param reciveEnabled flag for recifving DnD gestures
60  	 * @param exportEnabled flag for exporting DnD gestures
61  	 * @param f the array of flavors, whih are inseted to this handler at beginning of default 
62  	 *          flavors. If null or 0 length then ignored.
63  	 * @param resetFlavors if <code>true</code>, then provided flavors replaces default 
64  	 *                     flavors, otherwise provided flavors are inserted ad beginning of 
65  	 *                     default flavor list.
66  	 */
67  	public AbstractDisplayerParametersTransferHandler(JComponent comp, boolean reciveEnabled, boolean exportEnabled, DataFlavor[] f, boolean resetFlavors) {
68  		this(comp, reciveEnabled, exportEnabled);
69  		if (f==null || f.length==0) {
70  			return;
71  		}
72  		if (resetFlavors) {
73  			flavors= new DataFlavor[f.length];
74  			System.arraycopy(f, 0, flavors, 0, f.length);
75  		} else {
76  			DataFlavor[] ff= new DataFlavor[f.length+flavors.length];
77  			System.arraycopy(f, 0, ff, 0, f.length);
78  			System.arraycopy(flavors, 0, ff, f.length, flavors.length);
79  		}
80  	}
81  
82  	/* (non-Javadoc)
83  	 * @see com.cosylab.gui.components.util.CosyTransferHandler#getTransferData(java.awt.datatransfer.DataFlavor)
84  	 */
85  	@Override
86  	public Object getTransferData(DataFlavor flavor)
87  			throws UnsupportedFlavorException, IOException {
88  		if (DataFlavor.stringFlavor.equals(flavor)) {
89  			DisplayerParameters p= exportDisplayerParameters();
90  			if (p!=null) {
91  				return p.toString();
92  			}
93  		}
94  		if (flavor instanceof DisplayerParametersFlavor) {
95  			DisplayerParameters p= exportDisplayerParameters();
96  			return p;
97  		}		
98  		throw new UnsupportedFlavorException(flavor);
99  	}
100 
101 	abstract protected DisplayerParameters exportDisplayerParameters();
102 
103 	/* (non-Javadoc)
104 	 * @see com.cosylab.gui.components.util.CosyTransferHandler#getTransferDataFlavors()
105 	 */
106 	@Override
107 	public DataFlavor[] getTransferDataFlavors() {
108 		return flavors;
109 	}
110 
111 	/* (non-Javadoc)
112 	 * @see javax.swing.TransferHandler#importData(javax.swing.JComponent, java.awt.datatransfer.Transferable)
113 	 */
114 	@Override
115 	public boolean importData(JComponent comp, Transferable t) {
116 		try {
117 			Object drop=null;
118 			if (t.isDataFlavorSupported(DisplayerParametersFlavor.FLAVOR)) {
119 				drop = t.getTransferData(DisplayerParametersFlavor.FLAVOR);
120 				DisplayerParameters[] dp = null;
121 				dp = castParameters(drop);
122 				if (dp!=null) {
123 					return importDisplayerParameters(dp);
124 				}
125 			}
126 			if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
127 				drop = t.getTransferData(DataFlavor.stringFlavor);
128 				if (drop!=null) {
129 					return importString(drop.toString());
130 				}
131 			}			
132 		} catch (Exception e) {
133 			e.printStackTrace();
134 		}
135 		
136 		return false;
137 	}
138 	
139 	protected boolean importString(String string) throws PropertyVetoException {
140 		return false;
141 	}
142 
143 	protected DisplayerParameters[] castParameters(Object... parameters) {
144 		if (parameters instanceof DisplayerParameters[]) {
145 			return (DisplayerParameters[])parameters.getClass().cast(parameters);
146 		} else if (parameters.length == 1) {
147 			if (parameters[0] instanceof DisplayerParameters[]) {
148 				return (DisplayerParameters[]) parameters[0];
149 			} else if (parameters[0] instanceof DisplayerParameters) {
150 				return new DisplayerParameters[] {(DisplayerParameters)parameters[0]};
151 			}
152 		}
153 		return null;
154 	}
155 	
156 	/**
157 	 * @param dp
158 	 * @throws PropertyVetoException 
159 	 */
160 	protected boolean importDisplayerParameters(DisplayerParameters[] dp) throws PropertyVetoException {
161 		int i= selectParameters((Component)displayer,dp);
162 		if (i<0) {
163 			return false;
164 		}
165 		return setParametersToDisplayer(displayer,dp[i]);
166 	}
167 
168 	protected DisplayerParametersSelectorDialog getParameterSelectionDialog() {
169 		if (dialog == null) {
170 			dialog = new DisplayerParametersSelectorDialog(displayer, "Adding Source", "Select Source:");
171 		}
172 		return dialog;
173 	}
174 	
175 	protected int selectParameters(Component c,DisplayerParameters[] dp) {
176 		return getParameterSelectionDialog().showSelectionDialog(c,dp);
177 	}
178 
179 	protected int selectParameters(Component c,String[] dp) {
180 		return getParameterSelectionDialog().showSelectionDialog(c,dp);
181 	}
182 	
183 	/**
184 	 * Sets the supplied parameters to the displayer.
185 	 * 
186 	 * @param disp destination displayer
187 	 * @param parameters parameters to be set
188 	 * @return true if successful
189 	 * 
190 	 * @throws PropertyVetoException when setting of parameters failed
191 	 */
192 	public boolean setParametersToDisplayer(Object disp, DisplayerParameters parameters) throws PropertyVetoException {
193 		String[] n= parameters.getNames();
194 		Object[] o= parameters.getValues();
195 		
196 		for (int i = 0; i < n.length; i++) {
197 			if (o[i]!=null && (!(o[i] instanceof Double) || !((Double)o[i]).isNaN())) {
198 				try {
199 					BeanIntrospector.setPropertyValue(disp,n[i],o[i]);
200 				} catch(NoSuchMethodException e) {
201 					//do nothing
202 				} catch (Exception e) {
203 					throw new PropertyVetoException("Property '"+n[i]+"' not set: "+e.getMessage(),new PropertyChangeEvent(disp,n[i],null,o[i]));
204 				}
205 			}
206 		}
207 		return true;
208 	}
209 	
210 	/**
211 	 * Returns the displayer.
212 	 * @return Returns the displayer.
213 	 */
214 	public JComponent getComponent() {
215 		return displayer;
216 	}
217 	
218 	/*
219 	 * (non-Javadoc)
220 	 * @see com.cosylab.gui.components.util.CosyTransferHandler#canImport(javax.swing.JComponent, java.awt.datatransfer.DataFlavor[])
221 	 */
222 	@Override
223 	public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
224 		return super.canImport(comp, transferFlavors) & !isDragging;
225 	}
226 }