Statistics
| Revision:

gvsig-projects-pool / org.gvsig.topology / trunk / org.gvsig.topology / org.gvsig.topology.swing / org.gvsig.topology.swing.impl / src / main / java / org / gvsig / topology / swing / impl / DefaultJTopologyReport.java @ 727

History | View | Annotate | Download (26 KB)

1 688 jjdelcerro
package org.gvsig.topology.swing.impl;
2
3 722 jjdelcerro
import java.awt.BorderLayout;
4 688 jjdelcerro
import java.awt.Dimension;
5
import java.awt.event.ActionEvent;
6
import java.awt.event.ActionListener;
7 723 jjdelcerro
import java.awt.event.MouseAdapter;
8
import java.awt.event.MouseEvent;
9 727 jjdelcerro
import java.net.URL;
10
import java.util.ArrayList;
11 688 jjdelcerro
import java.util.HashSet;
12
import java.util.List;
13
import java.util.Set;
14
import javax.swing.DefaultComboBoxModel;
15 727 jjdelcerro
import javax.swing.ImageIcon;
16 688 jjdelcerro
import javax.swing.JComponent;
17
import javax.swing.JMenuItem;
18
import javax.swing.JPopupMenu;
19
import javax.swing.JTable;
20
import javax.swing.SwingUtilities;
21
import javax.swing.event.ChangeEvent;
22
import javax.swing.event.ChangeListener;
23
import javax.swing.event.ListSelectionEvent;
24
import javax.swing.event.ListSelectionListener;
25
import javax.swing.event.TableModelEvent;
26
import javax.swing.event.TableModelListener;
27
import javax.swing.table.TableModel;
28 727 jjdelcerro
import org.apache.commons.io.FilenameUtils;
29 688 jjdelcerro
import org.apache.commons.lang3.StringUtils;
30
import org.gvsig.expressionevaluator.ExpressionBuilder;
31
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
32
import org.gvsig.fmap.dal.feature.FeatureSelection;
33
import org.gvsig.fmap.geom.Geometry;
34
import org.gvsig.fmap.geom.primitive.Envelope;
35
import org.gvsig.tools.ToolsLocator;
36 722 jjdelcerro
import org.gvsig.tools.dynform.DynFormLocator;
37 688 jjdelcerro
import org.gvsig.tools.dynform.JDynForm;
38 722 jjdelcerro
import org.gvsig.tools.dynobject.DynObject;
39 688 jjdelcerro
import org.gvsig.tools.i18n.I18nManager;
40
import org.gvsig.tools.observer.Observable;
41
import org.gvsig.tools.observer.Observer;
42
import org.gvsig.tools.swing.api.ListElement;
43
import org.gvsig.tools.swing.api.ToolsSwingLocator;
44
import org.gvsig.tools.swing.api.ToolsSwingManager;
45
import org.gvsig.tools.swing.api.task.TaskStatusController;
46 727 jjdelcerro
import org.gvsig.tools.swing.icontheme.IconTheme;
47 688 jjdelcerro
import org.gvsig.tools.task.TaskStatus;
48
import org.gvsig.topology.lib.api.TopologyLocator;
49
import org.gvsig.topology.lib.api.TopologyPlan;
50
import org.gvsig.topology.lib.api.TopologyReport;
51
import org.gvsig.topology.lib.api.TopologyReportLine;
52
import org.gvsig.topology.lib.api.TopologyReportLineSet;
53
import org.gvsig.topology.lib.api.TopologyRule;
54
import org.gvsig.topology.lib.api.TopologyRuleAction;
55
import org.gvsig.topology.lib.api.TopologyRuleFactory;
56
import org.gvsig.topology.swing.api.JTopologyReport;
57
import org.gvsig.topology.swing.api.TopologySwingLocator;
58
import org.gvsig.topology.swing.api.TopologySwingServices;
59
import org.gvsig.topology.swing.api.TopologySwingServices.WorkingAreaChangedListener;
60
import org.slf4j.Logger;
61
import org.slf4j.LoggerFactory;
62
63
/**
64
 *
65
 * @author jjdelcerro
66
 */
67
@SuppressWarnings("UseSpecificCatch")
68
public class DefaultJTopologyReport
69
        extends DefaultJTopologyReportView
