Commit ea746e26 authored by Jakob Schöttl's avatar Jakob Schöttl
Browse files

Merge branch 'dev/processors' into develop

parents 8752d962 b1c0578d
......@@ -33,3 +33,6 @@ VadereModelTests/TestOVM/processed output/*
#deprecated: can potentially be removed
bin/
VadereGui/output/
#mac osx files
.DS_Store
......@@ -95,6 +95,11 @@
<artifactId>jgoodies-forms</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>tablelayout</groupId>
<artifactId>TableLayout</artifactId>
<version>20050920</version>
</dependency>
<!-- movie & screenshot -->
<dependency>
......
......@@ -187,5 +187,6 @@
"attributes": {
"targetId": 1
}
} ]
} ],
"isTimestamped": true
}
package org.vadere.gui.components.view;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class JComboCheckBox<E> extends JComboBox {
private Map<Object, Boolean> memory = new HashMap<>(); // keys are the entries of the comboBox (that get rendered via toString()), values are true or false (=checkBox checked or not)
private String NO_CHECKED_ITEMS_TEXT = " ";
public JComboCheckBox(List<E> items) {
super(items.toArray());
items.forEach(item -> memory.put(item, false));
addActionListener(ae -> {
if (!ae.getActionCommand().equals("inputComplete")) {
memory.put(getSelectedItem(), !memory.get(getSelectedItem())); // toogle associated boolean in memory upon click on item
hidePopup();
setPopupVisible(true);
}
});
addPopupMenuListener(new PopupMenuListener() {
@Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
@Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
@Override public void popupMenuCanceled(PopupMenuEvent e) {
repaint();
inputCompleted();
}
});
setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (!isPopupVisible()) {
StringBuilder sb = new StringBuilder();
getCheckedItemsStream().forEach(key -> sb.append(", ").append(key));
JLabel label = new JLabel(sb.length() > 2 ? sb.substring(2) : NO_CHECKED_ITEMS_TEXT);
label.setBorder(new EmptyBorder(4, 0, 4, 0)); // empirical values, lead to the popup having the correct height
return label;
}
JCheckBox cb = new JCheckBox(value.toString());
cb.setSelected(memory.get(value));
if (isSelected) {
cb.setBackground(list.getSelectionBackground());
cb.setForeground(list.getSelectionForeground());
} else {
cb.setBackground(list.getBackground());
cb.setForeground(list.getForeground());
}
return cb;
}
});
}
@Override
public void setPopupVisible(boolean v) {
if (v) {
super.setPopupVisible(v);
}
}
@Override
public void hidePopup() {
super.setPopupVisible(false);
}
private void inputCompleted() {
SwingUtilities.invokeLater(() -> {
String oldCommand = getActionCommand();
setActionCommand("inputComplete");
fireActionEvent();
setActionCommand(oldCommand);
});
}
private Stream<Object> getCheckedItemsStream() {
return memory.keySet().stream().filter(item -> memory.get(item));
}
public void setCheckedItems(List<E> checkedItems) {
checkedItems.forEach(checkedItem -> memory.put(checkedItem, true));
}
public List<E> getCheckedItems() {
return getCheckedItemsStream().map(item -> (E) item).collect(Collectors.toList());
}
public void setNoCheckedItemsText(String text) {
NO_CHECKED_ITEMS_TEXT = text;
}
}
......@@ -45,7 +45,9 @@ public abstract class SimulationRenderer extends DefaultRenderer {
protected void renderPreTransformation(Graphics2D graphics2D, int width, int height) {
if (model.isFloorFieldAvailable() && model.config.isShowPotentialField()) {
synchronized (model) {
renderPotentialField(graphics2D, width, height);
renderPotentialField(graphics2D,
(int)(Math.min(model.getTopographyBound().width, model.getViewportBound().width) * model.getScaleFactor()),
(int)(Math.min(model.getTopographyBound().height, model.getViewportBound().height) * model.getScaleFactor()));
}
}
super.renderPreTransformation(graphics2D, width, height);
......
......@@ -89,7 +89,7 @@ public class PostVisualizationConsole {
if (trajectoryFile.isPresent() && scenarioFile.isPresent()) {
TrajectoryReader reader = new TrajectoryReader(trajectoryFile.get().toPath());
model.init(reader.readFile(), IOOutput.readScenario(scenarioFile.get().toPath()));
model.init(reader.readFile(), IOOutput.readScenario(scenarioFile.get().toPath()), trajectoryFile.get().getParent());
} else {
System.err.println("could not find trajectory or scenario file in: " + outputDirectoryPath);
}
......
......@@ -82,7 +82,7 @@ public class ActionOpenFile extends ActionVisualization {
if (trajectoryFile.isPresent() && snapshotFile.isPresent()) {
ScenarioRunManager vadere = IOOutput.readScenario(snapshotFile.get().toPath());
model.init(IOOutput.readTrajectories(trajectoryFile.get().toPath(), vadere), vadere);
model.init(IOOutput.readTrajectories(trajectoryFile.get().toPath(), vadere), vadere, trajectoryFile.get().getParent());
model.notifyObservers();
dialog.dispose();
setLastDirectories(scenarioOutputDir);
......
......@@ -6,16 +6,11 @@ import org.vadere.gui.components.utils.Resources;
import org.vadere.gui.postvisualization.model.PostvisualizationModel;
import org.vadere.gui.postvisualization.utils.PotentialFieldContainer;
import org.vadere.gui.postvisualization.view.DialogFactory;
import org.vadere.gui.projectview.VadereApplication;
import org.vadere.state.scenario.Topography;
import org.vadere.util.potential.CellGrid;
import org.vadere.util.potential.CellGridConverter;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.List;
import java.util.prefs.Preferences;
public class ActionShowPotentialField extends ActionVisualization {
......@@ -30,8 +25,8 @@ public class ActionShowPotentialField extends ActionVisualization {
public void actionPerformed(final ActionEvent event) {
if (!model.config.isShowPotentialField()) {
final JFileChooser fc = new JFileChooser(resources.getProperty("View.outputDirectory.path"));
//final JFileChooser fc = new JFileChooser(resources.getProperty("View.outputDirectory.path"));
final JFileChooser fc = new JFileChooser(model.getOutputPath());
int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
......@@ -47,7 +42,7 @@ public class ActionShowPotentialField extends ActionVisualization {
try {
Topography topography = model.getTopography();
PotentialFieldContainer container = new PotentialFieldContainer(file,
topography.getBounds().getWidth(), topography.getBounds().getHeight(), true);
topography.getBounds().getWidth(), topography.getBounds().getHeight(), false);
model.setPotentialFieldContainer(container);
model.config.setShowPotentialField(true);
model.notifyObservers();
......
......@@ -2,7 +2,6 @@ package org.vadere.gui.postvisualization.model;
import java.awt.Color;
import java.io.IOException;
import java.security.cert.PKIXRevocationChecker;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
......@@ -15,7 +14,6 @@ import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.vadere.gui.components.model.SimulationModel;
......@@ -29,11 +27,12 @@ import org.vadere.state.scenario.TopographyIterator;
import org.vadere.state.simulation.Step;
import org.vadere.state.simulation.Trajectory;
import org.vadere.state.util.StateJsonConverter;
import org.vadere.util.io.IOUtils;
import org.vadere.util.io.parser.JsonLogicParser;
import org.vadere.util.io.parser.VPredicate;
import org.vadere.util.potential.CellGrid;
import com.fasterxml.jackson.databind.JsonNode;
public class PostvisualizationModel extends SimulationModel<PostvisualizationConfig> {
private static Logger logger = LogManager.getLogger(PostvisualizationModel.class);
......@@ -58,6 +57,8 @@ public class PostvisualizationModel extends SimulationModel<PostvisualizationCon
private List<Step> steps;
private String outputPath;
// public Configuration config;
public PostvisualizationModel() {
......@@ -97,10 +98,9 @@ public class PostvisualizationModel extends SimulationModel<PostvisualizationCon
});
}
public void init(final Map<Step, List<Agent>> agentsByStep, final ScenarioRunManager vadere) {
public void init(final Map<Step, List<Agent>> agentsByStep, final ScenarioRunManager vadere, final String projectPath) {
logger.info("start init postvis model");
init(vadere);
this.vadere = vadere;
init(vadere, projectPath);
this.agentsByStep = agentsByStep;
Map<Integer, Step> map = agentsByStep
.keySet().stream()
......@@ -136,12 +136,13 @@ public class PostvisualizationModel extends SimulationModel<PostvisualizationCon
logger.info("finished init postvis model");
}
public void init(final ScenarioRunManager vadere) {
public void init(final ScenarioRunManager vadere, final String projectPath) {
this.vadere = vadere;
this.agentsByStep = new HashMap<>();
this.steps = new ArrayList<>();
this.trajectories = new HashMap<>();
this.selectedElement = null;
this.outputPath = projectPath;
}
public Optional<Step> getLastStep() {
......@@ -160,6 +161,10 @@ public class PostvisualizationModel extends SimulationModel<PostvisualizationCon
}
}
public ScenarioRunManager getScenarioRunManager() {
return vadere;
}
@Override
public Optional<CellGrid> getPotentialField() {
if (potentialContainer == null || step == null) {
......@@ -324,10 +329,15 @@ public class PostvisualizationModel extends SimulationModel<PostvisualizationCon
return agentsByStep.size() == 0;
}
@Override
public int getTopographyId() {
return topographyId;
}
public String getOutputPath() {
return outputPath;
}
private void clear() {
setVoronoiDiagram(null);
......
......@@ -112,14 +112,14 @@ public class PotentialFieldContainer {
while ((line = reader.readLine()) != null) {
y++;
String[] splitLine = line.split(seperator);
if (resolution == null) {
resolution = width / (splitLine.length - 2);
}
// first line is the headline
if (!firstLine) {
if (resolution == null) {
resolution = width / (splitLine.length - 2);
}
readStep = Integer.parseInt(splitLine[0]);
double time = Double.parseDouble(splitLine[1]);
int row = Integer.parseInt(splitLine[1]);
if (readStep - 1 == requestedStep) {
return grid;
......
......@@ -48,11 +48,11 @@ public class PostvisualizationWindow extends JPanel implements Observer {
private static Resources resources = Resources.getInstance("postvisualization");
private final ScenarioElementView textView;
public PostvisualizationWindow() {
this(false);
public PostvisualizationWindow(final String projectPath) {
this(false, projectPath);
}
public PostvisualizationWindow(final boolean loadTopographyInformationsOnly) {
public PostvisualizationWindow(final boolean loadTopographyInformationsOnly, final String projectPath) {
// 1. get data from the user screen
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
......@@ -328,13 +328,13 @@ public class PostvisualizationWindow extends JPanel implements Observer {
public void loadOutputFile(final File trajectoryFile, final ScenarioRunManager scenario) throws IOException {
Player.getInstance(model).stop();
model.init(IOOutput.readTrajectories(trajectoryFile.toPath(), scenario), scenario);
model.init(IOOutput.readTrajectories(trajectoryFile.toPath(), scenario), scenario, trajectoryFile.getParent());
model.notifyObservers();
}
public void loadOutputFile(final ScenarioRunManager scenario) throws IOException {
Player.getInstance(model).stop();
model.init(scenario);
model.init(scenario, model.getOutputPath());
model.notifyObservers();
}
......@@ -371,7 +371,7 @@ public class PostvisualizationWindow extends JPanel implements Observer {
EventQueue.invokeLater(() -> {
JFrame frame = new JFrame();
PostvisualizationWindow postVisWindow = new PostvisualizationWindow(true);
PostvisualizationWindow postVisWindow = new PostvisualizationWindow(true, "./");
frame.add(postVisWindow);
frame.setJMenuBar(postVisWindow.getMenu());
......
......@@ -78,7 +78,7 @@ public class ActionLoadProject extends AbstractAction {
public static void loadProjectByPath(ProjectViewModel projectViewModel, String projectFilePath) {
try {
VadereProject project = IOVadere.readProjectJson(projectFilePath);
VadereProject project = IOVadere. readProjectJson(projectFilePath);
projectViewModel.setCurrentProjectPath(projectFilePath);
projectViewModel.setProject(project);
......
package org.vadere.gui.projectview.utils;
import org.apache.commons.lang3.tuple.Pair;
import org.vadere.simulator.models.MainModel;
import org.vadere.simulator.models.Model;
import org.vadere.simulator.projects.dataprocessing.datakey.DataKey;
import org.vadere.simulator.projects.dataprocessing.outputfile.OutputFile;
import org.vadere.simulator.projects.dataprocessing.processor.DataProcessor;
import org.vadere.state.attributes.Attributes;
......@@ -15,7 +17,10 @@ import java.lang.reflect.Type;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
public class ClassFinder {
......@@ -44,6 +49,46 @@ public class ClassFinder {
.collect(Collectors.toList());
}
public static Map<String, Class> getDataKeysOutputFileRelation() {
try {
return getClasses(DataKey.class.getPackage().getName())
.stream()
.filter(c -> !Modifier.isInterface(c.getModifiers()))
.filter(c -> DataKey.class.isAssignableFrom(c))
.map(c -> {
// Find corresponding outputfile class
try {
List<Class<?>> opClasses = getClasses(OutputFile.class.getPackage().getName());
Optional<Class<?>> corrOpClass = opClasses
.stream()
.filter(opc -> !Modifier.isAbstract(opc.getModifiers()))
.filter(opc -> ((ParameterizedType) opc.getGenericSuperclass()).getActualTypeArguments()[0].getTypeName().equals(c.getName()))
.findFirst();
return Pair.of((Class) c, corrOpClass);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
})
.filter(p -> p.getValue().isPresent())
.map(p -> Pair.of(p.getKey(), p.getValue().get()))
.collect(Collectors.toMap(p -> p.getKey().getSimpleName(), p -> (Class) p.getValue()));
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Map<String, Class> getProcessorClassesWithNames() {
Map<String, Class> map = new HashMap<>();
getAllProcessorClasses().forEach(procCls -> map.put(procCls.getSimpleName(), procCls));
return map;
}
public static List<Class<?>> getProcessorClasses(Type keyType) {
return findSubclassesInPackage(DataProcessor.class.getPackage().getName(), DataProcessor.class)
.stream()
......
package org.vadere.gui.projectview.view;
import org.vadere.simulator.projects.ScenarioRunManager;
public interface IJsonView {
void setVadereScenario(ScenarioRunManager scenario);
void isEditable(boolean isEditable);
}
......@@ -644,7 +644,7 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
ScenarioNamePanel.add(scenarioName);
scenarioName.setHorizontalAlignment(SwingConstants.CENTER);
scenarioJPanel = new ScenarioJPanel(this, scenarioName);
scenarioJPanel = new ScenarioJPanel(scenarioName, model);
model.setScenarioNameLabel(scenarioName); // TODO [priority=low] [task=refactoring] breaking mvc pattern (?) - but I need access to refresh the scenarioName
model.addProjectChangeListener(scenarioJPanel);
rightSidePanel.add(scenarioJPanel, BorderLayout.CENTER);
......
......@@ -6,6 +6,7 @@ import org.vadere.gui.components.utils.Messages;
import org.vadere.gui.onlinevisualization.OnlineVisualization;
import org.vadere.gui.postvisualization.view.PostvisualizationWindow;
import org.vadere.gui.projectview.control.IProjectChangeListener;
import org.vadere.gui.projectview.model.ProjectViewModel;
import org.vadere.gui.projectview.utils.ClassFinder;
import org.vadere.gui.topographycreator.view.TopographyWindow;
import org.vadere.simulator.projects.ProjectFinishedListener;
......@@ -35,15 +36,15 @@ public class ScenarioJPanel extends JPanel implements IProjectChangeListener, Pr
private static final long serialVersionUID = 7217609523783631174L;
private JTabbedPane tabbedPane;
private final JFrame owner;
private final JLabel scenarioName;
private ProjectViewModel model;
// tabs
private List<JMenu> menusInTabs = new ArrayList<>();
private TextView attributesSimulationView; // Simulation tab
private TextView attributesModelView; // Model tab
private TextView topographyFileView; // Topography tab
private TextView outputView; // new Output tab
private DataProcessingView dataProcessingGUIview; // DataProcessing
private TopographyWindow topographyCreatorView; // Topography creator tab... OR:
private final PostvisualizationWindow postVisualizationView; // Post-Visualization tab, replaces Topography tab if output is selected
......@@ -59,11 +60,11 @@ public class ScenarioJPanel extends JPanel implements IProjectChangeListener, Pr
private static String activeJsonParsingErrorMsg = null;
ScenarioJPanel(JFrame owner, JLabel scenarioName) {
this.owner = owner;
ScenarioJPanel(JLabel scenarioName, ProjectViewModel model) {
this.model = model;
this.scenarioName = scenarioName;
this.onlineVisualization = new OnlineVisualization(true);
this.postVisualizationView = new PostvisualizationWindow();
this.postVisualizationView = new PostvisualizationWindow(model.getCurrentProjectPath());
super.setBorder(new EmptyBorder(5, 5, 5, 5));
super.setLayout(new CardLayout(0, 0));
......@@ -99,7 +100,7 @@ public class ScenarioJPanel extends JPanel implements IProjectChangeListener, Pr
attributesSimulationView =
new TextView("/attributes", "default_directory_attributes", AttributeType.SIMULATION);
tabbedPane.addTab(Messages.getString("Tab.Simulation.title"), null, attributesSimulationView, null);
tabbedPane.addTab(Messages.getString("Tab.Simulation.title"), attributesSimulationView);
attributesModelView = new TextView("/attributes", "default_directory_attributes", AttributeType.MODEL);
......@@ -165,50 +166,14 @@ public class ScenarioJPanel extends JPanel implements IProjectChangeListener, Pr
})));
attributesModelView.getPanelTop().add(presetMenuBar, 0); // the 0 puts it at the leftest position instead of the rightest
tabbedPane.addTab(Messages.getString("Tab.Model.title"), null, attributesModelView, null);
tabbedPane.addTab(Messages.getString("Tab.Model.title"), attributesModelView);
topographyFileView = new TextView("/scenarios", "default_directory_scenarios", AttributeType.TOPOGRAPHY);
tabbedPane.addTab(Messages.getString("Tab.Topography.title"), null, topographyFileView, null);
tabbedPane.addTab(Messages.getString("Tab.Topography.title"), topographyFileView);
outputView = new TextView("/" + IOUtils.OUTPUT_DIR, "default_directory_outputprocessors", AttributeType.OUTPUTPROCESSOR);
dataProcessingGUIview = new DataProcessingView();
tabbedPane.addTab("Data processing GUI", dataProcessingGUIview);
JMenuBar processorsMenuBar = new JMenuBar();
JMenu processorsMenu = new JMenu(Messages.getString("Tab.Model.loadTemplateMenu.title"));
processorsMenuBar.add(processorsMenu);
menusInTabs.add(processorsMenu);
try {
File[] templateFiles = new File(this.getClass().getResource("/outputTemplates/").getPath()).listFiles();
for (File templateFile : Arrays.stream(templateFiles).filter(f -> f.isFile()).collect(Collectors.toList())) {
String templateFileName = templateFile.getName();
String templateJson = org.apache.commons.io.IOUtils.toString(this.getClass().getResourceAsStream("/outputTemplates/" + templateFileName), "UTF-8");
processorsMenu.add(new JMenuItem(new AbstractAction(templateFileName) {
@Override
public void actionPerformed(ActionEvent e) {
if (JOptionPane.showConfirmDialog(ProjectView.getMainWindow(),
Messages.getString("Tab.Model.confirmLoadTemplate.text"),
Messages.getString("Tab.Model.confirmLoadTemplate.title"),
JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
try {
outputView.setText(templateJson);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}));
}
outputView.getPanelTop().add(processorsMenuBar, 0);
} catch (IOException e) {
e.printStackTrace();
}
tabbedPane.addTab(Messages.getString("Tab.OutputProcessors.title"), null, outputView, null);
// online visualization card...
JPanel visualizationCard = new JPanel();
......@@ -289,8 +254,8 @@ public class ScenarioJPanel extends JPanel implements IProjectChangeListener, Pr
this.topographyFileView.setVadereScenario(scenario);
this.topographyFileView.isEditable(isEditable);
this.outputView.setVadereScenario(scenario);
this.outputView.isEditable(isEditable);
this.dataProcessingGUIview.setVadereScenario(scenario);
this.dataProcessingGUIview.isEditable(isEditable);
}
private void setTopography(Topography topography) {
......
......@@ -42,7 +42,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
*
*