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;
033:
034: import java.awt.*;
035: import java.text.SimpleDateFormat;
036: import java.util.ArrayList;
037: import java.util.Iterator;
038: import java.util.StringTokenizer;
039: import javax.swing.*;
040: import javax.swing.event.DocumentEvent;
041: import javax.swing.event.DocumentListener;
042: import com.vividsolutions.jump.workbench.ui.plugin.WKTDisplayHelper;
043: import java.awt.event.*;
044:
045: /**
046: *
047: * Allows user to enter annotations in Well Known Text format.
048: *
049: */
050: public class EnterWKTDialog extends JDialog {
051: private final static int THRESHOLD_WKT_LENGTH = 500;
052: JPanel mainPanel = new JPanel();
053: BorderLayout borderLayout1 = new BorderLayout();
054: private ArrayList actionListeners = new ArrayList();
055: JLabel descriptionLabel = new JLabel();
056: private boolean syncing = false;
057: //Updating the annotations is slow, so wait until the user stops typing. [Jon Aquino]
058: private Timer annotationUpdateTimer = GUIUtil
059: .createRestartableSingleEventTimer(500,
060: new ActionListener() {
061: public void actionPerformed(ActionEvent e) {
062: updateAnnotations();
063: }
064: });
065: private WKTDisplayHelper helper = new WKTDisplayHelper();
066: private JPanel buttonPanel = new JPanel();
067: private GridBagLayout gridBagLayout1 = new GridBagLayout();
068: private JButton formatButton = new JButton();
069: private OKCancelPanel okCancelPanel = new OKCancelPanel();
070: private JButton compressButton = new JButton();
071: private JPanel fillerPanel = new JPanel();
072: private JPanel centerPanel = new JPanel();
073: private GridBagLayout gridBagLayout2 = new GridBagLayout();
074: private GridBagLayout gridBagLayout3 = new GridBagLayout();
075: private JScrollPane annotationScrollPane = new JScrollPane();
076: private JTextArea annotationTextArea = new JTextArea();
077: private JTextArea textArea = new JTextArea() {
078: public void setText(String t) {
079: super .setText(t);
080: setCaretPosition(0);
081: }
082: };
083: private JScrollPane mainScrollPane = new JScrollPane();
084:
085: public EnterWKTDialog(Frame frame, String title, boolean modal) {
086: super (frame, title, modal);
087: try {
088: jbInit();
089: pack();
090: } catch (Exception ex) {
091: ex.printStackTrace();
092: }
093: textArea.getDocument().addDocumentListener(
094: new DocumentListener() {
095: public void insertUpdate(DocumentEvent e) {
096: queueAnnotationUpdate();
097: }
098:
099: public void removeUpdate(DocumentEvent e) {
100: queueAnnotationUpdate();
101: }
102:
103: public void changedUpdate(DocumentEvent e) {
104: queueAnnotationUpdate();
105: }
106: });
107: //Listen to mainScrollPane to get events when user moves scrollbar.
108: //Listen to annotationScrollPane to get events when user edits text.
109: //(Can't simply listen to document because
110: //BasicScrollPaneUI#syncScrollPaneWithViewport may get called after
111: //the document events are fired). [Jon Aquino]
112: mainScrollPane.getVerticalScrollBar().addAdjustmentListener(
113: new AdjustmentListener() {
114: public void adjustmentValueChanged(AdjustmentEvent e) {
115: syncScrollBars();
116: }
117: });
118: annotationScrollPane.getVerticalScrollBar()
119: .addAdjustmentListener(new AdjustmentListener() {
120: public void adjustmentValueChanged(AdjustmentEvent e) {
121: syncScrollBars();
122: }
123: });
124: }
125:
126: public EnterWKTDialog() {
127: this (null, "", true);
128: }
129:
130: private void syncScrollBars() {
131: if (syncing) {
132: return;
133: }
134: syncing = true;
135: try {
136: annotationScrollPane.getVerticalScrollBar().setValue(
137: Math.max(1, mainScrollPane.getVerticalScrollBar()
138: .getValue()));
139: } finally {
140: syncing = false;
141: }
142: }
143:
144: private void queueAnnotationUpdate() {
145: if (textArea.getText().length() < THRESHOLD_WKT_LENGTH) {
146: updateAnnotations();
147: } else {
148: annotationUpdateTimer.restart();
149: }
150: }
151:
152: private void updateAnnotations() {
153: if (textArea.getLineWrap()) {
154: //User has pressed the Compress button. [Jon Aquino]
155: annotationTextArea.setText("");
156: } else {
157: annotationTextArea.setText(helper.annotate(textArea
158: .getText()));
159: }
160: }
161:
162: public void setDescription(String d) {
163: descriptionLabel.setText(d);
164: }
165:
166: public void setEditable(boolean editable) {
167: textArea.setEditable(editable);
168: okCancelPanel.setCancelVisible(editable);
169: textArea.setOpaque(editable);
170: }
171:
172: public boolean wasOKPressed() {
173: return okCancelPanel.wasOKPressed();
174: }
175:
176: public void addActionListener(ActionListener l) {
177: actionListeners.add(l);
178: }
179:
180: void jbInit() throws Exception {
181: formatButton.setToolTipText("Beautify the Well-Known Text");
182: mainPanel.setLayout(borderLayout1);
183: buttonPanel.setLayout(gridBagLayout1);
184: formatButton.setText("Format");
185: formatButton
186: .addActionListener(new java.awt.event.ActionListener() {
187: public void actionPerformed(ActionEvent e) {
188: formatButton_actionPerformed(e);
189: }
190: });
191: okCancelPanel
192: .addActionListener(new java.awt.event.ActionListener() {
193: public void actionPerformed(ActionEvent e) {
194: okCancelPanel_actionPerformed(e);
195: }
196: });
197: compressButton.setText("Compress");
198: compressButton
199: .addActionListener(new java.awt.event.ActionListener() {
200: public void actionPerformed(ActionEvent e) {
201: compressButton_actionPerformed(e);
202: }
203: });
204: fillerPanel.setLayout(gridBagLayout2);
205: centerPanel.setLayout(gridBagLayout3);
206: annotationScrollPane
207: .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
208: annotationScrollPane
209: .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
210: annotationScrollPane.setBorder(null);
211: annotationScrollPane.setPreferredSize(new Dimension(73, 21));
212: //Must set the minimum size because a GridBagLayout "collapse" will occur
213: //if the WKT is higher than the window height. [Jon Aquino]
214: annotationScrollPane.setMinimumSize(annotationScrollPane
215: .getPreferredSize());
216: annotationTextArea.setMargin(new Insets(0, 5, 0, 0));
217: annotationTextArea.setBackground(Color.lightGray);
218: annotationTextArea.setFont(new java.awt.Font("Monospaced", 1,
219: 12));
220: annotationTextArea.setEditable(false);
221: textArea.setWrapStyleWord(false);
222: textArea.setLineWrap(false);
223: mainScrollPane.setBorder(null);
224: centerPanel.setBorder(BorderFactory.createEtchedBorder());
225: getContentPane().add(mainPanel);
226: mainPanel.add(buttonPanel, BorderLayout.SOUTH);
227: buttonPanel.add(formatButton, new GridBagConstraints(0, 0, 1,
228: 1, 0.0, 0.0, GridBagConstraints.CENTER,
229: GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0));
230: this .getContentPane().add(descriptionLabel, BorderLayout.NORTH);
231: buttonPanel.add(okCancelPanel, new GridBagConstraints(3, 0, 1,
232: 1, 0.0, 0.0, GridBagConstraints.CENTER,
233: GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
234: buttonPanel.add(compressButton, new GridBagConstraints(1, 0, 1,
235: 1, 0.0, 0.0, GridBagConstraints.CENTER,
236: GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0));
237: buttonPanel.add(fillerPanel, new GridBagConstraints(2, 0, 1, 1,
238: 1.0, 0.0, GridBagConstraints.CENTER,
239: GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0),
240: 0, 0));
241: mainPanel.add(centerPanel, BorderLayout.CENTER);
242: centerPanel.add(annotationScrollPane, new GridBagConstraints(0,
243: 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
244: GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
245: centerPanel.add(mainScrollPane, new GridBagConstraints(1, 0, 1,
246: 1, 1.0, 1.0, GridBagConstraints.CENTER,
247: GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
248: mainScrollPane.getViewport().add(textArea);
249: annotationScrollPane.getViewport().add(annotationTextArea);
250: }
251:
252: public String getText() {
253: return textArea.getText();
254: }
255:
256: /**
257: * @param text surround with <HTML> tags if you want word-wrap
258: */
259: public void setText(String text) {
260: textArea.setText(helper.format(text));
261: }
262:
263: void okCancelPanel_actionPerformed(ActionEvent e) {
264: for (Iterator i = actionListeners.iterator(); i.hasNext();) {
265: ActionListener l = (ActionListener) i.next();
266: l.actionPerformed(e);
267: }
268: //Let listeners decide whether to close dialog e.g. don't if a parse error
269: //occurs [Jon Aquino]
270: }
271:
272: void formatButton_actionPerformed(ActionEvent e) {
273: textArea.setLineWrap(false);
274: textArea.setText(helper.format(textArea.getText()));
275: }
276:
277: public static void main(String[] args) throws Exception {
278: System.out.println(new SimpleDateFormat().parse("2003-12-05"));
279: }
280:
281: void compressButton_actionPerformed(ActionEvent e) {
282: textArea.setLineWrap(true);
283: textArea.setText(compress(textArea.getText()));
284: }
285:
286: private String compress(String s) {
287: StringBuffer buffer = new StringBuffer();
288: StringTokenizer tokenizer = new StringTokenizer(s);
289: while (tokenizer.hasMoreTokens()) {
290: buffer.append(tokenizer.nextToken() + " ");
291: }
292: return buffer.toString().trim();
293: }
294: }
|