70
        implements JTopologyReport {
71
72
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultJTopologyReport.class);
73
74
75
    private class TopologyRuleActionParametersListener implements ActionListener {
76
77
        private final TopologyRule rule;
78 727 jjdelcerro
        private final List<TopologyReportLine> lines;
79 688 jjdelcerro
        private final TopologyRuleAction action;
80
        private final JDynForm form;
81
82
        public TopologyRuleActionParametersListener(
83
                TopologyRule rule,
84 727 jjdelcerro
                List<TopologyReportLine> lines,
85 688 jjdelcerro
                TopologyRuleAction action,
86
                JDynForm form
87
        ) {
88
            this.action = action;
89 727 jjdelcerro
            this.lines = lines;
90 688 jjdelcerro
            this.rule = rule;
91
            this.form = form;
92
        }
93
94
        @Override
95
        public void actionPerformed(ActionEvent e) {
96 727 jjdelcerro
            doExecuteRuleAction(rule, lines, action, form);
97 688 jjdelcerro
        }
98
    }
99
100
101
    private class TopologyRuleActionListener implements ActionListener {
102
103
        private final TopologyRule rule;
104 727 jjdelcerro
        private final List<TopologyReportLine> lines;
105 688 jjdelcerro
        private final TopologyRuleAction action;
106
107
        public TopologyRuleActionListener(
108
                TopologyRule rule,
109 727 jjdelcerro
                List<TopologyReportLine> lines,
110 688 jjdelcerro
                TopologyRuleAction action
111
        ) {
112
            this.action = action;
113 727 jjdelcerro
            this.lines = lines;
114 688 jjdelcerro
            this.rule = rule;
115
        }
116
117
        @Override
118
        public void actionPerformed(ActionEvent e) {
119 722 jjdelcerro
            if ( this.action.hasParameters() ) {
120 727 jjdelcerro
                doShowActionParametersPanel(this.rule, this.lines, this.action);
121 722 jjdelcerro
            } else {
122 727 jjdelcerro
                doExecuteRuleAction(rule, lines, action, null);
123 722 jjdelcerro
            }
124 688 jjdelcerro
        }
125
    }
126
127
    private ReportTable linesModel;
128
    private final TopologySwingServices services;
129
    private TaskStatusController taskStatusController;
130
    private TopologyPlan plan;
131
    private WorkingAreaChangedListener workingAreaChangedListener;
132
133
    public DefaultJTopologyReport(TopologyPlan plan) {
134
        this.services = TopologySwingLocator.getTopologySwingManager().getDefaultServices();
135
        this.initComponents();
136
    }
137
138
    private void initComponents() {
139
        I18nManager i18n = ToolsLocator.getI18nManager();
140
        this.linesModel = new ReportTable();
141
        this.workingAreaChangedListener = new WorkingAreaChangedListener() {
142
            @Override
143
            public void workingAreaChanged(Envelope workingArea) {
144
                doUpdateFilter();
145
            }
146
        };
147
        this.tblErrors.setModel(this.linesModel);
148
        this.tblErrors.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
149 727 jjdelcerro
        this.btnZoomGeometry.addActionListener(new ActionListener() {
150 688 jjdelcerro
            @Override
151
            public void actionPerformed(ActionEvent e) {
152 727 jjdelcerro
                doZoomGeometry();
153 688 jjdelcerro
            }
154
        });
155 727 jjdelcerro
        this.btnZoomError.addActionListener(new ActionListener() {
156 688 jjdelcerro
            @Override
157
            public void actionPerformed(ActionEvent e) {
158 727 jjdelcerro
                doZoomError();
159 688 jjdelcerro
            }
160
        });
161 727 jjdelcerro
        this.btnCenterGeometry.addActionListener(new ActionListener() {
162
            @Override
163
            public void actionPerformed(ActionEvent e) {
164
                doCenterGeometry();
165
            }
166
        });
167
        this.btnCenterError.addActionListener(new ActionListener() {
168
            @Override
169
            public void actionPerformed(ActionEvent e) {
170
                doCenterError();
171
            }
172
        });
173 688 jjdelcerro
        this.btnRefresh.addActionListener(new ActionListener() {
174
            @Override
175
            public void actionPerformed(ActionEvent e) {
176
                doExecutePlan();
177
            }
178
        });
179
        this.tblErrors.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
180
            @Override
181
            public void valueChanged(ListSelectionEvent e) {
182
                doRowSelected();
183
            }
184
        });
