Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_2_Build_1044 / prototypes / VectorialAvanzado / extensions / extGraph / src / com / iver / cit / gvsig / graph / gui / RouteControlPanel.java @ 20099

History | View | Annotate | Download (35.4 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: RouteControlPanel.java 20099 2008-04-14 08:44:55Z fpenarrubia $
45
 * $Log$
46
 * Revision 1.25.2.5  2007-08-06 16:54:34  fjp
47
 * Versi?n en desarrollo con velocidades y un esbozo de ?reas de influencia
48
 *
49
 * Revision 1.25.2.4  2007/06/14 10:02:25  fjp
50
 * Pliego de redes a publicar SIN el cuadro de di?logo setVelocities (bueno, con , pero invisible)
51
 *
52
 * Revision 1.25.2.3  2007/05/24 11:33:36  fjp
53
 * Para que puedas a?adir los puntos que est?n cerca de la red. Los que no lo est?n, lanzan un error informando de qu? punto no est? cerca de la red.
54
 *
55
 * Revision 1.25.2.2  2007/05/15 07:08:21  fjp
56
 * Para calcular matrices de distancias
57
 *
58
 * Revision 1.25  2006/11/14 18:32:32  fjp
59
 * *** empty log message ***
60
 *
61
 * Revision 1.24  2006/11/14 16:12:01  fjp
62
 * *** empty log message ***
63
 *
64
 * Revision 1.23  2006/11/14 09:23:30  fjp
65
 * cargar paradas desde cualquier tema de puntos
66
 *
67
 * Revision 1.22  2006/11/10 13:57:04  fjp
68
 * *** empty log message ***
69
 *
70
 * Revision 1.21  2006/11/09 21:08:32  azabala
71
 * *** empty log message ***
72
 *
73
 * Revision 1.20  2006/11/09 12:51:12  jaume
74
 * *** empty log message ***
75
 *
76
 * Revision 1.19  2006/11/09 11:00:43  jaume
77
 * *** empty log message ***
78
 *
79
 * Revision 1.18  2006/11/09 10:59:53  jaume
80
 * *** empty log message ***
81
 *
82
 * Revision 1.17  2006/11/09 10:27:50  fjp
83
 * *** empty log message ***
84
 *
85
 * Revision 1.16  2006/11/09 10:24:11  fjp
86
 * *** empty log message ***
87
 *
88
 * Revision 1.15  2006/11/09 09:16:35  fjp
89
 * Ya va!!
90
 *
91
 * Revision 1.14  2006/11/08 20:14:52  azabala
92
 * *** empty log message ***
93
 *
94
 * Revision 1.13  2006/11/08 19:32:22  azabala
95
 * saveroute and saveflags modifications
96
 *
97
 * Revision 1.12  2006/11/08 18:16:28  fjp
98
 * *** empty log message ***
99
 *
100
 * Revision 1.11  2006/11/08 16:48:19  fjp
101
 * *** empty log message ***
102
 *
103
 * Revision 1.10  2006/11/08 16:00:39  fjp
104
 * Por terminar el enlace flags-cuadro de di?logo
105
 *
106
 * Revision 1.9  2006/11/08 13:18:46  fjp
107
 * Por terminar el enlace flags-cuadro de di?logo
108
 *
109
 * Revision 1.8  2006/11/07 19:49:38  azabala
110
 * *** empty log message ***
111
 *
112
 * Revision 1.7  2006/11/06 13:13:53  azabala
113
 * *** empty log message ***
114
 *
115
 * Revision 1.6  2006/11/06 10:29:32  jaume
116
 * *** empty log message ***
117
 *
118
 * Revision 1.5  2006/11/03 19:39:29  azabala
119
 * *** empty log message ***
120
 *
121
 * Revision 1.4  2006/10/27 18:26:22  azabala
122
 * added implementation of load stages method
123
 *
124
 * Revision 1.3  2006/10/27 12:41:09  jaume
125
 * GUI
126
 *
127
 * Revision 1.2  2006/10/26 16:31:21  jaume
128
 * GUI
129
 *
130
 * Revision 1.1  2006/10/25 10:50:41  jaume
131
 * movement of classes and gui stuff
132
 *
133
 * Revision 1.4  2006/10/24 08:04:41  jaume
134
 * *** empty log message ***
135
 *
136
 * Revision 1.3  2006/10/23 16:00:20  jaume
137
 * *** empty log message ***
138
 *
139
 * Revision 1.2  2006/10/23 08:05:39  jaume
140
 * GUI
141
 *
142
 * Revision 1.1  2006/10/20 12:02:50  jaume
143
 * GUI
144
 *
145
 *
146
 */
147
package com.iver.cit.gvsig.graph.gui;
148

    
149
import java.awt.BorderLayout;
150
import java.awt.Component;
151
import java.awt.Dimension;
152
import java.awt.FlowLayout;
153
import java.awt.Font;
154
import java.awt.GridLayout;
155
import java.awt.event.ActionEvent;
156
import java.awt.event.ActionListener;
157
import java.awt.geom.Rectangle2D;
158
import java.text.NumberFormat;
159
import java.util.ArrayList;
160
import java.util.Hashtable;
161
import java.util.List;
162

    
163
import javax.swing.ImageIcon;
164
import javax.swing.JComboBox;
165
import javax.swing.JLabel;
166
import javax.swing.JOptionPane;
167
import javax.swing.JPanel;
168
import javax.swing.JScrollPane;
169
import javax.swing.JTable;
170
import javax.swing.ListSelectionModel;
171
import javax.swing.event.ListSelectionEvent;
172
import javax.swing.event.ListSelectionListener;
173
import javax.swing.event.TableModelEvent;
174
import javax.swing.event.TableModelListener;
175
import javax.swing.table.AbstractTableModel;
176
import javax.swing.table.TableColumnModel;
177
import javax.swing.table.TableModel;
178

    
179
import org.cresques.cts.IProjection;
180
import org.gvsig.gui.beans.swing.GridBagLayoutPanel;
181
import org.gvsig.gui.beans.swing.JBlank;
182
import org.gvsig.gui.beans.swing.JButton;
183

    
184
import com.hardcode.gdbms.engine.values.Value;
185
import com.hardcode.gdbms.engine.values.ValueFactory;
186
import com.iver.andami.PluginServices;
187
import com.iver.andami.messages.NotificationManager;
188
import com.iver.andami.ui.mdiManager.IWindow;
189
import com.iver.andami.ui.mdiManager.SingletonWindow;
190
import com.iver.andami.ui.mdiManager.WindowInfo;
191
import com.iver.cit.gvsig.fmap.DriverException;
192
import com.iver.cit.gvsig.fmap.MapContext;
193
import com.iver.cit.gvsig.fmap.MapControl;
194
import com.iver.cit.gvsig.fmap.ViewPort;
195
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
196
import com.iver.cit.gvsig.fmap.core.FPoint2D;
197
import com.iver.cit.gvsig.fmap.core.FShape;
198
import com.iver.cit.gvsig.fmap.core.IGeometry;
199
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
200
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
201
import com.iver.cit.gvsig.fmap.edition.EditionException;
202
import com.iver.cit.gvsig.fmap.layers.FLayer;
203
import com.iver.cit.gvsig.fmap.layers.FLayers;
204
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
205
import com.iver.cit.gvsig.fmap.layers.LayerEvent;
206
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
207
import com.iver.cit.gvsig.fmap.layers.LayerListenerAdapter;
208
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
209
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
210
import com.iver.cit.gvsig.fmap.layers.SingleLayerIterator;
211
import com.iver.cit.gvsig.graph.core.GraphException;
212
import com.iver.cit.gvsig.graph.core.GvEdge;
213
import com.iver.cit.gvsig.graph.core.GvFlag;
214
import com.iver.cit.gvsig.graph.core.IFlagListener;
215
import com.iver.cit.gvsig.graph.core.Network;
216
import com.iver.cit.gvsig.graph.core.NetworkUtils;
217
import com.iver.cit.gvsig.graph.solvers.FlagsMemoryDriver;
218
import com.iver.cit.gvsig.graph.solvers.Route;
219
import com.iver.cit.gvsig.graph.solvers.RouteMemoryDriver;
220
import com.iver.cit.gvsig.graph.tools.FlagListener;
221
import com.iver.cit.gvsig.project.documents.gui.FOpenDialog;
222
import com.iver.cit.gvsig.project.documents.view.gui.IView;
223
import com.iver.cit.gvsig.project.documents.view.gui.View;
224
import com.iver.cit.gvsig.util.GvSession;
225
import com.vividsolutions.jts.geom.Coordinate;
226
import com.vividsolutions.jts.geom.Geometry;
227
import com.vividsolutions.jts.geom.MultiPoint;
228
import com.vividsolutions.jts.geom.Point;
229

    
230
public class RouteControlPanel extends JPanel implements SingletonWindow,
231
                ActionListener, IFlagListener {
232
        WindowInfo wi;
233

    
234
        private JPanel westPanel = null;
235

    
236
        private JScrollPane scrlStages = null;
237

    
238
        private JTable tblStages = null;
239

    
240
        private GridBagLayoutPanel eastPanel = null;
241

    
242
        private MyTableModel tableModel = new MyTableModel(); // @jve:decl-index=0:visual-constraint=""
243

    
244
        private JButton btnLoadStage = null;
245

    
246
        private JButton btnSaveStage = null;
247
        
248
        private JButton btnSetVelocities = null;
249

    
250
        private Network network;
251

    
252
        private ArrayList routeFlags;
253

    
254
        private JLabel lblCost;
255

    
256
        private JLabel lblFlagAmout;
257

    
258
        private JButton btnPullDownStage;
259

    
260
        private JButton btnPushUpStage;
261

    
262
        private JButton btnRemoveStage;
263

    
264
        private JPanel southPanel;
265

    
266
        private final String[] colName = new String[] {
267
                        PluginServices.getText(this, "enable"),
268
                        PluginServices.getText(this, "stage"),
269
                        PluginServices.getText(this, "cost"), };
270

    
271
        private JButton btnCenterOnFlag;
272

    
273
        private JButton btnSaveRoute;
274

    
275
        private MapControl mapCtrl;
276

    
277
        private class MyTableModel extends AbstractTableModel {
278
                public int getColumnCount() {
279
                        return 3;
280
                }
281

    
282
                public int getRowCount() {
283
                        return _getFlags().size();
284
                }
285

    
286
                public Object getValueAt(int rowIndex, int columnIndex) {
287
                        GvFlag flag = (GvFlag) _getFlags().get(rowIndex);
288
                        switch (columnIndex) {
289
                        case 0:
290
                                return new Boolean(flag.isEnabled());
291
                        case 1:
292
                                return flag.getDescription();
293
                        case 2:
294
                                return new Double(flag.getCost());
295
                        }
296

    
297
                        return null;
298
                }
299

    
300
                public Class getColumnClass(int columnIndex) {
301
                        switch (columnIndex)
302
                        {
303
                        case 0:
304
                                return Boolean.class;
305
                        case 1:
306
                                return String.class;
307
                        case 2:
308
                                return Double.class;
309

    
310
                        }
311
                        return super.getColumnClass(columnIndex);
312
                }
313

    
314
                public String getColumnName(int column) {
315
                        return colName[column];
316
                }
317

    
318
                public boolean isCellEditable(int rowIndex, int columnIndex) {
319
                        if (columnIndex == 2)
320
                                return false;
321
                        return true;
322

    
323
                }
324

    
325
                public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
326
                        GvFlag flag = (GvFlag) _getFlags().get(rowIndex);
327
                        switch (columnIndex)
328
                        {
329
                        case 0:
330
                                Boolean bAux = (Boolean) aValue;
331
                                flag.setEnabled(bAux.booleanValue());
332
                                PluginServices.getMainFrame().enableControls();
333
                                return;
334
                        case 1:
335
                                String strAux = (String) aValue;
336
                                flag.setDescription(strAux);
337
                                return;
338

    
339
//                        case 2: // No es editable
340
//                                Double dblAux = (Double) aValue;
341
//                                flag.setCost(dblAux.doubleValue());
342
//                                return;
343

    
344
                        }
345

    
346
                }
347

    
348
        }
349

    
350
        /**
351
         * This method initializes
352
         *
353
         */
354
        public RouteControlPanel(Network network) {
355
                super();
356
                this.network = network;
357
//                GvFlag[] flags = network.getFlags();
358
//                List vflags = _getFlags();
359
//                for (int i = 0; i < flags.length; i++) {
360
//                        vflags.add(flags[i]);
361
//                }
362
                initialize();
363
        }
364

    
365
        /**
366
         * Method to remove all flags (use
367
         * */
368
        public void refresh(){
369
//                GvFlag[] flags = network.getFlags();
370
//                List vflags = _getFlags();
371
//                List tempFlags = Arrays.asList(flags);
372
//                vflags.addAll(tempFlags);
373
                lblFlagAmout.setText(String.valueOf(_getFlags()
374
                                .size()));
375
                updateTotalCost();
376
                ListSelectionModel rowSM = tblStages.getSelectionModel();
377
                if (_getFlags().size() == 0)
378
                        getBtnCenterOnFlag().setEnabled(false);
379
                else
380
                        getBtnCenterOnFlag().setEnabled(!rowSM.isSelectionEmpty());
381
                getTblStages().revalidate();
382
                System.out.println("Actualizo tabla");
383

    
384
        }
385
        private void processLayer(FLayer layer) {
386
                if (layer.isActive()) {
387
                        if (layer instanceof FLyrVect) {
388
                                Network net = (Network) layer
389
                                                .getProperty("network");
390
                                if (net != null) {
391
                                        network = net;
392
                                        network.addFlagListener(this);
393
                                        refresh();
394
                                }// if
395
                        }// if
396
                }// if
397

    
398
        }
399

    
400
        public void setMapControl(MapControl mapCtrl, Network net) {
401
                if (mapCtrl != null) {
402
                        this.mapCtrl = mapCtrl;
403
                        LayerListenerAdapter listener = new LayerListenerAdapter() {
404
                                public void activationChanged(LayerEvent e) {
405
                                        processLayer(e.getSource());
406
                                }
407
                        };
408
                        mapCtrl.getMapContext().getLayers().addLayerListener(listener);
409
                        mapCtrl.getMapContext().getLayers().addLayerCollectionListener(
410
                                        listener);
411
                        if (net != null) {
412
                                network = net;
413
                                network.addFlagListener(this);
414
                        }
415
                }
416
        }
417

    
418
        public RouteControlPanel() {
419
                super();
420
                initialize();
421
        }
422

    
423
        public void setCostUnits(String unitsName) {
424
                colName[2] = unitsName;
425
                getTblStages().repaint();
426
        }
427

    
428
        /**
429
         * This method initializes this
430
         *
431
         */
432
        private void initialize() {
433
                BorderLayout borderLayout = new BorderLayout();
434
                borderLayout.setHgap(10);
435
                borderLayout.setVgap(10);
436
                JPanel cont = new JPanel(borderLayout);
437
//                cont.setPreferredSize(new Dimension(490, 320));
438
                this.setPreferredSize(new Dimension(460, 280));
439
                cont.add(getWestPanel(), BorderLayout.CENTER);
440
                cont.add(getEastPanel(), BorderLayout.EAST);
441
                cont.add(getSouthPanel(), BorderLayout.SOUTH);
442
                this.setLayout(new FlowLayout(FlowLayout.LEADING, 10, 10));
443
                this.add(cont);
444
                updateFlags();
445
        }
446

    
447
        private void updateFlags() {
448
                lblFlagAmout.setText(String.valueOf(_getFlags().size()));
449
                updateTotalCost();
450
                getTblStages().repaint();
451
        }
452

    
453
        private JPanel getSouthPanel() {
454
                if (southPanel == null) {
455
                        southPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
456
                        southPanel.add(getBtnRemoveStage());
457
                        southPanel.add(new JBlank(50, 20));
458
                        southPanel.add(getBtnPushUpStage());
459
                        southPanel.add(getBtnPullDownStage());
460
                        southPanel.add(new JLabel(PluginServices.getText(this,
461
                                        "flag_amount")));
462
                        lblFlagAmout = new JLabel();
463
                        lblFlagAmout.setFont(lblFlagAmout.getFont().deriveFont(Font.BOLD));
464
                        southPanel.add(lblFlagAmout);
465
                }
466
                return southPanel;
467
        }
468

    
469
        public Object getWindowModel() {
470
                return this.getClass();
471
        }
472

    
473
        public WindowInfo getWindowInfo() {
474
                if (wi == null) {
475
                        wi = new WindowInfo(WindowInfo.MODELESSDIALOG
476
                                    | WindowInfo.MAXIMIZABLE
477
                                        | WindowInfo.ICONIFIABLE | WindowInfo.PALETTE);
478
                        wi.setWidth((int) this.getPreferredSize().getWidth());
479
                        wi.setHeight((int) this.getPreferredSize().getHeight());
480
                        wi.setTitle(PluginServices.getText(this, "route_control_panel"));
481
                }
482
                return wi;
483
        }
484

    
485
        /**
486
         * This method initializes westPanel
487
         *
488
         * @return javax.swing.JPanel
489
         */
490
        private JPanel getWestPanel() {
491
                if (westPanel == null) {
492
                        westPanel = new JPanel(new BorderLayout(5, 5));
493
                        lblCost = new JLabel();
494
                        lblCost.setFont(lblCost.getFont().deriveFont(Font.BOLD));
495
                        GridBagLayoutPanel aux = new GridBagLayoutPanel();
496
                        aux.addComponent(PluginServices.getText(this, "total_route_cost")
497
                                        + ":", lblCost);
498
                        aux.addComponent(getScrlStages());
499

    
500
                        westPanel.add(aux);
501
                }
502
                return westPanel;
503
        }
504

    
505
        private JButton getBtnPullDownStage() {
506
                if (btnPullDownStage == null) {
507
                        btnPullDownStage = new JButton(new ImageIcon(this.getClass()
508
                                        .getClassLoader().getResource("images/down-arrow.png")));
509
                        // btnPullDownStage.setName("btnPullDownStage");
510
                        btnPullDownStage.addActionListener(this);
511
                }
512
                return btnPullDownStage;
513
        }
514

    
515
        private JButton getBtnPushUpStage() {
516
                if (btnPushUpStage == null) {
517
                        btnPushUpStage = new JButton(new ImageIcon(this.getClass()
518
                                        .getClassLoader().getResource("images/up-arrow.png")));
519
                        // btnPushUpStage.setName("btnPushUpStage");
520
                        btnPushUpStage.addActionListener(this);
521
                }
522
                return btnPushUpStage;
523
        }
524

    
525
        private JButton getBtnRemoveStage() {
526
                if (btnRemoveStage == null) {
527
                        btnRemoveStage = new JButton(new ImageIcon(this.getClass()
528
                                        .getClassLoader().getResource("images/delete.png")));
529
                        // btnRemoveStage.setName("btnRemoveStage");
530
                        btnRemoveStage.addActionListener(this);
531
                }
532
                return btnRemoveStage;
533
        }
534

    
535
        /**
536
         * This method initializes scrlStages
537
         *
538
         * @return javax.swing.JScrollPane
539
         */
540
        private JScrollPane getScrlStages() {
541
                if (scrlStages == null) {
542
                        scrlStages = new JScrollPane();
543
                        scrlStages.setViewportView(getTblStages());
544
                        scrlStages.setPreferredSize(new Dimension(270, 200));
545
                }
546
                return scrlStages;
547
        }
548

    
549
        /**
550
         * @deprecated
551
         * @param flag
552
         */
553
        public void addFlag(GvFlag flag) {
554
                _getFlags().add(flag);
555
                lblFlagAmout.setText(String.valueOf(_getFlags().size()));
556
                updateTotalCost();
557
                getTblStages().repaint();
558
        }
559

    
560
        private void updateTotalCost() {
561
                GvFlag[] flags = getFlags();
562
                double cost = 0;
563
                for (int i = 0; i < flags.length; i++) {
564
                        if (!flags[i].isEnabled())
565
                                continue;
566
                        if (flags[i].getCost() >= Double.MAX_VALUE)
567
                        {
568
                                lblCost.setText(PluginServices.getText(this, "no_se_puede_pasar_por_todas_las_paradas"));
569
                                return;
570
                        }
571
                        if (flags[i].getCost() < 0)
572
                        {
573
                                lblCost.setText(PluginServices.getText(this, "solucion_no_valida"));
574
                                return;
575
                        }
576
                                
577
                        cost += flags[i].getCost();
578
                }
579
                NumberFormat nf = NumberFormat.getInstance();
580
                nf.setMaximumFractionDigits(2);
581
                lblCost.setText(nf.format(cost) + getCostUnitName());
582
        }
583

    
584
        private String getCostUnitName() {
585
                if (colName[2].equals(PluginServices.getText(this, "cost")))
586
                        return "";
587
                return colName[2];
588
        }
589

    
590
        public void removeFlag(GvFlag flag) {
591
                removeFlag(_getFlags().indexOf(flag));
592
        }
593

    
594
        public void removeFlag(int index) {
595
                _getFlags().remove(index);
596
                lblFlagAmout.setText(String.valueOf(_getFlags().size()));
597
                getTblStages().repaint();
598
        }
599

    
600
        /**
601
         * This method initializes tblStages
602
         *
603
         * @return javax.swing.JTable
604
         */
605
        private JTable getTblStages() {
606
                if (tblStages == null) {
607
                        tblStages = new JTable();
608
                        tblStages
609
                                        .setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
610
                        tblStages.setModel(getTableModel());
611
                        TableColumnModel cm = tblStages.getColumnModel();
612

    
613
                        int tablePreferredWidth = (int) tblStages.getPreferredSize()
614
                                        .getWidth();
615
                        int colSize = tblStages.getFontMetrics(tblStages.getFont())
616
                                        .stringWidth(tblStages.getModel().getColumnName(0)) * 2;
617
                        cm.getColumn(0).setPreferredWidth((int) (colSize));
618
                        cm.getColumn(0).setMinWidth((int) (colSize));
619
                        cm.getColumn(0).setMaxWidth((int) (colSize));
620
                        tablePreferredWidth -= colSize;
621
                        cm.getColumn(1)
622
                                        .setPreferredWidth((int) (tablePreferredWidth * 0.7));
623
                        cm.getColumn(2)
624
                                        .setPreferredWidth((int) (tablePreferredWidth * 0.3));
625

    
626
                        // Ask to be notified of selection changes.
627
                        ListSelectionModel rowSM = tblStages.getSelectionModel();
628
                        rowSM.addListSelectionListener(new ListSelectionListener() {
629
                            public void valueChanged(ListSelectionEvent e) {
630
                                //Ignore extra messages.
631
                                if (e.getValueIsAdjusting())
632
                                        return;
633

    
634
                                ListSelectionModel lsm =
635
                                    (ListSelectionModel)e.getSource();
636
                                getBtnCenterOnFlag().setEnabled(!lsm.isSelectionEmpty());
637
                            }
638
                        });
639
                        
640
                        tblStages.getModel().addTableModelListener(new TableModelListener() {
641

    
642
                                public void tableChanged(TableModelEvent e) {
643
                                        System.out.println("Table model changed");
644
//                                        getBtnCenterOnFlag().setEnabled(false);
645
                                }
646
                                
647
                        });
648

    
649
                        
650
                }
651
                return tblStages;
652
        }
653

    
654
        protected int getFlagCount() {
655
                return _getFlags().size();
656
        }
657

    
658
        private List _getFlags() {
659
//                if (routeFlags == null) {
660
//                        routeFlags = new ArrayList();
661
//                }
662
//                return routeFlags;
663

    
664
                return network.getOriginaFlags();
665
        }
666

    
667
        protected boolean isSelected(int row) {
668
                return ((GvFlag) _getFlags().get(row)).isEnabled();
669
        }
670

    
671
        /**
672
         * This method initializes eastPanel
673
         *
674
         * @return javax.swing.JPanel
675
         */
676
        private JPanel getEastPanel() {
677
                if (eastPanel == null) {
678
                        GridLayout layout = new GridLayout();
679
                        layout.setColumns(1);
680
                        layout.setVgap(5);
681
                        JPanel aux = new JPanel();
682
                        aux.add(getBtnLoadStage());
683
                        aux.add(getBtnSaveStage());
684
                        aux.add(getBtnSaveRoute());
685
                        aux.add(getBtnCenterOnFlag());
686
                        aux.add(getBtnSetVelocities());
687
                        layout.setRows(aux.getComponentCount());
688
                        aux.setLayout(layout);
689
                        eastPanel = new GridBagLayoutPanel();
690
                        eastPanel.addComponent(aux);
691
                }
692
                return eastPanel;
693
        }
694

    
695
        private JButton getBtnCenterOnFlag() {
696
                if (btnCenterOnFlag == null) {
697
                        btnCenterOnFlag = new JButton();
698
                        btnCenterOnFlag.setText(PluginServices.getText(this,
699
                                        "center_on_flag"));
700
                        btnCenterOnFlag.setEnabled(false);
701
                        btnCenterOnFlag.addActionListener(this);
702
                }
703
                return btnCenterOnFlag;
704
        }
705

    
706
        private JButton getBtnSetVelocities() {
707
                if (btnSetVelocities == null) {
708
                        btnSetVelocities = new JButton();
709
                        btnSetVelocities.setText(PluginServices.getText(this,
710
                                        "set_velocities"));
711
//                        btnSetVelocities.setEnabled(false);
712
                        
713
                        // TODO: PONERLO VISIBLE CUANDO SE CORRIJA LO DE ABRIR EL
714
                        // DIALOGO Y LEER LAS VELOCIDADES QUE HAB?A ANTES.
715
                        btnSetVelocities.setVisible(true);
716
                        btnSetVelocities.addActionListener(this);
717
                }
718
                return btnSetVelocities;
719
        }
720

    
721
        private JButton getBtnSaveRoute() {
722
                if (btnSaveRoute == null) {
723
                        btnSaveRoute = new JButton();
724
                        btnSaveRoute.setText(PluginServices.getText(this, "save_route"));
725
                        btnSaveRoute.addActionListener(this);
726
                }
727
                return btnSaveRoute;
728
        }
729

    
730
        /**
731
         * This method initializes defaultTableModel
732
         *
733
         * @return javax.swing.table.DefaultTableModel
734
         */
735
        private TableModel getTableModel() {
736
                return tableModel;
737
        }
738

    
739
        /**
740
         * This method initializes btnLoadStage
741
         *
742
         * @return javax.swing.JButton
743
         */
744
        private JButton getBtnLoadStage() {
745
                if (btnLoadStage == null) {
746
                        btnLoadStage = new JButton();
747
                        btnLoadStage.setText(PluginServices.getText(this, "load_stages"));
748
                        btnLoadStage.addActionListener(this);
749
                }
750
                return btnLoadStage;
751
        }
752

    
753
        /**
754
         * This method initializes btnSaveStages
755
         *
756
         * @return javax.swing.JButton
757
         */
758
        private JButton getBtnSaveStage() {
759
                if (btnSaveStage == null) {
760
                        btnSaveStage = new JButton();
761
                        btnSaveStage.setText(PluginServices.getText(this, "save_stages"));
762
                        btnSaveStage.addActionListener(this);
763
                }
764
                return btnSaveStage;
765
        }
766

    
767
        class FormatSelectionPanel extends JPanel implements IWindow {
768

    
769
                JComboBox formats;
770
                WindowInfo wi = null;
771

    
772
                public FormatSelectionPanel(String introductoryText) {
773
                        super(new BorderLayout());
774
                        String[] formatos = { "SHP", "DXF", "POSTGIS", "GML" };
775
                        formats = new JComboBox(formatos);
776
                        GridBagLayoutPanel contentPanel =
777
                                new GridBagLayoutPanel();
778
                        contentPanel.addComponent(new JLabel(introductoryText));
779
                        contentPanel.addComponent(formats);
780
                        JButton okButton = new JButton(PluginServices.getText(null,
781
                                        "Aceptar"));
782
                        okButton.addActionListener(new ActionListener() {
783
                                public void actionPerformed(ActionEvent arg0) {
784
                                        close();
785
                                }
786
                        });
787
                        contentPanel.addComponent(okButton);
788

    
789
                        add(contentPanel);
790
                }
791

    
792
                void close() {
793
                        PluginServices.getMDIManager().closeWindow(this);
794
                }
795

    
796
                public String getSelectedFormat() {
797
                        return (String) formats.getSelectedItem();
798
                }
799

    
800
                public WindowInfo getWindowInfo() {
801
                        if (wi == null) {
802
                                wi = new WindowInfo(WindowInfo.MODALDIALOG | WindowInfo.PALETTE);
803
                                wi.setTitle(PluginServices
804
                                                .getText(null, "Seleccion_de_formato"));// Internacionalizar
805
                                                                                                                                // esto
806
                                wi.setWidth(300);
807
                                wi.setHeight(55);
808
                        }
809
                        return wi;
810
                }
811

    
812
        }
813

    
814
        public void actionPerformed(ActionEvent e) {
815
                Component c = (Component) e.getSource();
816
                if (c.equals(getBtnLoadStage())) {
817
                        loadStages();
818
                } else if (c.equals(getBtnSaveStage())) {
819
                        saveStage();
820
                } else if (c.equals(getBtnPushUpStage())) {
821
                        int[] selected = tblStages.getSelectedRows();
822
                        if (selected.length == 0 || selected[0] == 0)
823
                                return;
824
                        tblStages.clearSelection();
825
                        for (int i = 0; i < selected.length; i++) {
826
                                Object aux = _getFlags().get(selected[i] - 1);
827
                                _getFlags().set(selected[i] - 1, _getFlags().get(selected[i]));
828
                                _getFlags().set(selected[i], aux);
829
                                selected[i]--;
830
                                tblStages.addRowSelectionInterval(selected[i], selected[i]);
831
                        }
832
                        invalidateSolution();
833
                } else if (c.equals(getBtnPullDownStage())) {
834
                        // pull down
835
                        int[] selected = tblStages.getSelectedRows();
836
                        if (selected.length == 0
837
                                        || selected[selected.length - 1] >= _getFlags().size() - 1)
838
                                return;
839

    
840
                        // move rows
841
                        tblStages.clearSelection();
842
                        for (int i = selected.length - 1; i >= 0; i--) {
843
                                Object aux = _getFlags().get(selected[i] + 1);
844
                                _getFlags().set(selected[i] + 1, _getFlags().get(selected[i]));
845
                                _getFlags().set(selected[i], aux);
846
                                selected[i]++;
847
                                tblStages.addRowSelectionInterval(selected[i], selected[i]);
848
                        }
849
                        invalidateSolution();
850

    
851
                } else if (c.equals(getBtnRemoveStage())) {
852
                        removeStage();                        
853
                } else if (c.equals(getBtnSaveRoute())) {
854
                        saveRoute();
855
                } else if (c.equals(getBtnSetVelocities())) {
856
                        setVelocities();                        
857
                } else if (c.equals(getBtnCenterOnFlag())) {
858
                        // Center on first selected flag.
859
                        int[] selected = tblStages.getSelectedRows();
860
                        if (selected.length == 0)
861
                                return;
862
                        GvFlag flag = (GvFlag) _getFlags().get(selected[0]);
863
                        IWindow window = PluginServices.getMDIManager().getActiveWindow();
864
                        if(! (window instanceof IView))
865
                                return;
866
                        IView view = (IView) window;
867
                        ViewPort vp = view.getMapControl().getViewPort();
868
                        Rectangle2D extent = vp.getAdjustedExtent();
869
                        double xNC = flag.getOriginalPoint().getX();
870
                        double yNC = flag.getOriginalPoint().getY();
871
                        double width = extent.getWidth();
872
                        double height = extent.getHeight();
873
                        
874
                        Rectangle2D.Double r = new Rectangle2D.Double();
875
                        
876
                        r.width = width;
877
                        r.height = height;
878
                        r.x = xNC - width/2;
879
                        r.y = yNC - height/2;
880

    
881
                        vp.setExtent(r);
882

    
883
                        
884
                                
885
                }
886
                repaint();
887
        }
888

    
889
        private void setVelocities() {
890
                if(network == null){
891
                        IWindow window = PluginServices.getMDIManager().getActiveWindow();
892
                        if(! (window instanceof IView))
893
                                return;
894
                        IView view = (View) window;
895
                        MapControl mapControl = view.getMapControl();
896
                        MapContext map = mapControl.getMapContext();
897
                        FLayers layers = map.getLayers();
898
                        SingleLayerIterator it = new SingleLayerIterator(layers);
899
                        while (it.hasNext() && network == null) {
900
                                FLayer aux = it.next();
901
                                if (!aux.isActive())
902
                                        continue;
903
                                network = (Network) aux.getProperty("network");
904
                        }
905
                }
906
                if (network == null)
907
                        return;
908
                
909
                ArrayList lstTipoTramo = network.getEdgeTypes();
910
                
911
                // I try to use a generic multiinputdialog. All this stuff can be extracted
912
                // from here and subclass MultiInputDlg
913
                Hashtable veloMeters  = network.getVelocities();        
914
                ArrayList veloKm = new ArrayList(lstTipoTramo.size());
915
                if (veloMeters != null)
916
                {                        
917
                        NumberFormat nf = NumberFormat.getInstance();
918
                        for (int i=0; i<lstTipoTramo.size(); i++)
919
                        {
920
                                Object key = lstTipoTramo.get(i);
921
                                Double velM = (Double) veloMeters.get(key);
922
                                System.out.println("Vel. Metros / seg = " + velM);
923
                                if (velM != null)                                        
924
                                        veloKm.add(i, nf.format(velM.doubleValue() * 3.6));
925
                                else
926
                                        veloKm.add(i, "0");
927
                        } // for
928
                }
929
                else
930
                {                        
931
                        for (int i=0; i<lstTipoTramo.size(); i++)
932
                        {
933
                                veloKm.add(i, "60");
934
                        } // for                        
935
                }
936
                try
937
                {
938
                        String msg = PluginServices.getText(this, "msg_set_velocities");
939
                        MultiInputDlg dlg = new MultiInputDlg(msg, lstTipoTramo, veloKm);
940
                        String col1 = PluginServices.getText(this, "col_arc_type");
941
                        String col2 = PluginServices.getText(this, "col_km_per_hour");
942
                        dlg.setColumnNames(col1, col2);
943
                        dlg.setModal(true);
944
                        dlg.setVisible(true);
945
                        if (dlg.isCanceled())
946
                                return;
947
                        
948
                        veloKm = dlg.getRightValues(); //{120, 110, 90, 80, 70, 60, 50, 40};
949
                        veloMeters = new Hashtable(veloKm.size());
950
                        for (int i=0; i<veloKm.size(); i++)
951
                        {
952
                                Object key = lstTipoTramo.get(i);
953
                                veloMeters.put(key, new Double(Double.parseDouble((String) veloKm.get(i)) / 3.6));
954
                        }
955
                        
956
                        network.setVelocities(veloMeters);
957
                }
958
                catch(Exception e)
959
                {
960
                        e.printStackTrace();
961
                }
962

    
963
                
964
        }
965

    
966
        private void invalidateSolution() {
967
                for (int i=0; i < _getFlags().size(); i++)
968
                {
969
                        GvFlag flag = (GvFlag) _getFlags().get(i);
970
                        flag.setCost(-1.0);
971
                }
972
                updateTotalCost();
973
        }
974

    
975
        private void saveStage(){
976
                if(network == null){
977
                        IWindow window = PluginServices.getMDIManager().getActiveWindow();
978
                        if(! (window instanceof IView))
979
                                return;
980
                        IView view = (View) window;
981
                        MapControl mapControl = view.getMapControl();
982
                        MapContext map = mapControl.getMapContext();
983
                        FLayers layers = map.getLayers();
984
                        SingleLayerIterator it = new SingleLayerIterator(layers);
985
                        while (it.hasNext() && network == null) {
986
                                FLayer aux = it.next();
987
                                if (!aux.isActive())
988
                                        continue;
989
                                network = (Network) aux.getProperty("network");
990
                        }
991
                }
992
                if (network == null)
993
                        return;
994

    
995
                List features = new ArrayList();
996
                GvFlag[] flags = network.getFlags();
997
                for(int i = 0; i < flags.length; i++){
998
                        GvFlag flag = flags[i];
999
                        // Solo se guardan los flags habilitados
1000
                        if (!flag.isEnabled())
1001
                                continue;
1002
                        FPoint2D point = new FPoint2D(flag.getOriginalPoint());
1003
                        Value[] values = new Value[6];
1004
                        values[GvFlag.ID_FLAG_INDEX] = ValueFactory.createValue(flag.getIdFlag());
1005
                        values[GvFlag.ID_ARC_INDEX] = ValueFactory.createValue(flag.getIdArc());
1006
                        values[GvFlag.DESCRIPTION_INDEX] = ValueFactory.createValue(flag.getDescription());
1007
                        values[GvFlag.DIREC_INDEX] = ValueFactory.createValue(flag.getDirec());
1008
                        values[GvFlag.PCT_INDEX] = ValueFactory.createValue(flag.getPct());
1009
                        values[GvFlag.COST_INDEX] = ValueFactory.createValue(flag.getCost());
1010
                        IGeometry geo = ShapeFactory.createPoint2D(point);
1011
                        DefaultFeature feature = new DefaultFeature(geo, values, new Integer(flag.getIdFlag()).toString() );
1012
                        features.add(feature);
1013
                }
1014

    
1015
                FlagsMemoryDriver driver = new FlagsMemoryDriver(features);
1016
                IProjection projection = FOpenDialog.getLastProjection();
1017
                FLyrVect routeLayer = (FLyrVect) LayerFactory.createLayer("Flags",
1018
                                driver, projection);
1019

    
1020
                FormatSelectionPanel selectionPanel =
1021
                        new FormatSelectionPanel(PluginServices.
1022
                                        getText(null,
1023
                                "Seleccione_un_formato_para_guardar_los_flags"));
1024
                PluginServices.getMDIManager().addWindow(selectionPanel);
1025

    
1026
                String format = selectionPanel.getSelectedFormat();
1027
                com.iver.cit.gvsig.ExportTo export = new com.iver.cit.gvsig.ExportTo();
1028
                IWindow window = PluginServices.getMDIManager().getActiveWindow();
1029
                if(! (window instanceof IView))
1030
                        return;
1031
                IView view = (View) window;
1032
                MapControl mapControl = view.getMapControl();
1033
                MapContext context = mapControl.getMapContext();
1034
                try {
1035
                        if (format.equalsIgnoreCase("SHP")) {
1036
                                export.saveToShp(context, routeLayer);
1037
                        } else if (format.equalsIgnoreCase("DXF")) {
1038
                                export.saveToDxf(context, routeLayer);
1039
                        } else if (format.equalsIgnoreCase("GML")) {
1040
                                export.saveToGml(context, routeLayer);
1041
                        } else if (format.equalsIgnoreCase("POSTGIS")) {
1042
                                export.saveToPostGIS(context, routeLayer);
1043
                        }
1044
                } catch (EditionException e1) {
1045
                        // TODO Auto-generated catch block
1046
                        e1.printStackTrace();
1047
                } catch (DriverIOException e1) {
1048
                        // TODO Auto-generated catch block
1049
                        e1.printStackTrace();
1050
                }
1051

    
1052
        }
1053
        private void saveRoute() {
1054
                IWindow window = PluginServices.getMDIManager().getActiveWindow();
1055
                if(! (window instanceof IView))
1056
                        return;
1057
                IView view = (View) window;
1058
                MapControl mapControl = view.getMapControl();
1059
                List routes = (List) GvSession.getInstance().get(mapControl, "Route");
1060
                if(routes == null || routes.size() == 0){
1061
                        JOptionPane.showMessageDialog(this, PluginServices.getText(this, "Ruta_borrada_o_inexistente"),
1062
                                        PluginServices.getText(this, "Ruta_no_encontrada"),
1063
                                        JOptionPane.ERROR_MESSAGE);
1064
                        return;
1065
                }        
1066
                Route lastRoute = (Route) routes.get(routes.size() - 1);
1067
                RouteMemoryDriver driver = new RouteMemoryDriver(lastRoute.getFeatureList());
1068
                IProjection projection = FOpenDialog.getLastProjection();
1069
                FLyrVect routeLayer = (FLyrVect) LayerFactory.createLayer("Route",
1070
                                driver, projection);
1071

    
1072
                FormatSelectionPanel selectionPanel = new FormatSelectionPanel(PluginServices.getText(null,
1073
                "Seleccione_un_formato_para_guardar_la_ruta"));
1074
                PluginServices.getMDIManager().addWindow(selectionPanel);
1075

    
1076
                String format = selectionPanel.getSelectedFormat();
1077
                com.iver.cit.gvsig.ExportTo export = new com.iver.cit.gvsig.ExportTo();
1078
                MapContext context = mapControl.getMapContext();
1079
                try {
1080
                        if (format.equalsIgnoreCase("SHP")) {
1081
                                export.saveToShp(context, routeLayer);
1082
                        } else if (format.equalsIgnoreCase("DXF")) {
1083
                                export.saveToDxf(context, routeLayer);
1084
                        } else if (format.equalsIgnoreCase("GML")) {
1085
                                export.saveToGml(context, routeLayer);
1086
                        } else if (format.equalsIgnoreCase("POSTGIS")) {
1087
                                export.saveToPostGIS(context, routeLayer);
1088
                        }
1089
                } catch (EditionException e1) {
1090
                        // TODO Auto-generated catch block
1091
                        e1.printStackTrace();
1092
                } catch (DriverIOException e1) {
1093
                        // TODO Auto-generated catch block
1094
                        e1.printStackTrace();
1095
                }
1096
        }
1097

    
1098
        /**
1099
         * Converts a point layer loaded in the active view's toc in a collection of
1100
         * flags of the active network
1101
         *
1102
         */
1103
        private void loadStages() {
1104

    
1105
                IWindow window = PluginServices.getMDIManager().getActiveWindow();
1106
                if(! (window instanceof IView))
1107
                        return;
1108
                IView view = (IView) window;
1109
                MapControl mapControl = view.getMapControl();
1110
                MapContext map = mapControl.getMapContext();
1111
                FLayers layers = map.getLayers();
1112

    
1113
                String title = PluginServices.getText(this,
1114
                                "Seleccionar_capa_con_puntos_de_parada");
1115
                String introductoryText = PluginServices.getText(this,
1116
                                "Seleccione_una_capa_de_puntos_para_crear_paradas");
1117

    
1118
                LayerSelectionPanel selectionPanel = new LayerSelectionPanel(layers,
1119
                                title, introductoryText, FLyrVect.class, FShape.POINT);
1120
                PluginServices.getMDIManager().addWindow(selectionPanel);
1121

    
1122
                if (!selectionPanel.wasFinishPressed())
1123
                        return;
1124
                else {
1125
                        FLayer layer = selectionPanel.getLayer();
1126
                        if (layer == null)
1127
                                return;
1128
                        if (!(layer instanceof FLyrVect))
1129
                                return;
1130
                        FLyrVect vectLyr = (FLyrVect) layer;
1131

    
1132
                        try {
1133
                                if (vectLyr.getShapeType() != FShape.POINT)
1134
                                        return;
1135

    
1136
                                // TODO
1137
                                // Hay que refinar bastante, para que el usuario elija
1138
                                // con que red y con qu? capa lineal quiere trabajar
1139
                                // tal y como est?, si hubiese varias se trabajaria
1140
                                // con la primera que devuelva el iterador
1141

    
1142
                                Network net = null;
1143
                                SingleLayerIterator it = new SingleLayerIterator(layers);
1144
                                while (it.hasNext() && net == null) {
1145
                                        FLayer aux = it.next();
1146
                                        if (!aux.isActive())
1147
                                                continue;
1148
                                        net = (Network) aux.getProperty("network");
1149
                                }
1150
                                if (net == null)
1151
                                        return;
1152

    
1153
                                // Por si queremos a?adir paradas a otras ya existentes
1154
//                                _getFlags().clear();
1155
                                
1156
                                GvFlag flag;
1157
                                ReadableVectorial reader = vectLyr.getSource();
1158
                                SelectableDataSource recordset = vectLyr.getRecordset();
1159
                                int numShapes = reader.getShapeCount();
1160

    
1161
                                double realTol = mapCtrl.getViewPort()
1162
                                                .toMapDistance(FlagListener.pixelTolerance);
1163
                                reader.start();
1164
                                for (int i = 0; i < numShapes; i++) {
1165
                                        Geometry geo = reader.getShape(i).toJTSGeometry();
1166
                                        if (!((geo instanceof Point) || (geo instanceof MultiPoint)))
1167
                                                continue;
1168
                                        
1169
                                        
1170

    
1171
                                        Coordinate[] coords = geo.getCoordinates();
1172
                                        for (int j = 0; j < coords.length; j++) {
1173

    
1174
                                                try {
1175
                                                        flag = net.addFlag(coords[j].x, coords[j].y, realTol);
1176
                                                        if (flag == null)
1177
                                                        {
1178
                                                                // segundo intento:
1179
                                                                flag = net.addFlag(coords[j].x, coords[j].y, 4*realTol);
1180
                                                                if (flag == null)
1181
                                                                {                                                                
1182
                                                                        NullPointerException e = new NullPointerException("Punto " + i + " fuera de la red. Tolerancia=" + realTol);
1183
                                                                        NotificationManager.addError("No se puedo situar el registro " + i + 
1184
                                                                                        "Por favor, compruebe que est? encima de la red o aumente la toleracina.", e);
1185
                                                                }
1186
                                                        }
1187
                                                        if (flag != null)
1188
                                                        {
1189
                                                        // TODO: Create use a IFlagListener to do this
1190
                                                        // inside flagsChanged. The best solution is
1191
                                                        // to put all the code in RouteControlPanel
1192
                                                                NetworkUtils.addGraphicFlag(mapControl, flag);
1193
                                                        }
1194
                                                } catch (GraphException e) {
1195
                                                        e.printStackTrace();
1196
                                                        NotificationManager.addError("No se puedo situar el registro " + i + 
1197
                                                                        "Por favor, compruebe que est? encima de la red.", e);
1198
                                                }
1199

    
1200
                                        } // for j
1201
                                } // for i
1202
                                reader.stop();
1203
                                mapControl.drawGraphics();
1204
                                PluginServices.getMainFrame().enableControls();
1205

    
1206
                        } catch (DriverException e1) {
1207
                                return;
1208
                        } catch (DriverIOException e2) {
1209
                                return;
1210
                        }
1211
                }
1212
        }
1213

    
1214
        /**
1215
         * Removes the selected flags in the component's table from: -the graphic
1216
         * layer of the active view -the active network -the own table
1217
         *
1218
         */
1219
        private void removeStage() {
1220
                int[] selected = tblStages.getSelectedRows();
1221

    
1222
                for (int i = selected.length - 1; i >= 0; i--) {
1223
                        try {
1224
                                // removeFlag(selected[i]);
1225
                                if (network != null) {
1226
                                        final GvFlag flag = (GvFlag) _getFlags().get(selected[i]);
1227
                                        NetworkUtils.clearFlagFromGraphics(mapCtrl, flag);
1228
                                        network.removeFlag(flag);
1229
                                        mapCtrl.repaint();
1230
                                }
1231
                        } catch (IndexOutOfBoundsException iobEx) {
1232
                        }
1233

    
1234
                }// for
1235
                tblStages.clearSelection();
1236
                invalidateSolution();
1237
                mapCtrl.drawMap(false);
1238
        }
1239

    
1240
        public GvFlag[] getFlags() {
1241
                return (GvFlag[]) _getFlags().toArray(new GvFlag[0]);
1242
        }
1243

    
1244
        public void flagsChanged(int reason) {
1245
                refresh();
1246
                mapCtrl.drawGraphics();
1247

    
1248
        }
1249
} // @jve:decl-index=0:visual-constraint="17,9"