/*
* The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
* for visualizing and manipulating spatial features with geometry and attributes.
*
* Copyright (C) 2003 Vivid Solutions
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* For more information, contact:
*
* Vivid Solutions
* Suite #1A
* 2328 Government Street
* Victoria BC V8T 5G5
* Canada
*
* (250)385-6040
* www.vividsolutions.com
*/
package com.vividsolutions.jump.workbench.ui;
import com.vividsolutions.jump.I18N;
import com.vividsolutions.jump.workbench.ui.plugin.WKTDisplayHelper;
import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
/**
*
* Allows user to enter annotations in Well Known Text format.
*
*/
public class EnterWKTDialog extends JDialog {
private final static int THRESHOLD_WKT_LENGTH = 500;
JPanel mainPanel = new JPanel();
BorderLayout borderLayout1 = new BorderLayout();
private ArrayList actionListeners = new ArrayList();
JLabel descriptionLabel = new JLabel();
private boolean syncing = false;
//Updating the annotations is slow, so wait until the user stops typing. [Jon Aquino]
private Timer annotationUpdateTimer =
GUIUtil.createRestartableSingleEventTimer(500, new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateAnnotations();
}
});
private WKTDisplayHelper helper = new WKTDisplayHelper();
private JPanel buttonPanel = new JPanel();
private GridBagLayout gridBagLayout1 = new GridBagLayout();
private JButton formatButton = new JButton();
private OKCancelPanel okCancelPanel = new OKCancelPanel();
private JButton compressButton = new JButton();
private JPanel fillerPanel = new JPanel();
private JPanel centerPanel = new JPanel();
private GridBagLayout gridBagLayout2 = new GridBagLayout();
private GridBagLayout gridBagLayout3 = new GridBagLayout();
private JScrollPane annotationScrollPane = new JScrollPane();
private JTextArea annotationTextArea = new JTextArea();
private JTextArea textArea = new JTextArea() {
public void setText(String t) {
super.setText(t);
setCaretPosition(0);
}
};
private JScrollPane mainScrollPane = new JScrollPane();
public EnterWKTDialog(Frame frame, String title, boolean modal) {
super(frame, title, modal);
try {
jbInit();
pack();
} catch (Exception ex) {
ex.printStackTrace();
}
textArea.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
queueAnnotationUpdate();
}
public void removeUpdate(DocumentEvent e) {
queueAnnotationUpdate();
}
public void changedUpdate(DocumentEvent e) {
queueAnnotationUpdate();
}
});
//Listen to mainScrollPane to get events when user moves scrollbar.
//Listen to annotationScrollPane to get events when user edits text.
//(Can't simply listen to document because
//BasicScrollPaneUI#syncScrollPaneWithViewport may get called after
//the document events are fired). [Jon Aquino]
mainScrollPane
.getVerticalScrollBar()
.addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
syncScrollBars();
}
});
annotationScrollPane
.getVerticalScrollBar()
.addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
syncScrollBars();
}
});
}
public EnterWKTDialog() {
this(null, "", true);
}
private void syncScrollBars() {
if (syncing) {
return;
}
syncing = true;
try {
annotationScrollPane.getVerticalScrollBar().setValue(
Math.max(1, mainScrollPane.getVerticalScrollBar().getValue()));
} finally {
syncing = false;
}
}
private void queueAnnotationUpdate() {
if (textArea.getText().length() < THRESHOLD_WKT_LENGTH) {
updateAnnotations();
} else {
annotationUpdateTimer.restart();
}
}
private void updateAnnotations() {
if (textArea.getLineWrap()) {
//User has pressed the Compress button. [Jon Aquino]
annotationTextArea.setText("");
} else {
annotationTextArea.setText(helper.annotate(textArea.getText()));
}
}
public void setDescription(String d) {
descriptionLabel.setText(d);
}
public void setEditable(boolean editable) {
textArea.setEditable(editable);
okCancelPanel.setCancelVisible(editable);
textArea.setOpaque(editable);
}
public boolean wasOKPressed() {
return okCancelPanel.wasOKPressed();
}
public void addActionListener(ActionListener l) {
actionListeners.add(l);
}
void jbInit() throws Exception {
formatButton.setToolTipText(I18N.get("com.vividsolutions.jump.workbench.ui.EnterWKTDialog.beautify"));
mainPanel.setLayout(borderLayout1);
buttonPanel.setLayout(gridBagLayout1);
formatButton.setText(I18N.get("com.vividsolutions.jump.workbench.ui.EnterWKTDialog.format"));
formatButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
formatButton_actionPerformed(e);
}
});
okCancelPanel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
okCancelPanel_actionPerformed(e);
}
});
compressButton.setText(I18N.get("com.vividsolutions.jump.workbench.ui.EnterWKTDialog.compress"));
compressButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
compressButton_actionPerformed(e);
}
});
fillerPanel.setLayout(gridBagLayout2);
centerPanel.setLayout(gridBagLayout3);
annotationScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
annotationScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
annotationScrollPane.setBorder(null);
annotationScrollPane.setPreferredSize(new Dimension(73, 21));
//Must set the minimum size because a GridBagLayout "collapse" will occur
//if the WKT is higher than the window height. [Jon Aquino]
annotationScrollPane.setMinimumSize(annotationScrollPane.getPreferredSize());
annotationTextArea.setMargin(new Insets(0, 5, 0, 0));
annotationTextArea.setBackground(Color.lightGray);
//remove setFont so that the same one is used for textArea and annotationTextArea
//if you want to change the font, change it in both components
//annotationTextArea.setFont(new java.awt.Font("Monospaced", 1, 12));
annotationTextArea.setEditable(false);
textArea.setWrapStyleWord(false);
textArea.setLineWrap(false);
mainScrollPane.setBorder(null);
centerPanel.setBorder(BorderFactory.createEtchedBorder());
getContentPane().add(mainPanel);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
buttonPanel.add(
formatButton,
new GridBagConstraints(
0,
0,
1,
1,
0.0,
0.0,
GridBagConstraints.CENTER,
GridBagConstraints.NONE,
new Insets(4, 4, 4, 4),
0,
0));
this.getContentPane().add(descriptionLabel, BorderLayout.NORTH);
buttonPanel.add(
okCancelPanel,
new GridBagConstraints(
3,
0,
1,
1,
0.0,
0.0,
GridBagConstraints.CENTER,
GridBagConstraints.NONE,
new Insets(0, 0, 0, 0),
0,
0));
buttonPanel.add(
compressButton,
new GridBagConstraints(
1,
0,
1,
1,
0.0,
0.0,
GridBagConstraints.CENTER,
GridBagConstraints.NONE,
new Insets(4, 4, 4, 4),
0,
0));
buttonPanel.add(
fillerPanel,
new GridBagConstraints(
2,
0,
1,
1,
1.0,
0.0,
GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0),
0,
0));
mainPanel.add(centerPanel, BorderLayout.CENTER);
centerPanel.add(annotationScrollPane, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
centerPanel.add(mainScrollPane, new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0
,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
mainScrollPane.getViewport().add(textArea);
annotationScrollPane.getViewport().add(annotationTextArea);
}
public String getText() {
return textArea.getText();
}
/**
* @param text surround with <HTML> tags if you want word-wrap
*/
public void setText(String text) {
textArea.setText(helper.format(text));
}
void okCancelPanel_actionPerformed(ActionEvent e) {
for (Iterator i = actionListeners.iterator(); i.hasNext();) {
ActionListener l = (ActionListener) i.next();
l.actionPerformed(e);
}
//Let listeners decide whether to close dialog e.g. don't if a parse error
//occurs [Jon Aquino]
}
void formatButton_actionPerformed(ActionEvent e) {
textArea.setLineWrap(false);
textArea.setText(helper.format(textArea.getText()));
}
public static void main(String[] args) throws Exception {
System.out.println(new SimpleDateFormat().parse("2003-12-05"));
}
void compressButton_actionPerformed(ActionEvent e) {
textArea.setLineWrap(true);
textArea.setText(compress(textArea.getText()));
}
private String compress(String s) {
StringBuffer buffer = new StringBuffer();
StringTokenizer tokenizer = new StringTokenizer(s);
while (tokenizer.hasMoreTokens()) {
buffer.append(tokenizer.nextToken() + " ");
}
return buffer.toString().trim();
}
}