package edu.kit.pse.ws2013.routekit.views;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import edu.kit.pse.ws2013.routekit.controllers.ProfileManagerController;
import edu.kit.pse.ws2013.routekit.models.ProgressReporter;
import edu.kit.pse.ws2013.routekit.profiles.Profile;
import edu.kit.pse.ws2013.routekit.profiles.VehicleType;
import edu.kit.pse.ws2013.routekit.util.TimeUtil;
/**
* Displays the window of the profile management on the screen.
*/
public class ProfileManagerView extends JDialog {
private static final long serialVersionUID = 1L;
private JComboBox<String> profilename;
private JRadioButton bus;
private JRadioButton motorcycle;
private JRadioButton truck;
private JRadioButton car;
private JSpinner hSpeedspinner;
private JSpinner srSpeedspinner;
private JSpinner heightspinner;
private JSpinner widthspinner;
private JSpinner weightspinner;
private JButton deleteButton;
private int listenerCheck = 0;
private Profile currentProfile;
private Set<Profile> availableProfiles;
private ProfileManagerController pmc;
private final KeyListener escEnterListener = new KeyAdapter() {
@Override
public void keyPressed(java.awt.event.KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_ENTER:
ok();
break;
case KeyEvent.VK_ESCAPE:
cancel();
break;
}
};
};
/**
* A constructor that creates a new ProfileManagerView.
* <p>
* This constructor does <i>not</i> call {@link #setVisible(boolean)
* setVisible(true)}, i. e. it doesn’t block.
*/
public ProfileManagerView(Window parent, ProfileManagerController pmc,
Profile currentProfile, Set<Profile> availableProfiles) {
super(parent, "Profilverwaltung", ModalityType.APPLICATION_MODAL);
this.currentProfile = currentProfile;
this.availableProfiles = availableProfiles;
this.pmc = pmc;
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setSize(600, 400);
setLocationRelativeTo(getParent());
setResizable(false);
JPanel contentPane = new JPanel(new BorderLayout());
JPanel north = initNorthPane();
JPanel center = initCenterPane();
JPanel south = initSouthPane();
contentPane.add(north, BorderLayout.NORTH);
contentPane.add(south, BorderLayout.SOUTH);
contentPane.add(center, BorderLayout.CENTER);
addKeyListener(escEnterListener);
setContentPane(contentPane);
setAvailableProfiles(availableProfiles);
setCurrentProfile(currentProfile);
}
private JPanel initNorthPane() {
JPanel north = new JPanel(new FlowLayout());
north.setBackground(Color.WHITE);
JLabel profile = new JLabel("Profil auswählen:");
profilename = new JComboBox<String>();
profilename.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (listenerCheck == 0) {
if (profilename.getSelectedItem() == null) {
return;
} else {
if (!currentProfile.isDefault()) {
Profile current = writeValues(currentProfile
.getName());
pmc.saveTemporaryProfile(current);
}
currentProfile = findProfile((String) profilename
.getSelectedItem());
if (currentProfile == null) {
throw new IllegalArgumentException(
"The current profile is null!");
}
pmc.changeTemporaryProfile(currentProfile.getName());
}
}
}
});
profilename.addKeyListener(escEnterListener);
profilename.setMinimumSize(new Dimension(250, 26));
profilename.setPreferredSize(new Dimension(250, 26));
north.add(profile);
north.add(profilename);
deleteButton = new JButton("Löschen");
deleteButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
pmc.deleteCurrentTemporaryProfile();
}
});
north.add(deleteButton);
JButton neuButton = new JButton("Neu");
neuButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
do {
String result = (String) JOptionPane.showInputDialog(
ProfileManagerView.this,
"Geben Sie einen Namen für das neue Profil ein:",
"Name", JOptionPane.QUESTION_MESSAGE, null, null,
null);
if (result == null || result.isEmpty()) {
return;
}
if (!currentProfile.isDefault()) {
Profile current = writeValues(currentProfile.getName());
pmc.saveTemporaryProfile(current);
}
try {
pmc.changeTemporaryProfile(result);
currentProfile = findProfile(result);
if (currentProfile == null) {
throw new IllegalArgumentException(
"The current profile is null!");
}
break;
} catch (IllegalArgumentException ex) {
JOptionPane
.showMessageDialog(
ProfileManagerView.this,
"Ungültiger Name – bitte geben Sie einen anderen Namen ein.",
"Fehler", JOptionPane.ERROR_MESSAGE);
continue;
}
} while (true);
}
});
north.add(neuButton);
return north;
}
private Profile findProfile(String name) {
for (Profile p : availableProfiles) {
if (p.getName().equals(name)) {
return p;
}
}
return null;
}
private Profile writeValues(String currentProfileName) {
Profile current = new Profile(currentProfileName, selectedButton(),
(int) heightspinner.getValue(), (int) widthspinner.getValue(),
(int) weightspinner.getValue(), (int) hSpeedspinner.getValue(),
(int) srSpeedspinner.getValue());
return current;
}
private VehicleType selectedButton() {
if (car.isSelected()) {
return VehicleType.Car;
}
if (bus.isSelected()) {
return VehicleType.Bus;
}
if (truck.isSelected()) {
return VehicleType.Truck;
}
return VehicleType.Motorcycle;
}
private JPanel initSouthPane() {
JPanel south = new JPanel(new GridLayout(1, 2));
south.setBackground(Color.WHITE);
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10));
buttons.setBackground(Color.WHITE);
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ok();
}
});
okButton.addKeyListener(escEnterListener);
buttons.add(okButton);
JButton cancel = new JButton("Abbrechen");
cancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cancel();
}
});
buttons.add(cancel);
south.add(buttons);
return south;
}
private JPanel initCenterPane() {
JPanel center = new JPanel(new BorderLayout());
JPanel type = innerTypePane();
JPanel dimensions = innerDimentionsPane();
JPanel velocity = innerVelocityPane();
type.addKeyListener(escEnterListener);
dimensions.addKeyListener(escEnterListener);
velocity.addKeyListener(escEnterListener);
center.add(type, BorderLayout.NORTH);
center.add(dimensions, BorderLayout.CENTER);
center.add(velocity, BorderLayout.SOUTH);
return center;
}
private JPanel innerTypePane() {
JPanel type = new JPanel(new FlowLayout());
type.setBackground(Color.WHITE);
JLabel vehicleType = new JLabel("Fahrzeugtyp:");
car = new JRadioButton("PKW");
car.setBackground(Color.WHITE);
truck = new JRadioButton("LKW");
truck.setBackground(Color.WHITE);
bus = new JRadioButton("Bus");
bus.setBackground(Color.WHITE);
motorcycle = new JRadioButton("Motorrad");
motorcycle.setBackground(Color.WHITE);
type.add(vehicleType);
type.add(car);
type.add(truck);
type.add(bus);
type.add(motorcycle);
ButtonGroup group = new ButtonGroup();
group.add(car);
group.add(truck);
group.add(bus);
group.add(motorcycle);
return type;
}
private JPanel innerDimentionsPane() {
JPanel dimentions = new JPanel(new GridLayout(4, 1));
dimentions.setBackground(Color.WHITE);
JPanel height = innerHeightPane();
JPanel width = innerWidthPane();
JPanel weight = innerWeightPane();
height.addKeyListener(escEnterListener);
width.addKeyListener(escEnterListener);
weight.addKeyListener(escEnterListener);
dimentions.add(height);
dimentions.add(width);
dimentions.add(weight);
return dimentions;
}
private JPanel innerVelocityPane() {
JPanel velocity = new JPanel(new GridLayout(3, 1));
velocity.setBackground(Color.WHITE);
JPanel highway = innerHighwayPane();
JPanel secondaryRoad = innerSecondaryRoadPane();
highway.addKeyListener(escEnterListener);
secondaryRoad.addKeyListener(escEnterListener);
velocity.add(highway);
velocity.add(secondaryRoad);
return velocity;
}
private JPanel innerHighwayPane() {
JPanel highway = new JPanel(new FlowLayout(FlowLayout.LEFT, 15, 5));
highway.setBackground(Color.WHITE);
JLabel highwaySpeed = new JLabel(
"Durchschnittsgeschwindigkeit auf der Autobahn:");
hSpeedspinner = new JSpinner(new SpinnerNumberModel(60, 60, 300, 5));
hSpeedspinner.setPreferredSize(new Dimension(50, 20));
hSpeedspinner.addKeyListener(escEnterListener);
JLabel kmPerh = new JLabel("km/h");
highway.add(highwaySpeed);
highway.add(hSpeedspinner);
highway.add(kmPerh);
return highway;
}
private JPanel innerSecondaryRoadPane() {
JPanel secondaryRoad = new JPanel(
new FlowLayout(FlowLayout.LEFT, 15, 5));
secondaryRoad.setBackground(Color.WHITE);
JLabel secondaryRoadSpeed = new JLabel(
"Durchschnittsgeschwindigkeit auf der Landstraße:");
srSpeedspinner = new JSpinner(new SpinnerNumberModel(50, 30, 150, 5));
srSpeedspinner.setPreferredSize(new Dimension(50, 20));
srSpeedspinner.addKeyListener(escEnterListener);
JLabel kmPerh = new JLabel("km/h");
secondaryRoad.add(secondaryRoadSpeed);
secondaryRoad.add(srSpeedspinner);
secondaryRoad.add(kmPerh);
return secondaryRoad;
}
private JPanel innerHeightPane() {
JPanel height = new JPanel(new FlowLayout(FlowLayout.LEFT, 15, 5));
height.setBackground(Color.WHITE);
JLabel vehicleHeight = new JLabel("Höhe des Fahrzeugs:");
heightspinner = new JSpinner(new SpinnerNumberModel(100, 100, 400, 10));
heightspinner.setPreferredSize(new Dimension(50, 20));
heightspinner.addKeyListener(escEnterListener);
JLabel cm = new JLabel("cm");
height.add(vehicleHeight);
height.add(heightspinner);
height.add(cm);
return height;
}
private JPanel innerWidthPane() {
JPanel width = new JPanel(new FlowLayout(FlowLayout.LEFT, 15, 5));
width.setBackground(Color.WHITE);
JLabel vehicleWidth = new JLabel("Breite des Fahrzeugs:");
widthspinner = new JSpinner(new SpinnerNumberModel(150, 80, 300, 10));
widthspinner.setPreferredSize(new Dimension(50, 20));
widthspinner.addKeyListener(escEnterListener);
JLabel cm = new JLabel("cm");
width.add(vehicleWidth);
width.add(widthspinner);
width.add(cm);
return width;
}
private JPanel innerWeightPane() {
JPanel weight = new JPanel(new FlowLayout(FlowLayout.LEFT, 15, 5));
weight.setBackground(Color.WHITE);
JLabel vehicleWeight = new JLabel("Gewicht des Fahrzeugs:");
weightspinner = new JSpinner(new SpinnerNumberModel(1500, 50, 50000,
100));
weightspinner.setPreferredSize(new Dimension(70, 20));
weightspinner.addKeyListener(escEnterListener);
JLabel kg = new JLabel("kg");
weight.add(vehicleWeight);
weight.add(weightspinner);
weight.add(kg);
return weight;
}
/**
* Sets the current profile to the specified profile, loads its values in
* the input fields, enables / disables the input elements and the
* „Löschen“-Button depending on whether it is a default profile or not.
*
* @param profile
* The new Profile.
*/
public void setCurrentProfile(Profile profile) {
currentProfile = profile;
listenerCheck++;
switch (profile.getVehicleType()) {
case Bus:
bus.setSelected(true);
break;
case Car:
car.setSelected(true);
break;
case Truck:
truck.setSelected(true);
break;
case Motorcycle:
motorcycle.setSelected(true);
break;
default:
break;
}
hSpeedspinner.setValue(profile.getSpeedHighway());
heightspinner.setValue(profile.getHeight());
srSpeedspinner.setValue(profile.getSpeedRoad());
widthspinner.setValue(profile.getWidth());
weightspinner.setValue(profile.getWeight());
profilename.setSelectedItem(profile.getName());
if (profile.isDefault()) {
deleteButton.setEnabled(false);
bus.setEnabled(false);
car.setEnabled(false);
truck.setEnabled(false);
motorcycle.setEnabled(false);
heightspinner.setEnabled(false);
hSpeedspinner.setEnabled(false);
weightspinner.setEnabled(false);
widthspinner.setEnabled(false);
srSpeedspinner.setEnabled(false);
} else {
deleteButton.setEnabled(true);
bus.setEnabled(true);
car.setEnabled(true);
truck.setEnabled(true);
motorcycle.setEnabled(true);
heightspinner.setEnabled(true);
hSpeedspinner.setEnabled(true);
weightspinner.setEnabled(true);
widthspinner.setEnabled(true);
srSpeedspinner.setEnabled(true);
}
listenerCheck--;
}
/**
* Sets the profiles that can be currently selected.
*
* @param profiles
* The available profiles.
*/
public void setAvailableProfiles(Set<Profile> profiles) {
listenerCheck++;
profilename.removeAllItems();
List<Profile> sortedProfiles = new ArrayList<>(profiles);
Collections.sort(sortedProfiles, new Comparator<Profile>() {
@Override
public int compare(Profile o1, Profile o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (Profile p : sortedProfiles) {
profilename.addItem(p.getName());
}
availableProfiles = profiles;
listenerCheck--;
}
private void ok() {
if (!currentProfile.isDefault()) {
Profile current = writeValues(currentProfile.getName());
pmc.saveTemporaryProfile(current);
}
int time;
if ((time = pmc.getDeletionTime()) != 0) {
StringBuilder text = new StringBuilder();
text.append("Sie speichern hiermit alle\n");
text.append("vorgenommenen Änderungen für alle Profile.\n");
text.append("Sie löschen ");
TimeUtil.timeSpanString(text, time);
text.append(" an Arbeit.\n");
text.append("Wollen Sie die Änderungen vornehmen?");
int showOptionDialog = JOptionPane.showOptionDialog(
ProfileManagerView.this, text.toString(), "Bestätigung",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
null, new String[] { "Ja", "Nein" }, "Nein");
if (showOptionDialog != JOptionPane.YES_OPTION) {
return;
}
}
ProgressDialog p = new ProgressDialog(ProfileManagerView.this);
ProgressReporter reporter = new ProgressReporter();
reporter.addProgressListener(p);
reporter.pushTask("Speichere Änderungen");
pmc.saveAllChanges(reporter);
p.setVisible(true);
ProfileManagerView.this.dispose();
}
private void cancel() {
dispose();
}
}