Notice to GitKraken users: A vulnerability has been found in the SSH key generation of GitKraken versions 7.6.0 to 8.0.0 (https://www.gitkraken.com/blog/weak-ssh-key-fix). If you use GitKraken and have generated a SSH key using one of these versions, please remove it both from your local workstation and from your LRZ GitLab profile.

21.10.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit 298f7729 authored by Stefan Schuhbaeck's avatar Stefan Schuhbaeck
Browse files

Merge branch 'checker_on_off' into 'master'

checkbox to deactivate ScenarioChecker in GUI.

See merge request !107
parents 5dd1d018 f010a5cc
Pipeline #201812 passed with stages
in 190 minutes and 35 seconds
......@@ -80,6 +80,7 @@ ProjectView.btnRunAllTests.text=Run all scenarios
ProjectView.mntmRunSelectetTests.text=Run selected scenario
ProjectView.mntmRunSelectedTests.text=Run selected scenarios
ProjectView.mntmSimulationResult.text=Show summary after simulation
ProjectView.btnToggleScenarioChecker.text=Activate ScenarioChecker
ProjectView.btnPauseRunningTests.text=Pause
ProjectView.btnRunSelectedTest.text=Run selected scenario
ProjectView.btnRunSelectedTest.toolTipText=Run selected scenario
......@@ -131,6 +132,10 @@ ProjectView.chooseMigrationBaseDialog.text=Choose the version of this project
ProjectView.chooseMigrationBaseDialog.title=Migration
ProjectView.chooseMigrationBaseDialog.defaultOption=automatic
ProjectView.chooseFile=Chose file
ProjectView.ScenarioChecker.title=Scenario Checker
ProjectView.ScenarioChecker.deactive.text=ScenarioChecker deactivated. Project > Activate ScenarioChecker
ProjectView.ScenarioChecker.active.text=The following problems where found
SaveBeforeClosing.text=Do you want to save the current project before closing?
SaveBeforeClosing.unsavedChanges.text=Unsaved changes:
......
......@@ -80,6 +80,7 @@ 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=Zusammenfassung nach Simulation anzeigen
ProjectView.btnToggleScenarioChecker.text=ScenarioChecker aktiv
ProjectView.btnPauseRunningTests.text=Pausieren
ProjectView.btnRunSelectedTest.text=Ausgew\u00E4hltes Szenario ausf\u00FChren
ProjectView.btnRunSelectedTest.toolTipText=Ausgew\u00E4hlten Szenario ausf\u00FChren
......@@ -132,6 +133,10 @@ ProjectView.chooseMigrationBaseDialog.defaultOption=Automatisch
ProjectView.chooseFile=Datei ausw\u00E4hlen
ProjectView.btnExpertCSV=Als CSV exportieren
ProjectView.label.simResults=Simulationsergebniss
ProjectView.ScenarioChecker.title=Scenario Checker
ProjectView.ScenarioChecker.deactive.text=ScenarioChecker deaktiviert. Projekt > ScenarioChecker aktivieren
ProjectView.ScenarioChecker.active.text=Probleme gefunden
SaveBeforeClosing.text=Aktuelles Projekt vor dem Beenden speichern?
SaveBeforeClosing.unsavedChanges.text=Ungespeicherte \u00c4nderungen:
......
package org.vadere.gui.components.control;
import org.vadere.gui.components.utils.Messages;
import org.vadere.gui.projectview.view.ScenarioNamePanel;
import org.vadere.gui.projectview.view.ScenarioPanel;
import org.vadere.gui.projectview.view.VDialogManager;
......@@ -7,6 +8,7 @@ import org.vadere.gui.topographycreator.model.IDrawPanelModel;
import org.vadere.simulator.projects.Scenario;
import org.vadere.simulator.utils.scenariochecker.ScenarioChecker;
import org.vadere.simulator.utils.scenariochecker.ScenarioCheckerMessage;
import org.vadere.util.config.VadereConfig;
import java.awt.event.ActionEvent;
import java.util.Observable;
......@@ -23,8 +25,7 @@ public class ActionScenarioChecker extends AbstractAction implements Observer {
private IDrawPanelModel model;
private ScenarioNamePanel view;
public
ActionScenarioChecker(String name, ScenarioNamePanel view) {
public ActionScenarioChecker(String name, ScenarioNamePanel view) {
super(name);
this.messages = new PriorityQueue<>();
this.view = view;
......@@ -36,15 +37,25 @@ public class ActionScenarioChecker extends AbstractAction implements Observer {
*/
@Override
public void actionPerformed(ActionEvent e) {
VDialogManager.showMessageDialogWithBodyAndTextEditorPane(
"Topography Checker",
"The following problems where found",
msgDocument,
JOptionPane.INFORMATION_MESSAGE
);
if (!VadereConfig.getConfig().getBoolean("Project.ScenarioChecker.active")) {
VDialogManager.showMessageDialogWithTextArea(
Messages.getString("ProjectView.ScenarioChecker.title"),
Messages.getString("ProjectView.ScenarioChecker.deactive.text"),
JOptionPane.INFORMATION_MESSAGE
);
} else {
VDialogManager.showMessageDialogWithBodyAndTextEditorPane(
Messages.getString("ProjectView.ScenarioChecker.title"),
Messages.getString("ProjectView.ScenarioChecker.active.text"),
msgDocument,
JOptionPane.INFORMATION_MESSAGE
);
}
}
public void observerModel(IDrawPanelModel model){
public void observerModel(IDrawPanelModel model) {
model.addObserver(this);
this.model = model;
}
......@@ -57,24 +68,27 @@ public class ActionScenarioChecker extends AbstractAction implements Observer {
*/
@Override
public void update(Observable o, Object arg) {
if(model != null){
if (model != null) {
check(model.getScenario());
}
}
public void check(final Scenario scenario){
ScenarioChecker checker = new ScenarioChecker(scenario);
messages.clear();
ScenarioPanel.setActiveTopographyErrorMsg(null);
messages = checker.checkBuildingStep();
msgDocument = new ScenarioCheckerMessageDocumentView(model);
msgDocument.setMessages(messages);
// VadereConfig.getConfig().setProperty("Project.ScenarioChecker.active", item.getState());
public void check(final Scenario scenario) {
if (!VadereConfig.getConfig().getBoolean("Project.ScenarioChecker.active")) {
// ScenarioChecker is deactivated.
view.setDeactivate();
return;
}
run_check(scenario);
view.setGreen();
if (messages.size() > 0){
if (!messages.isEmpty()) {
if(messages.peek().getMsgType().isWarnMsg()) {
if (messages.peek().getMsgType().isWarnMsg()) {
view.setYellow();
}
......@@ -84,4 +98,23 @@ public class ActionScenarioChecker extends AbstractAction implements Observer {
}
}
}
private void run_check(final Scenario scenario) {
ScenarioChecker checker = new ScenarioChecker(scenario);
messages.clear();
ScenarioPanel.setActiveTopographyErrorMsg(null);
messages = checker.checkBuildingStep();
msgDocument = new ScenarioCheckerMessageDocumentView(model);
msgDocument.setMessages(messages);
}
public static void performManualCheck(final Scenario scenario) {
ActionScenarioChecker action = new ActionScenarioChecker("", null);
action.run_check(scenario);
if (!action.messages.isEmpty() && action.messages.peek().getMsgType().isErrorMsg()) {
ScenarioPanel.setActiveTopographyErrorMsg(action.msgDocument);
} else {
ScenarioPanel.setActiveTopographyErrorMsg(null);
}
}
}
package org.vadere.gui.projectview.control;
import javax.swing.*;
import org.vadere.gui.projectview.model.ProjectViewModel;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ActionRunAllScenarios extends AbstractAction {
private final ProjectViewModel model;
......@@ -17,7 +17,7 @@ public class ActionRunAllScenarios extends AbstractAction {
@Override
public void actionPerformed(final ActionEvent e) {
if (model.runScenarioIsOk())
if (model.runScenarioIsOk(true))
model.getProject().runAllScenarios();
}
}
package org.vadere.gui.projectview.control;
import org.vadere.gui.components.control.ActionScenarioChecker;
import org.vadere.gui.projectview.model.ProjectViewModel;
import org.vadere.gui.projectview.view.VDialogManager;
import org.vadere.util.config.VadereConfig;
import org.vadere.util.logging.Logger;
import java.awt.event.ActionEvent;
......@@ -23,6 +25,10 @@ public class ActionSaveProject extends ActionAbstractSaveProject {
return;
}
try {
if (!VadereConfig.getConfig().getBoolean("Project.ScenarioChecker.active")) {
// run ScenarioChecker at least once before saving changes.
ActionScenarioChecker.performManualCheck(model.getCurrentScenario());
}
if (VDialogManager.continueSavingDespitePossibleJsonError())
saveProjectUnlessUserCancels(model);
} catch (IOException e) {
......
package org.vadere.gui.projectview.control;
import org.vadere.gui.projectview.VadereApplication;
import org.vadere.gui.projectview.model.ProjectViewModel;
import org.vadere.util.config.VadereConfig;
import java.awt.event.ActionEvent;
import java.util.prefs.Preferences;
import javax.swing.*;
......@@ -18,6 +16,7 @@ public class ShowResultDialogAction extends AbstractAction {
super(name);
this.model = model;
this.item = item;
this.item.setState(VadereConfig.getConfig().getBoolean("Project.simulationResult.show"));
}
@Override
......
package org.vadere.gui.projectview.control;
import org.vadere.gui.projectview.model.ProjectViewModel;
import org.vadere.util.config.VadereConfig;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ToggleScenarioManagerAction extends AbstractAction {
ProjectViewModel model;
JCheckBoxMenuItem item;
public ToggleScenarioManagerAction(final String name, final ProjectViewModel model, JCheckBoxMenuItem item) {
super(name);
this.model = model;
this.item = item;
this.item.setState(VadereConfig.getConfig().getBoolean("Project.ScenarioChecker.active"));
}
@Override
public void actionPerformed(ActionEvent e) {
VadereConfig.getConfig().setProperty("Project.ScenarioChecker.active", item.getState());
}
}
......@@ -2,10 +2,15 @@ package org.vadere.gui.projectview.model;
import org.jetbrains.annotations.NotNull;
import org.vadere.gui.components.control.ActionScenarioChecker;
import org.vadere.gui.components.utils.Messages;
import org.vadere.gui.projectview.control.IOutputFileRefreshListener;
import org.vadere.gui.projectview.control.IProjectChangeListener;
import org.vadere.gui.projectview.view.*;
import org.vadere.gui.projectview.view.ProjectView;
import org.vadere.gui.projectview.view.ScenarioNamePanel;
import org.vadere.gui.projectview.view.ScenarioPanel;
import org.vadere.gui.projectview.view.VDialogManager;
import org.vadere.gui.projectview.view.VTable;
import org.vadere.gui.topographycreator.model.IDrawPanelModel;
import org.vadere.simulator.projects.ProjectWriter;
import org.vadere.simulator.projects.Scenario;
......@@ -14,7 +19,6 @@ import org.vadere.simulator.projects.io.IOOutput;
import org.vadere.util.config.VadereConfig;
import org.vadere.util.logging.Logger;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
......@@ -23,11 +27,12 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import javax.swing.*;
public class ProjectViewModel implements IScenarioChecker {
private static Logger logger = Logger.getLogger(ProjectViewModel.class);
......@@ -36,7 +41,7 @@ public class ProjectViewModel implements IScenarioChecker {
private final OutputFileTableModel outputTableModel;
private final VadereScenarioTableModel scenarioTableModel;
// private String currentProjectPath;
// private String currentProjectPath;
private ExecutorService refreshOutputExecutor;
......@@ -46,7 +51,6 @@ public class ProjectViewModel implements IScenarioChecker {
private final Collection<IOutputFileRefreshListener> outputRefreshListeners;
private final Collection<IProjectChangeListener> projectChangeListeners;
private List<IScenarioChecker> scenarioCheckerListeners;
private ScenarioNamePanel scenarioNamePanel; // to add or remove the "*" to indicate unsaved changes and ScenarioChecker indicator
private boolean showSimulationResultDialog;
......@@ -59,16 +63,15 @@ public class ProjectViewModel implements IScenarioChecker {
this.refreshOutputExecutor = Executors.newSingleThreadExecutor();
this.showSimulationResultDialog = VadereConfig.getConfig()
.getBoolean("Project.simulationResult.show", true);
this.scenarioCheckerListeners = new ArrayList<>();
}
public void deleteOutputFiles(final int[] rows) throws IOException {
// 1. delete output files on the hard disc
int j = 0;
for(int i = 0; i < rows.length; i++) {
File dir = getOutputTableModel().getValue(rows[i]-j);
for (int i = 0; i < rows.length; i++) {
File dir = getOutputTableModel().getValue(rows[i] - j);
if(IOOutput.deleteOutputDirectory(dir)) {
if (IOOutput.deleteOutputDirectory(dir)) {
j++;
// 2. remove output files information from the output file table
......@@ -77,7 +80,7 @@ public class ProjectViewModel implements IScenarioChecker {
// 3. remove output files information from the project output
getProject().getProjectOutput().removeOutputDir(dir.getName());
logger.info("output dir "+ dir +" dir deleted.");
logger.info("output dir " + dir + " dir deleted.");
}
}
}
......@@ -209,7 +212,7 @@ public class ProjectViewModel implements IScenarioChecker {
if (isProjectAvailable())
project.setProjectDirectory(Paths.get(currentProjectPath));
else
throw new IllegalStateException();
throw new IllegalStateException();
}
public OutputBundle getSelectedOutputBundle() throws IOException {
......@@ -247,8 +250,8 @@ public class ProjectViewModel implements IScenarioChecker {
public boolean isScenarioNameInConflict(final String name) {
return isProjectAvailable()
&& project.getScenarios().stream()
.filter(scenario -> scenario.getName().equals(name))
.findAny().isPresent();
.filter(scenario -> scenario.getName().equals(name))
.findAny().isPresent();
}
public boolean getShowSimulationResultDialog() {
......@@ -303,7 +306,7 @@ public class ProjectViewModel implements IScenarioChecker {
private final Collection<String> outputDirectories;
public ScenarioBundle(final VadereProject project, final Scenario scenarioRM,
final Collection<String> outputDirectories) {
final Collection<String> outputDirectories) {
this.project = project;
this.scenarioRM = scenarioRM;
this.outputDirectories = outputDirectories;
......@@ -328,7 +331,7 @@ public class ProjectViewModel implements IScenarioChecker {
private final Collection<File> outputDirectories;
public OutputBundle(final File directory, final VadereProject project,
final Collection<File> outputDirectories) {
final Collection<File> outputDirectories) {
this.directory = directory;
this.project = project;
this.outputDirectories = outputDirectories;
......@@ -346,7 +349,7 @@ public class ProjectViewModel implements IScenarioChecker {
return outputDirectories;
}
public Scenario getScenarioRM(){
public Scenario getScenarioRM() {
return project.getProjectOutput().getScenario(directory.getName());
}
}
......@@ -363,24 +366,42 @@ public class ProjectViewModel implements IScenarioChecker {
}
/**
* Set selection in scenario JTable. Why in this class? It is GUI stuff!
* Because some Actions have use this method and Actions only have access to the model.
* "actions only access the model" -- that seems pretty idealistic. We already break this
* concept by using ProjectView's getMainWindow().
* Set selection in scenario JTable. Why in this class? It is GUI stuff! Because some Actions
* have use this method and Actions only have access to the model. "actions only access the
* model" -- that seems pretty idealistic. We already break this concept by using ProjectView's
* getMainWindow().
*/
public void setSelectedRowIndexInScenarioTable(final int rowIndex) {
if (scenarioTable.getRowCount() > 0)
scenarioTable.getSelectionModel().setSelectionInterval(rowIndex, rowIndex);
}
/** Set selection in scenario JTable. */
/**
* Set selection in scenario JTable.
*/
public void selectScenario(Scenario scenarioRM) {
int i = scenarioTableModel.indexOfRow(scenarioRM);
setSelectedRowIndexInScenarioTable(i);
}
public boolean runScenarioIsOk() {
for (Scenario srm : getScenarios(scenarioTable.getSelectedRows())) {
return runScenarioIsOk(false);
}
public boolean runScenarioIsOk(boolean checkAll) {
List<Scenario> scenariosToCheck = new ArrayList<>();
if (checkAll) {
scenariosToCheck = Arrays.asList(getProject().getScenarios().toArray(Scenario[]::new));
} else {
scenariosToCheck.add(getCurrentScenario());
}
if (scenariosToCheck.size() < 1) {
throw new IllegalArgumentException("runScenarioIsOk expected at least one scenario");
}
for (Scenario srm : scenariosToCheck) {
String response = srm.readyToRunResponse();
if (response != null) {
VDialogManager.showMessageDialogWithBodyAndTextArea("Error",
......@@ -399,13 +420,21 @@ public class ProjectViewModel implements IScenarioChecker {
return false;
}
JEditorPane errorPanel = ScenarioPanel.getActiveTopographyErrorMsg();
if (errorPanel != null) {
VDialogManager.showMessageDialogWithBodyAndTextEditorPane(
Messages.getString("RunScenarioTopographyCheckerErrors.title"),
Messages.getString("RunScenarioTopographyCheckerErrors.text"),
errorPanel, JOptionPane.ERROR_MESSAGE);
return false;
JEditorPane errorPanel = null;
for (Scenario s : scenariosToCheck) {
// always rerun the ScenarioChecker before running any simulations. This ensures
// that all scenarios which will be run are checked before any Scenario is stared
// to allow fixing any errors.
// This check will be executed even if the ScnearioChecker is deactivated in the GUI.
ActionScenarioChecker.performManualCheck(s);
errorPanel = ScenarioPanel.getActiveTopographyErrorMsg();
if (errorPanel != null) {
VDialogManager.showMessageDialogWithBodyAndTextEditorPane(
Messages.getString("RunScenarioTopographyCheckerErrors.title"),
Messages.getString("RunScenarioTopographyCheckerErrors.text"),
errorPanel, JOptionPane.ERROR_MESSAGE);
return false;
}
}
return true;
......@@ -434,15 +463,15 @@ public class ProjectViewModel implements IScenarioChecker {
this.showSimulationResultDialog = showSimulationResultDialog;
}
public void scenarioCheckerStopObserve(){
public void scenarioCheckerStopObserve() {
scenarioNamePanel.stopObserver();
}
public void scenarioCheckerStartObserve(IDrawPanelModel model){
public void scenarioCheckerStartObserve(IDrawPanelModel model) {
scenarioNamePanel.observerIDrawPanelModel(model);
}
public void scenarioCheckerCheck(final Scenario scenario){
public void scenarioCheckerCheck(final Scenario scenario) {
scenarioNamePanel.check(scenario);
}
......
......@@ -34,6 +34,7 @@ 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.control.ToggleScenarioManagerAction;
import org.vadere.gui.projectview.model.ProjectViewModel;
import org.vadere.gui.projectview.model.ProjectViewModel.OutputBundle;
import org.vadere.gui.projectview.model.ProjectViewModel.ScenarioBundle;
......@@ -59,7 +60,6 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
......@@ -73,8 +73,6 @@ import javax.swing.plaf.basic.BasicSplitPaneUI;
/**
* Main view of the Vadere GUI.
*
*
*/
public class ProjectView extends JFrame implements ProjectFinishedListener, SingleScenarioFinishedListener,
IOutputFileRefreshListener, IProjectChangeListener {
......@@ -83,7 +81,9 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
*/
private static final long serialVersionUID = -2081363246241235943L;
private static Logger logger = Logger.getLogger(ProjectView.class);
/** Store a reference to the main window as "owner" parameter for dialogs. */
/**
* Store a reference to the main window as "owner" parameter for dialogs.
*/
private static ProjectView mainWindow;
/**
......@@ -93,10 +93,10 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
/**
* GUI elements (part of the view) of the {@link ProjectView}
*
* TODO [priority=medium] [task=refactoring] do the actions have to be stored in member variables
* or could it be better to store them locally where they are needed?
* Some are used in different methods, maybe only store these as members?
*
* TODO [priority=medium] [task=refactoring] do the actions have to be stored in member
* variables or could it be better to store them locally where they are needed? Some are used in
* different methods, maybe only store these as members?
*/
private JPanel contentPane = new JPanel();
private JPanel controlPanel = new JPanel();
......@@ -134,7 +134,7 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
private void selectCurrentScenarioRunManager() {
int index = model.getProject().getScenarioIndexByName(model.getProject().getCurrentScenario());
if(index != -1) {
if (index != -1) {
scenarioTable.setRowSelectionInterval(index, index);
}
}
......@@ -283,7 +283,7 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
private static void checkDependencies(@NotNull final JFrame frame) {
try {
if(!CLUtils.isOpenCLSupported()) {
if (!CLUtils.isOpenCLSupported()) {
JOptionPane.showMessageDialog(frame,
Messages.getString("ProjectView.warning.opencl.text"),
Messages.getString("ProjectView.warning.opencl.title"),
......@@ -378,16 +378,16 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
}
private void buildKeyboardShortcuts(ActionPauseScenario pauseScenarioAction, Action interruptScenariosAction) {
addKeyboardShortcut("SPACE", "Typed Space", btnPauseRunningScenarios.getAction());
addKeyboardShortcut("BACK_SPACE", "Typed Backspace", btnStopRunningScenarios.getAction());
addKeyboardShortcut("SPACE", "Typed Space", btnPauseRunningScenarios.getAction());
addKeyboardShortcut("BACK_SPACE", "Typed Backspace", btnStopRunningScenarios.getAction());
}
private void addKeyboardShortcut(String key, String actionKey, Action action) {
controlPanel.getInputMap().put(KeyStroke.getKeyStroke(key), actionKey);
controlPanel.getActionMap().put(actionKey, action);
}
private void addKeyboardShortcut(String key, String actionKey, Action action) {
controlPanel.getInputMap().put(KeyStroke.getKeyStroke(key), actionKey);
controlPanel.getActionMap().put(actionKey, action);
}
private void buildMenuBar(ActionCloseApplication closeApplicationAction, ActionAddScenario addScenarioAction) {
private void buildMenuBar(ActionCloseApplication closeApplicationAction, ActionAddScenario addScenarioAction) {
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
......@@ -442,6 +442,13 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
showResultDialogMenu.setAction(showResultDialogMenuAction);
mnFile.add(showResultDialogMenu);
// Checkbox menu item to turn off Scenario Checker during topography creation
JCheckBoxMenuItem toggleScenarioCheckerDialogMenu = new JCheckBoxMenuItem(Messages.getString("ProjectView.btnToggleScenarioChecker.text"), null, model.getShowSimulationResultDialog());
Action toggleScenarioCheckerMenuAction = new ToggleScenarioManagerAction(Messages.getString("ProjectView.btnToggleScenarioChecker.text"), model, toggleScenarioCheckerDialogMenu);
toggleScenarioCheckerDialogMenu.setAction(toggleScenarioCheckerMenuAction);
mnFile.add(toggleScenarioCheckerDialogMenu);
JMenuItem mntmExit = new JMenuItem(closeApplicationAction);
mnFile.addSeparator();
mnFile.add(mntmExit);
......@@ -474,6 +481,7 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
JRadioButtonMenuItem mntmEnglishLocale =
new JRadioButtonMenuItem(new AbstractAction(Messages.getString("ProjectView.mntmEnglishLocale.text")) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
Messages.changeLanguage(Locale.ENGLISH);
......@@ -483,6 +491,7 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing
JRadioButtonMenuItem mntmGermanLocale =
new JRadioButtonMenuItem(new AbstractAction(Messages.getString("ProjectView.mntmGermanLocale.text")) {
private static final long serialVersionUID = 1L;
@Override