package nl.fontys.sofa.limo.view.node.property.editor;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyEditorSupport;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import nl.fontys.sofa.limo.domain.component.hub.Continent;
import nl.fontys.sofa.limo.domain.component.hub.Location;
import nl.fontys.sofa.limo.domain.component.hub.SerializableCountry;
import nl.fontys.sofa.limo.view.util.LIMOResourceBundle;
import org.openide.nodes.PropertyEditorRegistration;
/**
* Property editor for the location object of hubs.
*
* @author Dominik Kaisers {@literal <d.kaisers@student.fontys.nl>}
*/
@PropertyEditorRegistration(targetType = Location.class)
public class LocationPropertyEditor extends PropertyEditorSupport {
@Override
public boolean supportsCustomEditor() {
return true;
}
@Override
public Component getCustomEditor() {
final LocationEditor loc = new LocationEditor((Location) getValue());
loc.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
// Only save if wanted
if (loc.shouldSafe) {
setValue(loc.hubLocation);
}
}
});
return loc;
}
@Override
public String getAsText() {
Location location = ((Location) getValue());
return location.getContinent()
+ (location.getCountry() == null ? "" : (" - " + location.getCountry()))
+ (location.getTown() == null ? "" : (" - " + location.getTown()));
}
/**
* Custom location editor.
*/
private static class LocationEditor extends JDialog implements ActionListener {
private Location hubLocation;
private boolean shouldSafe;
private JButton btnOk;
private JButton btnCancel;
private JComboBox cmbContinent;
private JComboBox cmbCountry;
private JTextField tfStreet;
private JTextField tfNumber;
private JTextField tfCity;
private JTextField tfZip;
private JTextField tfState;
private Map<String, SerializableCountry> countriesByName;
/**
* Create location editor and init UI.
*
* @param hubLocation Old location.
*/
public LocationEditor(Location hubLocation) {
this.hubLocation = hubLocation;
this.shouldSafe = false;
setModal(true);
setPreferredSize(new Dimension(480, 240));
setTitle(LIMOResourceBundle.getString("EDIT_OF", "Location"));
initComponents();
setLocationRelativeTo(null);
}
/**
* Get updated location.
*
* @return Location.
*/
public Location getHubLocation() {
return hubLocation;
}
/**
* Should the new location be saved or not.
*
* @return Save true/false.
*/
public boolean isShouldSafe() {
return shouldSafe;
}
/**
* Initialize UI.
*/
public final void initComponents() {
JPanel container = new JPanel();
container.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
setLayout(new BorderLayout());
add(container, BorderLayout.CENTER);
btnOk = new JButton(LIMOResourceBundle.getString("OK"));
btnOk.addActionListener(this);
btnCancel = new JButton(LIMOResourceBundle.getString("CANCEL"));
btnCancel.addActionListener(this);
JPanel buttonBar = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttonBar.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));
buttonBar.add(btnCancel);
buttonBar.add(btnOk);
cmbContinent = new JComboBox(Continent.values());
cmbContinent.setSelectedItem(hubLocation.getContinent());
cmbContinent.addItemListener(new ItemListener() {
private Continent oldContinent = null;
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.DESELECTED) {
oldContinent = (Continent) e.getItem();
} else {
if (!oldContinent.equals(e.getItem())) {
cmbCountry.setModel(new DefaultComboBoxModel(getCountries((Continent) e.getItem())));
cmbCountry.setSelectedIndex(0);
}
oldContinent = null;
}
}
});
cmbCountry = new JComboBox(getCountries(hubLocation.getContinent()));
if (hubLocation.getCountry() != null) {
cmbCountry.setSelectedItem(hubLocation.getCountry().getName());
} else {
cmbCountry.setSelectedIndex(0);
}
cmbCountry.addActionListener((ActionEvent e) -> {
boolean enable = cmbCountry.getSelectedIndex() > 0;
tfStreet.setEnabled(enable);
tfNumber.setEnabled(enable);
tfCity.setEnabled(enable);
tfZip.setEnabled(enable);
tfState.setEnabled(enable);
});
tfStreet = new JTextField(hubLocation.getStreet());
tfNumber = new JTextField(hubLocation.getHousenumber());
tfCity = new JTextField(hubLocation.getTown());
tfZip = new JTextField(hubLocation.getPostcode());
tfState = new JTextField(hubLocation.getState());
boolean enable = cmbCountry.getSelectedIndex() > 0;
tfStreet.setEnabled(enable);
tfNumber.setEnabled(enable);
tfCity.setEnabled(enable);
tfZip.setEnabled(enable);
tfState.setEnabled(enable);
//<editor-fold defaultstate="collapsed" desc="Layout">
container.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.weightx = 0.0;
container.add(new JLabel(LIMOResourceBundle.getString("CONTINENT")), c);
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 4;
c.weightx = 0.8;
container.add(cmbContinent, c);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 1;
c.weightx = 0.0;
container.add(new JLabel(LIMOResourceBundle.getString("COUNTRY")), c);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 4;
c.weightx = 0.8;
container.add(cmbCountry, c);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 1;
c.weightx = 0.0;
container.add(new JLabel(LIMOResourceBundle.getString("STREET")), c);
c.gridx = 1;
c.gridy = 2;
c.gridwidth = 2;
c.weightx = 0.4;
container.add(tfStreet, c);
c.gridx = 3;
c.gridy = 2;
c.gridwidth = 1;
c.weightx = 0.0;
container.add(new JLabel(LIMOResourceBundle.getString("NUMBER")), c);
c.gridx = 4;
c.gridy = 2;
c.gridwidth = 1;
c.weightx = 0.2;
container.add(tfNumber, c);
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 1;
c.weightx = 0.0;
container.add(new JLabel(LIMOResourceBundle.getString("CITY")), c);
c.gridx = 1;
c.gridy = 3;
c.gridwidth = 2;
c.weightx = 0.4;
container.add(tfCity, c);
c.gridx = 3;
c.gridy = 3;
c.gridwidth = 1;
c.weightx = 0.0;
container.add(new JLabel(LIMOResourceBundle.getString("ZIPCODE")), c);
c.gridx = 4;
c.gridy = 3;
c.gridwidth = 1;
c.weightx = 0.2;
container.add(tfZip, c);
c.gridx = 0;
c.gridy = 4;
c.gridwidth = 1;
c.weightx = 0.0;
container.add(new JLabel(LIMOResourceBundle.getString("STATE")), c);
c.gridx = 1;
c.gridy = 4;
c.gridwidth = 2;
c.weightx = 0.4;
container.add(tfState, c);
add(buttonBar, BorderLayout.SOUTH);
//</editor-fold>
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(btnOk)) {
// Only done when should save data
shouldSafe = true;
Location loc = new Location();
loc.setContinent((Continent) cmbContinent.getSelectedItem());
loc.setCountry(countriesByName.get((String) cmbCountry.getSelectedItem()));
if (cmbCountry.getSelectedIndex() > 0) {
loc.setStreet(tfStreet.getText());
loc.setHousenumber(tfNumber.getText());
loc.setTown(tfCity.getText());
loc.setPostcode(tfZip.getText());
loc.setState(tfState.getText());
}
hubLocation = loc;
}
// Notify listeners of window close event
for (WindowListener wl : getWindowListeners()) {
wl.windowClosing(null);
}
// Close window
setVisible(false);
dispose();
}
/**
* Get possible countries for given continent.
*
* @param continent Continent.
* @return List of countries for continent.
*/
private String[] getCountries(Continent continent) {
List<SerializableCountry> countryList = continent == null ? SerializableCountry.getAll() : continent.getCountries();
String[] countries = new String[countryList.size() + 1];
countries[0] = "";
countriesByName = new HashMap<>(countryList.size());
for (int i = 0; i < countryList.size(); i++) {
SerializableCountry country = countryList.get(i);
countries[i + 1] = country.getName();
countriesByName.put(country.getName(), country);
}
return countries;
}
}
}