JTSTestBuilderFrame.java
/*
* Copyright (c) 2016 Vivid Solutions.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.locationtech.jtstest.testbuilder;
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.util.Assert;
import org.locationtech.jtstest.testbuilder.io.XMLTestWriter;
import org.locationtech.jtstest.testbuilder.model.DisplayParameters;
import org.locationtech.jtstest.testbuilder.model.GeometryEvent;
import org.locationtech.jtstest.testbuilder.model.TestBuilderModel;
import org.locationtech.jtstest.testbuilder.model.TestCaseEdit;
import org.locationtech.jtstest.testbuilder.ui.SwingUtil;
import org.locationtech.jtstest.testbuilder.ui.dnd.FileDrop;
import org.locationtech.jtstest.testbuilder.ui.tools.RectangleTool;
import org.locationtech.jtstest.util.StringUtil;
/**
* The main frame for the JTS Test Builder.
*
* @version 1.7
*/
public class JTSTestBuilderFrame extends JFrame
{
private static JTSTestBuilderFrame singleton = null;
static boolean isShowingIndicators = true;
static boolean isSavingIndicators = false;
TestBuilderModel tbModel;
private JTSTestBuilderMenuBar tbMenuBar = new JTSTestBuilderMenuBar(this);
private JTSTestBuilderToolBar tbToolBar = new JTSTestBuilderToolBar(this);
//---------------------------------------------
JPanel contentPane;
BorderLayout contentLayout = new BorderLayout();
Border border4;
JSplitPane jSplitPane1 = new JSplitPane();
JPanel panelTop = new JPanel();
BorderLayout borderLayout2 = new BorderLayout();
TestCasePanel testCasePanel = new TestCasePanel();
JPanel panelBottom = new JPanel();
JTabbedPane inputTabbedPane = new JTabbedPane();
BorderLayout borderLayout3 = new BorderLayout();
JPanel testPanel = new JPanel();
WKTPanel wktPanel = new WKTPanel(this);
CommandPanel commandPanel = new CommandPanel();
InspectorPanel inspectPanel = new InspectorPanel();
TestListPanel testListPanel = new TestListPanel(this);
LayerListPanel layerListPanel = new LayerListPanel();
GridBagLayout gridBagLayout2 = new GridBagLayout();
GridLayout gridLayout1 = new GridLayout();
ResultWKTPanel resultWKTPanel = new ResultWKTPanel();
ResultValuePanel resultValuePanel = new ResultValuePanel();
StatsPanel statsPanel = new StatsPanel();
InfoPanel logPanel = new InfoPanel();
private JFileChooser fileChooser = new JFileChooser();
private JFileChooser pngFileChooser;
private JFileChooser fileAndDirectoryChooser = new JFileChooser();
private JFileChooser directoryChooser = new JFileChooser();
/**
* Construct the frame
*/
public JTSTestBuilderFrame() {
try {
Assert.isTrue(singleton == null);
singleton = this;
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
setIconImage(AppIcons.APP.getImage());
jbInit();
testCasePanel.cbRevealTopo.addActionListener(
new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
displayRevealTopo();
}
});
//testCasePanel.editCtlPanel.stretchDist
testCasePanel.spStretchDist
.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent e) {
displayRevealTopo();
}
});
showGeomsTab();
initFileDrop(testCasePanel);
testCasePanel.getGeometryEditPanel().setCurrentTool(RectangleTool.getInstance());
}
catch (Exception e) {
e.printStackTrace();
}
}
private void initFileDrop(Component comp) {
new FileDrop(comp, new FileDrop.Listener() {
public void filesDropped(java.io.File[] files) {
try {
openXmlFilesAndDirectories(files);
} catch (Exception ex) {
SwingUtil.reportException(null, ex);
}
}
});
}
private void initFileChoosers() {
if (pngFileChooser == null) {
pngFileChooser = new JFileChooser();
pngFileChooser.addChoosableFileFilter(SwingUtil.PNG_FILE_FILTER);
pngFileChooser.setDialogTitle("Save PNG");
pngFileChooser.setSelectedFile(new File("geoms.png"));
}
}
public static JTSTestBuilderFrame instance() {
if (singleton == null) {
new JTSTestBuilderFrame();
}
return singleton;
}
/**
* Tests if the TestBuilder is running.
* Useful to allow functions to decide whether to show indicators
* (if functions are running under JtsOpCmd, they should not show indicators
* since that seriously impacts performance).
*
* @return true if there is a TestBuilder instance running
*/
public static boolean isRunning() {
return singleton != null;
}
public static boolean isShowingIndicators() {
return isRunning() && isShowingIndicators;
}
public static boolean isSavingIndicators() {
return isRunning() && isSavingIndicators;
}
public static GeometryEditPanel getGeometryEditPanel()
{
return instance().getTestCasePanel().getGeometryEditPanel();
}
public static SpatialFunctionPanel getSpatialFunctionPanel()
{
return instance().getTestCasePanel().spatialFunctionPanel;
}
public TestBuilderModel getModel()
{
return tbModel;
}
public void setModel(TestBuilderModel model)
{
tbModel = model;
testCasePanel.setModel(tbModel);
wktPanel.setModel(model);
inspectPanel.setModel(model);
resultWKTPanel.setModel(model);
resultValuePanel.setModel(model);
statsPanel.setModel(model);
model.getGeometryEditModel().addGeometryListener(
new org.locationtech.jtstest.testbuilder.model.GeometryListener() {
public void geometryChanged(GeometryEvent e) {
model_geometryChanged(e);
}
});
testListPanel.populateList();
//layerListPanel.init(getModel().getLayers());
layerListPanel.populateList();
updateTestCaseView();
updatePrecisionModelDescription();
}
public static void reportException(Exception e) {
SwingUtil.reportException(instance(), e);
}
public void setCursorWait() {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
}
public void setCursorNormal() {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
public void setCurrentTestCase(TestCaseEdit testCase) {
tbModel.cases().setCurrent(testCase);
updateTestCaseView();
JTSTestBuilder.controller().zoomToInput();
}
public TestCasePanel getTestCasePanel() {
return testCasePanel;
}
public ResultWKTPanel getResultWKTPanel() {
return resultWKTPanel;
}
public ResultValuePanel getResultValuePanel() {
return resultValuePanel;
}
public InfoPanel getLogPanel() {
return logPanel;
}
public CommandPanel getCommandPanel() {
return commandPanel;
}
/**
* File | Exit action performed
*/
public void actionExit() {
System.exit(0);
}
public void showTab(String name)
{
inputTabbedPane.setSelectedIndex(inputTabbedPane.indexOfTab(name));
}
public void showGeomsTab()
{
showTab(AppStrings.TAB_LABEL_INPUT);
}
public void showResultWKTTab()
{
showTab(AppStrings.TAB_LABEL_RESULT);
}
public void showResultValueTab()
{
showTab(AppStrings.TAB_LABEL_VALUE);
}
public void showInfoTab()
{
showTab(AppStrings.TAB_LABEL_LOG);
}
public void openXmlFilesAndDirectories(File[] files) throws Exception {
if (files.length == 1) {
fileChooser.setSelectedFile(files[0]);
}
tbModel.openXmlFilesAndDirectories(files);
reportProblemsParsingXmlTestFile(tbModel.getParsingProblems());
updateTestCaseView();
testListPanel.populateList();
updatePrecisionModelDescription();
JTSTestBuilder.controller().zoomToInput();
}
/**
* Overridden so we can exit when window is closed
*/
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
actionExit();
}
}
void model_geometryChanged(GeometryEvent e) {
JTSTestBuilder.controller().geometryChanged();
updateWktPanel();
}
TestCaseEdit currentCase() {
return tbModel.cases().getCurrentCase();
}
public void updateTestCases()
{
testListPanel.populateList();
updateTestCaseView();
}
public void copyResultToTest()
{
Object currResult = tbModel.getResult();
if (! (currResult instanceof Geometry))
return;
tbModel.addCase(new Geometry[] { (Geometry) currResult, null },
"Result of " + tbModel.getOpName());
updateTestCaseView();
testListPanel.populateList();
}
public void inspectResult()
{
Object currResult = tbModel.getResult();
if (! (currResult instanceof Geometry))
return;
inspectGeometry((Geometry) currResult, 0, "R", false);
}
public void inspectGeometry() {
int geomIndex = tbModel.getGeometryEditModel().getGeomIndex();
String tag = geomIndex == 0 ? AppStrings.GEOM_LABEL_A : AppStrings.GEOM_LABEL_B;
Geometry geometry = currentCase().getGeometry(geomIndex);
inspectGeometry(geometry, geomIndex, tag, true);
}
public void inspectGeometry(String tag, Geometry geometry) {
inspectPanel.setGeometry( tag, geometry, 0, false);
showTab(AppStrings.TAB_LABEL_INSPECT);
}
private void inspectGeometry(Geometry geometry, int geomIndex, String tag, boolean isEditable) {
inspectPanel.setGeometry( tag, geometry, geomIndex, isEditable);
showTab(AppStrings.TAB_LABEL_INSPECT);
}
void menuLoadXmlTestFile_actionPerformed(ActionEvent e) {
try {
fileChooser.removeChoosableFileFilter(SwingUtil.JAVA_FILE_FILTER);
fileChooser.addChoosableFileFilter(SwingUtil.XML_FILE_FILTER);
fileChooser.setDialogTitle("Open XML Test File(s)");
fileChooser.setMultiSelectionEnabled(true);
if (JFileChooser.APPROVE_OPTION == fileChooser.showOpenDialog(this)) {
File[] files = fileChooser.getSelectedFiles();
if (files.length == 0) {
files = new File[]{fileChooser.getSelectedFile()};
}
openXmlFilesAndDirectories(files);
}
}
catch (Exception x) {
SwingUtil.reportException(this, x);
}
}
public String getRunXml()
{
return XMLTestWriter.getRunXml(tbModel.getTestCaseList(), tbModel.getPrecisionModel());
}
void actionDeleteAllTestCases() {
tbModel.cases().init();
updateTestCaseView();
testListPanel.populateList();
}
void actionLoadXmlTestFolder() {
try {
directoryChooser.removeChoosableFileFilter(SwingUtil.JAVA_FILE_FILTER);
directoryChooser.setDialogTitle("Open Folder(s) Containing XML Test Files");
directoryChooser.setMultiSelectionEnabled(true);
if (JFileChooser.APPROVE_OPTION == directoryChooser.showOpenDialog(this)) {
File[] files = directoryChooser.getSelectedFiles();
if (files.length == 0) {
files = new File[]{fileChooser.getSelectedFile()};
}
openXmlFilesAndDirectories(files);
}
}
catch (Exception x) {
reportException(x);
}
}
private void displayRevealTopo() {
DisplayParameters.setRevealingTopology(testCasePanel.cbRevealTopo.isSelected());
DisplayParameters.setTopologyStretchSize(testCasePanel.getStretchSize());
JTSTestBuilder.controller().geometryViewChanged();
}
/**
* Component initialization
*/
private void jbInit() throws Exception {
this.setSize(new Dimension(800, 800));
this.setTitle("JTS TestBuilder");
this.setJMenuBar(tbMenuBar.getMenuBar());
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setMultiSelectionEnabled(false);
fileAndDirectoryChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
fileAndDirectoryChooser.setMultiSelectionEnabled(true);
directoryChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
directoryChooser.setMultiSelectionEnabled(false);
//Center the window
//Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
//---------------------------------------------------
wktPanel.setMinimumSize(new Dimension(111, 0));
wktPanel.setPreferredSize(new Dimension(600, 100));
testPanel.setLayout(gridBagLayout2);
gridLayout1.setRows(4);
gridLayout1.setColumns(1);
panelTop.setLayout(borderLayout2);
panelTop.setMinimumSize(new Dimension(431, 0));
panelTop.add(testCasePanel, BorderLayout.CENTER);
panelBottom.setLayout(borderLayout3);
panelBottom.setMinimumSize(new Dimension(431, 0));
panelBottom.add(tbToolBar.getToolBar(), BorderLayout.NORTH);
panelBottom.add(inputTabbedPane, BorderLayout.CENTER);
//---- Input tabs
inputTabbedPane.setTabPlacement(JTabbedPane.LEFT);
inputTabbedPane.add(testListPanel, AppStrings.TAB_LABEL_CASES);
inputTabbedPane.add(layerListPanel, AppStrings.TAB_LABEL_LAYERS);
inputTabbedPane.add(wktPanel, AppStrings.TAB_LABEL_INPUT);
inputTabbedPane.add(resultWKTPanel, AppStrings.TAB_LABEL_RESULT);
inputTabbedPane.add(resultValuePanel, AppStrings.TAB_LABEL_VALUE);
inputTabbedPane.add(inspectPanel, AppStrings.TAB_LABEL_INSPECT);
inputTabbedPane.add(statsPanel, AppStrings.TAB_LABEL_STATS);
inputTabbedPane.add(logPanel, AppStrings.TAB_LABEL_LOG);
inputTabbedPane.add(commandPanel, AppStrings.TAB_LABEL_COMMAND);
inputTabbedPane.setSelectedIndex(1);
inputTabbedPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e)
{
updateStatsPanelIfVisible();
}
});
//--- main frame
jSplitPane1.setOrientation(JSplitPane.VERTICAL_SPLIT);
jSplitPane1.setPreferredSize(new Dimension(601, 690));
jSplitPane1.setBorder(new EmptyBorder(2,2,2,2));
jSplitPane1.setResizeWeight(1);
jSplitPane1.setDividerLocation(500);
jSplitPane1.add(panelTop, JSplitPane.TOP);
jSplitPane1.add(panelBottom, JSplitPane.BOTTOM);
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(contentLayout);
contentPane.setPreferredSize(new Dimension(601, 690));
contentPane.add(jSplitPane1, BorderLayout.CENTER);
}
public JTSTestBuilderToolBar getToolbar()
{
return tbToolBar;
}
private void updateStatsPanelIfVisible()
{
int index = inputTabbedPane.getSelectedIndex();
if (index < 0) return;
if (inputTabbedPane.getComponent(index) == statsPanel) {
statsPanel.refresh();
}
}
public void geometryChanged() {
testCasePanel.relatePanel.clearResults();
testCasePanel.setTestCase(currentCase());
updateWktPanel();
}
private void updateWktPanel() {
Geometry g0 = tbModel.getGeometryEditModel().getGeometry(0);
wktPanel.setText(g0, 0);
Geometry g1 = tbModel.getGeometryEditModel().getGeometry(1);
wktPanel.setText(g1, 1);
}
void updatePrecisionModelDescription() {
testCasePanel.setPrecisionModelDescription(tbModel.getPrecisionModel().toString());
}
public void updateTestCaseView() {
testCasePanel.setTestCase(currentCase());
getTestCasePanel().setCurrentTestCaseIndex(tbModel.getCurrentCaseIndex() + 1);
getTestCasePanel().setMaxTestCaseIndex(tbModel.getCasesSize());
updateWktPanel();
updateStatsPanelIfVisible();
}
public void updateLayerList() {
layerListPanel.updateList();
}
public void refreshLayerList() {
layerListPanel.populateList();
}
private void reportProblemsParsingXmlTestFile(List parsingProblems) {
if (parsingProblems.isEmpty()) {
return;
}
for (Iterator i = parsingProblems.iterator(); i.hasNext(); ) {
String problem = (String) i.next();
System.out.println(problem);
}
JOptionPane.showMessageDialog(this, StringUtil.wrap(parsingProblems.size()
+ " problems occurred parsing the XML test file."
+ " The first problem was: " + parsingProblems.get(0), 80),
"Error", JOptionPane.ERROR_MESSAGE);
}
private Coordinate pickOffset(Geometry a, Geometry b) {
if (a != null && ! a.isEmpty()) {
return a.getCoordinates()[0];
}
if (b != null && ! b.isEmpty()) {
return b.getCoordinates()[0];
}
return null;
}
}