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 com.vividsolutions.jump.workbench.ui.style;
033:
034: import com.vividsolutions.jts.geom.Coordinate;
035: import com.vividsolutions.jts.geom.Envelope;
036: import com.vividsolutions.jts.io.ParseException;
037: import com.vividsolutions.jts.io.WKTReader;
038: import com.vividsolutions.jts.util.Assert;
039:
040: import com.vividsolutions.jump.I18N;
041: import com.vividsolutions.jump.feature.AttributeType;
042: import com.vividsolutions.jump.feature.Feature;
043: import com.vividsolutions.jump.feature.FeatureSchema;
044: import com.vividsolutions.jump.feature.FeatureUtil;
045: import com.vividsolutions.jump.util.Blackboard;
046: import com.vividsolutions.jump.workbench.model.Layer;
047: import com.vividsolutions.jump.workbench.model.LayerManager;
048: import com.vividsolutions.jump.workbench.ui.*;
049: import com.vividsolutions.jump.workbench.ui.renderer.style.BasicStyle;
050: import com.vividsolutions.jump.workbench.ui.renderer.style.Style;
051: import com.vividsolutions.jump.workbench.ui.renderer.style.VertexStyle;
052:
053: import java.awt.*;
054: import java.awt.event.ActionEvent;
055: import java.awt.geom.AffineTransform;
056: import java.awt.geom.Point2D;
057:
058: import java.util.Enumeration;
059: import java.util.Hashtable;
060:
061: import javax.swing.*;
062: import javax.swing.event.ChangeEvent;
063: import javax.swing.event.ChangeListener;
064:
065: public class RenderingStylePanel extends BasicStylePanel implements
066: StylePanel {
067: private Layer layer;
068: private JTextArea fillPatternTipLabel = new JTextArea();
069: private JCheckBox vertexCheckBox = new JCheckBox();
070: private JSlider vertexSlider = new JSlider() {
071:
072: {
073: addChangeListener(new ChangeListener() {
074: public void stateChanged(ChangeEvent e) {
075: updateControls();
076: }
077: });
078: }
079: };
080:
081: private JPanel previewPanel = new JPanel() {
082:
083: {
084: setBackground(Color.white);
085: setBorder(BorderFactory.createLoweredBevelBorder());
086: setMaximumSize(new Dimension(200, 40));
087: setMinimumSize(new Dimension(200, 40));
088: setPreferredSize(new Dimension(200, 40));
089: }
090:
091: private LayerViewPanel dummyLayerViewPanel = new LayerViewPanel(
092: new LayerManager(), new LayerViewPanelContext() {
093: public void setStatusMessage(String message) {
094: }
095:
096: public void warnUser(String warning) {
097: }
098:
099: public void handleThrowable(Throwable t) {
100: }
101: });
102:
103: //Enough of a viewport to satisfy the two styles [Jon Aquino]
104: private Viewport viewport = new Viewport(dummyLayerViewPanel) {
105: private AffineTransform transform = new AffineTransform();
106:
107: public Envelope getEnvelopeInModelCoordinates() {
108: return new Envelope(0, 200, 0, 40);
109: }
110:
111: public AffineTransform getModelToViewTransform() {
112: return transform;
113: }
114:
115: public Point2D toViewPoint(Coordinate modelCoordinate) {
116: return new Point2D.Double(modelCoordinate.x,
117: modelCoordinate.y);
118: }
119: };
120:
121: private void paint(Style style, Graphics2D g) {
122: Stroke originalStroke = g.getStroke();
123:
124: try {
125: style.paint(feature, g, viewport);
126: } catch (Exception e) {
127: //Eat it [Jon Aquino]
128: } finally {
129: //Restore original stroke. Otherwise preview-panel's borders
130: //will have dashes. [Jon Aquino]
131: g.setStroke(originalStroke);
132: }
133: }
134:
135: protected void paintComponent(Graphics g) {
136: super .paintComponent(g);
137: ((Graphics2D) g).setRenderingHint(
138: RenderingHints.KEY_ANTIALIASING,
139: RenderingHints.VALUE_ANTIALIAS_ON);
140: paint(getBasicStyle(), (Graphics2D) g);
141:
142: if (vertexCheckBox.isSelected()) {
143: VertexStyle vertexStyle = getVertexStyle();
144:
145: //Ensure the vertex colour shown on the preview panel stays
146: //up to date. [Jon Aquino]
147: vertexStyle.initialize(new Layer() {
148: public BasicStyle getBasicStyle() {
149: return RenderingStylePanel.this .getBasicStyle();
150: }
151: });
152: paint(vertexStyle, (Graphics2D) g);
153: }
154: }
155:
156: private Feature feature = createFeature();
157:
158: private Feature createFeature() {
159: try {
160: return FeatureUtil
161: .toFeature(
162: new WKTReader()
163: .read("POLYGON ((-200 80, 100 20, 400 -40, 400 80, -200 80))"),
164: new FeatureSchema() {
165: private static final long serialVersionUID = -8627306219650589202L;
166: {
167: addAttribute("GEOMETRY",
168: AttributeType.GEOMETRY);
169: }
170: });
171: } catch (ParseException e) {
172: Assert.shouldNeverReachHere();
173:
174: return null;
175: }
176: }
177: };
178:
179: /**
180: * Parameterless constructor for JBuilder GUI designer.
181: */
182: public RenderingStylePanel() {
183: }
184:
185: public RenderingStylePanel(Blackboard blackboard, Layer layer) {
186: super (blackboard, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
187:
188: Hashtable labelTable = new Hashtable();
189: labelTable.put(new Integer(5), new JLabel("5"));
190: labelTable.put(new Integer(10), new JLabel("10"));
191: labelTable.put(new Integer(15), new JLabel("15"));
192: labelTable.put(new Integer(20), new JLabel("20"));
193: vertexSlider.setLabelTable(labelTable);
194: setBasicStyle(layer.getBasicStyle());
195:
196: try {
197: jbInit();
198: updateControls();
199: } catch (Exception ex) {
200: ex.printStackTrace();
201: }
202:
203: //Set layer after #jbInit, because both methods initialize the components. [Jon Aquino]
204: setLayer(layer);
205: }
206:
207: public void updateControls() {
208: super .updateControls();
209:
210: if (vertexSlider == null) {
211: //Get here during superclass initialization. [Jon Aquino]
212: return;
213: }
214:
215: previewPanel.repaint();
216: vertexSlider.setEnabled(vertexCheckBox.isSelected());
217:
218: for (Enumeration e = vertexSlider.getLabelTable().elements(); e
219: .hasMoreElements();) {
220: JLabel label = (JLabel) e.nextElement();
221: label.setEnabled(vertexCheckBox.isSelected());
222: }
223: }
224:
225: public String getTitle() {
226: return I18N.get("ui.style.RenderingStylePanel.rendering");
227: }
228:
229: private void setLayer(Layer layer) {
230: this .layer = layer;
231: setSynchronizingLineColor(layer.isSynchronizingLineColor());
232: vertexCheckBox.setSelected(layer.getVertexStyle().isEnabled());
233: vertexSlider.setValue(layer.getVertexStyle().getSize());
234: }
235:
236: //UT made protected
237: protected void jbInit() throws Exception {
238: if (vertexSlider == null) {
239: //Get here during superclass initialization. [Jon Aquino]
240: super .jbInit();
241:
242: return;
243: }
244:
245: vertexCheckBox.setText(I18N
246: .get("ui.style.RenderingStylePanel.vertices-size"));
247: vertexCheckBox
248: .addActionListener(new java.awt.event.ActionListener() {
249: public void actionPerformed(ActionEvent e) {
250: showVerticesCheckBox_actionPerformed(e);
251: }
252: });
253: vertexSlider.setMinorTickSpacing(1);
254: vertexSlider.setMajorTickSpacing(0);
255: vertexSlider.setPaintLabels(true);
256: vertexSlider.setMinimum(4);
257: vertexSlider.setValue(4);
258: vertexSlider.setMaximum(20);
259: vertexSlider.setSnapToTicks(true);
260: vertexSlider.setPreferredSize(SLIDER_DIMENSION);
261: fillPatternTipLabel.setFont(new java.awt.Font("SansSerif", 2,
262: 10));
263: fillPatternTipLabel.setOpaque(false);
264: fillPatternTipLabel.setEditable(false);
265: fillPatternTipLabel
266: .setText(I18N
267: .get("ui.style.RenderingStylePanel.tip-after-selecting-a-pattern-use-your-keyboard"));
268: fillPatternTipLabel.setLineWrap(true);
269: fillPatternTipLabel.setWrapStyleWord(true);
270:
271: centerPanel.add(vertexSlider, new GridBagConstraints(1, 35, 1,
272: 1, 0.0, 0.0, GridBagConstraints.WEST,
273: GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
274: centerPanel.add(GUIUtil.createSyncdTextField(vertexSlider,
275: SLIDER_TEXT_FIELD_COLUMNS), new GridBagConstraints(2,
276: 35, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
277: GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
278: centerPanel.add(vertexCheckBox, new GridBagConstraints(0, 35,
279: 2, 1, 0.0, 0.0, GridBagConstraints.WEST,
280: GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
281: centerPanel.add(new JLabel(I18N
282: .get("ui.style.RenderingStylePanel.preview")),
283: new GridBagConstraints(0, 40, 3, 1, 0.0, 0.0,
284: GridBagConstraints.WEST,
285: GridBagConstraints.NONE,
286: new Insets(2, 2, 0, 2), 0, 0));
287: centerPanel
288: .add(previewPanel, new GridBagConstraints(0, 45, 3, 1,
289: 0.0, 0.0, GridBagConstraints.WEST,
290: GridBagConstraints.NONE,
291: new Insets(0, 10, 2, 2), 0, 0));
292: centerPanel.add(fillPatternTipLabel, new GridBagConstraints(0,
293: 8, 3, 1, 0.0, 0.0, GridBagConstraints.CENTER,
294: GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
295: }
296:
297: public VertexStyle getVertexStyle() {
298: VertexStyle vertexStyle = (VertexStyle) layer.getVertexStyle()
299: .clone();
300: vertexStyle.setEnabled(vertexCheckBox.isSelected());
301: vertexStyle.setSize(vertexSlider.getValue());
302:
303: return vertexStyle;
304: }
305:
306: public void updateStyles() {
307: boolean firingEvents = layer.getLayerManager().isFiringEvents();
308: layer.getLayerManager().setFiringEvents(false);
309:
310: try {
311: layer.removeStyle(layer.getBasicStyle());
312: layer.addStyle(getBasicStyle());
313:
314: //Call #getVertexStyle before removing layer's vertex style,
315: //because one depends on the other. [Jon Aquino]
316: VertexStyle newVertexStyle = getVertexStyle();
317: layer.removeStyle(layer.getVertexStyle());
318: layer.addStyle(newVertexStyle);
319: layer.setSynchronizingLineColor(synchronizeCheckBox
320: .isSelected());
321: } finally {
322: layer.getLayerManager().setFiringEvents(firingEvents);
323: }
324:
325: layer.fireAppearanceChanged();
326: }
327:
328: void showVerticesCheckBox_actionPerformed(ActionEvent e) {
329: updateControls();
330: }
331:
332: public String validateInput() {
333: return null;
334: }
335: }
|