Notice: If you are member of any public project or group, please make sure that your GitLab username is not the same as the LRZ identifier/Kennung (see https://gitlab.lrz.de/profile/account). Please change your username if necessary. For more information see the section "Public projects / Öffentliche Projekte" at https://doku.lrz.de/display/PUBLIC/GitLab . Thank you!

Commit d14b7201 authored by hm-schuhba1's avatar hm-schuhba1

add stand alone features from VadereManagement module:

* single step mode in GUI:
  Allows the user to step through the simulation one step at a time to
  identify bugs.
* simplify obstacles:
  Merge multiple obstacles based on the convex hull their points create.
  The merge can be undon
* add features to open street map (osm) importer:
  1) import 'open' paths as polygons with a specified width. With this
     it is possible to create walls or subway entrance
  2) add option to include osm ids into each obstacle
parent fd7953ae
Pipeline #125635 passed with stages
in 109 minutes and 1 second
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -3,6 +3,35 @@ from lxml import etree
import osm2vadere
import unittest
import utm
import os
TEST_DATA_LON_LAT = os.path.join(os.path.dirname(__file__), 'maps/map_for_testing.osm')
TEST_DATA_2 = os.path.join(os.path.dirname(__file__), 'maps/map_mf_small.osm')
TEST_DATA="""{
"shape" : {
"type" : "POLYGON",
"points" : [ { "x" : 143.92115343943564, "y" : 168.69565355275918 },
{ "x" : 143.8295708812843, "y" : 158.46319241869656 },
{ "x" : 147.9524496438901, "y" : 158.453088570111 },
{ "x" : 148.04042161765545, "y" : 168.57734735060853 },
{ "x" : 148.54040274306163, "y" : 168.57300290155786 },
{ "x" : 148.44811333818495, "y" : 157.95187235651085 },
{ "x" : 143.3250868078719, "y" : 157.96442724530158 },
{ "x" : 143.42117346474575, "y" : 168.70012847277175 },
{ "x" : 143.92115343943564, "y" : 168.69565355275918 },
{ "x" : 143.92115343943564, "y" : 168.69565355275918 },
{ "x" : 143.8295708812843, "y" : 158.46319241869656 },
{ "x" : 147.9524496438901, "y" : 158.453088570111 },
{ "x" : 148.04042161765545, "y" : 168.57734735060853 },
{ "x" : 148.54040274306163, "y" : 168.57300290155786 },
{ "x" : 148.44811333818495, "y" : 157.95187235651085 },
{ "x" : 143.3250868078719, "y" : 157.96442724530158 },
{ "x" : 143.42117346474575, "y" : 168.70012847277175 },
{ "x" : 143.92115343943564, "y" : 168.69565355275918 } ]
},
"id" : 258139209
}
"""
class TestOsm2vadere(unittest.TestCase):
......@@ -24,7 +53,7 @@ class TestOsm2vadere(unittest.TestCase):
self.assertTrue(y_distance > 258 and y_distance < 275)
def test_extract_latitude_and_longitude_for_each_xml_node(self):
xml_tree = etree.parse("maps/map_for_testing.osm")
xml_tree = etree.parse(TEST_DATA_LON_LAT)
nodes_dictionary_with_lat_and_lon = osm2vadere.extract_latitude_and_longitude_for_each_xml_node(xml_tree)
self.assertTrue(nodes_dictionary_with_lat_and_lon.get("1")[0] == "1.1")
......@@ -34,12 +63,14 @@ class TestOsm2vadere(unittest.TestCase):
self.assertTrue (nodes_dictionary_with_lat_and_lon.get("3")[0] == "3.1")
self.assertTrue (nodes_dictionary_with_lat_and_lon.get("3")[1] == "3.2")
def test_find_width_and_height(self):
building_normal = [(1, 1), (3, 1), (1, 3), (3, 3)]
building_negative_coordinates = [(-1, 4), (-3, 2), (10, 2)]
building_with_floating_points = [(2.3, 1.4), (-10.5, 7), (9.99, 3), (5, 7.1), (3, 4)]
buildings_cartesian = [building_normal, building_negative_coordinates, building_with_floating_points]
width, height = osm2vadere.find_width_and_height(buildings_cartesian)
building_points = [building_normal, building_negative_coordinates, building_with_floating_points]
buildings = [osm2vadere.PolyObjectWidthId(-1, building) for building in building_points]
width, height = osm2vadere.find_width_and_height(buildings)
self.assertTrue(width == 10)
self.assertTrue(height == 8) # 7.1 is the maximum but the function returns math.ceil
......@@ -48,26 +79,45 @@ class TestOsm2vadere(unittest.TestCase):
building_normal = [(1, 1), (3, 1), (1, 3), (3, 3)]
building_negative_coordinates = [(-1, 4), (-3, 2), (10, 2)]
building_with_floating_points = [(2.3, 1.4), (-10.5, 7), (9.99, 3), (5, 7.1), (3, 4)]
buildings_cartesian = [building_normal, building_negative_coordinates, building_with_floating_points]
new_base_point = osm2vadere.find_new_basepoint(buildings_cartesian)
building_points = [building_normal, building_negative_coordinates, building_with_floating_points]
buildings = [osm2vadere.PolyObjectWidthId(-1, building) for building in building_points]
new_base_point = osm2vadere.find_new_basepoint(buildings)
self.assertTrue(new_base_point == [-10.5, 0])
self.assertTrue(new_base_point == (-10.5, 1))
building_negative_coordinates.append((3, -5))
new_base_point = osm2vadere.find_new_basepoint(buildings_cartesian)
new_base_point = osm2vadere.find_new_basepoint(buildings)
self.assertTrue(new_base_point == [-10.5, -5])
self.assertTrue(new_base_point == (-10.5, -5))
buildings_cartesian_only_positive = [[(1, 3), (1, 2), (2, 2)], [(2, 4), (7, 7), (6, 6)]]
new_base_point = osm2vadere.find_new_basepoint(buildings_cartesian_only_positive)
buildings = [osm2vadere.PolyObjectWidthId(-1, building) for building in buildings_cartesian_only_positive]
new_base_point = osm2vadere.find_new_basepoint(buildings)
self.assertTrue(new_base_point == (1, 2))
def test_get_wall(self):
class Ns():
def __init__(self, d, osm_file, way):
self.d = d
self.osm_file = osm_file
self.way = way
self.output = None
self.use_osm_id = True
o = osm2vadere.main_way_to_polygon(Ns(0.25, TEST_DATA_2, [258139209]))
self.assertEqual(len(o), 1)
self.assertEqual(''.join(TEST_DATA.split()), ''.join(o[0].split()))
self.assertTrue(new_base_point == [0, 0])
def test_shift_points(self):
buildings_cartesian = [[(1, 3), (-1, 2), (2.2, 2)], [(2, 4), (7, 7), (6, 6)]]
buildings_cartesian_shifted_by_one_and_two = osm2vadere.shift_points(buildings_cartesian, 1, 2)
building_points = [[(1, 3), (-1, 2), (2, 2)], [(2, 4), (7, 7), (6, 6)]]
buildings = [osm2vadere.PolyObjectWidthId(-1, points) for points in building_points]
for b in buildings:
b.shift_points([1,2])
self.assertEqual(buildings[0].cartesian_points, [(0, 1), (-2, 0), (1, 0)])
self.assertEqual(buildings[1].cartesian_points, [(1, 2), (6, 5), (5, 4)])
self.assertTrue(buildings_cartesian_shifted_by_one_and_two == [[(2, 5), (0, 4), (3.2, 4)], [(3, 6), (8, 9), (7, 8)]])
if __name__ == "__main__":
unittest.main()
......@@ -80,11 +80,13 @@ ProjectView.btnRunAllTests.text=Run all scenarios
ProjectView.mntmRunSelectetTests.text=Run selected scenario
ProjectView.mntmRunSelectedTests.text=Run selected scenarios
ProjectView.mntmSimulationResult.text=Show Simulation Result Dialog
ProjectView.btnPauseRunningTests.text=Pause running scenarios
ProjectView.btnPauseRunningTests.text=Pause
ProjectView.btnRunSelectedTest.text=Run selected scenario
ProjectView.btnRunSelectedTest.toolTipText=Run selected scenario
ProjectView.btnPauseRunningTests.toolTipText=Pause the scenario run
ProjectView.btnStopRunningTests.text=Stop running scenarios
ProjectView.btnResumeNormalSpeed.text=Resume
ProjectView.btnNextSimulationStep=Step
ProjectView.lblCurrentTest.text=Current scenario\:
ProjectView.lblNewLabel.text=New label
ProjectView.mnFile.text=Project
......@@ -194,6 +196,7 @@ Unavailable.text=Unavailable
Running.text=Running
Paused.text=Paused
Initialized.text=Initialized
Step.text=Singlestep
OutputprocessorsView.columnNames.text=["No dataProcessor chosen"]
OutputprocessorsView.dataProcessor.text={Processor: ""}
......@@ -256,6 +259,7 @@ OnlineVis.msgDialogShowPotentialfield.none=None
TopographyBoundDialog.title=Width x Height
TopographyBoundDialog.tooltip=Set topography bounds
InformationDialogError.title=Internal Error
InformationDialogFileError=Could not load file!
LoadingDialog.title=Loading...
......@@ -309,6 +313,7 @@ TopographyCreator.btnRedo.tooltip=Redo
TopographyCreator.btnCutTopography.tooltip=Cut Scenario
TopographyCreator.btnInsertPedestrian.tooltip=Pedestrian
TopographyCreator.btnTopographyBound.tooltip=Topography Bound
TopographyCreator.btnMergeWithConvexHull.tooltip=Merge With Convex Hull
TopographyCreator.btnTranslation.tooltip=Translate topography
TopographyCreator.btnElementTranslation.tooltip=Translate topography elements
TopographyCreator.btnInsertObstacle.tooltip=Obstacle
......
......@@ -80,11 +80,13 @@ ProjectView.btnRunAllTests.text=Alle Szenarios ausf\u00FChren
ProjectView.mntmRunSelectetTests.text=Ausgew\u00E4hlte Szenarios ausf\u00FChren
ProjectView.mntmRunSelectedTests.text=Ausgew\u00E4hlte Szenarios ausf\u00FChren
ProjectView.mntmSimulationResult.text=Ergebnis Dialog anzeigen
ProjectView.btnPauseRunningTests.text=Laufende Szenarios pausieren
ProjectView.btnPauseRunningTests.text=Pausieren
ProjectView.btnRunSelectedTest.text=Ausgew\u00E4hltes Szenario ausf\u00FChren
ProjectView.btnRunSelectedTest.toolTipText=Ausgew\u00E4hlten Szenario ausf\u00FChren
ProjectView.btnPauseRunningTests.toolTipText=Pausiert den Szenariodurchlauf
ProjectView.btnStopRunningTests.text=Laufende Szenarios anhalten
ProjectView.btnResumeNormalSpeed.text=Ausf\u00FChren
ProjectView.btnNextSimulationStep=Einzelschritt
ProjectView.lblCurrentTest.text=Aktuelles Szenario\:
ProjectView.lblNewLabel.text=Neues Label
ProjectView.mnFile.text=Projekt
......@@ -199,6 +201,7 @@ Unavailable.text=Nicht verf\u00FCgbar
Running.text=L\u00E4uft
Paused.text=Pausiert
Initialized.text=Initialisiert
Step.text=Einzelschritt
OutputprocessorsView.columnNames.text=["Kein Prozessor gew\u00E4hlt"]
OutputprocessorsView.dataProcessor.text={"Processor": ""}
......@@ -307,6 +310,7 @@ TopographyCreator.btnInsertObstacle.tooltip=Hindernis
TopographyCreator.btnInsertTarget.tooltip=Ziel
TopographyCreator.btnInsertAbsorbingArea.tooltip=Absorbierender Bereich
TopographyCreator.btnTopographyBound.tooltip=Topographie Grenze
TopographyCreator.btnMergeWithConvexHull.tooltip=Verbinde mit Convex H\u00fclle
TopographyCreator.btnTranslation.tooltip=Topographie verschieben
TopographyCreator.btnElementTranslation.tooltip=Elemente der Topography verschieben
TopographyCreator.btnInsertSource.tooltip=Quelle
......
package org.vadere.gui.projectview.control;
import org.vadere.gui.projectview.model.ProjectViewModel;
import org.vadere.gui.projectview.model.VadereScenarioTableModel;
import org.vadere.gui.projectview.model.VadereState;
import org.vadere.simulator.projects.Scenario;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ActionNextTimeStep extends AbstractAction {
private ProjectViewModel model;
public ActionNextTimeStep(final String name, final ProjectViewModel model) {
super(name);
this.model = model;
}
@Override
public void actionPerformed(ActionEvent e) {
Scenario scenario = model.getRunningScenario().getScenario();
model.getScenarioTableModel().replace(scenario,
new VadereScenarioTableModel.VadereDisplay(scenario, VadereState.STEP));
if(model.getProject().isScenarioInSingleStepMode()){
model.getProject().nextSimCommand(-1);
} else {
// activate SingleStepMode and start waiting
model.getProject().setSingleStepMode(true);
model.getProject().nextSimCommand(-1); // wait on each simulation step.
}
}
}
package org.vadere.gui.projectview.control;
import org.vadere.gui.projectview.model.ProjectViewModel;
import org.vadere.gui.projectview.model.VadereScenarioTableModel;
import org.vadere.gui.projectview.model.VadereState;
......@@ -22,17 +21,11 @@ public class ActionPauseScenario extends AbstractAction {
this.model = model;
}
@Override
public void actionPerformed(final ActionEvent e) {
ProjectViewModel.ScenarioBundle optionalScenarioBundle = model.getRunningScenario();
Scenario scenario = optionalScenarioBundle.getScenario();
if (model.getProject().isScenarioPaused()) {
model.getProject().resumePausedScenarios();
model.getScenarioTableModel().replace(scenario,
new VadereScenarioTableModel.VadereDisplay(scenario, VadereState.RUNNING));
logger.info(String.format("all running scenarios resumed"));
} else {
if (! model.getProject().isScenarioPaused()) {
model.getProject().pauseRunnningScenario();
model.getScenarioTableModel().replace(scenario,
new VadereScenarioTableModel.VadereDisplay(scenario, VadereState.PAUSED));
......
package org.vadere.gui.projectview.control;
import org.vadere.gui.projectview.model.ProjectViewModel;
import org.vadere.gui.projectview.model.VadereScenarioTableModel;
import org.vadere.gui.projectview.model.VadereState;
import org.vadere.simulator.projects.Scenario;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ActionResumeNormalSpeed extends AbstractAction {
private ProjectViewModel model;
public ActionResumeNormalSpeed(String name, ProjectViewModel model) {
super(name);
this.model = model;
}
@Override
public void actionPerformed(ActionEvent e) {
Scenario scenario = model.getRunningScenario().getScenario();
model.getProject().resumePausedScenarios();
model.getScenarioTableModel().replace(scenario,
new VadereScenarioTableModel.VadereDisplay(scenario, VadereState.RUNNING));
}
}
......@@ -3,7 +3,7 @@ package org.vadere.gui.projectview.model;
import org.vadere.gui.components.utils.Messages;
public enum VadereState {
RUNNING, PAUSED, INTERRUPTED, INITIALIZED;
RUNNING, PAUSED, INTERRUPTED, INITIALIZED, STEP;
@Override
public String toString() {
......@@ -16,8 +16,10 @@ public enum VadereState {
return Messages.getString("Interrupted.text");
case INITIALIZED:
return Messages.getString("Initialized.text");
case STEP:
return Messages.getString("Step.text");
default:
return this.toString();
throw new IllegalStateException("VadereState. Should not be reached. All enums already tested.");
}
}
}
......@@ -5,7 +5,36 @@ import org.jetbrains.annotations.NotNull;
import org.vadere.gui.components.utils.Messages;
import org.vadere.gui.postvisualization.control.Player;
import org.vadere.gui.projectview.VadereApplication;
import org.vadere.gui.projectview.control.*;
import org.vadere.gui.projectview.control.ActionAddScenario;
import org.vadere.gui.projectview.control.ActionCloneScenario;
import org.vadere.gui.projectview.control.ActionCloseApplication;
import org.vadere.gui.projectview.control.ActionCreateProject;
import org.vadere.gui.projectview.control.ActionDeleteOutputDirectories;
import org.vadere.gui.projectview.control.ActionDeleteScenarios;
import org.vadere.gui.projectview.control.ActionEditScenarioDescription;
import org.vadere.gui.projectview.control.ActionGenerateScenarioFromOutputFile;
import org.vadere.gui.projectview.control.ActionInterruptScenarios;
import org.vadere.gui.projectview.control.ActionLoadProject;
import org.vadere.gui.projectview.control.ActionLoadRecentProject;
import org.vadere.gui.projectview.control.ActionNextTimeStep;
import org.vadere.gui.projectview.control.ActionOpenInExplorer;
import org.vadere.gui.projectview.control.ActionOutputToScenario;
import org.vadere.gui.projectview.control.ActionPauseScenario;
import org.vadere.gui.projectview.control.ActionRenameOutputFile;
import org.vadere.gui.projectview.control.ActionRenameProject;
import org.vadere.gui.projectview.control.ActionRenameScenario;
import org.vadere.gui.projectview.control.ActionResumeNormalSpeed;
import org.vadere.gui.projectview.control.ActionRunAllScenarios;
import org.vadere.gui.projectview.control.ActionRunOutput;
import org.vadere.gui.projectview.control.ActionRunSelectedScenarios;
import org.vadere.gui.projectview.control.ActionSaveAsProject;
import org.vadere.gui.projectview.control.ActionSaveProject;
import org.vadere.gui.projectview.control.ActionSeeDiscardChanges;
import org.vadere.gui.projectview.control.ActionShowAboutDialog;
import org.vadere.gui.projectview.control.ActionToClipboard;
import org.vadere.gui.projectview.control.IOutputFileRefreshListener;
import org.vadere.gui.projectview.control.IProjectChangeListener;
import org.vadere.gui.projectview.control.ShowResultDialogAction;
import org.vadere.gui.projectview.model.ProjectViewModel;
import org.vadere.gui.projectview.model.ProjectViewModel.OutputBundle;
import org.vadere.gui.projectview.model.ProjectViewModel.ScenarioBundle;
......@@ -20,9 +49,6 @@ import org.vadere.util.io.IOUtils;
import org.vadere.util.logging.Logger;
import org.vadere.util.opencl.CLUtils;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
......@@ -37,6 +63,10 @@ import java.util.Optional;
import java.util.Set;
import java.util.prefs.Preferences;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
/**
* Main view of the Vadere GUI.
*
......@@ -72,6 +102,8 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
private JButton btnRunAllScenarios;
private JButton btnStopRunningScenarios;
private JButton btnPauseRunningScenarios;
private JButton btnNextSimulationStep;
private JButton btnResumeNormalSpeed;
private JMenu mntmRecentProjects;
private ProgressPanel progressPanel = new ProgressPanel();
private ScenarioPanel scenarioJPanel;
......@@ -288,6 +320,8 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
btnRunSelectedScenario.setVisible(!flag);
btnStopRunningScenarios.setVisible(flag);
btnPauseRunningScenarios.setVisible(flag);
btnNextSimulationStep.setVisible(flag);
btnResumeNormalSpeed.setVisible(flag);
scenarioTable.setEnabled(!flag);
scenarioTable.clearSelection();
outputTable.setEnabled(!flag);
......@@ -698,6 +732,13 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
btnStopRunningScenarios = new JButton(interruptScenariosAction);
toolBar.add(btnStopRunningScenarios);
ActionResumeNormalSpeed resumeNormalSpeedAction =
new ActionResumeNormalSpeed(Messages.getString("ProjectView.btnResumeNormalSpeed.text"), model);
resumeNormalSpeedAction.putValue(Action.LARGE_ICON_KEY,
new ImageIcon(ProjectView.class.getResource("/icons/greenarrow_right_small.png")));
btnResumeNormalSpeed = new JButton(resumeNormalSpeedAction);
toolBar.add(btnResumeNormalSpeed);
ActionPauseScenario pauseScenarioAction =
new ActionPauseScenario(Messages.getString("ProjectView.btnPauseRunningTests.text"), model);
pauseScenarioAction.putValue(Action.LONG_DESCRIPTION,
......@@ -711,6 +752,14 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
KeyStroke.getKeyStroke(Messages.getString("ProjectView.pauseTests.shortcut").charAt(0)), "pauseTests");
toolBar.getActionMap().put("pauseTests", pauseScenarioAction);
ActionNextTimeStep nextTimeStepAction =
new ActionNextTimeStep(Messages.getString("ProjectView.btnNextSimulationStep"), model);
nextTimeStepAction.putValue(Action.LONG_DESCRIPTION, "Next Step");
nextTimeStepAction.putValue(Action.LARGE_ICON_KEY,
new ImageIcon(ProjectView.class.getResource("/icons/greenarrow_step.png")));
btnNextSimulationStep = new JButton(nextTimeStepAction);
toolBar.add(btnNextSimulationStep);
buildKeyboardShortcuts(pauseScenarioAction, interruptScenariosAction);
}
......
package org.vadere.gui.topographycreator.control;
import org.vadere.gui.topographycreator.model.IDrawPanelModel;
import org.vadere.gui.topographycreator.model.TopographyCreatorModel;
import org.vadere.gui.topographycreator.view.ActionCombineDialog;
import org.vadere.util.geometry.GrahamScan;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VPolygon;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.swing.*;
import javax.swing.undo.UndoableEditSupport;
public class ActionSimplifyObstacles extends TopographyAction{
private TopographyAction action;
private final UndoableEditSupport undoableEditSupport;
ActionCombineDialog dialog;
private List<Integer> obstacleIds;
public ActionSimplifyObstacles(String name, ImageIcon icon, IDrawPanelModel<?> panelModel,
TopographyAction action, final UndoableEditSupport undoSupport) {
super(name, icon, panelModel);
this.action = action;
this.undoableEditSupport = undoSupport;
this.obstacleIds = new ArrayList<>();
}
public void setIds(List<Integer> ids) {
this.obstacleIds = ids;
}
public void dialogListener(ActionEvent e){
if (obstacleIds.isEmpty())
return;
TopographyCreatorModel model = (TopographyCreatorModel) getScenarioPanelModel();
List<VPoint> obstaclesVpoints = model.getObstacles()
.stream()
.filter(o-> obstacleIds.contains(o.getId()))
.map(o-> o.getShape().getPath())
.flatMap(List::stream)
.collect(Collectors.toList());
GrahamScan scan = new GrahamScan(obstaclesVpoints);
VPolygon newObstacle = scan.getPolytope();
//remove old obstacles
obstacleIds.forEach(o -> {
model.getObstacles().stream()
.filter(el -> el.getId() == o)
.findAny()
.ifPresent(el -> {
if (model.removeElement(el)){
undoableEditSupport.postEdit(new EditDeleteShape(model, el));
}
});
});
//add new obstacle
model.setSelectionShape(newObstacle);
new ActionAddElement("add element", model, undoableEditSupport).actionPerformed(null);
}
@Override
public void actionPerformed(ActionEvent e) {
dialog = new ActionCombineDialog(this, this::dialogListener, getScenarioPanelModel());
}
}
package org.vadere.gui.topographycreator.view;
import org.vadere.gui.components.view.ISelectScenarioElementListener;
import org.vadere.gui.projectview.view.ProjectView;
import org.vadere.gui.topographycreator.control.ActionSimplifyObstacles;
import org.vadere.gui.topographycreator.model.IDrawPanelModel;
import org.vadere.state.scenario.ScenarioElement;
import java.awt.*;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
/**
* Dialog which collects the ids of selected obstacles. The collected list will be combined into
* a single obstacle based on the convex hull.
*
* @author Stefan Schuhbäck
*/
public class ActionCombineDialog extends JDialog implements ISelectScenarioElementListener {
private JButton ok;
private JButton close;
private JTextField textField;
private IDrawPanelModel<?> panelModel;
private ActionSimplifyObstacles action;
private ActionListener okBtn;
public ActionCombineDialog(ActionSimplifyObstacles action, ActionListener okBtn, IDrawPanelModel<?> panelModel) {
super(new JFrame(), "xxx", false);
this.panelModel = panelModel;
this.action = action;
this.okBtn = okBtn;
panelModel.addSelectScenarioElementListener(this);
setLocationRelativeTo(ProjectView.getMainWindow());
textField = new JTextField("", 40);
JPanel messagePane = new JPanel();
messagePane.add(textField);
getContentPane().add(messagePane);
textField.getDocument().addDocumentListener(new SimpleDocumentListener() {
@Override
public void handle(DocumentEvent e) {
String text = textField.getText().replace(" ", "");
String[] tmp = text.split(",");
try {
action.setIds(Arrays.stream(tmp).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()));
textField.setForeground(Color.BLACK);
} catch (NumberFormatException ex){
action.setIds(new ArrayList<>());
textField.setForeground(Color.red);
}
}
});
JPanel btnPane = new JPanel();
ok = new JButton("OK");
ok.addActionListener(e -> {
this.okBtn.actionPerformed(e);
this.textField.setText("");
});
close = new JButton("Close");
close.addActionListener(e -> {
panelModel.removeSelectScenarioElementListener(this);
setVisible(false);
dispose();
});
btnPane.add(ok);
btnPane.add(close);
getContentPane().add(btnPane, BorderLayout.PAGE_END);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
setVisible(true);
setAlwaysOnTop(true);
}
@Override
public void selectionChange(ScenarioElement scenarioElement) {
if (scenarioElement.getId() != -1){
String tmp = textField.getText().strip();
if (tmp.length() == 0){
textField.setText(Integer.toString(scenarioElement.getId()));
} else if (tmp.endsWith(",")){
textField.setText(tmp + " " + scenarioElement.getId());
} else {
textField.setText(tmp + ", " + scenarioElement.getId());
}
}
}
}
package org.vadere.gui.topographycreator.view;
import org.vadere.gui.components.utils.Messages;
import org.vadere.gui.projectview.view.ProjectView;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.util.Locale;
import org.vadere.gui.components.utils.Messages;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class ActionResizeTopographyBoundDialog {
......@@ -23,7 +22,28 @@ public class ActionResizeTopographyBoundDialog {
textField = new JTextField();
textField.setText(String.format(Locale.US, "%.3f x %.3f", topographyBound.getWidth(), topographyBound.getHeight()));
textField.getDocument().addDocumentListener(new DialogListener());
textField.getDocument().addDocumentListener(new SimpleDocumentListener() {
@Override
public void handle(DocumentEvent e) {
String text = textField.getText().replace(" ", "");
String[] tmp = text.split("x");
double width;
double height;
try {
width = Double.valueOf(tmp[0]);
height = Double.valueOf(tmp[1]);
ActionResizeTopographyBoundDialog.this.bound =
new Rectangle2D.Double(ActionResizeTopographyBoundDialog.this.boundOld.getMinX(),
ActionResizeTopographyBoundDialog.this.boundOld.getMinY(), width, height);
ActionResizeTopographyBoundDialog.this.valid = true;
textField.setForeground(Color.BLACK);
}catch (Exception ex){
ActionResizeTopographyBoundDialog.this.valid = false;
textField.setForeground(Color.RED);
}
}
});
bound = topographyBound;
boundOld = topographyBound;
......@@ -42,51 +62,6 @@ public class ActionResizeTopographyBoundDialog {
JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION;
}
private class DialogListener implements DocumentListener{
private JTextField textField;
private String text;
DialogListener(){
textField = ActionResizeTopographyBoundDialog.this.textField;
}
@Override
public void insertUpdate(DocumentEvent e) {
handle(e);
}
@Override
public void removeUpdate(DocumentEvent e) {
handle(e);
}
@Override
public void changedUpdate(DocumentEvent e) {
handle(e);
}
private void handle(DocumentEvent e){
text = textField.getText().replace(" ", "");
String[] tmp = text.split("x");
double width;
double height;
try {
width = Double.valueOf(tmp[0]);
height = Double.valueOf(tmp[1]);
ActionResizeTopographyBoundDialog.this.bound =