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 f50e2e76 authored by BZoennchen's avatar BZoennchen

improved video and picture making for the PostVis and change the PostVis from...

improved video and picture making for the PostVis and change the PostVis from time step granularity to simulation time granularity.
parent 3e147ded
Pipeline #126921 failed with stages
in 3 minutes and 13 seconds
......@@ -204,6 +204,7 @@ OutputprocessorsView.dataProcessor.text={Processor: ""}
AdjustPanel.lblVelocity.text=FPS
AdjustPanel.lblTime=Time
AdjustPanel.lblStep.text=Timestep
AdjustPanel.lblVisTime.text=Res.
ProjectView.warning.lwjgl.title=Warning
ProjectView.warning.opencl.title=Warning
......
......@@ -209,6 +209,7 @@ OutputprocessorsView.dataProcessor.text={"Processor": ""}
AdjustPanel.lblVelocity.text=FPS
AdjustPanel.lblTime=Zeit
AdjustPanel.lblStep.text=Zeitschritt
AdjustPanel.lblVisTime.text=Aufl.
ProjectView.mntmOutputToSceneario.text=Generiere Szenario
ProjectView.mntmRunOutput.text=Offline erneut starten
......
......@@ -135,8 +135,26 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
@Override
public boolean setScale(final double scale) {
boolean hasChanged = true;
double oldScale = scaleFactor;
boolean hasChanged = setScaleWithoutChangingViewport(scale);
// update the viewport, since it depends on the scaleFactor
if (hasChanged) {
Rectangle2D.Double oldViewPort = getViewportBound();
Rectangle2D.Double newViewPort = new Rectangle2D.Double(
oldViewPort.getMinX(),
oldViewPort.getMinY(),
oldViewPort.getWidth() * oldScale / scaleFactor,
oldViewPort.getHeight() * oldScale / scaleFactor);
setViewportBound(newViewPort);
setChanged();
}
return hasChanged;
}
@Override
public boolean setScaleWithoutChangingViewport(double scale) {
boolean hasChanged = true;
if (scale < MIN_SCALE_FACTOR) {
this.scaleFactor = MIN_SCALE_FACTOR;
......@@ -148,17 +166,10 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
hasChanged = false;
}
// update the viewport, since it depends on the scaleFactor
if (hasChanged) {
Rectangle2D.Double oldViewPort = getViewportBound();
Rectangle2D.Double newViewPort = new Rectangle2D.Double(
oldViewPort.getMinX(),
oldViewPort.getMinY(),
oldViewPort.getWidth() * oldScale / scaleFactor,
oldViewPort.getHeight() * oldScale / scaleFactor);
setViewportBound(newViewPort);
if(hasChanged) {
setChanged();
}
return hasChanged;
}
......@@ -254,7 +265,7 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
}
@Override
public void setViewportBound(final Rectangle2D.Double viewportBound) {
public synchronized void setViewportBound(final Rectangle2D.Double viewportBound) {
Rectangle2D.Double oldViewportBound = this.viewportBound;
if (!oldViewportBound.equals(viewportBound)) {
......
......@@ -28,6 +28,8 @@ public interface IDefaultModel<T extends DefaultConfig> extends Iterable<Scenari
boolean setScale(final double scale);
boolean setScaleWithoutChangingViewport(final double scale);
void notifyScaleListeners();
Color getScenarioElementColor(final ScenarioElementType elementType);
......
......@@ -87,7 +87,7 @@ public abstract class SimulationModel<T extends DefaultSimulationConfig> extends
}*/
@Override
public void notifyObservers() {
public synchronized void notifyObservers() {
// synchronized (config) {
if (config.hasChanged()) {
setChanged();
......
......@@ -59,37 +59,45 @@ public abstract class DefaultRenderer {
* @param height
*/
public void render(final Graphics2D targetGraphics2D, final int width, final int height) {
render(targetGraphics2D, 0, 0, width, height);
synchronized (defaultModel) {
render(targetGraphics2D, 0, 0, width, height);
}
}
public void render(final Graphics2D targetGraphics2D, final int x, final int y, final int width, final int height) {
targetGraphics2D.drawImage(renderImage(width, height), x, y, null);
targetGraphics2D.dispose();
synchronized (defaultModel) {
targetGraphics2D.drawImage(renderImage(width, height), x, y, null);
targetGraphics2D.dispose();
}
}
public void renderGraphics(final Graphics2D targetGraphics2D, final int width, final int height) {
targetGraphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
synchronized (defaultModel) {
targetGraphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// (1) clear background
targetGraphics2D.setColor(Color.GRAY);
//targetGraphics2D.fill();
targetGraphics2D.fillRect(0, 0, width, height);
// (1) clear background
targetGraphics2D.setColor(Color.GRAY);
//targetGraphics2D.fill();
targetGraphics2D.fillRect(0, 0, width, height);
// (2) render everything which can be rendered before the transformation
renderPreTransformation(targetGraphics2D, width, height);
// (2) render everything which can be rendered before the transformation
renderPreTransformation(targetGraphics2D, width, height);
// (3)
transformGraphics(targetGraphics2D);
// (3)
transformGraphics(targetGraphics2D);
// (4) render everything which can be rendered after the transformation
renderPostTransformation(targetGraphics2D, width, height);
// (4) render everything which can be rendered after the transformation
renderPostTransformation(targetGraphics2D, width, height);
}
}
public BufferedImage renderImage(final int width, final int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D bufferGraphics2D = (Graphics2D) image.getGraphics();
renderGraphics(bufferGraphics2D, width, height);
return image;
synchronized (defaultModel) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D bufferGraphics2D = (Graphics2D) image.getGraphics();
renderGraphics(bufferGraphics2D, width, height);
return image;
}
}
public void setLogo(final BufferedImage logo) {
......@@ -99,33 +107,36 @@ public abstract class DefaultRenderer {
protected void renderPreTransformation(final Graphics2D graphics2D, final int width, final int height) {}
protected void renderPostTransformation(final Graphics2D graphics2D, final int width, final int height) {
graphics2D.setColor(Color.WHITE);
Rectangle2D.Double topographyBound = defaultModel.getTopographyBound();
fill(new VRectangle(
topographyBound.getMinX() + defaultModel.getBoundingBoxWidth(),
topographyBound.getMinY() + defaultModel.getBoundingBoxWidth(),
(defaultModel.getTopographyBound().getWidth() - defaultModel.getBoundingBoxWidth() * 2),
(defaultModel.getTopographyBound().getHeight() - defaultModel.getBoundingBoxWidth() * 2)), graphics2D);
synchronized (defaultModel) {
graphics2D.setColor(Color.WHITE);
Rectangle2D.Double topographyBound = defaultModel.getTopographyBound();
fill(new VRectangle(
topographyBound.getMinX() + defaultModel.getBoundingBoxWidth(),
topographyBound.getMinY() + defaultModel.getBoundingBoxWidth(),
(defaultModel.getTopographyBound().getWidth() - defaultModel.getBoundingBoxWidth() * 2),
(defaultModel.getTopographyBound().getHeight() - defaultModel.getBoundingBoxWidth() * 2)), graphics2D);
}
}
protected void transformGraphics(final Graphics2D graphics2D) {
Rectangle2D.Double topographyBound = defaultModel.getTopographyBound();
mirrowHorizonzal(graphics2D, (int) (topographyBound.getHeight() * defaultModel.getScaleFactor()));
graphics2D.scale(defaultModel.getScaleFactor(), defaultModel.getScaleFactor());
synchronized (defaultModel) {
Rectangle2D.Double topographyBound = defaultModel.getTopographyBound();
mirrowHorizonzal(graphics2D, (int) (topographyBound.getHeight() * defaultModel.getScaleFactor()));
graphics2D.scale(defaultModel.getScaleFactor(), defaultModel.getScaleFactor());
//graphics2D.translate(-topographyBound.getMinX(), -topographyBound.getMinY());
//graphics2D.translate(-topographyBound.getMinX(), -topographyBound.getMinY());
/*
* This calculation we need since the viewport.y = 0 if the user scrolls to the bottom
*/
Rectangle2D.Double viewportBound = defaultModel.getViewportBound();
double dy = topographyBound.getHeight() - viewportBound.getHeight();
graphics2D.translate(-viewportBound.getX(), Math.max((dy - viewportBound.getY()), - viewportBound.getY()));
// graphics2D.translate(+viewportBound.getX(), -Math.max((dy - viewportBound.getY()), 0));
/*
* This calculation we need since the viewport.y = 0 if the user scrolls to the bottom
*/
Rectangle2D.Double viewportBound = defaultModel.getViewportBound();
double dy = topographyBound.getHeight() - viewportBound.getHeight();
graphics2D.translate(-viewportBound.getX(), Math.max((dy - viewportBound.getY()), - viewportBound.getY()));
// graphics2D.translate(+viewportBound.getX(), -Math.max((dy - viewportBound.getY()), 0));
}
}
protected void renderScenarioElement(final Iterable<? extends ScenarioElement> elements, final Graphics2D g,
......
......@@ -11,6 +11,7 @@ import org.vadere.gui.postvisualization.utils.ImageGenerator;
import org.vadere.gui.postvisualization.utils.SVGGenerator;
import org.vadere.gui.postvisualization.utils.TikzGenerator;
import org.vadere.gui.postvisualization.view.PostvisualizationRenderer;
import org.vadere.simulator.projects.Scenario;
import org.vadere.simulator.projects.io.IOOutput;
import org.vadere.simulator.projects.io.TrajectoryReader;
import org.vadere.util.io.IOUtils;
......@@ -22,7 +23,6 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Locale;
import java.util.Optional;
......@@ -118,8 +118,9 @@ public class PostVisualizationConsole {
Optional<File> scenarioFile = IOUtils.getFirstFile(path.toFile(), IOUtils.SCENARIO_FILE_EXTENSION);
if (trajectoryFile.isPresent() && scenarioFile.isPresent()) {
TrajectoryReader reader = new TrajectoryReader(trajectoryFile.get().toPath());
model.init(reader.readFile(), IOOutput.readScenario(scenarioFile.get().toPath()), trajectoryFile.get().getParent());
Scenario scenario = IOOutput.readScenario(scenarioFile.get().toPath());
TrajectoryReader reader = new TrajectoryReader(trajectoryFile.get().toPath(), scenario);
model.init(reader.readFile(), scenario, trajectoryFile.get().getParent());
} else {
System.err.println("could not find trajectory or scenario file in: " + outputDirectoryPath);
}
......@@ -142,7 +143,7 @@ public class PostVisualizationConsole {
if (step != -1) {
model.setStep(step);
} else {
model.setTime(time);
model.setVisTime(time);
}
if (showGroups){
......
......@@ -2,13 +2,15 @@ package org.vadere.gui.postvisualization.control;
import org.vadere.gui.postvisualization.model.PostvisualizationModel;
import org.vadere.state.simulation.Step;
import org.vadere.util.logging.Logger;
import java.util.Optional;
public class Player implements Runnable {
private static Logger logger = Logger.getLogger(Player.class);
private static volatile Player instance;
private Thread currentThread;
private int currentStep;
enum State {
STOPPED, PAUSED, RUNNING
......@@ -29,7 +31,6 @@ public class Player implements Runnable {
private Player(final PostvisualizationModel model) {
this.model = model;
this.currentStep = 1;
this.currentThread = null;
state = State.STOPPED;
}
......@@ -41,7 +42,6 @@ public class Player implements Runnable {
public void stop() {
state = State.STOPPED;
running = false;
currentStep = 1;
if (currentThread != null) {
currentThread.interrupt();
......@@ -63,8 +63,6 @@ public class Player implements Runnable {
currentThread.start();
}
state = State.RUNNING;
model.getStep().ifPresent(s -> currentStep = s.getStepNumber());
synchronized (model) {
model.notifyAll();
}
......@@ -79,8 +77,8 @@ public class Player implements Runnable {
}
}
private boolean isRunable() {
return model.getStep().isPresent() && model.getFirstStep().isPresent() && model.getLastStep().isPresent();
private boolean isRunnable() {
return !model.isEmpty();
}
@Override
......@@ -91,17 +89,16 @@ public class Player implements Runnable {
// synchronized (model) {
switch (state) {
case RUNNING: {
if (isRunable()) {
if (model.getLastStep().get().getStepNumber() > model.getStep().get().getStepNumber()) {
currentStep = model.getStep().get().getStepNumber() + 1;
model.setStep(currentStep);
} else {
pause();
if (isRunnable()) {
double newSimeTimeInSec = model.getSimTimeInSec() + model.getVisTimeStepLength();
if(model.getSimTimeInSec() >= model.getMaxSimTimeInSec()) {
newSimeTimeInSec = 0;
}
model.setVisTime(newSimeTimeInSec);
}
}
model.notifyObservers();
break;
model.notifyObservers();
break;
case PAUSED: {
synchronized (model) {
......@@ -112,17 +109,18 @@ public class Player implements Runnable {
}
}
}
break;
default:
break;
break;
default: break;
}
// }
diffMs = System.currentTimeMillis() - ms;
sleepTimeMS = (int) Math.round((1000.0 - diffMs) / model.config.getFps());
try {
Thread.sleep(Math.max(0, sleepTimeMS));
} catch (InterruptedException e) {
logger.info("Player interrupted while sleeping");
sleepTimeMS = (int) Math.round((1000.0 / model.config.getFps() - diffMs));
if(sleepTimeMS > 0) {
try {
Thread.sleep(Math.max(0, sleepTimeMS));
} catch (InterruptedException e) {
logger.info("Player interrupted while sleeping");
}
}
}
}
......
......@@ -23,28 +23,31 @@ public class ImageGenerator<T extends DefaultSimulationConfig> {
}
public BufferedImage generateImage(final double scaleFactor) {
BufferedImage bi = null;
synchronized (renderer) {
synchronized (model) {
BufferedImage bi = null;
double oldScale = model.getScaleFactor();
try {
model.setScale(scaleFactor);
bi = renderer.renderImage(ImageGenerator.calculateOptimalWidth(model),
ImageGenerator.calculateOptimalHeight(model));
model.setScaleWithoutChangingViewport(scaleFactor);
bi = renderer.renderImage(ImageGenerator.calculateOptimalWidth(model), ImageGenerator.calculateOptimalHeight(model));
} catch (Exception e) {
logger.error("could not render image " + e.getMessage());
} finally {
model.setScale(oldScale);
model.setScaleWithoutChangingViewport(oldScale);
}
return bi;
}
return bi;
}
public BufferedImage generateImage(final Rectangle2D.Double imageSize) {
return generateImage(imageSize.getWidth() / model.getTopographyBound().getWidth());
synchronized (model) {
return generateImage(imageSize.getWidth() / model.getTopographyBound().getWidth());
}
}
public BufferedImage generateImage() {
return generateImage(model.getScaleFactor());
synchronized (model) {
return generateImage(model.getScaleFactor());
}
}
public static int calculateOptimalWidth(final DefaultModel model) {
......
......@@ -27,86 +27,102 @@ public class MovRecorder implements IRecorder {
private final PostvisualizationModel model;
private ImageGenerator generator;
private SequenceEncoder enc;
private int step;
private double simTimeInSec;
private Rectangle2D.Double imageSize;
private Rectangle2D.Double viewport;
private boolean finished;
public MovRecorder(final PostvisualizationRenderer renderer) {
this.model = renderer.getModel();
this.imageSize = model.getWindowBound();
this.viewport = model.getViewportBound();
this.generator = new ImageGenerator(renderer, renderer.getModel());
this.step = 0;
this.simTimeInSec = 0.0;
this.enc = null;
this.finished = false;
}
@Override
public synchronized void update(Observable o, Object arg) {
try {
if (model.config.isRecording() && model.getStep().isPresent()
&& model.getStep().get().getStepNumber() != step) {
step = model.getStep().get().getStepNumber();
addPicture();
public void update(Observable o, Object arg) {
synchronized(model) {
try {
if (model.config.isRecording() && model.getSimTimeInSec() > simTimeInSec) {
addPicture();
}
} catch (IOException ioe) {
ioe.printStackTrace();
logger.error(ioe.getMessage());
}
} catch (IOException ioe) {
ioe.printStackTrace();
logger.error(ioe.getMessage());
}
}
private synchronized void addPicture() throws IOException {
Rectangle2D.Double oldViewport = model.getViewportBound();
model.setViewportBound(viewport);
BufferedImage bi = generator.generateImage(imageSize);
enc.encodeImage(bi);
logger.info(this + " add picture");
model.setViewportBound(oldViewport);
private void addPicture() throws IOException {
synchronized(model) {
if(!this.finished) {
simTimeInSec = model.getSimTimeInSec();
Rectangle2D.Double oldViewport = model.getViewportBound();
model.setViewportBound(viewport);
BufferedImage bi = generator.generateImage(imageSize);
logger.info(this + " add picture " + bi.getWidth() + " (width), " + bi.getHeight() + " (height).");
enc.encodeImage(bi);
model.setViewportBound(oldViewport);
}
}
}
@Override
public synchronized void stopRecording() throws IOException {
try {
enc.finish();
} catch (IndexOutOfBoundsException error) {
logger.debug("Nothing recorded! " + error.getMessage());
throw error;
public void stopRecording() throws IOException {
synchronized(model) {
try {
this.finished = true;
enc.finish();
} catch (IndexOutOfBoundsException error) {
logger.debug("Nothing recorded! " + error.getMessage());
throw error;
}
logger.info(this + " stop recording");
}
logger.info(this + " stop recording");
}
@Override
public synchronized void startRecording(final Rectangle2D.Double imageSize) throws IOException {
try {
this.imageSize = imageSize;
this.viewport = model.getViewportBound();
startRecording();
logger.info(this + " start recording");
} catch (IOException e) {
e.printStackTrace();
logger.error(e.getMessage());
public void startRecording(final Rectangle2D.Double imageSize) throws IOException {
synchronized(model) {
try {
this.finished = false;
this.imageSize = imageSize;
this.viewport = model.getViewportBound();
this.simTimeInSec = 0;
startRecording();
logger.info(this + " start recording");
} catch (IOException e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}
}
@Override
public synchronized void startRecording() throws IOException {
Date todaysDate = new java.util.Date();
SimpleDateFormat formatter = new SimpleDateFormat(resources.getProperty("SettingsDialog.dataFormat"));
String formattedDate = formatter.format(todaysDate);
JFileChooser fileChooser = new JFileChooser(Preferences.userNodeForPackage(PostVisualisation.class).get("SettingsDialog.snapshotDirectory.path", "."));
File outputFile = new File(Messages.getString("FileDialog.filenamePrefix") + formattedDate + ".mov");
fileChooser.setSelectedFile(outputFile);
int returnVal = fileChooser.showDialog(null, "Save");
if (returnVal == JFileChooser.APPROVE_OPTION) {
outputFile = fileChooser.getSelectedFile().toString().endsWith(".mov") ? fileChooser.getSelectedFile()
: new File(fileChooser.getSelectedFile().toString() + ".mov");
try {
enc = new SequenceEncoder(outputFile);
} catch (IOException e) {
enc = null;
throw e;
public void startRecording() throws IOException {
synchronized(model) {
Date todaysDate = new java.util.Date();
SimpleDateFormat formatter = new SimpleDateFormat(resources.getProperty("SettingsDialog.dataFormat"));
String formattedDate = formatter.format(todaysDate);
JFileChooser fileChooser = new JFileChooser(Preferences.userNodeForPackage(PostVisualisation.class).get("SettingsDialog.snapshotDirectory.path", "."));
File outputFile = new File(Messages.getString("FileDialog.filenamePrefix") + formattedDate + ".mov");
fileChooser.setSelectedFile(outputFile);
int returnVal = fileChooser.showDialog(null, "Save");
if (returnVal == JFileChooser.APPROVE_OPTION) {
outputFile = fileChooser.getSelectedFile().toString().endsWith(".mov") ? fileChooser.getSelectedFile()
: new File(fileChooser.getSelectedFile().toString() + ".mov");
try {
enc = new SequenceEncoder(outputFile);
} catch (IOException e) {
enc = null;
throw e;
}
}
}
}
......
......@@ -286,28 +286,27 @@ public class TikzGenerator {
final StringBuffer generatedCode = new StringBuffer("");
Stream<Trajectory> trajectoryStream = model.getAlivePedestrians();
Step currentTimeStep = model.getStep().orElseGet(null);
//Step currentTimeStep = model.getStep().orElseGet(null);
if (currentTimeStep != null) {
trajectoryStream.forEach(trajectory -> {
Stream<VPoint> trajectoryPoints = trajectory.getPositionsReverse(currentTimeStep);
// Use a newline ("to\n") for joining because TeX could possibly choke up on long lines.
String trajectoryAsTikzString = trajectoryPoints
.map(point -> String.format(Locale.US, "(%f,%f)", point.x, point.y))
.collect(Collectors.joining(" to\n"));
trajectoryStream.forEach(trajectory -> {
Stream<VPoint> trajectoryPoints = trajectory.getPositionsReverse(model.getSimTimeInSec());
String coloredTrajectory = applyAgentColorToTrajectory(trajectoryAsTikzString, trajectory.getAgent(currentTimeStep));
// Use a newline ("to\n") for joining because TeX could possibly choke up on long lines.
String trajectoryAsTikzString = trajectoryPoints
.map(point -> String.format(Locale.US, "(%f,%f)", point.x, point.y))
.collect(Collectors.joining(" to\n"));
int pedestrianId = trajectory.getPedestrianId();
Optional<Step> trajectoryEndStep = trajectory.getEndStep();
String trajectoryEndStepAsString = (trajectoryEndStep.isPresent()) ? "" + trajectoryEndStep.get().toString() : "unknown end step" ;
String currentTimeStepAsString = currentTimeStep.toString();
String coloredTrajectory = applyAgentColorToTrajectory(trajectoryAsTikzString, trajectory.getAgent(model.getSimTimeInSec()));
int pedestrianId = trajectory.getPedestrianId();
Optional<Step> trajectoryEndStep = trajectory.getEndStep();
String trajectoryEndStepAsString = (trajectoryEndStep.isPresent()) ? "" + trajectoryEndStep.get().toString() : "unknown end step" ;
generatedCode.append(String.format(Locale.US, "%% Trajectory Agent %d @ simTimeInSec %f of %s\n", pedestrianId, model.getSimTimeInSec(), trajectoryEndStepAsString));
generatedCode.append(coloredTrajectory);
});
generatedCode.append(String.format(Locale.US, "%% Trajectory Agent %d @ step %s of %s\n", pedestrianId, currentTimeStepAsString, trajectoryEndStepAsString));
generatedCode.append(coloredTrajectory);
});
}
return generatedCode.toString();
......
......@@ -4,18 +4,18 @@ import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.vadere.gui.components.utils.Messages;
import org.vadere.gui.components.utils.Resources;
import org.vadere.gui.postvisualization.control.ActionSetTimeStep;
import org.vadere.gui.postvisualization.control.EJSliderAction;
import org.vadere.gui.postvisualization.model.PostvisualizationModel;
import org.vadere.state.simulation.Step;
import java.awt.*;
import java.util.Observable;
import java.util.Observer;
import java.util.Optional;
public class AdjustPanel extends JPanel implements Observer {
private static Resources resources = Resources.getInstance("postvisualization");
......@@ -23,10 +23,14 @@ public class AdjustPanel extends JPanel implements Observer {
private final JSlider slider;
private final JSpinner sStep;
private final JSpinner sVelocity;
private final JSpinner sVisTimeStepLength;
private final JSpinner sTime;
private final SpinnerModel sModelTime;
private final SpinnerModel sModelTimeStep;
private final SpinnerModel sModelVelocity;
private final SpinnerModel sModelVisTimeStepLength;
private final PostvisualizationModel model;
public AdjustPanel(final PostvisualizationModel model) {
......@@ -42,11 +46,15 @@ public class AdjustPanel extends JPanel implements Observer {
// sStep.setEditable(false);
sModelVelocity = new SpinnerNumberModel(model.config.getFps(), 1, 200, 1);
sModelTimeStep = new SpinnerNumberModel(1, 1, Integer.MAX_VALUE, 1);
sModelTime = new SpinnerNumberModel(0.0, 0.0, 0.0, 0);
sModelTime = new SpinnerNumberModel(0.0, 0.0, Double.MAX_VALUE, 0.01);
sModelVisTimeStepLength = new SpinnerNumberModel(model.getVisTimeStepLength(), 0.01, Double.MAX_VALUE, 0.01);
sVelocity = new JSpinner(sModelVelocity);
sTime = new JSpinner(sModelTime);
sStep = new JSpinner(sModelTimeStep);
sTime.setEnabled(false);
sVisTimeStepLength = new JSpinner(sModelVisTimeStepLength);
//sTime.setEnabled(false);
// lTime.set
......@@ -54,9 +62,10 @@ public class AdjustPanel extends JPanel implements Observer {
sStep.setPreferredSize(new Dimension(50, 30));
sVelocity.setPreferredSize(new Dimension(50, 30));
sTime.setPreferredSize(new Dimension(70, 30));
sVisTimeStepLength.setPreferredSize(new Dimension(70, 30));
// Layout definition!
FormLayout layout = new FormLayout(
"2dlu, default:grow, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu", // col
"2dlu, default:grow, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu", // col
"2dlu, default, 2dlu"); // rows
setLayout(layout);
CellConstraints cc = new CellConstraints();
......@@ -67,23 +76,31 @@ public class AdjustPanel extends JPanel implements Observer {
add(sTime, cc.xy(10, 2));
add(new JLabel(Messages.getString("AdjustPanel.lblStep.text")), cc.xy(12, 2));
add(sStep, cc.xy(14, 2));
add(new JLabel(Messages.getString("AdjustPanel.lblVisTime.text")), cc.xy(16, 2));
add(sVisTimeStepLength, cc.xy(18, 2));
sVelocity.addChangeListener(new ChangeListener() {
@Override