185 723 jjdelcerro
        this.tblErrors.addMouseListener(new MouseAdapter() {
186
            @Override
187
            public void mouseClicked(MouseEvent e) {
188
                if( e.getButton()==MouseEvent.BUTTON1 && e.getClickCount()==2 ) {
189 727 jjdelcerro
                    doCenterError();
190 723 jjdelcerro
                }
191
            }
192
        });
193
194 688 jjdelcerro
        this.btnActions.addActionListener(new ActionListener() {
195
            @Override
196
            public void actionPerformed(ActionEvent e) {
197
                doSelectAction();
198
            }
199
        });
200
        this.btnParametersCancel.addActionListener(new ActionListener() {
201
            @Override
202
            public void actionPerformed(ActionEvent e) {
203
                tabData.setEnabledAt(0, true);
204
                tabData.setEnabledAt(1, false);
205
                tabData.setSelectedIndex(0);
206
                pnlParameters.removeAll();
207
            }
208
        });
209
        this.btnShowErrors.addActionListener(new ActionListener() {
210
            @Override
211
            public void actionPerformed(ActionEvent e) {
212
                doUpdateFilter();
213
            }
214
        });
215
        this.btnShowExceptions.addActionListener(new ActionListener() {
216
            @Override
217
            public void actionPerformed(ActionEvent e) {
218
                doUpdateFilter();
219
            }
220
        });
221
        this.btnVisibleExtentOnly.addActionListener(new ActionListener() {
222
            @Override
223
            public void actionPerformed(ActionEvent e) {
224
                doUpdateFilter();
225
            }
226
        });
227 727 jjdelcerro
        this.btnShowForm.addActionListener(new ActionListener() {
228
            @Override
229
            public void actionPerformed(ActionEvent e) {
230
                services.setShowFormWhenEdit(btnShowForm.isSelected());
231
            }
232
        });
233
        this.btnEraseErrorMarks.addActionListener(new ActionListener() {
234
            @Override
235
            public void actionPerformed(ActionEvent e) {
236
                services.addError(null);
237
            }
238
        });
239 688 jjdelcerro
        DefaultComboBoxModel<ListElement<TopologyRuleFactory>> modelRules = new DefaultComboBoxModel<>();
240
        modelRules.addElement(new ListElement<>(i18n.getTranslation("_Any_rule"), (TopologyRuleFactory)null));
241
        List<TopologyRuleFactory> factories = TopologyLocator.getTopologyManager().getRuleFactories();
242
        for (TopologyRuleFactory factory : factories) {
243
            modelRules.addElement(new ListElement<>(factory.getName(), factory));
244
        }
245
        this.cboRules.setModel(modelRules);
246
        this.cboRules.addActionListener(new ActionListener() {
247
            @Override
248
            public void actionPerformed(ActionEvent e) {
249
                // Llama al invokeLater para poder debugguear
250
                SwingUtilities.invokeLater(new Runnable() {
251
                    @Override
252
                    public void run() {
253
                        doUpdateFilter();
254
                    }
255
                });
256
            }
257
        });
258
        this.taskStatusController = ToolsSwingLocator.getTaskStatusSwingManager().createTaskStatusController(
259
                null,
260
                this.lblTaskStatusTitle,
261
                this.lblTaskStatusMessage,
262
                this.pbTaskStatusProgress,
263
                this.btnTaskStatusCancel,
264
                null
265
        );
266
        this.translate();
267
        this.setPreferredSize(new Dimension(700, 200));
268
269
        this.btnShowErrors.setSelected(false);
270
        this.btnShowExceptions.setSelected(false);
271
        this.btnVisibleExtentOnly.setSelected(false);
272
273
        this.tabData.setEnabledAt(1, false);
274
275
    }
276 727 jjdelcerro
277
    @Override
278
    public ImageIcon loadImage(String imageName) {
279
        String name = FilenameUtils.getBaseName(imageName);
280
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
281
        if (theme.exists(name)) {
282
            return theme.get(name);
283
        }
284
        URL url = this.getClass().getResource("/"+imageName);
285
        if (url == null) {
286
            return null;
287
        }
288
        return new ImageIcon(url);
289
    }
