Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 696a81f4 authored by Daniel Lehmberg's avatar Daniel Lehmberg
Browse files

Merge branch 'dev/PostVisUpdate' into 'master'

Use FootStepProcessor in Postviz and as default trajectory output processor

Closes #253

See merge request !85
parents 50f028be 5bf355a9
Pipeline #161796 passed with stages
in 123 minutes and 33 seconds
......@@ -215,7 +215,8 @@ ProjectView.OpenInExplorer.text=Open in Explorer
ProjectView.mntmCopyOutputDir.text=Copy output path to clipboard
SettingsDialog.chbShowPedestrianIds.text=Show PedestrianIds
PostVis.chShowEvacTimeColor.text=Color Pedestrians regarding to Evacuation Times
PostVis.chShowEvacTimeColor.text=Coloring by Evacuation Times
PostVis.chShowCriteriaColor.text=Coloring by Predicate
PostVis.additional.border.text=PostVis
PostVis.btnPlay.tooltip=Play (Space)
......@@ -228,12 +229,13 @@ PostVis.title=Vadere Post-Visualization
PostVis.version= Version {0}
PostVis.license.text=This product is licensed under the {0}
PostVis.chbHidePedAtTarget.text=Hide Pedestrians at Target
PostVis.chbHideTrajAtTarget.text=Hide Trajectories at Target
PostVis.chbHidePedAtTarget.text=Hide disappeared Pedestrians
PostVis.chbHideTrajAtTarget.text=Hide Trajectories of disappeared Pedestrians
PostVis.chShowAllTrajOnSnapshot.text=Show all Trajectories on Snapshot
PostVis.chbCleanSnapshot.text=Hide Trajectories on Snapshots
SettingsDialog.chbUseRandomColors.text=Random Coloring
SettingsDialog.chbGroupColors.text=Coloring by Group
SettingsDialog.chbHideVoronoiDiagram.text=Hide VoronoiDiagram
SettingsDialog.chbShowObstacles.text=Show Obstacles
SettingsDialog.chbShowTargets.text=Show Targets
......@@ -269,7 +271,8 @@ LoadingDialog.title=Loading...
FileDialog.filenamePrefix=vadere_
SettingsDialog.title=Settings
SettingsDialog.colors.border.text=Colors
SettingsDialog.colors.border.text=Element coloring
SettingsDialog.pedcolors.border.text=Pedestrian coloring
SettingsDialog.additional.border.text=Additional
SettingsDialog.lblTarget.text=Target
#SettingsDialog.lblPedestrian.text=Pedestrian
......@@ -284,7 +287,8 @@ SettingsDialog.btnClose.text=Close
SettingsDialog.lblDensityColor.text=Density
SettingsDialog.lblAbsorbingAreaColor.text=Absorbing Area
SettingsDialog.lblStair.text=Stair
SettingsDialog.lblPedestrianNoTarget.text=Without Target (-1)
SettingsDialog.lblPedestrianNoTarget.text=Without Target
SettingsDialog.lblTargetColoring.text=Coloring by Target
ProjectView.menuOpenFloorFieldFile.title=Add Floor Field File...
ProjectView.btnDrawVoronoiDiagram.tooltip=Draw and display a Voronoi Diagram
......
......@@ -218,18 +218,20 @@ ProjectView.mntmCopyOutputDir.text=Kopiere Output Pfad in Zwischenablage
SettingsDialog.chbShowPedestrianIds.text=Fu\u00dfg\u00E4nger-Ids anzeigen
PostVis.additional.border.text=PostVis
PostVis.chShowEvacTimeColor.text=F\u00e4rbe Fu\u00dfg\u00E4nger nach ihrer Evakuierungszeit
PostVis.chShowEvacTimeColor.text=F\u00e4rbe nach Evakuierungszeit
PostVis.chShowCriteriaColor.text=F\u00e4rbung nach Bedingung
PostVis.btnPlay.tooltip=Start (Leertaste)
PostVis.btnPause.tooltip=Pause (Leertaste)
PostVis.btnStop.tooltip=Stopp (Backspace-Taste)
PostVis.btnRecord.tooltip=Starte Aufnahme
PostVis.chbHidePedAtTarget.text=Fu\u00dfg\u00E4nger im Ziel nicht anzeigen
PostVis.chbHideTrajAtTarget.text=Trajektorien am Ziel nicht anzeigen
PostVis.chbHidePedAtTarget.text=Verschwundene Fu\u00dfg\u00E4nger im Ziel nicht anzeigen
PostVis.chbHideTrajAtTarget.text=Verschwundene Trajektorien am Ziel nicht anzeigen
PostVis.chbCleanSnapshot.text=Trajektorien auf Snapshots nicht anzeigen
PostVis.chShowAllTrajOnSnapshot.text=Alle Trajektorien auf Snapshot anzeigen
SettingsDialog.chbUseRandomColors.text=Zuf\u00E4llige Farben
SettingsDialog.chbGroupColors.text=F\u00E4rbung nach Gruppe
SettingsDialog.chbHideVoronoiDiagram.text=Voronoi-Diagramm nicht anzeigen
SettingsDialog.chbShowObstacles.text=Hindernisse anzeigen
SettingsDialog.chbShowTargets.text=Ziele anzeigen
......@@ -264,7 +266,8 @@ LoadingDialog.title=Lade...
FileDialog.filenamePrefix=vadere_
SettingsDialog.title=Einstellungen
SettingsDialog.colors.border.text=Farben
SettingsDialog.colors.border.text=Elementfarben
SettingsDialog.pedcolors.border.text=Fu\u00dfg\u00e4ngerfarben
SettingsDialog.additional.border.text=Extras
SettingsDialog.lblTarget.text=Ziel
SettingsDialog.lblPedestrian.text=Pedestrian
......@@ -279,7 +282,8 @@ SettingsDialog.btnClose.text=Schlie\u00dfen
SettingsDialog.lblDensityColor.text=Dichte
SettingsDialog.lblAbsorbingAreaColor.text=Absorbierender Bereich
SettingsDialog.lblStair.text=Treppe
SettingsDialog.lblPedestrianNoTarget.text=Ohne Ziel (-1)
SettingsDialog.lblPedestrianNoTarget.text=Ohne Ziel
SettingsDialog.lblTargetColoring.text=F\u00e4rbung nach Ziel
SettingsDialog.menuOpenFloorFieldFile.title=Floor Field-Datei hinzuf\u00fcgen...
SettingsDialog.btnDrawVoronoiDiagram.tooltip=Voronoi-Diagramm zeichnen und anzeigen
SettingsDialog.chbLogo.text=VADERE-Logo anzeigen
......
......@@ -19,7 +19,7 @@ public abstract class ActionSetColor extends ActionVisualization {
@Override
public void actionPerformed(final ActionEvent event) {
Color color = JColorChooser.showDialog(null, "Choose Color", coloredPanel.getBackground());
Color color = JColorChooser.showDialog(coloredPanel.getParent(), "Choose Color", coloredPanel.getBackground());
if (color != null) {
coloredPanel.setBackground(color);
saveColor(color);
......
......@@ -13,18 +13,20 @@ public class ActionSetSnapshotDirectory extends ActionVisualization {
private static final Configuration CONFIG = VadereConfig.getConfig();
private final JTextField textField;
private final JDialog parent;
public ActionSetSnapshotDirectory(final String name, final SimulationModel<? extends DefaultSimulationConfig> model,
final JTextField textField) {
final JTextField textField, final JDialog parent) {
super(name, model);
this.textField = textField;
this.parent = parent;
}
@Override
public void actionPerformed(ActionEvent e) {
final JFileChooser fc = new JFileChooser(CONFIG.getString("SettingsDialog.snapshotDirectory.path"));
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returnVal = fc.showOpenDialog(null);
int returnVal = fc.showOpenDialog(parent);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
......
package org.vadere.gui.components.model;
public enum AgentColoring {
TARGET, RANDOM, GROUP, EVACUATION_TIMES, PREDICATE;
}
......@@ -174,36 +174,36 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
return hasChanged;
}
protected void notifyViewportListeners(final ViewportChangeEvent event) {
protected synchronized void notifyViewportListeners(final ViewportChangeEvent event) {
for (IViewportChangeListener listener : viewportChangeListeners) {
listener.viewportChange(event);
}
}
@Override
public void notifyScaleListeners() {
public synchronized void notifyScaleListeners() {
for (IScaleChangeListener listener : scaleChangeListeners) {
listener.scaleChange(getScaleFactor());
}
}
@Override
public void addViewportChangeListener(final IViewportChangeListener listener) {
public synchronized void addViewportChangeListener(final IViewportChangeListener listener) {
viewportChangeListeners.add(listener);
}
@Override
public void removeViewportChangeListener(final IViewportChangeListener listener) {
public synchronized void removeViewportChangeListener(final IViewportChangeListener listener) {
viewportChangeListeners.remove(listener);
}
@Override
public void addScaleChangeListener(final IScaleChangeListener listener) {
public synchronized void addScaleChangeListener(final IScaleChangeListener listener) {
this.scaleChangeListeners.add(listener);
}
@Override
public void removeScaleChangeListener(final IScaleChangeListener listener) {
public synchronized void removeScaleChangeListener(final IScaleChangeListener listener) {
this.scaleChangeListeners.remove(listener);
}
......@@ -236,7 +236,7 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
*/
@Override
public void setMousePosition(final Point mousePosition) {
public synchronized void setMousePosition(final Point mousePosition) {
// this is needed cause of the mirrowing!
VPoint mouseWorldPosition = pixelToWorld(new VPoint(mousePosition.x, mousePosition.y));
double factor = Math.max(10, 1 / getGridResolution());
......@@ -246,7 +246,7 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
}
@Override
public void setStartSelectionPoint(final Point startSelectionPoint) {
public synchronized void setStartSelectionPoint(final Point startSelectionPoint) {
VPoint worldPosition = pixelToWorld(new VPoint(startSelectionPoint.x, startSelectionPoint.y));
double factor = Math.max(10, 1 / getGridResolution());
this.startSelectionPoint = new VPoint((Math.round(worldPosition.x * factor)) / factor,
......@@ -255,13 +255,13 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
}
@Override
public void setSelectionShape(final VShape shape) {
public synchronized void setSelectionShape(final VShape shape) {
selectionShape = shape;
setChanged();
}
@Override
public void fireChangeViewportEvent(final Rectangle2D.Double viewportBound) {
public synchronized void fireChangeViewportEvent(final Rectangle2D.Double viewportBound) {
notifyViewportListeners(new ViewportChangeEvent(viewportBound));
}
......@@ -343,7 +343,7 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
}
@Override
public void setVoronoiDiagram(final VoronoiDiagram voronoiDiagram) {
public synchronized void setVoronoiDiagram(final VoronoiDiagram voronoiDiagram) {
this.voronoiDiagram = voronoiDiagram;
}
......@@ -382,7 +382,7 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
}
@Override
public void setWindowBound(final Rectangle2D.Double windowBound) {
public synchronized void setWindowBound(final Rectangle2D.Double windowBound) {
this.windowBound = windowBound;
setChanged();
}
......@@ -393,18 +393,18 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
return selectedElement;
}
private Optional<ScenarioElement> getElementsByPosition(final VPoint position) {
private synchronized Optional<ScenarioElement> getElementsByPosition(final VPoint position) {
return getElements(e -> e.getShape().intersects(new Rectangle2D.Double(position.x - 0.1, position.y - 0.1, 0.2, 0.2))).findFirst();
}
protected ScenarioElement getClickedElement(final VPoint position) {
protected synchronized ScenarioElement getClickedElement(final VPoint position) {
Optional<ScenarioElement> optional = getElementsByPosition(position);
if (optional.isPresent())
return optional.get();
return null;
}
protected Stream<ScenarioElement> getElements(final Predicate<ScenarioElement> predicate) {
protected synchronized Stream<ScenarioElement> getElements(final Predicate<ScenarioElement> predicate) {
return StreamSupport.stream(this.spliterator(), false).filter(predicate);
}
......@@ -430,12 +430,12 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
}
@Override
public void addSelectScenarioElementListener(final ISelectScenarioElementListener listener) {
public synchronized void addSelectScenarioElementListener(final ISelectScenarioElementListener listener) {
this.selectScenarioElementListener.add(listener);
}
@Override
public void removeSelectScenarioElementListener(final ISelectScenarioElementListener listener) {
public synchronized void removeSelectScenarioElementListener(final ISelectScenarioElementListener listener) {
this.selectScenarioElementListener.remove(listener);
}
......@@ -454,13 +454,13 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
setChanged();
}
protected void notifySelectSecenarioElementListener(final ScenarioElement scenarioElement) {
protected synchronized void notifySelectSecenarioElementListener(final ScenarioElement scenarioElement) {
for (ISelectScenarioElementListener listener : selectScenarioElementListener) {
listener.selectionChange(scenarioElement);
}
}
protected void calculateScaleFactor() {
protected synchronized void calculateScaleFactor() {
scaleFactor = Math.min(getWindowBound().getWidth() / getViewportBound().getWidth(),
getWindowBound().getHeight() / getViewportBound().getHeight());
}
......@@ -470,7 +470,7 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
* @param pInPixel the mouse position of the mouse event
* @return
*/
protected VPoint pixelToWorld(final VPoint pInPixel) {
protected synchronized VPoint pixelToWorld(final VPoint pInPixel) {
if(pInPixel != null) {
return new VPoint(pInPixel.getX() / scaleFactor + getTopographyBound().getMinX(),
getTopographyBound().getMinY() + (getTopographyBound().getHeight() * scaleFactor - pInPixel.getY()) / scaleFactor);
......
......@@ -20,7 +20,6 @@ public class DefaultSimulationConfig extends DefaultConfig {
private double densityStandardDerivation = CONFIG.getDouble("Density.standardDeviation");
private double pedestrianTorso = CONFIG.getDouble("Pedestrian.radius") * 2;
private boolean useRandomPedestrianColors = false;
private boolean showPedestrianIds = false;
private boolean showTargets = true;
private boolean showAbsorbingAreas = true;
......@@ -43,6 +42,7 @@ public class DefaultSimulationConfig extends DefaultConfig {
private double gridWidth = CONFIG.getDouble("ProjectView.cellWidth");
private final double MIN_CELL_WIDTH = CONFIG.getDouble("ProjectView.minCellWidth");
private final double MAX_CELL_WIDTH = CONFIG.getDouble("ProjectView.maxCellWidth");
private AgentColoring agentColoring = AgentColoring.TARGET;
public DefaultSimulationConfig() {
super();
......@@ -71,6 +71,7 @@ public class DefaultSimulationConfig extends DefaultConfig {
this.showGroups = config.showGroups;
this.showPotentialField = config.showPotentialField;
this.showTargetPotentielFieldMesh = config.showTargetPotentielFieldMesh;
this.agentColoring = config.agentColoring;
}
public boolean isShowGroups() {
......@@ -262,6 +263,17 @@ public class DefaultSimulationConfig extends DefaultConfig {
}
}
public void setAgentColoring(final AgentColoring agentColoring) {
if(agentColoring != this.agentColoring) {
this.agentColoring = agentColoring;
setChanged();
}
}
public AgentColoring getAgentColoring() {
return agentColoring;
}
public void clearRandomColors() {
randomColors.clear();
}
......@@ -273,14 +285,6 @@ public class DefaultSimulationConfig extends DefaultConfig {
return randomColors.get(pedId);
}
public void setUseRandomPedestrianColors(final boolean useRandomPedestrianColors) {
this.useRandomPedestrianColors = useRandomPedestrianColors;
}
public boolean isUseRandomPedestrianColors() {
return useRandomPedestrianColors;
}
public void setGridWidth(double gridWidth) {
this.gridWidth = gridWidth;
}
......@@ -305,4 +309,8 @@ public class DefaultSimulationConfig extends DefaultConfig {
this.showPedestrianIds = showPedestrianIds;
}
public boolean isShowFaydedPedestrians() {
return false;
}
}
package org.vadere.gui.components.model;
import java.awt.*;
import java.util.Collection;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import org.jetbrains.annotations.NotNull;
import org.vadere.meshing.mesh.gen.PMesh;
import org.vadere.meshing.mesh.inter.IMesh;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VRectangle;
public abstract class SimulationModel<T extends DefaultSimulationConfig> extends DefaultModel {
public final T config;
private ConcurrentHashMap<Integer, Color> colorMap;
private Random random;
@SuppressWarnings("unchecked")
public SimulationModel(final T config) {
super(config);
this.config = config;
this.colorMap = new ConcurrentHashMap<>();
this.colorMap.put(-1, config.getPedestrianDefaultColor());
this.random = new Random();
}
public abstract Collection<Agent> getAgents();
......@@ -43,6 +53,8 @@ public abstract class SimulationModel<T extends DefaultSimulationConfig> extends
return new PMesh();
}
public abstract void setAgentColoring(@NotNull final AgentColoring agentColoring);
/*public double getPotential(final int x, final int y) {
double result = 0.0;
......@@ -83,13 +95,29 @@ public abstract class SimulationModel<T extends DefaultSimulationConfig> extends
return result;
}*/
public abstract boolean isAlive(int pedId);
public Color getGroupColor(@NotNull final Pedestrian ped) {
if (ped.getGroupIds().isEmpty() || (!ped.getGroupSizes().isEmpty() && ped.getGroupSizes().getFirst() == 1)) {
return config.getPedestrianDefaultColor();
}
int groupId = ped.getGroupIds().getFirst();
Color c = colorMap.get(groupId);
if (c == null) {
c = new Color(Color.HSBtoRGB(random.nextFloat(), 1f, 0.75f));
colorMap.put(groupId, c);
}
return c;
}
@Override
public synchronized void notifyObservers() {
// synchronized (config) {
if (config.hasChanged()) {
setChanged();
config.clearChange();
if(!config.isUseRandomPedestrianColors()) {
if(config.getAgentColoring() != AgentColoring.RANDOM) {
config.clearRandomColors();
}
}
......
......@@ -3,8 +3,10 @@ package org.vadere.gui.components.view;
import org.jetbrains.annotations.NotNull;
import org.vadere.gui.components.model.SimulationModel;
import org.vadere.gui.components.utils.CLGaussianCalculator;
import org.vadere.gui.postvisualization.model.PostvisualizationModel;
import org.vadere.gui.renderer.agent.AgentRender;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.geometry.shapes.VTriangle;
......@@ -280,11 +282,23 @@ public abstract class SimulationRenderer extends DefaultRenderer {
public Color getPedestrianColor(@NotNull final Agent agent) {
int targetId = agent.hasNextTarget() ? agent.getNextTargetId() : -1;
if (model.config.isUseRandomPedestrianColors()) {
return model.config.getRandomColor(agent.getId());
}
return model.config.getColorByTargetId(targetId)
.orElseGet(model.config::getPedestrianColor);
switch (model.config.getAgentColoring()) {
case TARGET: return model.config.getColorByTargetId(targetId).orElseGet(model.config::getPedestrianDefaultColor);
case RANDOM: return model.config.getRandomColor(agent.getId());
case PREDICATE: {
if(model instanceof PostvisualizationModel) {
return ((PostvisualizationModel)model).getPredicateColoringModel().getColorByPredicate(agent)
.orElse(model.config.getPedestrianColor());
}
}
case GROUP: {
if(agent instanceof Pedestrian) {
return model.getGroupColor((Pedestrian)agent);
}
}
default: return model.config.getPedestrianColor();
}
}
}
\ No newline at end of file
......@@ -8,6 +8,8 @@ import java.util.LinkedList;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
import org.vadere.gui.components.model.AgentColoring;
import org.vadere.gui.components.model.DefaultSimulationConfig;
import org.vadere.gui.components.model.SimulationModel;
import org.vadere.gui.onlinevisualization.OnlineVisualization;
......@@ -228,4 +230,19 @@ public class OnlineVisualizationModel extends SimulationModel<DefaultSimulationC
public double getSimTimeInSec() {
return simTimeInSec;
}
@Override
public void setAgentColoring(@NotNull AgentColoring agentColoring) {
switch (agentColoring) {
case TARGET:
case GROUP:
case RANDOM: config.setAgentColoring(agentColoring); break;
default: throw new IllegalArgumentException(agentColoring + " is not supported for the online simulation.");
}
}
@Override
public boolean isAlive(int pedId) {
return topography.getPedestrianDynamicElements().idExists(pedId);
}
}
......@@ -61,10 +61,10 @@ public class OnlinevisualizationRenderer extends SimulationRenderer {
private void renderPedestrians(final Graphics2D g) {
AgentRender agentRender = getAgentRender();
for (Agent ped : model.getAgents()) {
Color nonGroupColor = getPedestrianColor(ped);
g.setColor(nonGroupColor);
Color agentColor = getPedestrianColor(ped);
g.setColor(agentColor);
VPoint position = ped.getPosition();
agentRender.render(ped, nonGroupColor, g);
agentRender.render(ped, agentColor, g);
if (!pedestrianPositions.containsKey(ped.getId())) {
pedestrianPositions.put(ped.getId(), new LinkedList());
......
......@@ -106,8 +106,6 @@ public class PostVisualizationConsole {
PostvisualizationModel model = new PostvisualizationModel();
PostvisualizationRenderer renderer = new PostvisualizationRenderer(model);
/*
* Set all necessary data to the model (topography, viewport, scaleFactor, time or step).
*/
......@@ -119,7 +117,7 @@ public class PostVisualizationConsole {
if (trajectoryFile.isPresent() && scenarioFile.isPresent()) {
Scenario scenario = IOOutput.readScenario(scenarioFile.get().toPath());
TrajectoryReader reader = new TrajectoryReader(trajectoryFile.get().toPath(), scenario);
TrajectoryReader reader = new TrajectoryReader(trajectoryFile.get().toPath());
model.init(reader.readFile(), scenario, trajectoryFile.get().getParent());
} else {
System.err.println("could not find trajectory or scenario file in: " + outputDirectoryPath);
......
......@@ -16,7 +16,12 @@ import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class ActionOpenFile extends ActionVisualization {
private static Logger logger = Logger.getLogger(ActionOpenFile.class);
......@@ -78,7 +83,7 @@ public class ActionOpenFile extends ActionVisualization {
if (trajectoryFile.isPresent() && snapshotFile.isPresent()) {
Scenario vadere = IOOutput.readScenario(snapshotFile.get().toPath());
model.init(IOOutput.readTrajectories(trajectoryFile.get().toPath(), vadere), vadere, trajectoryFile.get().getParent());
model.init(IOOutput.readTrajectories(trajectoryFile.get().toPath()), vadere, trajectoryFile.get().getParent());
model.notifyObservers();
dialog.dispose();
setLastDirectories(scenarioOutputDir);
......@@ -111,22 +116,11 @@ public class ActionOpenFile extends ActionVisualization {
if (file == null || !file.isDirectory() || !file.exists()) {
throw new IllegalArgumentException("path is empty" + file);
}
String[] dirs =
VadereConfig.getConfig().getString("recentlyOpenedFiles", "").split(",");
int maxSavedDirs = CONFIG.getInt("PostVis.maxNumberOfSaveDirectories");
List<String> pathsList = VadereConfig.getConfig().getList(String.class, "recentlyOpenedFiles", new ArrayList<>());
pathsList.add(0, file.getAbsolutePath());
if (dirs != null) {
int i = 0;
String absPath = file.getAbsolutePath();
StringBuilder paths = new StringBuilder(absPath);
while (i < dirs.length && i < maxSavedDirs) {
if (!dirs[i].equals(absPath)) {
paths.append(",");
paths.append(dirs[i]);
}
i++;
}
VadereConfig.getConfig().setProperty("recentlyOpenedFiles", paths.toString());
}
pathsList = pathsList.stream().filter(entry -> Files.exists(Path.of(entry))).limit(maxSavedDirs).collect(Collectors.toList());
VadereConfig.getConfig().setProperty("recentlyOpenedFiles", pathsList);
}
}
......@@ -26,9 +26,9 @@ public class ActionSetTimeStep extends ActionVisualization implements ChangeList
JTextField field = (JTextField) e.getSource();
try {