001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032: package de.latlon.deejump.plugin.style;
033:
034: import java.awt.Color;
035: import java.awt.Dimension;
036: import java.awt.Graphics;
037: import java.awt.Graphics2D;
038: import java.awt.GridBagConstraints;
039: import java.awt.Image;
040: import java.awt.Insets;
041: import java.awt.RenderingHints;
042: import java.awt.Stroke;
043: import java.awt.event.ActionEvent;
044: import java.awt.event.ActionListener;
045: import java.awt.event.ItemEvent;
046: import java.awt.event.ItemListener;
047: import java.awt.geom.AffineTransform;
048: import java.awt.geom.Point2D;
049: import java.util.Enumeration;
050: import java.util.Hashtable;
051: import java.util.Iterator;
052:
053: import javax.swing.BorderFactory;
054: import javax.swing.JCheckBox;
055: import javax.swing.JLabel;
056: import javax.swing.JPanel;
057: import javax.swing.JSlider;
058: import javax.swing.JTextArea;
059: import javax.swing.ScrollPaneConstants;
060: import javax.swing.event.ChangeEvent;
061: import javax.swing.event.ChangeListener;
062:
063: import com.vividsolutions.jts.geom.Coordinate;
064: import com.vividsolutions.jts.geom.Envelope;
065: import com.vividsolutions.jts.io.ParseException;
066: import com.vividsolutions.jts.io.WKTReader;
067: import com.vividsolutions.jts.util.Assert;
068: import com.vividsolutions.jump.I18N;
069: import com.vividsolutions.jump.feature.AttributeType;
070: import com.vividsolutions.jump.feature.Feature;
071: import com.vividsolutions.jump.feature.FeatureSchema;
072: import com.vividsolutions.jump.feature.FeatureUtil;
073: import com.vividsolutions.jump.util.Blackboard;
074: import com.vividsolutions.jump.workbench.model.Layer;
075: import com.vividsolutions.jump.workbench.model.LayerManager;
076: import com.vividsolutions.jump.workbench.ui.GUIUtil;
077: import com.vividsolutions.jump.workbench.ui.LayerViewPanel;
078: import com.vividsolutions.jump.workbench.ui.LayerViewPanelContext;
079: import com.vividsolutions.jump.workbench.ui.Viewport;
080: import com.vividsolutions.jump.workbench.ui.renderer.style.BasicStyle;
081: import com.vividsolutions.jump.workbench.ui.renderer.style.SquareVertexStyle;
082: import com.vividsolutions.jump.workbench.ui.renderer.style.Style;
083: import com.vividsolutions.jump.workbench.ui.renderer.style.VertexStyle;
084: import com.vividsolutions.jump.workbench.ui.style.BasicStylePanel;
085: import com.vividsolutions.jump.workbench.ui.style.StylePanel;
086:
087: public class DeeRenderingStylePanel extends BasicStylePanel implements
088: StylePanel {
089:
090: VertexStyleChooser vertexStyleChooser = new VertexStyleChooser(
091: false);
092: private Layer layer;
093: private JTextArea fillPatternTipLabel = new JTextArea();
094: private JCheckBox vertexCheckBox = new JCheckBox() {
095: };
096: private JSlider vertexSlider = new JSlider() {
097:
098: {
099: addChangeListener(new ChangeListener() {
100: public void stateChanged(ChangeEvent e) {
101: JSlider test = (JSlider) e.getSource();
102: updateControls();
103: }
104: });
105: }
106: };
107:
108: private Image image;
109: private String currentFilename;
110: private JPanel previewPanel = new JPanel() {
111:
112: {
113: setBackground(Color.white);
114: setBorder(BorderFactory.createLoweredBevelBorder());
115: setMaximumSize(new Dimension(200, 40));
116: setMinimumSize(new Dimension(200, 40));
117: setPreferredSize(new Dimension(200, 40));
118: }
119:
120: private LayerViewPanel dummyLayerViewPanel = new LayerViewPanel(
121: new LayerManager(), new LayerViewPanelContext() {
122: public void setStatusMessage(String message) {
123: }
124:
125: public void warnUser(String warning) {
126: }
127:
128: public void handleThrowable(Throwable t) {
129: }
130: });
131:
132: //Enough of a viewport to satisfy the two styles [Jon Aquino]
133: private Viewport viewport = new Viewport(dummyLayerViewPanel) {
134: private AffineTransform transform = new AffineTransform();
135:
136: public Envelope getEnvelopeInModelCoordinates() {
137: return new Envelope(0, 200, 0, 40);
138: }
139:
140: public AffineTransform getModelToViewTransform() {
141: return transform;
142: }
143:
144: public Point2D toViewPoint(Coordinate modelCoordinate) {
145: return new Point2D.Double(modelCoordinate.x,
146: modelCoordinate.y);
147: }
148: };
149:
150: private void paint(Style style, Graphics2D g) {
151: Stroke originalStroke = g.getStroke();
152:
153: try {
154: style.paint(feature, g, viewport);
155: } catch (Exception e) {
156: //Eat it [Jon Aquino]
157: } finally {
158: //Restore original stroke. Otherwise preview-panel's borders
159: //will have dashes. [Jon Aquino]
160: g.setStroke(originalStroke);
161: }
162: }
163:
164: protected void paintComponent(Graphics g) {
165: super .paintComponent(g);
166: ((Graphics2D) g).setRenderingHint(
167: RenderingHints.KEY_ANTIALIASING,
168: RenderingHints.VALUE_ANTIALIAS_ON);
169: paint(getBasicStyle(), (Graphics2D) g);
170:
171: if (vertexCheckBox.isSelected()) {
172: VertexStyle vertexStyle = getVertexStyle();
173: vertexStyleChooser
174: .setSelectedStyle(getCurrentVertexStyle());
175:
176: //Ensure the vertex colour shown on the preview panel stays
177: //up to date. [Jon Aquino]
178: vertexStyle.initialize(new Layer() {
179: public BasicStyle getBasicStyle() {
180: return DeeRenderingStylePanel.this
181: .getBasicStyle();
182: }
183: });
184: paint(vertexStyle, (Graphics2D) g);
185: }
186: }
187:
188: private Feature feature = createFeature();
189:
190: private Feature createFeature() {
191: try {
192: return FeatureUtil
193: .toFeature(
194: new WKTReader()
195: .read("POLYGON ((-200 80, 100 20, 400 -40, 400 80, -200 80))"),
196: new FeatureSchema() {
197: private static final long serialVersionUID = -8627306219650589202L;
198: {
199: addAttribute("GEOMETRY",
200: AttributeType.GEOMETRY);
201: }
202: });
203: } catch (ParseException e) {
204: Assert.shouldNeverReachHere();
205:
206: return null;
207: }
208: }
209: };
210:
211: /**
212: * Parameterless constructor for JBuilder GUI designer.
213: */
214: public DeeRenderingStylePanel() {
215: this .vertexStyleChooser.sizeSlider = this .vertexSlider;
216: }
217:
218: // GH 2005.09.22 this Methode returns the current VertexStyle
219: private String getCurrentVertexStyle() {
220: VertexStyle currentVertexStyle = layer.getVertexStyle();
221: if (currentVertexStyle instanceof SquareVertexStyle) {
222: return VertexStylesFactory.SQUARE_STYLE;
223: } else if (currentVertexStyle instanceof CircleVertexStyle) {
224: return VertexStylesFactory.CIRCLE_STYLE;
225: } else if (currentVertexStyle instanceof CrossVertexStyle) {
226: return VertexStylesFactory.CROSS_STYLE;
227: } else if (currentVertexStyle instanceof TriangleVertexStyle) {
228: return VertexStylesFactory.TRIANGLE_STYLE;
229: } else if (currentVertexStyle instanceof StarVertexStyle) {
230: return VertexStylesFactory.STAR_STYLE;
231: }
232: // else if(currentVertexStyle instanceof BitmapVertexStyle){
233: // return I18N.get( "ui.style.RenderingStylePanel.bitmap" ) ;
234: // }
235:
236: return "";
237: }
238:
239: public DeeRenderingStylePanel(Blackboard blackboard, Layer layer) {
240: super (blackboard, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
241:
242: Hashtable labelTable = new Hashtable();
243: labelTable.put(new Integer(5), new JLabel("5"));
244: labelTable.put(new Integer(10), new JLabel("10"));
245: labelTable.put(new Integer(15), new JLabel("15"));
246: labelTable.put(new Integer(20), new JLabel("20"));
247: vertexSlider.setLabelTable(labelTable);
248: setBasicStyle(layer.getBasicStyle());
249: //initPointDisplayType();
250: try {
251: jbInit();
252: updateControls();
253: } catch (Exception ex) {
254: ex.printStackTrace();
255: }
256:
257: //Set layer after #jbInit, because both methods initialize the components. [Jon Aquino]
258: setLayer(layer);
259: }
260:
261: public void updateControls() {
262: super .updateControls();
263:
264: if (vertexSlider == null) {
265: //Get here during superclass initialization. [Jon Aquino]
266: return;
267: }
268:
269: previewPanel.repaint();
270:
271: // GH 2005-09-08 set pointDisplayType enable
272: vertexSlider.setEnabled(vertexCheckBox.isSelected());
273: vertexStyleChooser.setEnabled(vertexCheckBox.isSelected());
274:
275: //// GH 2005-09-08 set pointDisplayType enable
276: // bitmapChangeButton.setEnabled(vertexCheckBox.isSelected() );
277: ////&& SymbolConstant.CIRCLE.equals( pointDisplayType.getSelectedItem())));
278:
279: for (Enumeration e = vertexSlider.getLabelTable().elements(); e
280: .hasMoreElements();) {
281: JLabel label = (JLabel) e.nextElement();
282: label.setEnabled(vertexCheckBox.isSelected());
283: }
284: }
285:
286: public String getTitle() {
287: return I18N.get("ui.style.RenderingStylePanel.rendering");
288: }
289:
290: private void setLayer(Layer layer) {
291: this .layer = layer;
292: setSynchronizingLineColor(layer.isSynchronizingLineColor());
293: vertexCheckBox.setSelected(layer.getVertexStyle().isEnabled());
294: vertexSlider.setValue(layer.getVertexStyle().getSize());
295: // [UT] click box by default, if layer is of point type
296: Iterator iter = layer.getFeatureCollectionWrapper()
297: .getUltimateWrappee().getFeatures().iterator();
298: String type = "";
299: if (iter.hasNext()) {
300: Feature f = (Feature) iter.next();
301: type = f.getGeometry().getGeometryType();
302:
303: }
304: if ("MultiPoint".equals(type) || "Point".equals(type)) {
305: vertexCheckBox.doClick();
306: }
307: }
308:
309: protected void jbInit() throws Exception {
310: if (vertexSlider == null) {
311: //Get here during superclass initialization. [Jon Aquino]
312: super .jbInit();
313:
314: return;
315: }
316: vertexCheckBox.setText(I18N
317: .get("ui.style.RenderingStylePanel.vertices-size"));
318: //GH 2005.09.22 this Listner is better than actionListener for this Checkbox
319: vertexCheckBox.addItemListener(new ItemListener() {
320: public void itemStateChanged(ItemEvent e) {
321: showVerticesCheckBox_actionPerformed(e);
322: }
323: });
324:
325: vertexSlider.setMinorTickSpacing(1);
326: vertexSlider.setMajorTickSpacing(0);
327: vertexSlider.setPaintLabels(true);
328: vertexSlider.setMinimum(4);
329: vertexSlider.setValue(4);
330: vertexSlider.setMaximum(20);
331: vertexSlider.setSnapToTicks(true);
332: vertexSlider.setPreferredSize(SLIDER_DIMENSION);
333: fillPatternTipLabel.setFont(new java.awt.Font("SansSerif", 2,
334: 10));
335: fillPatternTipLabel.setOpaque(false);
336: fillPatternTipLabel.setEditable(false);
337: fillPatternTipLabel
338: .setText(I18N
339: .get("ui.style.RenderingStylePanel.tip-after-selecting-a-pattern-use-your-keyboard"));
340: fillPatternTipLabel.setLineWrap(true);
341: fillPatternTipLabel.setWrapStyleWord(true);
342:
343: centerPanel.add(vertexSlider, new GridBagConstraints(1, 35, 1,
344: 1, 0.0, 0.0, GridBagConstraints.WEST,
345: GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
346: centerPanel.add(GUIUtil.createSyncdTextField(vertexSlider,
347: SLIDER_TEXT_FIELD_COLUMNS), new GridBagConstraints(2,
348: 35, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
349: GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
350: centerPanel.add(vertexCheckBox, new GridBagConstraints(0, 35,
351: 2, 1, 0.0, 0.0, GridBagConstraints.WEST,
352: GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
353: centerPanel.add(new JLabel(I18N
354: .get("ui.style.RenderingStylePanel.preview")),
355: new GridBagConstraints(0, 40, 3, 1, 0.0, 0.0,
356: GridBagConstraints.WEST,
357: GridBagConstraints.NONE,
358: new Insets(2, 2, 0, 2), 0, 0));
359: centerPanel
360: .add(previewPanel, new GridBagConstraints(0, 45, 3, 1,
361: 0.0, 0.0, GridBagConstraints.WEST,
362: GridBagConstraints.NONE,
363: new Insets(0, 10, 2, 2), 0, 0));
364:
365: centerPanel.add(vertexStyleChooser, new GridBagConstraints(0,
366: 50, 3, 1, 0.0, 0.0, GridBagConstraints.WEST,
367: GridBagConstraints.NONE, new Insets(2, 2, 0, 2), 0, 0));//
368:
369: // GH 2005.10.26 I have deleted the actionListner of the BitmapButton
370: //where is the suitable place to call ChangeVertexStyle()??.
371:
372: vertexStyleChooser.addActionListener(new ActionListener() {
373: public void actionPerformed(ActionEvent arg0) {
374: changeVertexStyle();
375: }
376: });
377:
378: centerPanel.add(fillPatternTipLabel, new GridBagConstraints(0,
379: 8, 3, 1, 0.0, 0.0, GridBagConstraints.CENTER,
380: GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
381:
382: vertexStyleChooser.addChangeListener(new ChangeListener() {
383: public void stateChanged(ChangeEvent e) {
384: JSlider slider = (JSlider) e.getSource();
385: vertexSlider.setValue(slider.getValue());
386: }
387: });
388:
389: }
390:
391: // GH 2005-08-30
392: public void changeVertexStyle() {
393: Style st = layer.getStyle(VertexStyle.class);
394: layer.removeStyle(st);
395: layer.addStyle(vertexStyleChooser.getSelectedStyle());
396:
397: }
398:
399: public VertexStyle getVertexStyle() {
400:
401: VertexStyle vertexStyle = (VertexStyle) layer.getVertexStyle()
402: .clone();
403: vertexStyle.setEnabled(vertexCheckBox.isSelected());
404: vertexStyle.setSize(vertexSlider.getValue());
405: return vertexStyle;
406: }
407:
408: public void updateStyles() {
409: boolean firingEvents = layer.getLayerManager().isFiringEvents();
410: layer.getLayerManager().setFiringEvents(false);
411:
412: try {
413: layer.removeStyle(layer.getBasicStyle());
414: layer.addStyle(getBasicStyle());
415:
416: //Call #getVertexStyle before removing layer's vertex style,
417: //because one depends on the other. [Jon Aquino]
418: VertexStyle newVertexStyle = getVertexStyle();
419: layer.removeStyle(layer.getVertexStyle());
420:
421: layer.addStyle(newVertexStyle);
422:
423: layer.setSynchronizingLineColor(synchronizeCheckBox
424: .isSelected());
425: } finally {
426: layer.getLayerManager().setFiringEvents(firingEvents);
427: }
428: layer.fireAppearanceChanged();
429:
430: }
431:
432: void showVerticesCheckBox_actionPerformed(ActionEvent e) {
433: updateControls();
434: }
435:
436: public String validateInput() {
437: return null;
438: }
439:
440: void showVerticesCheckBox_actionPerformed(ItemEvent e) {
441: updateControls();
442: }
443:
444: }
|