290 688 jjdelcerro
291
    private void translate() {
292
        ToolsSwingManager tsm = ToolsSwingLocator.getToolsSwingManager();
293
        tsm.translate(this.btnActions);
294 727 jjdelcerro
        tsm.translate(this.btnCenterError);
295
        tsm.translate(this.btnCenterGeometry);
296 688 jjdelcerro
        tsm.translate(this.btnRefresh);
297
        tsm.translate(this.btnShowErrors);
298
        tsm.translate(this.btnShowExceptions);
299 727 jjdelcerro
        tsm.translate(this.btnZoomError);
300
        tsm.translate(this.btnZoomGeometry);
301
        tsm.translate(this.btnEraseErrorMarks);
302 688 jjdelcerro
        tsm.translate(this.btnVisibleExtentOnly);
303
        tsm.translate(this.btnParametersAccept);
304
        tsm.translate(this.btnParametersCancel);
305 727 jjdelcerro
        tsm.translate(this.btnShowForm);
306 688 jjdelcerro
        tsm.translate(this.lblShow);
307
        tsm.translate(this.tabData);
308
    }
309
310
    @Override
311
    public void put(TopologyPlan plan) {
312
        this.plan = plan;
313
        this.taskStatusController.bind(this.plan.getTaskStatus());
314
        this.plan.getTaskStatus().addObserver(new Observer() {
315
            @Override
316
            public void update(Observable o, Object o1) {
317
                doTaskStatusUpdated(o, o1);
318
            }
319
        });
320
        this.linesModel.setReport(plan.getReport());
321
    }
322
323
    @Override
324
    public JComponent asJComponent() {
325
        return this;
326
    }
327
328
    private void doUpdateFilter() {
329
        this.linesModel.setFilter(this.getFilter());
330
    }
331
332
    private String getFilter() {
333
        ExpressionBuilder builder = ExpressionEvaluatorLocator.getManager().createExpressionBuilder();
334
        TopologyRuleFactory ruleFactory = (TopologyRuleFactory) ListElement.getSelected(cboRules);
335
        if( ruleFactory != null ) {
336
            builder.setValue(
337
                builder.eq(
338
                    builder.column(TopologyReport.RULE_ID),
339
                    builder.constant(ruleFactory.getId())
340
                )
341
            );
342
        }
343
        if( this.btnShowErrors.isSelected() ) {
344
            if( btnShowExceptions.isSelected()) {
345
                builder.and(
346
                        builder.or(
347
                            builder.column(TopologyReport.IS_ERROR),
348
                            builder.column(TopologyReport.IS_EXCEPTION)
349
                        )
350
                );
351
            } else {
352
                builder.and(
353
                    builder.column(TopologyReport.IS_ERROR)
354
                );
355
            }
356
        } else if( btnShowExceptions.isSelected()) {
357
            builder.and(
358
                builder.column(TopologyReport.IS_EXCEPTION)
359
            );
360
        }
361
        if( this.btnVisibleExtentOnly.isSelected() ) {
362
            Envelope workingArea = this.services.getWorkingArea();
363
            if( workingArea!=null ) {
364
                builder.and(
365
                        builder.ST_Intersects(
366
                                builder.column(TopologyReport.GEOMETRY),
367
                                builder.geometry(workingArea.getGeometry())
368
                        )
369
                );
370
            }
371
            this.services.addWorkingAreaChangedListener(this.workingAreaChangedListener);
372
        } else {
373
            this.services.removeWorkingAreaChangedListener(this.workingAreaChangedListener);
374
        }
375
        if( builder.getValue()==null ) {
376
            return null;
377
        }
378
        return builder.toString();
379
    }
380
381
    private void doExecutePlan() {
382
        Thread th = new Thread(new Runnable() {
383
            @Override
384
            public void run() {
385
                plan.execute();
386
            }
387
        }, "TopologyPlan-" + plan.getName());
388
        th.start();
389
    }
