svn-gvsig-desktop / tags / v1_0_2_Build_892 / libraries / libUI / src / org / gvsig / gui / beans / controls / dnd / JDnDTable.java @ 10278
History | View | Annotate | Download (10.9 KB)
1 | 7451 | jaume | /* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|---|---|
2 | *
|
||
3 | * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
|
||
4 | *
|
||
5 | * This program is free software; you can redistribute it and/or
|
||
6 | * modify it under the terms of the GNU General Public License
|
||
7 | * as published by the Free Software Foundation; either version 2
|
||
8 | * of the License, or (at your option) any later version.
|
||
9 | *
|
||
10 | * This program is distributed in the hope that it will be useful,
|
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
13 | * GNU General Public License for more details.
|
||
14 | *
|
||
15 | * You should have received a copy of the GNU General Public License
|
||
16 | * along with this program; if not, write to the Free Software
|
||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
||
18 | *
|
||
19 | * For more information, contact:
|
||
20 | *
|
||
21 | * Generalitat Valenciana
|
||
22 | * Conselleria d'Infraestructures i Transport
|
||
23 | * Av. Blasco Ib??ez, 50
|
||
24 | * 46010 VALENCIA
|
||
25 | * SPAIN
|
||
26 | *
|
||
27 | * +34 963862235
|
||
28 | * gvsig@gva.es
|
||
29 | * www.gvsig.gva.es
|
||
30 | *
|
||
31 | * or
|
||
32 | *
|
||
33 | * IVER T.I. S.A
|
||
34 | * Salamanca 50
|
||
35 | * 46005 Valencia
|
||
36 | * Spain
|
||
37 | *
|
||
38 | * +34 963163400
|
||
39 | * dac@iver.es
|
||
40 | */
|
||
41 | |||
42 | /* CVS MESSAGES:
|
||
43 | *
|
||
44 | * $Id$
|
||
45 | * $Log$
|
||
46 | 9037 | ppiqueras | * Revision 1.1.2.3 2006-11-28 09:46:36 ppiqueras
|
47 | * Actualizaci?n desde HEAD a v10 de libUI fruto de cambio de dependencia de libUI con el proyecto _fwAndami. (cambiado PluginServices.getText(..., ...) por Messages.getText(...)
|
||
48 | 7451 | jaume | *
|
49 | 8767 | jjdelcerro | * Revision 1.1 2006/09/21 16:35:12 jaume
|
50 | * *** empty log message ***
|
||
51 | 7451 | jaume | *
|
52 | 8767 | jjdelcerro | *
|
53 | 7451 | jaume | */
|
54 | package org.gvsig.gui.beans.controls.dnd; |
||
55 | |||
56 | import java.awt.Component; |
||
57 | import java.awt.Point; |
||
58 | import java.awt.datatransfer.DataFlavor; |
||
59 | import java.awt.datatransfer.StringSelection; |
||
60 | import java.awt.datatransfer.Transferable; |
||
61 | import java.awt.datatransfer.UnsupportedFlavorException; |
||
62 | import java.awt.dnd.DnDConstants; |
||
63 | import java.awt.dnd.DragGestureEvent; |
||
64 | import java.awt.dnd.DragGestureListener; |
||
65 | import java.awt.dnd.DragSource; |
||
66 | import java.awt.dnd.DragSourceDragEvent; |
||
67 | import java.awt.dnd.DragSourceDropEvent; |
||
68 | import java.awt.dnd.DragSourceEvent; |
||
69 | import java.awt.dnd.DragSourceListener; |
||
70 | import java.awt.dnd.DropTarget; |
||
71 | import java.awt.dnd.DropTargetDragEvent; |
||
72 | import java.awt.dnd.DropTargetDropEvent; |
||
73 | import java.awt.dnd.DropTargetEvent; |
||
74 | import java.awt.dnd.DropTargetListener; |
||
75 | import java.awt.geom.Point2D; |
||
76 | import java.io.IOException; |
||
77 | import java.util.ArrayList; |
||
78 | import java.util.StringTokenizer; |
||
79 | |||
80 | import javax.swing.JTable; |
||
81 | import javax.swing.table.TableCellRenderer; |
||
82 | /**
|
||
83 | * Preten ser una taula que accepte arrossegar i soltar. Ja mou coses i aix?
|
||
84 | * per? encara est? en proves.
|
||
85 | *
|
||
86 | * La intenci? ?s que pugues moure columnes, per? una volta posats, que moga
|
||
87 | * l?nies i cel?les lliurement.
|
||
88 | * @author jaume dominguez faus - jaume.dominguez@iver.es
|
||
89 | *
|
||
90 | */
|
||
91 | public class JDnDTable extends JTable implements DragSourceListener, |
||
92 | DragGestureListener, DropTargetListener{ |
||
93 | |||
94 | private CellCoordinates overCellCoordinates = null; |
||
95 | private DragSource dragSource; |
||
96 | private DropTarget dropTarget; |
||
97 | private CellCoordinates[] selectedCells; |
||
98 | private boolean dragging; |
||
99 | private CellCoordinates currSelectedCell;
|
||
100 | static final short FREE_CELL_MOVING = -4; |
||
101 | public static final short ONLY_ALLOW_MOVING_ROWS = -2; |
||
102 | public static final short ONLY_ALLOW_MOVING_COLUMNS = -1; |
||
103 | |||
104 | |||
105 | |||
106 | public JDnDTable() {
|
||
107 | // Configure ourselves to be a drag source
|
||
108 | dragSource = new DragSource(); |
||
109 | dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, this); |
||
110 | |||
111 | // Configure ourselves to be a drop target
|
||
112 | dropTarget = new DropTarget(this, this); |
||
113 | } |
||
114 | |||
115 | public JDnDTable( JDnDTableModel model ) {
|
||
116 | super( model );
|
||
117 | // Configure ourselves to be a drag source
|
||
118 | dragSource = new DragSource(); |
||
119 | dragSource.createDefaultDragGestureRecognizer( this, DnDConstants.ACTION_MOVE, this); |
||
120 | |||
121 | // Configure ourselves to be a drop target
|
||
122 | dropTarget = new DropTarget( this, this ); |
||
123 | } |
||
124 | |||
125 | public void dragEnter(DragSourceDragEvent dsde) { |
||
126 | Point thisLocation = this.getLocationOnScreen(); |
||
127 | Point clickLocation = dsde.getLocation();
|
||
128 | |||
129 | Point2D relativeLocation = new Point2D.Double( |
||
130 | (clickLocation.getX() - thisLocation.getX()), |
||
131 | (clickLocation.getY() - thisLocation.getY())); |
||
132 | |||
133 | this.overCellCoordinates = locationToCellCoord(relativeLocation);
|
||
134 | } |
||
135 | |||
136 | public void setSelectionMode(short mode) { |
||
137 | if (mode == ONLY_ALLOW_MOVING_COLUMNS) {
|
||
138 | setColumnSelectionAllowed(true);
|
||
139 | setRowSelectionAllowed(false);
|
||
140 | } else if ( mode == ONLY_ALLOW_MOVING_ROWS) { |
||
141 | setColumnSelectionAllowed(false);
|
||
142 | setRowSelectionAllowed(true);
|
||
143 | } |
||
144 | ((JDnDTableModel) this.getModel()).setSelectionMode(mode);
|
||
145 | } |
||
146 | private CellCoordinates locationToCellCoord(Point2D location) { |
||
147 | |||
148 | int[] ij = new int[2]; |
||
149 | int width = (int) location.getX(); |
||
150 | int height = (int) location.getY(); |
||
151 | |||
152 | for (int i = 0; i < this.getColumnCount(); i++) { |
||
153 | int iColumnWidth = this.getColumnModel().getColumn(i).getWidth(); |
||
154 | // it seems to be right, but just in case consideer to use:
|
||
155 | // ? int iColumnWidth = this.getColumnModel().getColumn(i).getPreferredWidth();
|
||
156 | if ((width - iColumnWidth) <= 0) { |
||
157 | ij[1] = i;
|
||
158 | break;
|
||
159 | } |
||
160 | width = width - iColumnWidth; |
||
161 | } |
||
162 | |||
163 | // Get the current default height for all rows
|
||
164 | int jRowHeight = this.getRowHeight(); |
||
165 | for (int j = 0; j < this.getRowCount(); j++) { |
||
166 | // Determine highest cell in the row
|
||
167 | for (int c=0; c<this.getColumnCount(); c++) { |
||
168 | TableCellRenderer renderer = this.getCellRenderer(j, c); |
||
169 | Component comp = this.prepareRenderer(renderer, j, c); |
||
170 | int h = comp.getPreferredSize().height - 2*rowMargin; |
||
171 | jRowHeight = Math.max(jRowHeight, h);
|
||
172 | } |
||
173 | |||
174 | if ((height - jRowHeight) <= 0) { |
||
175 | ij[0] = j;
|
||
176 | break;
|
||
177 | } |
||
178 | height = height - jRowHeight; |
||
179 | } |
||
180 | |||
181 | return new CellCoordinates(ij[0], ij[1]); |
||
182 | } |
||
183 | |||
184 | |||
185 | public void dragOver(DragSourceDragEvent dsde) { |
||
186 | // TODO Auto-generated method stub
|
||
187 | } |
||
188 | |||
189 | public void dropActionChanged(DragSourceDragEvent dsde) { |
||
190 | // TODO Auto-generated method stub
|
||
191 | } |
||
192 | |||
193 | public void dragDropEnd(DragSourceDropEvent dsde) { |
||
194 | System.out.println("dragDropEnd"); |
||
195 | this.dragging = false; |
||
196 | } |
||
197 | |||
198 | public void dragExit(DragSourceEvent dse) { |
||
199 | this.overCellCoordinates = null; |
||
200 | } |
||
201 | |||
202 | public void dragGestureRecognized(DragGestureEvent dge) { |
||
203 | // TODO Auto-generated method stub
|
||
204 | this.selectedCells = this.getSelectedCells(); |
||
205 | Object[] selectedObjects = this.getSelectedValues(); |
||
206 | if (selectedObjects.length>0) { |
||
207 | StringBuffer sb = new StringBuffer(); |
||
208 | for( int i=0; i<selectedObjects.length; i++ ) { |
||
209 | sb.append( selectedObjects[ i ].toString() + "\n" );
|
||
210 | } |
||
211 | |||
212 | // Build a StringSelection object that the Drag Source
|
||
213 | // can use to transport a string to the Drop Target
|
||
214 | StringSelection text = new StringSelection( sb.toString() ); |
||
215 | |||
216 | // Start dragging the object
|
||
217 | this.dragging = true; |
||
218 | dragSource.startDrag( dge, DragSource.DefaultMoveDrop, text, this ); |
||
219 | System.err.println("Selected objects\n"+sb.toString()); |
||
220 | } |
||
221 | } |
||
222 | |||
223 | private Object[] getSelectedValues() { |
||
224 | ArrayList values = new ArrayList(selectedCells.length); |
||
225 | for (int i = 0; i < selectedCells.length; i++) { |
||
226 | values.add(this.getValueAt(selectedCells[i].i, selectedCells[i].j));
|
||
227 | } |
||
228 | return values.toArray();
|
||
229 | } |
||
230 | |||
231 | private CellCoordinates[] getSelectedCells() { |
||
232 | ArrayList cells = new ArrayList(); |
||
233 | for (int i = 0; i < this.getColumnCount(); i++) { |
||
234 | for (int j = 0; j < this.getRowCount(); j++) { |
||
235 | if (this.isCellSelected(i, j)) |
||
236 | cells.add( new CellCoordinates(i,j) );
|
||
237 | } |
||
238 | } |
||
239 | return (CellCoordinates[]) cells.toArray(new CellCoordinates[0]); |
||
240 | } |
||
241 | |||
242 | public void dragEnter(DropTargetDragEvent dtde) { |
||
243 | // TODO
|
||
244 | System.out.println("dragEnter"); |
||
245 | } |
||
246 | |||
247 | public void dragOver(DropTargetDragEvent dtde) { |
||
248 | // See who we are over...
|
||
249 | CellCoordinates overCellCoordinates = this.locationToCellCoord( dtde.getLocation());
|
||
250 | if( overCellCoordinates != null && !overCellCoordinates.equals(this.overCellCoordinates) ) { |
||
251 | // If the value has changed from what we were previously over
|
||
252 | // then change the selected object to the one we are over; this
|
||
253 | // is a visual representation that this is where the drop will occur
|
||
254 | this.overCellCoordinates = overCellCoordinates;
|
||
255 | |||
256 | currSelectedCell = this.overCellCoordinates;
|
||
257 | System.out.println("Current cell ["+currSelectedCell.i+","+currSelectedCell.j+"]"); |
||
258 | |||
259 | } |
||
260 | } |
||
261 | |||
262 | public void dropActionChanged(DropTargetDragEvent dtde) { |
||
263 | // TODO Auto-generated method stub
|
||
264 | } |
||
265 | |||
266 | public void drop(DropTargetDropEvent dtde) { |
||
267 | try {
|
||
268 | Transferable transferable = dtde.getTransferable();
|
||
269 | if( transferable.isDataFlavorSupported( DataFlavor.stringFlavor ) ) { |
||
270 | dtde.acceptDrop( DnDConstants.ACTION_MOVE );
|
||
271 | |||
272 | // Find out where the item was dropped
|
||
273 | CellCoordinates newCellCoord = locationToCellCoord(dtde.getLocation()); |
||
274 | |||
275 | // Get the items out of the transferable object and build an
|
||
276 | // array out of them...
|
||
277 | String s = ( String ) transferable.getTransferData( DataFlavor.stringFlavor ); |
||
278 | StringTokenizer st = new StringTokenizer( s ); |
||
279 | ArrayList items = new ArrayList(); |
||
280 | while( st.hasMoreTokens() ) {
|
||
281 | items.add( st.nextToken() ); |
||
282 | } |
||
283 | |||
284 | JDnDTableModel model = (JDnDTableModel) this.getModel();
|
||
285 | |||
286 | // If we are dragging from our this to our list them move the items,
|
||
287 | // otherwise just add them...
|
||
288 | if( this.dragging ) { |
||
289 | //model.itemsMoved( newIndex, items );
|
||
290 | model.itemsMoved( newCellCoord, this.selectedCells );
|
||
291 | } else {
|
||
292 | model.insertItems( newCellCoord, items ); |
||
293 | } |
||
294 | |||
295 | // Update the selected cells
|
||
296 | /* TODO
|
||
297 | int[] newIndicies = new int[ items.size() ];
|
||
298 | for( int i=0; i<items.size(); i++ ) {
|
||
299 | newIndicies[ i ] = newIndex + i;
|
||
300 | }
|
||
301 | this.setSelectedIndices( newIndicies );
|
||
302 | */
|
||
303 | // Reset the over index
|
||
304 | this.overCellCoordinates = null; |
||
305 | |||
306 | dtde.getDropTargetContext().dropComplete( true );
|
||
307 | } else {
|
||
308 | dtde.rejectDrop(); |
||
309 | } |
||
310 | } catch( IOException exception ) { |
||
311 | exception.printStackTrace(); |
||
312 | System.err.println( "Exception" + exception.getMessage()); |
||
313 | dtde.rejectDrop(); |
||
314 | } catch( UnsupportedFlavorException ufException ) { |
||
315 | ufException.printStackTrace(); |
||
316 | System.err.println( "Exception" + ufException.getMessage()); |
||
317 | dtde.rejectDrop(); |
||
318 | } |
||
319 | } |
||
320 | |||
321 | public void dragExit(DropTargetEvent dte) { |
||
322 | // TODO Auto-generated method stub
|
||
323 | System.out.println("dragExit"); |
||
324 | } |
||
325 | |||
326 | } |
||
327 | |||
328 | class CellCoordinates { |
||
329 | int i, j;
|
||
330 | |||
331 | public CellCoordinates(int i, int j) { |
||
332 | this.i = i;
|
||
333 | this.j = j;
|
||
334 | } |
||
335 | |||
336 | public boolean equals(Object obj) { |
||
337 | if (!(obj instanceof CellCoordinates)) |
||
338 | return false; |
||
339 | |||
340 | CellCoordinates other = (CellCoordinates) obj; |
||
341 | return (this.i == other.i) && (this.j == other.j); |
||
342 | } |
||
343 | } |