Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.labeling.app / org.gvsig.labeling.app.mainplugin / src / main / java / org / gvsig / labeling / gui / layerproperties / DefaultLabeling.java @ 41920

History | View | Annotate | Download (11.4 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.labeling.gui.layerproperties;
25

    
26
import java.awt.BorderLayout;
27
import java.awt.FlowLayout;
28
import java.awt.IllegalComponentStateException;
29
import java.awt.Rectangle;
30
import java.awt.event.ActionEvent;
31
import java.awt.event.ActionListener;
32
import java.awt.event.ItemEvent;
33
import java.awt.event.ItemListener;
34
import java.awt.geom.Rectangle2D;
35
import java.beans.PropertyChangeEvent;
36

    
37
import javax.swing.JButton;
38
import javax.swing.JCheckBox;
39
import javax.swing.JOptionPane;
40
import javax.swing.JPanel;
41
import javax.swing.JSplitPane;
42

    
43
import org.gvsig.andami.messages.NotificationManager;
44
import org.gvsig.app.ApplicationLocator;
45
import org.gvsig.fmap.dal.exception.DataException;
46
import org.gvsig.fmap.dal.exception.ReadException;
47
import org.gvsig.fmap.dal.feature.Feature;
48
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
49
import org.gvsig.fmap.dal.feature.FeatureSelection;
50
import org.gvsig.fmap.dal.feature.FeatureSet;
51
import org.gvsig.fmap.dal.feature.FeatureStore;
52
import org.gvsig.fmap.dal.feature.FeatureType;
53
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelClass;
54
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingMethod;
55
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
56
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IPlacementConstraints;
57
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IZoomConstraints;
58
import org.gvsig.fmap.mapcontext.rendering.symbols.styles.ILabelStyle;
59
import org.gvsig.gui.beans.swing.JBlank;
60
import org.gvsig.i18n.Messages;
61
import org.gvsig.labeling.gui.styling.LayerPreview;
62
import org.gvsig.labeling.label.GeneralLabelingStrategy;
63
import org.gvsig.labeling.lang.LabelClassUtils;
64
import org.gvsig.symbology.SymbologyLocator;
65
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.DefaultLabelingMethod;
66
import org.gvsig.tools.dispose.DisposableIterator;
67
import org.slf4j.Logger;
68
import org.slf4j.LoggerFactory;
69

    
70
public class DefaultLabeling extends AbstractLabelingMethodPanel implements
71
                ActionListener {
72

    
73
        private static final Logger logger = LoggerFactory
74
                        .getLogger(DefaultLabeling.class);
75

    
76
        private static final long serialVersionUID = 7100208944546698724L;
77
        private ILabelClass defaultLabel;
78
        private IPlacementConstraints placementConstraints;
79
        private LayerPreview layerPrev;
80
        private JCheckBox enableLayerPrev;
81
        private LabelClassPreview labelPrev;
82
        private JButton btnProperties;
83

    
84
        private FeatureAttributeDescriptor[] fieldDescs;
85

    
86
        private boolean allowOverlap;
87
        private IZoomConstraints zoomConstraints;
88
        private LabelClassProperties lcProp;
89

    
90
        public Class<? extends ILabelingMethod> getLabelingMethodClass() {
91
                return DefaultLabelingMethod.class;
92
        }
93

    
94
        public String getName() {
95
                return Messages.getText("label_features_in_the_same_way") + ".";
96
        }
97

    
98
        @Override
99
        public void fillPanel(ILabelingMethod method, FeatureType fty) {
100
                try {
101
                        if (enableLayerPrev.isSelected()) {
102
                                layerPrev.setLayer(layer);
103
                        } else {
104
                                layerPrev.setLayer(null);
105
                        }
106

    
107
                        fieldDescs = fty.getAttributeDescriptors();
108

    
109
                        ILabelingStrategy labeling = layer.getLabelingStrategy();
110
                        if (!(labeling instanceof GeneralLabelingStrategy)) {
111
                                labeling = new GeneralLabelingStrategy();
112
                                labeling.setLayer(layer);
113
                                layer.setLabelingStrategy(labeling);
114
                        }
115

    
116
                } catch (Exception e) {
117
                        NotificationManager.addWarning(e.getMessage(), e);
118
                }
119

    
120
                ILabelClass lc = null;
121
                if (method.getLabelClasses() != null
122
                                && method.getLabelClasses().length > 0) {
123
                        lc = method.getLabelClasses()[0];
124
                } else {
125
                        lc = SymbologyLocator.getSymbologyManager().createDefaultLabel();
126
                }
127
                setLabel(lc);
128
                getLcProp();
129
        }
130

    
131
        private JButton getBtnProperties() {
132
                if (btnProperties == null) {
133
                        btnProperties = new JButton(Messages.getText("properties"));
134
                        btnProperties.addActionListener(this);
135
                }
136
                return btnProperties;
137
        }
138

    
139
        private LabelClassPreview getLabelPrev() {
140
                if (labelPrev == null) {
141
                        labelPrev = new LabelClassPreview();
142
                }
143
                return labelPrev;
144
        }
145

    
146
        private JCheckBox getEnableLayerPreview() {
147
                if (enableLayerPrev == null) {
148
                        enableLayerPrev = new JCheckBox(
149
                                        Messages.getText("Enable_layer_preview"));
150
                        enableLayerPrev.addItemListener(new ItemListener() {
151

    
152
                                public void itemStateChanged(ItemEvent e) {
153
                                        try {
154
                                                if (e.getStateChange() == ItemEvent.SELECTED) {
155
                                                        layerPrev.setLayer(layer);
156
                                                        updatePreview();
157
                                                } else if (e.getStateChange() == ItemEvent.DESELECTED) {
158
                                                        layerPrev.setLayer(null);
159
                                                }
160
                                        } catch (ReadException e1) {
161
                                                logger.error("While setting changing layer in preview",
162
                                                                e1);
163
                                        }
164
                                }
165
                        });
166
                }
167
                return enableLayerPrev;
168
        }
169

    
170
        private LayerPreview getLayerPreview() {
171
                if (layerPrev == null) {
172
                        layerPrev = new LayerPreview();
173
                }
174
                return layerPrev;
175
        }
176

    
177
        @Override
178
        protected void initializePanel() {
179
                setLayout(new BorderLayout());
180
                JSplitPane scrl = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
181
                scrl.add(getLayerPreview(), JSplitPane.LEFT);
182

    
183
                labelPrev = getLabelPrev(); // new LabelClassPreview();
184
                JPanel aux = new JPanel(new BorderLayout());
185
                aux.add(new JBlank(10, 10), BorderLayout.NORTH);
186
                aux.add(new JBlank(10, 10), BorderLayout.WEST);
187
                aux.add(labelPrev, BorderLayout.CENTER);
188
                aux.add(new JBlank(10, 10), BorderLayout.EAST);
189
                JPanel aux2 = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10));
190
                btnProperties = getBtnProperties();
191
                aux2.add(btnProperties);
192
                aux.add(aux2, BorderLayout.SOUTH);
193
                scrl.add(aux, JSplitPane.RIGHT);
194
                add(scrl, BorderLayout.CENTER);
195
                scrl.setDividerLocation(500);
196

    
197
                getEnableLayerPreview().setSelected(false);
198
                add(enableLayerPrev, BorderLayout.SOUTH);
199
        }