390
391
    private void doTaskStatusUpdated(final Observable observable, final Object notification) {
392
        if (observable != null && !(observable instanceof TaskStatus)) {
393
            return;
394
        }
395
        if (!SwingUtilities.isEventDispatchThread()) {
396
            SwingUtilities.invokeLater(new Runnable() {
397
                public void run() {
398
                    doTaskStatusUpdated(observable, notification);
399
                }
400
            });
401
            return;
402
        }
403
        TaskStatus taskStatus = (TaskStatus) observable;
404 722 jjdelcerro
        if (taskStatus==null || !taskStatus.isRunning()) {
405
            this.lblTaskStatusTitle.setVisible(false);
406 688 jjdelcerro
            this.lblTaskStatusMessage.setVisible(false);
407
            this.pbTaskStatusProgress.setVisible(false);
408
            this.btnTaskStatusCancel.setVisible(false);
409
            this.btnRefresh.setEnabled(true);
410 722 jjdelcerro
            I18nManager i18n = ToolsLocator.getI18nManager();
411
            message(i18n.getTranslation("_Errors")+": "+this.linesModel.getRowCount());
412 688 jjdelcerro
            return;
413
        }
414
        if (!this.pbTaskStatusProgress.isVisible()) {
415 722 jjdelcerro
            this.lblTaskStatusTitle.setVisible(true);
416 688 jjdelcerro
            this.lblTaskStatusMessage.setVisible(true);
417
            this.pbTaskStatusProgress.setVisible(true);
418
            this.btnTaskStatusCancel.setVisible(true);
419
            this.btnRefresh.setEnabled(false);
420
        }
421
    }
422
423 722 jjdelcerro
    private void message(String msg) {
424
        this.lblTaskStatusTitle.setText(msg);
425
        this.lblTaskStatusTitle.setVisible(true);
426
    }
427
428 688 jjdelcerro
    private void doSelectAction() {
429
        int n = this.tblErrors.getSelectedRow();
430
        if (n < 0) {
431
            return;
432
        }
433 727 jjdelcerro
        int[] selectedRows = this.tblErrors.getSelectedRows();
434
        TopologyRule rule = this.linesModel.getLine(selectedRows[0]).getRule();
435 688 jjdelcerro
        List<TopologyRuleAction> actions = rule.getActions();
436
        if (actions == null || actions.isEmpty()) {
437
            return;
438 727 jjdelcerro
        }
439
        List<TopologyReportLine>lines = new ArrayList<>();
440
        for (int selectedRow : selectedRows) {
441
            TopologyReportLine line = this.linesModel.getLine(selectedRow);
442
            if( line.getRule()==rule ) {
443
                lines.add(line);
444
            }
445 688 jjdelcerro
        }
446
        JPopupMenu menu = new JPopupMenu();
447
        for (TopologyRuleAction action : actions) {
448 722 jjdelcerro
            JMenuItem item;
449
            if( action.hasParameters() ) {
450
                item = new JMenuItem(action.getName()+"...");
451
            } else {
452
                item = new JMenuItem(action.getName());
453
            }
454 727 jjdelcerro
            item.addActionListener(new TopologyRuleActionListener(rule, lines, action));
455
            if( lines.size()>1 && action.hasParameters() ) {
456
                item.setEnabled(false);
457
            }
458 688 jjdelcerro
            menu.add(item);
459
        }
460
        menu.show(this.btnActions, 0, this.btnActions.getHeight());
461
    }
462
463
    private void doExecuteRuleAction(
464
            TopologyRule rule,
465 727 jjdelcerro
            List<TopologyReportLine> lines,
466 688 jjdelcerro
            TopologyRuleAction action,
467
            JDynForm form
468
    ) {
469 722 jjdelcerro
        DynObject parameters = null;
470
        if( form!=null ) {
471
            parameters = action.createParameters();
472
            if( parameters!=null ) {
473
                form.getValues(parameters);
474
            }
475
        }
476 727 jjdelcerro
        for (TopologyReportLine line : lines) {
477
            action.execute(rule, line, parameters);
478
        }
479 726 jjdelcerro
        this.tabData.setEnabledAt(0, true);
480
        this.tabData.setEnabledAt(1, false);
481
        this.tabData.setSelectedIndex(0);
482
        this.pnlParameters.removeAll();
483 727 jjdelcerro
        this.services.addError(null);
484 688 jjdelcerro
    }
