Statistics
| Revision:

root / trunk / libraries / libUIComponent / src / org / gvsig / gui / beans / controls / dnd / JDnDTable.java @ 13198

History | View | Annotate | Download (10.8 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 13198 2007-08-21 09:57:17Z bsanchez $
45
* $Log$
46
* Revision 1.2  2007-08-21 09:56:44  bsanchez
47
* - Variable no usada
48
*
49
* Revision 1.1  2007/08/20 08:34:46  evercher
50
* He fusionado LibUI con LibUIComponents
51
*
52
* Revision 1.1  2006/09/21 16:35:12  jaume
53
* *** empty log message ***
54
*
55
*
56
*/
57
package org.gvsig.gui.beans.controls.dnd;
58

    
59
import java.awt.Component;
60
import java.awt.Point;
61
import java.awt.datatransfer.DataFlavor;
62
import java.awt.datatransfer.StringSelection;
63
import java.awt.datatransfer.Transferable;
64
import java.awt.datatransfer.UnsupportedFlavorException;
65
import java.awt.dnd.DnDConstants;
66
import java.awt.dnd.DragGestureEvent;
67
import java.awt.dnd.DragGestureListener;
68
import java.awt.dnd.DragSource;
69
import java.awt.dnd.DragSourceDragEvent;
70
import java.awt.dnd.DragSourceDropEvent;
71
import java.awt.dnd.DragSourceEvent;
72
import java.awt.dnd.DragSourceListener;
73
import java.awt.dnd.DropTarget;
74
import java.awt.dnd.DropTargetDragEvent;
75
import java.awt.dnd.DropTargetDropEvent;
76
import java.awt.dnd.DropTargetEvent;
77
import java.awt.dnd.DropTargetListener;
78
import java.awt.geom.Point2D;
79
import java.io.IOException;
80
import java.util.ArrayList;
81
import java.util.StringTokenizer;
82

    
83
import javax.swing.JTable;
84
import javax.swing.table.TableCellRenderer;
85
/**
86
 * Preten ser una taula que accepte arrossegar i soltar. Ja mou coses i aix?
87
 * per? encara est? en proves.
88
 *
89
 * La intenci? ?s que pugues moure columnes, per? una volta posats, que moga
90
 * l?nies i cel?les lliurement.
91
 * @author jaume dominguez faus - jaume.dominguez@iver.es
92
 *
93
 */
94
public class JDnDTable extends JTable implements DragSourceListener,
95
                                                                DragGestureListener, DropTargetListener{
96

    
97
        private CellCoordinates        overCellCoordinates = null;
98
        private DragSource        dragSource;
99
        private CellCoordinates[]        selectedCells;
100
        private boolean        dragging;
101
        private CellCoordinates currSelectedCell;
102
        static final short FREE_CELL_MOVING = -4;
103
        public static final short ONLY_ALLOW_MOVING_ROWS = -2;
104
        public static final short ONLY_ALLOW_MOVING_COLUMNS = -1;
105

    
106

    
107

    
108
        public JDnDTable() {
109
                // Configure ourselves to be a drag source
110
                dragSource = new DragSource();
111
                dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, this);
112

    
113
                // Configure ourselves to be a drop target
114
                new DropTarget(this, this);
115
        }
116

    
117
        public JDnDTable( JDnDTableModel model ) {
118
        super( model );
119
        // Configure ourselves to be a drag source
120
        dragSource = new DragSource();
121
        dragSource.createDefaultDragGestureRecognizer( this, DnDConstants.ACTION_MOVE, this);
122

    
123
        // Configure ourselves to be a drop target
124
        new DropTarget( this, this );
125
    }
126

    
127
        public void dragEnter(DragSourceDragEvent dsde) {
128
                Point thisLocation = this.getLocationOnScreen();
129
                Point clickLocation = dsde.getLocation();
130

    
131
                Point2D relativeLocation = new Point2D.Double(
132
                                (clickLocation.getX() - thisLocation.getX()),
133
                                (clickLocation.getY() - thisLocation.getY()));
134

    
135
                this.overCellCoordinates = locationToCellCoord(relativeLocation);
136
        }
137

    
138
        public void setSelectionMode(short mode) {
139
                if (mode == ONLY_ALLOW_MOVING_COLUMNS) {
140
                        setColumnSelectionAllowed(true);
141
                        setRowSelectionAllowed(false);
142
                } else if ( mode == ONLY_ALLOW_MOVING_ROWS) {
143
                        setColumnSelectionAllowed(false);
144
                        setRowSelectionAllowed(true);
145
                }
146
                ((JDnDTableModel) this.getModel()).setSelectionMode(mode);
147
        }
148
        private CellCoordinates locationToCellCoord(Point2D location) {
149

    
150
                int[] ij = new int[2];
151
                int width = (int) location.getX();
152
                int height = (int) location.getY();
153

    
154
                for (int i = 0; i < this.getColumnCount(); i++) {
155
                        int iColumnWidth = this.getColumnModel().getColumn(i).getWidth();
156
                        // it seems to be right, but just in case consideer to use:
157
                        // ? int iColumnWidth = this.getColumnModel().getColumn(i).getPreferredWidth();
158
                        if ((width - iColumnWidth) <= 0) {
159
                                ij[1] = i;
160
                                break;
161
                        }
162
                        width = width - iColumnWidth;
163
                }
164

    
165
                // Get the current default height for all rows
166
        int jRowHeight = this.getRowHeight();
167
                for (int j = 0; j < this.getRowCount(); j++) {
168
                // Determine highest cell in the row
169
                for (int c=0; c<this.getColumnCount(); c++) {
170
                    TableCellRenderer renderer = this.getCellRenderer(j, c);
171
                    Component comp = this.prepareRenderer(renderer, j, c);
172
                    int h = comp.getPreferredSize().height - 2*rowMargin;
173
                    jRowHeight = Math.max(jRowHeight, h);
174
                }
175

    
176
                if ((height - jRowHeight) <= 0) {
177
                        ij[0] = j;
178
                        break;
179
                }
180
                height = height - jRowHeight;
181
                }
182

    
183
                return new CellCoordinates(ij[0], ij[1]);
184
        }
185

    
186

    
187
        public void dragOver(DragSourceDragEvent dsde) {
188
                // TODO Auto-generated method stub
189
        }
190

    
191
        public void dropActionChanged(DragSourceDragEvent dsde) {
192
                // TODO Auto-generated method stub
193
        }
194

    
195
        public void dragDropEnd(DragSourceDropEvent dsde) {
196
                System.out.println("dragDropEnd");
197
                this.dragging = false;
198
        }
199

    
200
        public void dragExit(DragSourceEvent dse) {
201
                this.overCellCoordinates = null;
202
        }
203

    
204
        public void dragGestureRecognized(DragGestureEvent dge) {
205
                // TODO Auto-generated method stub
206
                this.selectedCells = this.getSelectedCells();
207
                Object[] selectedObjects = this.getSelectedValues();
208
                if (selectedObjects.length>0) {
209
                        StringBuffer sb = new StringBuffer();
210
            for( int i=0; i<selectedObjects.length; i++ ) {
211
                sb.append( selectedObjects[ i ].toString() + "\n" );
212
            }
213

    
214
            // Build a StringSelection object that the Drag Source
215
            // can use to transport a string to the Drop Target
216
            StringSelection text = new StringSelection( sb.toString() );
217

    
218
            // Start dragging the object
219
            this.dragging = true;
220
            dragSource.startDrag( dge, DragSource.DefaultMoveDrop, text, this );
221
            System.err.println("Selected objects\n"+sb.toString());
222
                }
223
        }
224

    
225
        private Object[] getSelectedValues() {
226
                ArrayList values = new ArrayList(selectedCells.length);
227
                for (int i = 0; i < selectedCells.length; i++) {
228
                        values.add(this.getValueAt(selectedCells[i].i, selectedCells[i].j));
229
                }
230
                return values.toArray();
231
        }
232

    
233
        private CellCoordinates[] getSelectedCells() {
234
                ArrayList cells = new ArrayList();
235
                for (int i = 0; i < this.getColumnCount(); i++) {
236
                        for (int j = 0; j < this.getRowCount(); j++) {
237
                                if (this.isCellSelected(i, j))
238
                                        cells.add( new CellCoordinates(i,j) );
239
                        }
240
                }
241
                return (CellCoordinates[]) cells.toArray(new CellCoordinates[0]);
242
        }
243

    
244
        public void dragEnter(DropTargetDragEvent dtde) {
245
                // TODO
246
                System.out.println("dragEnter");
247
        }
248

    
249
        public void dragOver(DropTargetDragEvent dtde) {
250
                 // See who we are over...
251
                CellCoordinates overCellCoordinates = this.locationToCellCoord( dtde.getLocation());
252
        if( overCellCoordinates != null && !overCellCoordinates.equals(this.overCellCoordinates) ) {
253
            // If the value has changed from what we were previously over
254
            // then change the selected object to the one we are over; this
255
            // is a visual representation that this is where the drop will occur
256
            this.overCellCoordinates = overCellCoordinates;
257

    
258
            currSelectedCell = this.overCellCoordinates;
259
            System.out.println("Current cell  ["+currSelectedCell.i+","+currSelectedCell.j+"]");
260

    
261
        }
262
        }
263

    
264
        public void dropActionChanged(DropTargetDragEvent dtde) {
265
                // TODO Auto-generated method stub
266
        }
267

    
268
        public void drop(DropTargetDropEvent dtde) {
269
                try {
270
                        Transferable transferable = dtde.getTransferable();
271
                        if( transferable.isDataFlavorSupported( DataFlavor.stringFlavor ) ) {
272
                                dtde.acceptDrop( DnDConstants.ACTION_MOVE );
273

    
274
                                // Find out where the item was dropped
275
                                CellCoordinates newCellCoord = locationToCellCoord(dtde.getLocation());
276

    
277
                                // Get the items out of the transferable object and build an
278
                                // array out of them...
279
                                String s = ( String ) transferable.getTransferData( DataFlavor.stringFlavor );
280
                                StringTokenizer st = new StringTokenizer( s );
281
                                ArrayList items = new ArrayList();
282
                                while( st.hasMoreTokens() ) {
283
                                        items.add( st.nextToken() );
284
                                }
285

    
286
                                JDnDTableModel model = (JDnDTableModel) this.getModel();
287

    
288
                // If we are dragging from our this to our list them move the items,
289
                // otherwise just add them...
290
                if( this.dragging ) {
291
                    //model.itemsMoved( newIndex, items );
292
                    model.itemsMoved( newCellCoord, this.selectedCells );
293
                } else {
294
                    model.insertItems( newCellCoord, items );
295
                }
296

    
297
                // Update the selected cells
298
                /* TODO
299
                int[] newIndicies = new int[ items.size() ];
300
                for( int i=0; i<items.size(); i++ ) {
301
                    newIndicies[ i ] = newIndex + i;
302
                }
303
                this.setSelectedIndices( newIndicies );
304
                */
305
                // Reset the over index
306
                this.overCellCoordinates = null;
307

    
308
                dtde.getDropTargetContext().dropComplete( true );
309
                        } else {
310
                                dtde.rejectDrop();
311
                        }
312
                } catch( IOException exception ) {
313
                        exception.printStackTrace();
314
                        System.err.println( "Exception" + exception.getMessage());
315
                        dtde.rejectDrop();
316
                } catch( UnsupportedFlavorException ufException ) {
317
                        ufException.printStackTrace();
318
                        System.err.println( "Exception" + ufException.getMessage());
319
                        dtde.rejectDrop();
320
                }
321
        }
322

    
323
        public void dragExit(DropTargetEvent dte) {
324
                // TODO Auto-generated method stub
325
                System.out.println("dragExit");
326
        }
327

    
328
}
329

    
330
class CellCoordinates {
331
        int i, j;
332

    
333
        public CellCoordinates(int i, int j) {
334
                this.i = i;
335
                this.j = j;
336
        }
337

    
338
        public boolean equals(Object obj) {
339
                if (!(obj instanceof CellCoordinates))
340
                        return false;
341

    
342
                CellCoordinates other = (CellCoordinates) obj;
343
                return (this.i == other.i) && (this.j == other.j);
344
        }
345
}