200

    
201
        private LabelClassProperties getLcProp() {
202
                if (lcProp == null) {
203

    
204
                        int n = this.fieldDescs.length;
205
                        String[] fnames = new String[n];
206
                        int[] ftypes = new int[n];
207
                        for (int i = 0; i < n; i++) {
208
                                fnames[i] = fieldDescs[i].getName();
209
                                ftypes[i] = fieldDescs[i].getType();
210
                        }
211
                        lcProp = new LabelClassProperties(this.layer.getFeatureStore());
212
                        lcProp.setLabelClass(method.getLabelClasses()[0]);
213
                }
214
                return lcProp;
215

    
216
        }
217

    
218
        public void actionPerformed(ActionEvent e) {
219
                if (e.getSource().equals(getBtnProperties())) {
220
                        LabelClassProperties lcProp = getLcProp();
221
                        ILabelClass lc = defaultLabel;
222
                        lcProp.setLabelClass(lc);
223
                        boolean eval = false;
224
                        while (!eval) {
225

    
226
                                ApplicationLocator.getManager().getUIManager()
227
                                                .addWindow(lcProp);
228
                                if (!lcProp.isAccepted()) {
229
                                        break;
230
                                }
231
                                ;
232
                                lc = lcProp.getLabelClass();
233
                                eval = checkValidSQL(lc);
234
                                if (eval) {
235
                                        /*
236
                                         * Show warning if number of expressions != number of
237
                                         * rectangles
238
                                         */
239
                                        checkRectangles(lc);
240
                                }
241
                        }
242
                        setLabel(lc);
243
                }
244
        }
245

    
246
        /**
247
         * Checks whether the number of expressions euqls the number of rectangles
248
         * in the style
249
         *
250
         * @param lc
251
         * @return
252
         */