485
486
    private void doShowActionParametersPanel(
487
            TopologyRule rule,
488 727 jjdelcerro
            List<TopologyReportLine> lines,
489 688 jjdelcerro
            TopologyRuleAction action
490
    ) {
491
        I18nManager i18n = ToolsLocator.getI18nManager();
492
        this.tabData.setEnabledAt(0, false);
493
        this.tabData.setEnabledAt(1, true);
494
        this.tabData.setSelectedIndex(1);
495
496
        try {
497
            JDynForm form = null;
498
            this.lblActionTitle.setText(
499
                    "<html>" +
500
                    i18n.getTranslation("_Rule") + ": <b>" +
501
                    rule.getName() + "</b>, " +
502
                    i18n.getTranslation("_Action") + ": <b>" +
503
                    action.getName() + "</b></html>"
504
            );
505
            this.lblActionDescription.setText("<html>"+action.getShortDescription()+"</html>");
506 722 jjdelcerro
            DynObject parameters = action.createParameters();
507
            if( parameters!=null ) {
508
                form = DynFormLocator.getDynFormManager().createJDynForm(parameters);
509
                if( form!=null ) {
510
                    this.pnlParameters.setLayout(new BorderLayout());
511
                    this.pnlParameters.removeAll();
512
                    this.pnlParameters.add(form.asJComponent(), BorderLayout.CENTER);
513
                    this.pnlParameters.revalidate();
514
                    this.pnlParameters.repaint();
515
                }
516
            }
517 688 jjdelcerro
            this.btnParametersAccept.addActionListener(
518 727 jjdelcerro
                new TopologyRuleActionParametersListener(rule, lines, action, form)
519 688 jjdelcerro
            );
520
        } catch (Exception ex) {
521
            LOGGER.warn("Can't show action parameters panel.",ex);
522
        }
523
    }
524
525 727 jjdelcerro
    private void doZoomGeometry() {
526 688 jjdelcerro
        int n = this.tblErrors.getSelectedRow();
527
        if (n < 0) {
528
            return;
529
        }
530
        TopologyReportLine line = this.linesModel.getLine(n);
531
        Geometry geom = line.getGeometry();
532
        this.services.zoomTo(geom.getEnvelope());
533
    }
534
535 727 jjdelcerro
    private void doZoomError() {
536
        int n = this.tblErrors.getSelectedRow();
537
        if (n < 0) {
538
            return;
539
        }
540
        TopologyReportLine line = this.linesModel.getLine(n);
541
        Geometry geom = line.getError();
542
        if( geom == null ) {
543
            geom = line.getGeometry();
544
            services.addError(null);
545
        } else {
546
            services.addError(geom);
547
        }
548
        this.services.zoomTo(geom.getEnvelope());
549
    }
550
551
    private void doCenterGeometry() {
552 688 jjdelcerro
        try {
553
            int n = this.tblErrors.getSelectedRow();
554
            if (n < 0) {
555
                return;
556
            }
557
            TopologyReportLine line = this.linesModel.getLine(n);
558
            Geometry geom = line.getGeometry();
559
            this.services.centerTo(geom.centroid());
560
        } catch (Exception ex) {
561
            LOGGER.warn("Can't center topology error", ex);
562
        }
563
    }
564
565 727 jjdelcerro
    private void doCenterError() {
566
        try {
567
            int n = this.tblErrors.getSelectedRow();
568
            if (n < 0) {
569
                return;
570
            }
571
            TopologyReportLine line = this.linesModel.getLine(n);
572
            Geometry geom = line.getError();
573
            if( geom == null ) {
574
                geom = line.getGeometry();
575
                services.addError(null);
576
            } else {
577
                services.addError(geom);
578
            }
579
            this.services.centerTo(geom.centroid());
580
        } catch (Exception ex) {
581
            LOGGER.warn("Can't center topology error", ex);
582
        }
583
    }
584
585 688 jjdelcerro
    private void doRowSelected() {
586
        try {
587
            int n = this.tblErrors.getSelectedRow();
588
            if (n < 0) {
589
                return;
590
            }
591
            TopologyReportLine line = this.linesModel.getLine(n);
592
            if (line.getFeature1() == null) {
593
                return;
594
            }
595 727 jjdelcerro
            this.services.addError(null);
596
            FeatureSelection selection = line.getDataSet1().getFeatureStore().getFeatureSelection();
597 688 jjdelcerro
            selection.deselectAll();
598
            selection.select(line.getFeature1());
599
        } catch (Exception ex) {
600
            LOGGER.warn("Can't select topology error", ex);
601
        }
602
    }
