/*
* The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
* for visualizing and manipulating spatial features with geometry and attributes.
*
* JUMP is Copyright (C) 2003 Vivid Solutions
*
* This program implements extensions to JUMP and is
* Copyright (C) 2004 Integrated Systems Analysts, Inc.
*
* 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:
*
* Integrated Systems Analysts, Inc.
* 630C Anchors St., Suite 101
* Fort Walton Beach, Florida
* USA
*
* (850)862-7321
*/
package org.openjump.core.ui.plugin.mousemenu;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.geom.NoninvertibleTransformException;
import java.text.DecimalFormat;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.openjump.core.geomutils.Arc;
import org.openjump.core.geomutils.GeoUtils;
import org.openjump.core.geomutils.MathVector;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateList;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jump.I18N;
import com.vividsolutions.jump.feature.AttributeType;
import com.vividsolutions.jump.feature.BasicFeature;
import com.vividsolutions.jump.feature.Feature;
import com.vividsolutions.jump.feature.FeatureDataset;
import com.vividsolutions.jump.feature.FeatureSchema;
import com.vividsolutions.jump.workbench.model.CategoryEvent;
import com.vividsolutions.jump.workbench.model.FeatureEvent;
import com.vividsolutions.jump.workbench.model.Layer;
import com.vividsolutions.jump.workbench.model.LayerEvent;
import com.vividsolutions.jump.workbench.model.LayerEventType;
import com.vividsolutions.jump.workbench.model.LayerListener;
import com.vividsolutions.jump.workbench.model.StandardCategoryNames;
import com.vividsolutions.jump.workbench.model.UndoableEditReceiver;
import com.vividsolutions.jump.workbench.plugin.PlugInContext;
import com.vividsolutions.jump.workbench.ui.EditTransaction;
import com.vividsolutions.jump.workbench.ui.GUIUtil;
import com.vividsolutions.jump.workbench.ui.MenuNames;
import com.vividsolutions.jump.workbench.ui.OKCancelPanel;
import com.vividsolutions.jump.workbench.ui.SelectionManager;
import com.vividsolutions.jump.workbench.ui.renderer.style.ArrowLineStringEndpointStyle;
//adapted from MultiInputDialog
public class EditSelectedSideDialog extends JDialog
{
final static String sIsAnInvalidDouble=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.is-an-invalid-double");
final static String sLength=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.length");
final static String sAngle=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.angle");
final static String sInteriorAngle=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.interior-angle");
final static String sSide=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.Side");
final static String sChangeDirection=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.Change-Direction");
final static String sZoomToSide=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.Zoom-To-Side");
final static String sMakeSideOne=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.Make-Side-One");
final static String sFront=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.Front");
final static String sSelectedSide=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.Selected-Side");
final static String sEditSelectedSide=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.Edit-Selected-Side");
final static String sNA=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.NA");
final static String sLengthMustBeGreaterThanZero=I18N.get("org.openjump.core.ui.plugin.mousemenu.EditSelectedSideDialog.Length-must-be-greater-than-zero");
private final static int SIDEBAR_WIDTH = 150;
OKCancelPanel okCancelPanel = new OKCancelPanel();
GridBagLayout gridBagLayout2 = new GridBagLayout();
JPanel outerMainPanel = new JPanel();
static final int LENGTH = 0;
static final int ANGLE = 1;
static final int INTERIOR_ANGLE = 2;
private BorderLayout borderLayout2 = new BorderLayout();
private JPanel imagePanel = new JPanel();
private GridBagLayout gridBagLayout3 = new GridBagLayout();
private JLabel imageLabel = new JLabel();
private JPanel mainPanel = new JPanel();
private GridBagLayout mainPanelGridBagLayout = new GridBagLayout();
private JPanel innerMainPanel = new JPanel();
private JPanel innerMainPanel2 = new JPanel();
private GridBagLayout gridBagLayout5 = new GridBagLayout();
private GridBagLayout gridBagLayout7 = new GridBagLayout();
private GridBagLayout gridBagLayout6 = new GridBagLayout();
private JTextArea descriptionTextArea = new JTextArea();
private JPanel strutPanel = new JPanel();
private JPanel currentMainPanel = innerMainPanel;
private JPanel verticalSeparatorPanel = new JPanel();
//edit dialog variables
private JPanel mainEditPanel = new JPanel();
private Border titleBorder;
private JPanel inputPanel = new JPanel();
private JPanel inputSubPanel = new JPanel();
private GridBagLayout inputPanelGridBagLayout = new GridBagLayout();
private GridBagLayout inputSubPanelGridBagLayout = new GridBagLayout();
private TitledBorder inputPanelTitle = new TitledBorder(titleBorder, "");;
private JCheckBox readonlyCheckBox = new JCheckBox();
// private JTextField sideTextField = new JTextField(3);
private JTextField lengthTextField = new JTextField(10);
private JTextField angleTextField = new JTextField(6);
private JTextField interiorAngleTextField = new JTextField(6);
private JLabel sideLabel = new JLabel();
private JLabel lengthLabel = new JLabel();
private JLabel angleLabel = new JLabel();
private JLabel interiorAngleLabel = new JLabel();
private JPanel buttonPanel = new JPanel();
private JPanel buttonSubPanel = new JPanel();
private GridBagLayout buttonPanelGridBagLayout = new GridBagLayout();
private GridBagLayout buttonSubPanelGridBagLayout = new GridBagLayout();
private TitledBorder buttonPanelTitle = new TitledBorder(titleBorder, "");;
private JButton changeDirectionButton = new JButton();
private JButton makeSideOneButton = new JButton();
private JCheckBox zoomToSideCheckBox = new JCheckBox();
// private JButton zoomToSideButton = new JButton();
// private JButton zoomToShapeButton = new JButton();
private JButton selectedButton;
private PlugInContext context;
private Layer selectedSideLayer;
private Layer editLayer;
private Layer activeLayer;
private Collection selectedFeatures;
private Feature selectedFeature;
private Geometry selectedGeo;
public Geometry ghostGeo;
private Coordinate[] ghostCoords;
private Arc angleArc;
private Feature arrowFeature;
private int direction;
private JSpinner sideSpinner;
private DecimalFormat df2 = new DecimalFormat("##0.0#");
private DecimalFormat df3 = new DecimalFormat("########0.0##");
private int currSide;
private boolean isClockwise;
private boolean isLineString;
private boolean hasPendingEdits; //if true then user has done some editing and has not applied them
/**
* @param context the context on which to make this dialog modal and centred
*/
public EditSelectedSideDialog(PlugInContext context, String title, boolean modal)
{
super(context.getWorkbenchFrame(), title, modal);
this.context = context;
try
{
verticalSeparatorPanel.setBackground(Color.black);
okCancelPanel.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
okCancelPanel_actionPerformed(e);
}
});
this.addComponentListener(new java.awt.event.ComponentAdapter()
{
public void componentShown(ComponentEvent e)
{
this_componentShown(e);
}
});
this.setResizable(true);
this.getContentPane().setLayout(borderLayout2);
this.getContentPane().add(okCancelPanel, BorderLayout.SOUTH);
this.getContentPane().add(outerMainPanel, BorderLayout.CENTER);
} catch (Exception ex)
{
ex.printStackTrace();
}
inputPanel.setBorder(inputPanelTitle);
inputPanel.setLayout(inputPanelGridBagLayout);
inputSubPanel.setLayout(inputSubPanelGridBagLayout);
sideLabel.setText(sSide + ": ");
SpinnerModel sideSpinnerModel = new SpinnerNumberModel(1, 1, 1, 1);
sideSpinner = new JSpinner(sideSpinnerModel);
sideSpinner.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
JSpinner spinner = (JSpinner)e.getSource();
currSide = ((Integer)spinner.getValue()).intValue();
if (currSide == 0)
{
currSide = ghostCoords.length - 1;
spinner.setValue(new Integer(ghostCoords.length - 1));
}
if (currSide == ghostCoords.length)
{
currSide = 1;
spinner.setValue(new Integer(1));
}
changeSide();
if (zoomToSideCheckBox.isSelected()) zoomToSide();
}
});
lengthLabel.setText(sLength + ": ");
lengthTextField.setText("999999.000");
lengthTextField.setHorizontalAlignment(SwingConstants.LEADING);
angleLabel.setText(sAngle + ": ");
angleTextField.setText("000.00");
angleTextField.setHorizontalAlignment(SwingConstants.LEADING);
interiorAngleLabel.setText(sInteriorAngle + ": ");
interiorAngleTextField.setText("000.00");
interiorAngleTextField.setHorizontalAlignment(SwingConstants.LEADING);
lengthTextField.addFocusListener(new FocusListener()
{ //need these to handle tab key; will also handle click in/out
public void focusGained(FocusEvent e)
{
}
public void focusLost(FocusEvent e)
{
updateGeo(LENGTH);
}
});
angleTextField.addFocusListener(new FocusListener()
{ //need these to handle tab key; will also handle click in/out
public void focusGained(FocusEvent e)
{
}
public void focusLost(FocusEvent e)
{
updateGeo(ANGLE);
}
});
interiorAngleTextField.addFocusListener(new FocusListener()
{ //need these to handle tab key; will also handle click in/out
public void focusGained(FocusEvent e)
{
}
public void focusLost(FocusEvent e)
{
updateGeo(INTERIOR_ANGLE);
}
});
inputPanel.add(inputSubPanel,
new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0));
inputSubPanel.add(sideLabel,
new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
inputSubPanel.add(sideSpinner,
new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 5), 0, 0));
inputSubPanel.add(lengthLabel,
new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
inputSubPanel.add(lengthTextField,
new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 5), 0, 0));
inputSubPanel.add(angleLabel,
new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
inputSubPanel.add(angleTextField,
new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 5), 0, 0));
inputSubPanel.add(interiorAngleLabel,
new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
inputSubPanel.add(interiorAngleTextField,
new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 5), 0, 0));
buttonPanel.setBorder(buttonPanelTitle);
buttonPanel.setLayout(buttonPanelGridBagLayout);
buttonSubPanel.setLayout(buttonSubPanelGridBagLayout);
changeDirectionButton.setText(sChangeDirection);
makeSideOneButton.setText(sMakeSideOne + " (" + sFront + ")");
zoomToSideCheckBox.setText(sZoomToSide);
// zoomToSideButton.setText("Zoom To Side");
// zoomToShapeButton.setText("Zoom To Shape");
changeDirectionButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
selectedButton = changeDirectionButton;
changeDirection();
}
});
makeSideOneButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
selectedButton = makeSideOneButton;
makeSideOne();
}
});
zoomToSideCheckBox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (zoomToSideCheckBox.isSelected()) zoomToSide();
}
});
// zoomToSideButton.addActionListener(new ActionListener()
// {
// public void actionPerformed(ActionEvent e)
// {
// selectedButton = zoomToSideButton;
// zoomToSide();
// }
// });
//
// zoomToShapeButton.addActionListener(new ActionListener()
// {
// public void actionPerformed(ActionEvent e)
// {
// selectedButton = zoomToSideButton;
// zoomToShape();
// }
// });
buttonPanel.add(buttonSubPanel,
new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0));
buttonSubPanel.add(changeDirectionButton,
new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
buttonSubPanel.add(makeSideOneButton,
new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
buttonSubPanel.add(zoomToSideCheckBox,
new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
// buttonSubPanel.add(zoomToSideButton,
// new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0,
// GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
// new Insets(0, 0, 0, 0), 0, 0));
//
// buttonSubPanel.add(zoomToShapeButton,
// new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0,
// GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
// new Insets(0, 0, 0, 0), 0, 0));
mainEditPanel.add(inputPanel,
new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
mainEditPanel.add(buttonPanel,
new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0,
GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
this.getContentPane().add(okCancelPanel, BorderLayout.SOUTH);
this.getContentPane().add(mainEditPanel, BorderLayout.CENTER);
init();
}
public EditSelectedSideDialog()
{
this(null, "", false);
}
public void init()//(PlugInContext context)//, Layer selectedSideLayer, Layer editLayer, Layer activeLayer, Collection selectedFeatures)//, ArrayList transactions, EditTransaction transaction)
{
SelectionManager selectionManager = context.getLayerViewPanel().getSelectionManager();
Collection selectedLayers = selectionManager.getLayersWithSelectedItems();
activeLayer = (Layer)selectedLayers.iterator().next();
selectedFeatures = selectionManager.getFeaturesWithSelectedItems();
selectedFeature = (Feature) selectedFeatures.iterator().next();
Collection selectedItems = selectionManager.getSelectedItems(activeLayer);
selectedGeo = (Geometry) selectedItems.iterator().next();
//set up the selected side layer
FeatureSchema featureSchema = new FeatureSchema();
featureSchema.addAttribute("GEOMETRY", AttributeType.GEOMETRY);
FeatureDataset featureDataset = new FeatureDataset(featureSchema);
Collection selectedCategories = context.getLayerNamePanel()
.getSelectedCategories();
selectedSideLayer = context.addLayer(selectedCategories.isEmpty()
? StandardCategoryNames.WORKING
: selectedCategories.iterator().next().toString(), sSelectedSide,
featureDataset);
selectedSideLayer.setFeatureCollectionModified(false).setEditable(true);
selectedSideLayer.addStyle(new ArrowLineStringEndpointStyle.SolidEnd());
selectedSideLayer.getBasicStyle().setLineColor(Color.red);
selectedSideLayer.getLayerManager().addLayerListener(new LayerListener()
{
public void featuresChanged(FeatureEvent e){}
public void categoryChanged(CategoryEvent e){}
public void layerChanged(LayerEvent e){
if (e.getType() == LayerEventType.METADATA_CHANGED)
selectedSideLayer.setEditable(false);}
});
//set up the edit layer
FeatureSchema featureSchema2 = new FeatureSchema();
featureSchema2.addAttribute("GEOMETRY", AttributeType.GEOMETRY);
FeatureDataset featureDataset2 = new FeatureDataset(featureSchema2);
editLayer = context.addLayer(selectedCategories.isEmpty()
? StandardCategoryNames.WORKING
//: selectedCategories.iterator().next().toString(), "Edit", //[sstein 19.10.2005] hope that works
: selectedCategories.iterator().next().toString(), MenuNames.EDIT,
featureDataset2);
editLayer.getBasicStyle().setLineColor(Color.red);
editLayer.getLayerManager().addLayerListener(new LayerListener()
{
public void featuresChanged(FeatureEvent e){}
public void categoryChanged(CategoryEvent e){}
public void layerChanged(LayerEvent e){
if (e.getType() == LayerEventType.METADATA_CHANGED)
editLayer.setEditable(false);}
});
// selectionManager.clear();
final ArrayList transactions = new ArrayList();
EditTransaction transaction = new EditTransaction(selectedFeatures, getName(), activeLayer, false, false, context.getWorkbenchContext().getLayerViewPanel());
selectedGeo = selectedFeature.getGeometry();
direction = 0;
isClockwise = new GeoUtils().clockwise(selectedGeo);
hasPendingEdits = false;
Coordinate[] geoCoords = selectedGeo.getCoordinates();
ghostCoords = new Coordinate[geoCoords.length];
for (int i = 0; i < ghostCoords.length; i++)
{
ghostCoords[i] = (Coordinate) geoCoords[i].clone();
}
Coordinate clickPoint = new Coordinate(0,0,0);
try
{
clickPoint = context.getLayerViewPanel().getViewport().toModelCoordinate(context.getLayerViewPanel().getLastClickedPoint());
}
catch (NoninvertibleTransformException e)
{
}
double distToSide = new GeoUtils().getDistance(clickPoint, (Coordinate) ghostCoords[0], (Coordinate) ghostCoords[1]);
currSide = 1;
for (int i = 1; i < ghostCoords.length - 1; i++)
{
double currDistToSide = new GeoUtils().getDistance(clickPoint, (Coordinate) ghostCoords[i], (Coordinate) ghostCoords[i+1]);
if (currDistToSide < distToSide)
{
distToSide = currDistToSide;
currSide = i + 1;
}
}
sideSpinner.setModel(new SpinnerNumberModel(currSide, 0, ghostCoords.length, 1));
//set up ghost shape
FeatureSchema fs2 = editLayer.getFeatureCollectionWrapper().getFeatureSchema();
Feature feature2 = new BasicFeature(fs2);
if ((selectedGeo instanceof Polygon) || (selectedGeo instanceof LinearRing))
{
isLineString = false;
ghostGeo = new GeometryFactory().createLinearRing(ghostCoords);
}
else
{
isLineString = true;
ghostGeo = new GeometryFactory().createLineString(ghostCoords);
makeSideOneButton.setEnabled(false);
}
ghostCoords = ghostGeo.getCoordinates();
feature2.setGeometry(ghostGeo);
editLayer.getFeatureCollectionWrapper().add(feature2);
//set up the edit arrow
FeatureSchema fs = selectedSideLayer.getFeatureCollectionWrapper().getFeatureSchema();
arrowFeature = new BasicFeature(fs);
arrowFeature.setGeometry(getArcArrow());
selectedSideLayer.getFeatureCollectionWrapper().add(arrowFeature);
changeSide();
}
public void setVisible(boolean visible)
{
//Workaround for Java bug 4446522 " JTextArea.getPreferredSize()
//incorrect when line wrapping is used": call #pack twice [Jon Aquino]
pack();
pack();
GUIUtil.centreOnWindow(EditSelectedSideDialog.this);
super.setVisible(visible);
}
protected Coordinate[] toArray(List coordinates)
{
return (Coordinate[]) coordinates.toArray(new Coordinate[]
{ });
}
public boolean wasOKPressed()
{
return okCancelPanel.wasOKPressed();
}
//Experience suggests that one should avoid using weights when using the
//GridBagLayout. I find that nonzero weights can cause layout bugs that are
//hard to track down. [Jon Aquino]
// void jbInit() throws Exception
// {
// verticalSeparatorPanel.setBackground(Color.black);
//
// okCancelPanel.addActionListener(new java.awt.event.ActionListener()
// {
// public void actionPerformed(ActionEvent e)
// {
// okCancelPanel_actionPerformed(e);
// }
// });
//
// this.addComponentListener(new java.awt.event.ComponentAdapter()
// {
// public void componentShown(ComponentEvent e)
// {
// this_componentShown(e);
// }
// });
// this.setResizable(false);
// this.getContentPane().setLayout(borderLayout2);
// this.getContentPane().add(okCancelPanel, BorderLayout.SOUTH);
// this.getContentPane().add(outerMainPanel, BorderLayout.CENTER);
// }
void okCancelPanel_actionPerformed(ActionEvent e)
{
if (okCancelPanel.wasOKPressed())
{
if (hasPendingEdits)
{
// SelectionManager selectionManager = context.getLayerViewPanel().getSelectionManager();
// Collection selectedLayers = selectionManager.getLayersWithSelectedItems();
// Layer activeLayer = (Layer)selectedLayers.iterator().next();
// Collection selectedFeatures = selectionManager.getFeaturesWithSelectedItems();
// Feature selectedFeature = (Feature) selectedFeatures.iterator().next();
UndoableEditReceiver undoableEditReceiver =
context.getWorkbenchContext().getLayerManager() != null
? context.getWorkbenchContext()
.getLayerManager()
.getUndoableEditReceiver()
: null;
if (undoableEditReceiver != null)
{
undoableEditReceiver.startReceiving();
}
if (selectedGeo instanceof Polygon)
ghostGeo = new GeometryFactory().createPolygon((LinearRing)ghostGeo, null);
EditTransaction transaction = new EditTransaction(selectedFeatures, sEditSelectedSide,
activeLayer, false, false,
context.getWorkbenchContext().getLayerViewPanel());
transaction.setGeometry(selectedFeature, ghostGeo);
transaction.commit();
if (undoableEditReceiver != null)
{
undoableEditReceiver.stopReceiving();
}
}
}
setVisible(false);
selectedSideLayer.getLayerManager().remove(selectedSideLayer);
editLayer.getLayerManager().remove(editLayer);
return;
}
void this_componentShown(ComponentEvent e)
{
okCancelPanel.setOKPressed(false);
}
private void reportValidationError(String errorMessage)
{
JOptionPane.showMessageDialog(
this,
errorMessage,
"JUMP",
JOptionPane.ERROR_MESSAGE);
}
void changeDirection()
{
direction = 1 - direction;
changeSide();
};
void makeSideOne()
{
if (currSide != 1)
{
Coordinate[] tempCoords = new Coordinate[ghostCoords.length];
for (int i = 0; i < ghostCoords.length; i++)
{
tempCoords[i] = (Coordinate) ghostCoords[i].clone();
}
int index = 0;
for (int i = currSide-1; i < ghostCoords.length; i++)
{
ghostCoords[index] = tempCoords[i];
index++;
}
for (int i = 1; i < currSide; i++)
{
ghostCoords[index] = tempCoords[i];
index++;
}
ghostGeo = new GeometryFactory().createLinearRing(ghostCoords);
sideSpinner.setModel(new SpinnerNumberModel(1, 0, ghostCoords.length, 1));
hasPendingEdits = true;
currSide = 1;
}
return;
};
void zoomToSide()
{
Envelope sideEnv = getArcArrow().getEnvelopeInternal();
double width = sideEnv.getWidth() / 10.0;
double height = sideEnv.getHeight() / 10.0;
double extraOnRight = sideEnv.getMaxX() + width;
double extraOnLeft = sideEnv.getMinX() - width;
double extraOnTop = sideEnv.getMaxY() + height;
double extraOnBot = sideEnv.getMinY() - height;
sideEnv.expandToInclude(extraOnRight, extraOnTop);
sideEnv.expandToInclude(extraOnLeft, extraOnBot);
try
{
context.getWorkbenchContext().getLayerViewPanel().getViewport().zoom(sideEnv);
}
catch (NoninvertibleTransformException e)
{
}
changeSide();
return;
};
void zoomToShape()
{
Envelope shapeEnv = ghostGeo.getEnvelopeInternal();
shapeEnv.expandToInclude(selectedGeo.getEnvelopeInternal());
double width = shapeEnv.getWidth() / 10.0;
double height = shapeEnv.getHeight() / 10.0;
double extraOnRight = shapeEnv.getMaxX() + width;
double extraOnLeft = shapeEnv.getMinX() - width;
double extraOnTop = shapeEnv.getMaxY() + height;
double extraOnBot = shapeEnv.getMinY() - height;
shapeEnv.expandToInclude(extraOnRight, extraOnTop);
shapeEnv.expandToInclude(extraOnLeft, extraOnBot);
try
{
context.getWorkbenchContext().getLayerViewPanel().getViewport().zoom(shapeEnv);
}
catch (NoninvertibleTransformException e)
{
}
changeSide();
return;
};
private void changeSide()
{
Coordinate startPt = ghostCoords[getStartIndex()];
Coordinate endPt = ghostCoords[getEndIndex()];
Coordinate prevPt = ghostCoords[getPrevIndex()]; //point prior to startPt
lengthTextField.setText(df3.format(startPt.distance(endPt)));
angleTextField.setText(df2.format(new GeoUtils().getBearing180(startPt, endPt)));
if (prevPt.equals2D(startPt))
{
interiorAngleTextField.setEnabled(false);
interiorAngleTextField.setText(sNA);
}
else
{
interiorAngleTextField.setEnabled(true);
interiorAngleTextField.setText(df2.format(getInteriorAngle(prevPt, startPt, endPt)));
}
selectedSideLayer.getFeatureCollectionWrapper().remove(arrowFeature);
FeatureSchema fs = selectedSideLayer.getFeatureCollectionWrapper().getFeatureSchema();
arrowFeature = new BasicFeature(fs);
arrowFeature.setGeometry(getArcArrow());
selectedSideLayer.getFeatureCollectionWrapper().add(arrowFeature);
selectedSideLayer.fireAppearanceChanged();
}
private LineString getArcArrow()
{
Coordinate startPt = ghostCoords[getStartIndex()];
Coordinate endPt = ghostCoords[getEndIndex()];
Coordinate prevPt = ghostCoords[getPrevIndex()]; //point prior to startPt
CoordinateList arcCoords = new CoordinateList();
if (prevPt.equals2D(startPt))
{
arcCoords.add(startPt);
}
else
{
double scale = context.getWorkbenchContext().getLayerViewPanel().getViewport().getScale();
double arcAngle = getInteriorAngle(prevPt, startPt, endPt);
Coordinate startArcPt = new GeoUtils().along(15/scale, startPt, prevPt);;
boolean cw = isClockwise;
if (direction == 1) cw = !cw;
if (cw) arcAngle = -arcAngle;
angleArc = new Arc(startPt, startArcPt, arcAngle);
arcCoords = angleArc.getCoordinates();
}
arcCoords.add(endPt);
return new GeometryFactory().createLineString(arcCoords.toCoordinateArray());
}
private double getInteriorAngle(Coordinate prevPt, Coordinate startPt, Coordinate endPt)
{
if (prevPt.equals2D(startPt))
{
return 0.0;
}
else
{
MathVector v1 = (new MathVector(prevPt)).vectorBetween(new MathVector(startPt));
MathVector v2 = (new MathVector(startPt)).vectorBetween(new MathVector(endPt));
boolean toRight = new GeoUtils().pointToRight(endPt, prevPt, startPt);
boolean cw = isClockwise;
if (direction == 1) cw = !cw;
double angle = v1.angleDeg(v2);
if ((cw && toRight) || (!cw && !toRight))
angle = 180 - angle;
else
angle = 180 + angle;
return angle;
}
}
private void updateGeo(int from)
{
switch (from)
{
case LENGTH:
{
try
{ double length = df3.parse(lengthTextField.getText().trim(), new ParsePosition(0)).doubleValue();
//double length = Double.parseDouble(lengthTextField.getText().trim());
if (length <= 0)
{
reportValidationError(sLengthMustBeGreaterThanZero);
}
else
{
Coordinate startPt = ghostCoords[getStartIndex()];
Coordinate endPt = ghostCoords[getEndIndex()];
Coordinate newPt = new GeoUtils().along(length, startPt, endPt);
replaceVertex(getEndIndex(), newPt);
}
}
catch (NumberFormatException e)
{
reportValidationError(
"\""
+ lengthTextField.getText().trim()
+ "\" " + sIsAnInvalidDouble + " ("
+ sLength
+ ")");
}
break;
}
case ANGLE:
{
try
{ double angle = df2.parse(angleTextField.getText().trim(), new ParsePosition(0)).doubleValue();
//double angle = Double.parseDouble(angleTextField.getText().trim());
Coordinate startPt = ghostCoords[getStartIndex()];
Coordinate endPt = ghostCoords[getEndIndex()];
double length = startPt.distance(endPt);
Coordinate newPt = (Coordinate) startPt.clone();
newPt.x += length;
newPt = new GeoUtils().rotPt(newPt, startPt, -angle);
replaceVertex(getEndIndex(), newPt);
}
catch (NumberFormatException e)
{
reportValidationError(
"\""
+ angleTextField.getText().trim()
+ "\" " + sIsAnInvalidDouble + " ("
+ sAngle
+ ")");
}
break;
}
case INTERIOR_ANGLE:
{
try
{
Coordinate prevPt = ghostCoords[getPrevIndex()];
Coordinate startPt = ghostCoords[getStartIndex()];
Coordinate endPt = ghostCoords[getEndIndex()];
double angle = df2.parse(interiorAngleTextField.getText().trim(), new ParsePosition(0)).doubleValue();
//double angle = Double.parseDouble(interiorAngleTextField.getText().trim());
double length = startPt.distance(endPt);
boolean cw = isClockwise;
if (direction == 1) cw = !cw;
if (cw) angle = -angle;
Coordinate newPt = new GeoUtils().rotPt(prevPt, startPt, angle);
newPt = new GeoUtils().along(length, startPt, newPt);
replaceVertex(getEndIndex(), newPt);
}
catch (NumberFormatException e)
{
reportValidationError(
"\""
+ interiorAngleTextField.getText().trim()
+ "\" " + sIsAnInvalidDouble + " ("
+ sInteriorAngle
+ ")");
}
break;
}
}
changeSide();
editLayer.fireAppearanceChanged();
}
private void replaceVertex(int index, Coordinate coord)
{
ghostCoords[index].x = coord.x;
ghostCoords[index].y = coord.y;
if (!isLineString)
{
if (index == 0)
{
ghostCoords[ghostCoords.length - 1].x = coord.x;
ghostCoords[ghostCoords.length - 1].y = coord.y;
}
if (index == ghostCoords.length - 1)
{
ghostCoords[0].x = coord.x;
ghostCoords[0].y = coord.y;
}
}
ghostGeo.geometryChanged();
hasPendingEdits = true;
}
private int getStartIndex()
{
if (direction == 0)
return currSide - 1;
else
return currSide;
}
private int getEndIndex()
{
if (direction == 0)
return currSide;
else
return currSide - 1;
}
private int getPrevIndex()
{
int prevIndex = currSide - 2;
int nextIndex = currSide + 1;
if (isLineString)
{
if (prevIndex < 0) prevIndex = 0;
if (nextIndex >= ghostCoords.length) nextIndex = ghostCoords.length - 1;
}
else
{
if (prevIndex < 0) prevIndex = ghostCoords.length - 2;
if (nextIndex >= ghostCoords.length) nextIndex = 1;
}
if (direction == 1) prevIndex = nextIndex;
return prevIndex;
}
private int getNextIndex()
{
int prevIndex = currSide - 2;
int nextIndex = currSide + 1;
if (isLineString)
{
if (prevIndex < 0) prevIndex = 0;
if (nextIndex >= ghostCoords.length) nextIndex = ghostCoords.length - 1;
}
else
{
if (prevIndex < 0) prevIndex = ghostCoords.length - 2;
if (nextIndex >= ghostCoords.length) nextIndex = 1;
}
if (direction == 1) nextIndex = prevIndex;
return nextIndex;
}
private boolean goodDouble(String fieldName)
{
try
{
df3.parse(lengthTextField.getText().trim(), new ParsePosition(0)).doubleValue();
//Double.parseDouble(lengthTextField.getText().trim());
return true;
}
catch (NumberFormatException e)
{
reportValidationError(
"\""
+ lengthTextField.getText().trim()
+ "\" " + sIsAnInvalidDouble + " ("
+ fieldName
+ ")");
return false;
}
}
}