253
        private void checkRectangles(ILabelClass lc) {
254

    
255
                ILabelStyle lbl_sty = lc.getLabelStyle();
256
                if (lbl_sty != null) {
257
                        String[] lbl_exps = lc.getLabelExpressions();
258
                        Rectangle2D[] lbl_rects = lbl_sty.getTextBounds();
259
                        int empty = countEmpty(lbl_exps);
260

    
261
                        if (lbl_exps != null && lbl_rects != null
262
                                        && (empty > 0 || (lbl_exps.length != lbl_rects.length))) {
263

    
264
                                String[] pars = new String[3];
265
                                pars[0] = Integer.toString(lbl_exps.length);
266
                                pars[1] = Integer.toString(empty);
267
                                pars[2] = Integer.toString(lbl_rects.length);
268

    
269
                                JOptionPane
270
                                                .showMessageDialog(
271
                                                                ApplicationLocator.getManager()
272
                                                                                .getRootComponent(),
273
                                                                Messages.getText(
274
                                                                                "_There_are_N_expressions_N_are_empty_and_N_rectangles_"
275
                                                                                                + "Check_label_expressions_and_background_image_properties",
276
                                                                                pars), Messages
277
                                                                                .getText("label_expression_editor"),
278
                                                                JOptionPane.WARNING_MESSAGE);
279

    
280
                        }
281
                }
282

    
283
        }
284

    
285
        private int countEmpty(String[] strs) {
286
                if (strs == null || strs.length == 0) {
287
                        return 0;
288
                } else {
289
                        int resp = 0;
290
                        for (int i = 0; i < strs.length; i++) {
291
                                if (strs[i] == null || strs[i].trim().length() == 0) {
292
                                        resp++;
293
                                }
294
                        }
295
                        return resp;
296
                }
297
        }
298

    
299
        private boolean checkValidSQL(ILabelClass lc) {
300

    
301
                String sqlQuery = lc.getSQLQuery();
302
                if (sqlQuery != null && sqlQuery.trim().length() > 0) {
303
                        return LabelClassUtils.validExpression(sqlQuery,
304
                                        layer.getFeatureStore(), true);
305
                } else {
306
                        return true;
307
                }
308

    
309
        }
310

    
311
        private void setLabel(ILabelClass labelClass) {
312

    
313
                defaultLabel = labelClass;
314
                labelPrev.setLabelClass(defaultLabel);
315
                method = newMethodForThePreview(defaultLabel);
316

    
317
                updatePreview();
318

    
319
        }
320

    
321
        protected ILabelingMethod newMethodForThePreview(ILabelClass defaultLabel) {
322

    
323
                ILabelingMethod resp = SymbologyLocator.getSymbologyManager()
324
                                .createDefaultLabelingMethod();
325
                resp.addLabelClass(defaultLabel);
326
                return resp;
327
        }
328

    
329
        private void updatePreview() {
330

    
331
            ILabelingStrategy stra = layer.getLabelingStrategy();
332
            if (method == null) {
333
                stra.setLabelingMethod(newMethodForThePreview(defaultLabel));
334
            } else {
335
                stra.setLabelingMethod(method);
336
            }
337

    
338
            layer.setIsLabeled(true);
339
            try {
340
                Rectangle r = layerPrev.getBounds();
341
                r.setLocation(layerPrev.getLocationOnScreen());
342
                layerPrev.paintImmediately(r);
343
                layerPrev.doLayout();
344
            } catch (IllegalComponentStateException ex) {
345
                        // this happens when the component is not showing in the
346
                // screen. If that is the case, then we don't need to do
347
                // anything.
348
            }
349
        }
350

    
351
        public void propertyChange(PropertyChangeEvent evt) {
352

    
353
                String prop = evt.getPropertyName();
354
                ILabelingStrategy strat = layer.getLabelingStrategy();
355

    
356
                if (AbstractLabelingMethodPanel.PLACEMENT_CONSTRAINTS.equals(prop)) {
357
                        placementConstraints = (IPlacementConstraints) evt.getNewValue();
358
                        strat.setPlacementConstraints(placementConstraints);
359
                } else if ((strat instanceof GeneralLabelingStrategy)
360
                                && AbstractLabelingMethodPanel.ALLOW_OVERLAP.equals(prop)) {
361
                        allowOverlap = (Boolean) evt.getNewValue();
362
                        ((GeneralLabelingStrategy) strat).setAllowOverlapping(allowOverlap);
363
                } else if (AbstractLabelingMethodPanel.ZOOM_CONSTRAINTS.equals(prop)) {
364
                        zoomConstraints = (IZoomConstraints) evt.getNewValue();
365
                        strat.setZoomConstraints(zoomConstraints);
366
                }
367

    
368
                updatePreview();
369
        }
370

    
371
        public void setEnabled(boolean enabled) {
372
                super.setEnabled(enabled);
373
                if (layerPrev != null) {
374
                        layerPrev.setEnabled(enabled);
375
                }
376
                ;
377
                if (labelPrev != null) {
378
                        labelPrev.setEnabled(enabled);
379
                }
380
                ;
381
                if (btnProperties != null) {
382
                        btnProperties.setEnabled(enabled);
383
                }
384
                ;
385
        }
386

    
387
}