root / tags / v1_0_2_Build_916 / extensions / extGeoProcessing / src / com / iver / cit / gvsig / geoprocess / core / gui / AbstractGeoprocessGridbagPanel.java @ 12327
History | View | Annotate | Download (15.1 KB)
1 | 6746 | azabala | /*
|
---|---|---|---|
2 | * Created on 30-jun-2006
|
||
3 | *
|
||
4 | * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
||
5 | *
|
||
6 | * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
|
||
7 | *
|
||
8 | * This program is free software; you can redistribute it and/or
|
||
9 | * modify it under the terms of the GNU General Public License
|
||
10 | * as published by the Free Software Foundation; either version 2
|
||
11 | * of the License, or (at your option) any later version.
|
||
12 | *
|
||
13 | * This program is distributed in the hope that it will be useful,
|
||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
16 | * GNU General Public License for more details.
|
||
17 | *
|
||
18 | * You should have received a copy of the GNU General Public License
|
||
19 | * along with this program; if not, write to the Free Software
|
||
20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
||
21 | *
|
||
22 | * For more information, contact:
|
||
23 | *
|
||
24 | * Generalitat Valenciana
|
||
25 | * Conselleria d'Infraestructures i Transport
|
||
26 | * Av. Blasco Ib??ez, 50
|
||
27 | * 46010 VALENCIA
|
||
28 | * SPAIN
|
||
29 | *
|
||
30 | * +34 963862235
|
||
31 | * gvsig@gva.es
|
||
32 | * www.gvsig.gva.es
|
||
33 | *
|
||
34 | * or
|
||
35 | *
|
||
36 | * IVER T.I. S.A
|
||
37 | * Salamanca 50
|
||
38 | * 46005 Valencia
|
||
39 | * Spain
|
||
40 | *
|
||
41 | * +34 963163400
|
||
42 | * dac@iver.es
|
||
43 | */
|
||
44 | /* CVS MESSAGES:
|
||
45 | *
|
||
46 | * $Id$
|
||
47 | * $Log$
|
||
48 | 8765 | jjdelcerro | * Revision 1.1.2.1 2006-11-15 00:08:17 jjdelcerro
|
49 | * *** empty log message ***
|
||
50 | *
|
||
51 | * Revision 1.2 2006/09/15 10:42:54 caballero
|
||
52 | * extensibilidad de documentos
|
||
53 | *
|
||
54 | * Revision 1.1 2006/08/11 16:11:38 azabala
|
||
55 | 6746 | azabala | * first version in cvs
|
56 | *
|
||
57 | * Revision 1.2 2006/07/04 16:43:18 azabala
|
||
58 | * *** empty log message ***
|
||
59 | *
|
||
60 | * Revision 1.1 2006/07/03 20:28:20 azabala
|
||
61 | * *** empty log message ***
|
||
62 | *
|
||
63 | *
|
||
64 | */
|
||
65 | package com.iver.cit.gvsig.geoprocess.core.gui; |
||
66 | |||
67 | import java.awt.BorderLayout; |
||
68 | import java.awt.Component; |
||
69 | import java.awt.GridBagConstraints; |
||
70 | import java.awt.Insets; |
||
71 | import java.awt.Rectangle; |
||
72 | import java.awt.event.ItemEvent; |
||
73 | import java.awt.event.ItemListener; |
||
74 | import java.io.File; |
||
75 | import java.io.FileNotFoundException; |
||
76 | import java.util.ArrayList; |
||
77 | import java.util.Arrays; |
||
78 | |||
79 | import javax.swing.BorderFactory; |
||
80 | import javax.swing.DefaultComboBoxModel; |
||
81 | import javax.swing.JButton; |
||
82 | import javax.swing.JCheckBox; |
||
83 | import javax.swing.JComboBox; |
||
84 | import javax.swing.JFileChooser; |
||
85 | import javax.swing.JLabel; |
||
86 | import javax.swing.JOptionPane; |
||
87 | import javax.swing.JPanel; |
||
88 | import javax.swing.JTextField; |
||
89 | import javax.swing.border.EtchedBorder; |
||
90 | |||
91 | import org.gvsig.gui.beans.swing.GridBagLayoutPanel; |
||
92 | |||
93 | import com.iver.andami.PluginServices; |
||
94 | import com.iver.cit.gvsig.fmap.DriverException; |
||
95 | import com.iver.cit.gvsig.fmap.drivers.DriverIOException; |
||
96 | import com.iver.cit.gvsig.fmap.layers.FBitSet; |
||
97 | import com.iver.cit.gvsig.fmap.layers.FLayer; |
||
98 | import com.iver.cit.gvsig.fmap.layers.FLayers; |
||
99 | import com.iver.cit.gvsig.fmap.layers.FLyrVect; |
||
100 | import com.iver.cit.gvsig.fmap.layers.ReadableVectorial; |
||
101 | import com.iver.cit.gvsig.fmap.layers.layerOperations.SingleLayer; |
||
102 | 8765 | jjdelcerro | import com.iver.cit.gvsig.project.documents.view.legend.CreateSpatialIndexMonitorableTask; |
103 | 6746 | azabala | import com.iver.utiles.GenericFileFilter; |
104 | import com.iver.utiles.swing.threads.IMonitorableTask; |
||
105 | |||
106 | /**
|
||
107 | * Abstract base panel to easily build GeoprocessPanels
|
||
108 | * (View GUI component with which user could launch a given
|
||
109 | * geoprocess).
|
||
110 | *
|
||
111 | * All panels that extends this class will have a header
|
||
112 | * (textual label that describes the geoprocess).
|
||
113 | *
|
||
114 | * In the next row, they will have a layer combo box, where users could
|
||
115 | * select the input layer of the geoprocess (all geoprocesses at least
|
||
116 | * will work with an input layer), and a check box to specify working only
|
||
117 | * with input layer selection.
|
||
118 | *
|
||
119 | * Nex, each descendant panels must implement addSpecificDesign()
|
||
120 | * abstract method, to add specific components with which users could
|
||
121 | * introduce the information needed by the geoprocess.
|
||
122 | *
|
||
123 | * Finally, the last row has a panel to allow users to select where
|
||
124 | * to save the results of the geoprocess.
|
||
125 | *
|
||
126 | *
|
||
127 | *
|
||
128 | * @author azabala
|
||
129 | *
|
||
130 | */
|
||
131 | public abstract class AbstractGeoprocessGridbagPanel extends GridBagLayoutPanel implements |
||
132 | IGeoprocessPanel{ |
||
133 | |||
134 | protected final int DEFAULT_FILL = GridBagConstraints.BOTH; |
||
135 | |||
136 | /**
|
||
137 | * textual description of the associated geoprocess
|
||
138 | */
|
||
139 | protected String titleText; |
||
140 | |||
141 | /**
|
||
142 | * View's layers showed in TOC
|
||
143 | */
|
||
144 | protected FLayers layers;
|
||
145 | |||
146 | /**
|
||
147 | * Combo box to show layer names to user
|
||
148 | */
|
||
149 | protected JComboBox layersComboBox; |
||
150 | |||
151 | /**
|
||
152 | * Check box to specify that geoprocess will only process
|
||
153 | * input layer selection
|
||
154 | */
|
||
155 | protected JCheckBox selectedOnlyCheckBox; |
||
156 | |||
157 | /**
|
||
158 | * Shows the number of selected features of input layer
|
||
159 | */
|
||
160 | protected JLabel numSelectedLabel; |
||
161 | |||
162 | /**
|
||
163 | * Text field to show user the full path (or a representative string)
|
||
164 | * of the result layer selection
|
||
165 | */
|
||
166 | |||
167 | protected JTextField resultTf; |
||
168 | |||
169 | /**
|
||
170 | * Default constructor
|
||
171 | *
|
||
172 | */
|
||
173 | |||
174 | public AbstractGeoprocessGridbagPanel(FLayers layers, String titleText) { |
||
175 | super();
|
||
176 | this.layers = layers;
|
||
177 | this.titleText = titleText;
|
||
178 | initialize(); |
||
179 | } |
||
180 | |||
181 | protected void initialize(){ |
||
182 | Insets insets = new Insets(5, 5, 5, 5); |
||
183 | addComponent(new JLabel(titleText), insets); |
||
184 | JLabel firstLayerLab = new JLabel(PluginServices. |
||
185 | getText(this, "Cobertura_de_entrada")+":"); |
||
186 | JComboBox layersComboBox = getLayersComboBox();
|
||
187 | addComponent(firstLayerLab, layersComboBox, GridBagConstraints.BOTH, insets);
|
||
188 | addComponent(getSelectedOnlyCheckBox(), GridBagConstraints.BOTH, insets);
|
||
189 | |||
190 | String numSelectedText = PluginServices.
|
||
191 | getText(this, "Numero_de_elementos_seleccionados") + ":"; |
||
192 | numSelectedLabel = new JLabel("00"); |
||
193 | addComponent(numSelectedText, numSelectedLabel, insets); |
||
194 | |||
195 | addSpecificDesign(); |
||
196 | |||
197 | JPanel aux = new JPanel(new BorderLayout()); |
||
198 | String resultLayerText = PluginServices.
|
||
199 | getText(this, "Cobertura_de_salida") + ":"; |
||
200 | resultTf = getFileNameResultTextField(); |
||
201 | JButton openButton = getOpenResultButton();
|
||
202 | aux.add(resultTf, BorderLayout.WEST);
|
||
203 | aux.add(new JLabel(" "), BorderLayout.CENTER); |
||
204 | aux.add(openButton, BorderLayout.EAST);
|
||
205 | addComponent(resultLayerText, aux, GridBagConstraints.HORIZONTAL, insets );
|
||
206 | setBounds(0, 0, 520, 410); |
||
207 | } |
||
208 | |||
209 | |||
210 | protected void initSelectedItemsJCheckBox() { |
||
211 | String selectedLayer = (String) layersComboBox.getSelectedItem(); |
||
212 | FLyrVect inputLayer = (FLyrVect) layers.getLayer(selectedLayer); |
||
213 | FBitSet fBitSet = null;
|
||
214 | try {
|
||
215 | fBitSet = inputLayer.getRecordset().getSelection(); |
||
216 | } catch (DriverException e) {
|
||
217 | // TODO Auto-generated catch block
|
||
218 | e.printStackTrace(); |
||
219 | } |
||
220 | |||
221 | if (fBitSet.cardinality() == 0) { |
||
222 | selectedOnlyCheckBox.setEnabled(false);
|
||
223 | selectedOnlyCheckBox.setSelected(false);
|
||
224 | } else {
|
||
225 | selectedOnlyCheckBox.setEnabled(true);
|
||
226 | selectedOnlyCheckBox.setSelected(true);
|
||
227 | } |
||
228 | selectedOnlyCheckBox.setSelected(false);
|
||
229 | |||
230 | updateNumSelectedFeaturesLabel(); |
||
231 | } |
||
232 | |||
233 | |||
234 | protected void updateNumSelectedFeaturesLabel() { |
||
235 | if (selectedOnlyCheckBox.isSelected()) {
|
||
236 | FLyrVect inputSelectable = (FLyrVect)(layers.getLayer((String)layersComboBox.getSelectedItem()));
|
||
237 | FBitSet fBitSet = null;
|
||
238 | try {
|
||
239 | fBitSet = inputSelectable.getRecordset().getSelection(); |
||
240 | } catch (DriverException e) {
|
||
241 | // TODO Auto-generated catch block
|
||
242 | e.printStackTrace(); |
||
243 | } |
||
244 | numSelectedLabel.setText(new Integer(fBitSet.cardinality()).toString()); |
||
245 | } else {
|
||
246 | ReadableVectorial va = ((SingleLayer)(layers. |
||
247 | getLayer((String)layersComboBox.
|
||
248 | getSelectedItem()))). |
||
249 | getSource(); |
||
250 | try {
|
||
251 | numSelectedLabel.setText(new Integer(va.getShapeCount()).toString()); |
||
252 | } catch (DriverIOException e) {
|
||
253 | // TODO Auto-generated catch block
|
||
254 | e.printStackTrace(); |
||
255 | } |
||
256 | } |
||
257 | } |
||
258 | |||
259 | |||
260 | private JButton getOpenResultButton() { |
||
261 | JButton openResultButton = new JButton(); |
||
262 | openResultButton.setText(PluginServices.getText(this, "Abrir")); |
||
263 | openResultButton.addActionListener(new java.awt.event.ActionListener() {
|
||
264 | public void actionPerformed(java.awt.event.ActionEvent e) { |
||
265 | openResultFile(); |
||
266 | } |
||
267 | } |
||
268 | ); |
||
269 | return openResultButton;
|
||
270 | } |
||
271 | |||
272 | |||
273 | /**
|
||
274 | * This method must be overwrited by all descendant classes to
|
||
275 | * add specific desing of each Geoprocess Panel.
|
||
276 | */
|
||
277 | protected abstract void addSpecificDesign(); |
||
278 | |||
279 | /**
|
||
280 | * Returns the layer selected in layer combo box
|
||
281 | *
|
||
282 | * @return
|
||
283 | */
|
||
284 | public FLyrVect getInputLayer() {
|
||
285 | FLyrVect solution = null;
|
||
286 | String selectedLayer = (String) layersComboBox.getSelectedItem(); |
||
287 | solution = (FLyrVect) layers.getLayer(selectedLayer); |
||
288 | return solution;
|
||
289 | } |
||
290 | |||
291 | /**
|
||
292 | * Sets view's layers from the TOC
|
||
293 | *
|
||
294 | * @param layers
|
||
295 | */
|
||
296 | public void setFLayers(FLayers layers) { |
||
297 | this.layers = layers;
|
||
298 | } |
||
299 | |||
300 | /**
|
||
301 | * Returns layers.
|
||
302 | *
|
||
303 | * @return
|
||
304 | */
|
||
305 | public FLayers getFLayers() {
|
||
306 | return layers;
|
||
307 | } |
||
308 | |||
309 | /**
|
||
310 | * Filters TOC layers to get only FLyrVect layers.
|
||
311 | *
|
||
312 | * @param layers
|
||
313 | * @return
|
||
314 | *
|
||
315 | * FIXME Mover a una utility class
|
||
316 | */
|
||
317 | protected FLyrVect[] getVectorialLayers(FLayers layers) { |
||
318 | FLyrVect[] solution = null; |
||
319 | ArrayList list = new ArrayList(); |
||
320 | int numLayers = layers.getLayersCount();
|
||
321 | for (int i = 0; i < numLayers; i++) { |
||
322 | FLayer layer = layers.getLayer(i); |
||
323 | if (layer instanceof FLyrVect) |
||
324 | list.add(layer); |
||
325 | else if (layer instanceof FLayers) |
||
326 | list.addAll(Arrays.asList(getVectorialLayers((FLayers) layer)));
|
||
327 | } |
||
328 | solution = new FLyrVect[list.size()];
|
||
329 | list.toArray(solution); |
||
330 | return solution;
|
||
331 | |||
332 | } |
||
333 | |||
334 | /**
|
||
335 | * Obtains layer names from FLayers and returns like an array of strings.
|
||
336 | *
|
||
337 | * @return
|
||
338 | *
|
||
339 | * TODO Llevar a una utility class
|
||
340 | */
|
||
341 | protected String[] getLayerNames() { |
||
342 | String[] solution = null; |
||
343 | int numLayers = layers.getLayersCount();
|
||
344 | if (layers != null && numLayers > 0) { |
||
345 | ArrayList list = new ArrayList(); |
||
346 | for (int i = 0; i < numLayers; i++) { |
||
347 | FLayer layer = layers.getLayer(i); |
||
348 | if (layer instanceof FLyrVect) |
||
349 | list.add(layer.getName()); |
||
350 | if (layer instanceof FLayers) { |
||
351 | FLayers layers = (FLayers) layer; |
||
352 | FLyrVect[] vectorials = getVectorialLayers(layers);
|
||
353 | for (int j = 0; j < vectorials.length; j++) { |
||
354 | list.add(vectorials[j].getName()); |
||
355 | } |
||
356 | } |
||
357 | }// for
|
||
358 | solution = new String[list.size()]; |
||
359 | list.toArray(solution); |
||
360 | } |
||
361 | return solution;
|
||
362 | } |
||
363 | |||
364 | /**
|
||
365 | * Shows to the user a dialog error, whith the title and message body
|
||
366 | * specified as parameters.
|
||
367 | *
|
||
368 | * @param message
|
||
369 | * body of the error message
|
||
370 | * @param title
|
||
371 | * title of the error message
|
||
372 | */
|
||
373 | public void error(String message, String title) { |
||
374 | JOptionPane.showMessageDialog(this, message, title, |
||
375 | JOptionPane.ERROR_MESSAGE);
|
||
376 | } |
||
377 | |||
378 | /**
|
||
379 | * Asks to the user for the creation of a spatial index for the specified
|
||
380 | * layer. It will be of help for certain geoprocesses.
|
||
381 | *
|
||
382 | * FLyrVect default spatial index is MapServer quadtree, that hasnt the
|
||
383 | * ability to do nearest neighbour searches.
|
||
384 | *
|
||
385 | * For those geoprocesses that needs it (NN searches) overwrite this method
|
||
386 | * and use JSI RTree, or SIL RTree.
|
||
387 | *
|
||
388 | * It returns an IMonitorableTask, a task to build the spatial index in
|
||
389 | * background.
|
||
390 | *
|
||
391 | * @param layer
|
||
392 | * @return an ITask
|
||
393 | */
|
||
394 | public IMonitorableTask askForSpatialIndexCreation(FLyrVect layer) {
|
||
395 | String title = PluginServices.getText(this, "Crear_Indice"); |
||
396 | String confirmDialogText = PluginServices.getText(this, |
||
397 | "Crear_Indice_Pregunta_1")
|
||
398 | + " "
|
||
399 | + layer.getName() |
||
400 | + " "
|
||
401 | + PluginServices.getText(this, "Crear_Indice_Pregunta_2"); |
||
402 | int option = JOptionPane.showConfirmDialog(this, confirmDialogText, |
||
403 | title, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, |
||
404 | null);
|
||
405 | if (option == JOptionPane.YES_OPTION) { |
||
406 | // Usually we want task like spatial index creation dont block
|
||
407 | // GUI responses. Now, we dont want to start geoprocess execution
|
||
408 | // until spatial index creation would finish, to have advantage
|
||
409 | // of the spatial index
|
||
410 | try {
|
||
411 | CreateSpatialIndexMonitorableTask task = new CreateSpatialIndexMonitorableTask(
|
||
412 | layer); |
||
413 | return task;
|
||
414 | } catch (DriverIOException e) {
|
||
415 | // TODO Auto-generated catch block
|
||
416 | e.printStackTrace(); |
||
417 | return null; |
||
418 | } catch (DriverException e) {
|
||
419 | // TODO Auto-generated catch block
|
||
420 | e.printStackTrace(); |
||
421 | return null; |
||
422 | } |
||
423 | } else
|
||
424 | return null; |
||
425 | |||
426 | } |
||
427 | |||
428 | /**
|
||
429 | * Confirm overwrite the output file if it allready exist.
|
||
430 | *
|
||
431 | *
|
||
432 | * @param outputFile
|
||
433 | * @return answer
|
||
434 | */
|
||
435 | public boolean askForOverwriteOutputFile(File outputFile) { |
||
436 | String title = PluginServices.getText(this, "Sobreescribir_fichero"); |
||
437 | String confirmDialogText = PluginServices.getText(this, |
||
438 | "Sobreescribir_fichero_Pregunta_1")
|
||
439 | + "\n'"
|
||
440 | + outputFile.getAbsolutePath() |
||
441 | + "'\n"
|
||
442 | + PluginServices.getText(this,
|
||
443 | "Sobreescribir_fichero_Pregunta_2");
|
||
444 | int option = JOptionPane.showConfirmDialog(this, confirmDialogText, |
||
445 | title, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, |
||
446 | null);
|
||
447 | if (option == JOptionPane.YES_OPTION) { |
||
448 | return true; |
||
449 | } |
||
450 | return false; |
||
451 | } |
||
452 | |||
453 | |||
454 | /**
|
||
455 | * Opens a dialog to select where (file, database, etc)
|
||
456 | * to save the result layer.
|
||
457 | *
|
||
458 | */
|
||
459 | public void openResultFile() { |
||
460 | JFileChooser jfc = new JFileChooser(); |
||
461 | jfc |
||
462 | .addChoosableFileFilter(new GenericFileFilter("shp", |
||
463 | "Ficheros SHP"));
|
||
464 | if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) { |
||
465 | File file = jfc.getSelectedFile();
|
||
466 | if (!(file.getPath().endsWith(".shp") || file.getPath().endsWith( |
||
467 | ".SHP"))) {
|
||
468 | file = new File(file.getPath() + ".shp"); |
||
469 | } |
||
470 | }// if
|
||
471 | if (jfc.getSelectedFile() != null) { |
||
472 | getFileNameResultTextField().setText( |
||
473 | jfc.getSelectedFile().getAbsolutePath()); |
||
474 | } |
||
475 | |||
476 | } |
||
477 | |||
478 | |||
479 | protected JTextField getFileNameResultTextField() { |
||
480 | if(resultTf == null) |
||
481 | resultTf = new JTextField(25); |
||
482 | return resultTf;
|
||
483 | } |
||
484 | |||
485 | public File getOutputFile() throws FileNotFoundException{ |
||
486 | String fileName = getFileNameResultTextField().getText();
|
||
487 | if(fileName.length() == 0){ |
||
488 | throw new FileNotFoundException("No se ha seleccionado ningun fichero de salida"); |
||
489 | } |
||
490 | if(! fileName.endsWith(".shp")){ |
||
491 | if(! fileName.endsWith(".")) |
||
492 | fileName += ".";
|
||
493 | fileName += "shp";
|
||
494 | } |
||
495 | return new File(fileName); |
||
496 | } |
||
497 | |||
498 | protected JComboBox getLayersComboBox() { |
||
499 | if (layersComboBox == null) { |
||
500 | layersComboBox = new JComboBox(); |
||
501 | DefaultComboBoxModel defaultModel = new DefaultComboBoxModel( |
||
502 | getLayerNames()); |
||
503 | layersComboBox.setModel(defaultModel); |
||
504 | layersComboBox.setBounds(142, 63, 260, 21); |
||
505 | layersComboBox.addItemListener(new java.awt.event.ItemListener() {
|
||
506 | public void itemStateChanged(ItemEvent e) { |
||
507 | if (e.getStateChange() == ItemEvent.SELECTED) { |
||
508 | initSelectedItemsJCheckBox(); |
||
509 | updateNumSelectedFeaturesLabel(); |
||
510 | processLayerComboBoxStateChange(e); |
||
511 | } |
||
512 | }// itemStateChange
|
||
513 | }); |
||
514 | } |
||
515 | return layersComboBox;
|
||
516 | } |
||
517 | |||
518 | protected JCheckBox getSelectedOnlyCheckBox() { |
||
519 | if (selectedOnlyCheckBox == null) { |
||
520 | selectedOnlyCheckBox = new JCheckBox(); |
||
521 | selectedOnlyCheckBox.addItemListener(new ItemListener(){ |
||
522 | public void itemStateChanged(ItemEvent arg0) { |
||
523 | updateNumSelectedFeaturesLabel(); |
||
524 | }}); |
||
525 | selectedOnlyCheckBox.setText(PluginServices.getText(this, "Usar_solamente_los_elementos_seleccionados")); |
||
526 | } |
||
527 | return selectedOnlyCheckBox;
|
||
528 | } |
||
529 | |||
530 | public boolean isFirstOnlySelected(){ |
||
531 | return getSelectedOnlyCheckBox().isSelected();
|
||
532 | } |
||
533 | |||
534 | protected abstract void processLayerComboBoxStateChange(ItemEvent e); |
||
535 | } |