603
604
    private static class ReportTable implements TableModel {
605
606
        private TopologyReport report;
607
        private TopologyReportLineSet lines;
608
        private final String[] columnNames;
609
        private final Class[] columnClasses;
610
        private final Set<TableModelListener> tableListeners;
611
        private final ChangeListener reportListener;
612
        private String lastFilter;
613
614
        public ReportTable() {
615
            I18nManager i18n = ToolsLocator.getI18nManager();
616
            this.report = null;
617
            this.lines = null;
618
            this.tableListeners = new HashSet<>();
619
            this.columnNames = new String[]{
620
                i18n.getTranslation("_Rule"),
621
                i18n.getTranslation("_Dataset1"),
622
                i18n.getTranslation("_Dataset2"),
623
                i18n.getTranslation("_Exception"),
624
                i18n.getTranslation("_Description")
625
            };
626
            this.columnClasses = new Class[]{
627
                String.class,
628
                String.class,
629
                String.class,
630
                Boolean.class,
631
                String.class
632
            };
633
            this.reportListener = new ChangeListener() {
634
                @Override
635
                public void stateChanged(final ChangeEvent e) {
636
                    if( !SwingUtilities.isEventDispatchThread() ) {
637
                        SwingUtilities.invokeLater(new Runnable() {
638
                            @Override
639
                            public void run() {
640
                                stateChanged(e);
641
                            }
642
                        });
643
                        return;
644
                    }
645
                    fireTableChanged();
646
                }
647
            };
648
        }
649
650
        public void setReport(TopologyReport report) {
651
            if (this.report != null) {
652
                this.report.removeChangeListener(this.reportListener);
653
            }
654
            this.report = report;
655
            this.lines = this.report;
656
            this.lines.addChangeListener(this.reportListener);
657
        }
658
659
        public void setFilter(String filter) {
660
            if( StringUtils.equals(filter, this.lastFilter) ) {
661
                return;
662
            }
663
            this.lines = this.report.getLineSet(filter);
664
            this.lines.addChangeListener(this.reportListener);
665
            this.lastFilter = filter;
666
            this.fireTableChanged();
667
        }
668
669
        public TopologyReport getReport() {
670
            return this.report;
671
        }
672
673
        @Override
674
        public int getRowCount() {
675
            if (this.lines == null) {
676
                return 0;
677
            }
678
            return this.lines.size();
679
        }
680
681
        @Override
682
        public int getColumnCount() {
683
            return 5;
684
        }
685
686
        @Override
687
        public String getColumnName(int columnIndex) {
688
            return this.columnNames[columnIndex];
689
        }
690
691
        @Override
692
        public Class<?> getColumnClass(int columnIndex) {
693
            return this.columnClasses[columnIndex];
694
        }
695
696
        @Override
697
        public boolean isCellEditable(int rowIndex, int columnIndex) {
698
            return false;
699
        }
700
701
        @Override
702
        public Object getValueAt(int rowIndex, int columnIndex) {
703
            if (this.lines == null) {
704
                return "";
705
            }
706
            TopologyReportLine line = this.lines.get(rowIndex);
707
            switch (columnIndex) {
708
                case 0:
709
                    return line.getRule().getName();
710
                case 1:
711
                    return line.getDataSet1().getName();
712
                case 2:
713
                    if (line.getDataSet2() == null) {
714
                        return "";
715
                    }
716
                    return line.getDataSet2().getName();
717
                case 3:
718
                    return line.isException();
719
                case 4:
720
                    return line.getDescription();
721
                default:
722
                    return "???";
723
            }
724
        }
725
726
        @Override
727
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
728
        }
729
730
        @Override
731
        public void addTableModelListener(TableModelListener l) {
732
            this.tableListeners.add(l);
733
        }
734
735
        @Override
736
        public void removeTableModelListener(TableModelListener l) {
737
            this.tableListeners.remove(l);
738
        }
739
740
        private void fireTableChanged() {
741
            for (TableModelListener tableListener : this.tableListeners) {
742
                tableListener.tableChanged(new TableModelEvent(this));
743
            }
744
        }
745
746
        public TopologyReportLine getLine(int lineNum) {
747
            return this.lines.get(lineNum);
748
        }
749
750
    }
751
}