Statistics
| Revision:

svn-gvsig-desktop / tags / v1_0_2_Build_903 / libraries / libUI / src / org / gvsig / gui / beans / controls / dnd / JDnDTable.java @ 10704

History | View | Annotate | Download (10.9 KB)

1
/* 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: JDnDTable.java 10704 2007-03-12 12:06:33Z  $
45
* $Log$
46
* 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
*
49
* Revision 1.1  2006/09/21 16:35:12  jaume
50
* *** empty log message ***
51
*
52
*
53
*/
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
}