package nl.fontys.sofa.limo.view.node.property.editor;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyEditorSupport;
import java.util.Arrays;
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.procedure.value.RangeValue;
import nl.fontys.sofa.limo.domain.component.procedure.value.SingleValue;
import nl.fontys.sofa.limo.domain.component.procedure.value.Value;
import nl.fontys.sofa.limo.view.util.LIMOResourceBundle;
import org.openide.nodes.PropertyEditorRegistration;
/**
* This class implements property editor for procedures.
*
* @author Christia Neumann
*/
@PropertyEditorRegistration(targetType = Value.class)
public class ValuePropertyEditor extends PropertyEditorSupport {
@Override
public String getAsText() {
Value value = (Value) getValue();
return value.getValue() + " - " + value.getMin() + " - " + value.getMax();
}
@Override
public Component getCustomEditor() {
final ValueEditor val = new ValueEditor((Value) getValue());
val.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
// Only save if wanted
if (val.shouldSafe) {
setValue(val.procedureValue);
}
}
});
return val;
}
@Override
public boolean supportsCustomEditor() {
return true;
}
/**
* Custom location editor.
*/
private static class ValueEditor extends JDialog implements ActionListener {
private Value procedureValue;
private boolean shouldSafe;
private JButton btnOk;
private JButton btnCancel;
private JComboBox<String> comboboxValueTypes;
private JTextField textfieldValue, textfieldMin, textfieldMax;
private JPanel singlePanel, rangePanel;
private JLabel labelType, labelValue, labelMin, lableMax, labelError;
private int activeType = 0;
private final CellConstraints cc;
/**
* Create location editor and init UI.
*
* @param hubLocation Old location.
*/
public ValueEditor(Value procedureValue) {
this.procedureValue = procedureValue;
cc = new CellConstraints();
this.shouldSafe = false;
setModal(true);
setPreferredSize(new Dimension(480, 240));
setTitle("Edit of Value");
initComponents();
setLocationRelativeTo(null);
}
/**
* Get updated location.
*
* @return Location.
*/
public Value getProcedureValue() {
return procedureValue;
}
/**
* Should the new location be saved or not.
*
* @return Save true/false.
*/
public boolean isShouldSafe() {
return shouldSafe;
}
/**
* Initialize UI.
*/
public final void initComponents() {
textfieldValue = new JTextField();
textfieldMin = new JTextField();
textfieldMax = new JTextField();
singlePanel = new JPanel();
rangePanel = new JPanel();
labelType = new JLabel(LIMOResourceBundle.getString("TYPE"));
labelValue = new JLabel(LIMOResourceBundle.getString("VALUE"));
labelMin = new JLabel(LIMOResourceBundle.getString("MIN"));
lableMax = new JLabel(LIMOResourceBundle.getString("MAX"));
labelError = new JLabel();
labelError.setForeground(Color.RED);
btnCancel = new JButton(LIMOResourceBundle.getString("CANCEL"));
btnOk = new JButton(LIMOResourceBundle.getString("SAVE"));
comboboxValueTypes = new JComboBox<>(new String[]{LIMOResourceBundle.getString("SINGLE"), LIMOResourceBundle.getString("RANGE")});
FormLayout mainLayout = new FormLayout("5px, pref, 5px, pref, 5px, pref:grow, 5px",
"5px, pref, 5px, pref, 5px, pref, 5px, pref, 5px");
FormLayout rangeLayout = new FormLayout("5px, pref, 5px, pref:grow, 5px", "5px, pref, 5px, pref, 5px");
FormLayout singleLayout = new FormLayout("5px, pref, 5px, pref:grow, 5px", "5px, pref, 5px");
this.setLayout(mainLayout);
//ADD COMPONENTS TO SINGLE PANEL
singlePanel.setLayout(singleLayout);
singlePanel.add(labelValue, cc.xy(2, 2));
singlePanel.add(textfieldValue, cc.xy(4, 2));
//ADD COMPONENTS TO RANGE PANEL
rangePanel.setLayout(rangeLayout);
rangePanel.add(labelMin, cc.xy(2, 2));
rangePanel.add(textfieldMin, cc.xy(4, 2));
rangePanel.add(lableMax, cc.xy(2, 4));
rangePanel.add(textfieldMax, cc.xy(4, 4));
//ADD COMPONENTS TO DIALOG
addComponentsToDialog(procedureValue);
//ADD COMPONENTS TO LISTENER
btnCancel.addActionListener(this);
btnOk.addActionListener(this);
comboboxValueTypes.addActionListener(this);
//DIALOG OPTIONS
this.setModal(true);
this.setSize(300, 350);
this.setAlwaysOnTop(true);
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screenSize = toolkit.getScreenSize();
int x = (screenSize.width - this.getWidth()) / 2;
int y = (screenSize.height - this.getHeight()) / 2;
this.setLocation(x, y);
}
/**
* Adds the components to the dialog.
*
* @param value The value that has to be used.
*/
private void addComponentsToDialog(Value value) {
this.add(labelType, cc.xy(2, 2));
this.add(comboboxValueTypes, cc.xyw(4, 2, 3));
if (value != null) {
if (value instanceof SingleValue) {
this.add(singlePanel, cc.xyw(2, 4, 5));
comboboxValueTypes.setSelectedIndex(0);
textfieldValue.setText(value.getValue() + "");
activeType = 0;
} else {
this.add(rangePanel, cc.xyw(2, 4, 5));
comboboxValueTypes.setSelectedIndex(1);
textfieldMin.setText(value.getMin() + "");
textfieldMax.setText(value.getMax() + "");
activeType = 1;
}
} else {
this.add(singlePanel, cc.xyw(2, 4, 5));
comboboxValueTypes.setSelectedIndex(0);
activeType = 0;
}
this.add(btnOk, cc.xy(2, 6));
this.add(btnCancel, cc.xy(4, 6));
this.add(labelError, cc.xyw(2, 8, 5));
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(comboboxValueTypes)) {
actionCombobox();
}
if (e.getSource().equals(btnCancel)) {
this.dispose();
}
if (e.getSource().equals(btnOk)) {
System.out.println("Save");
actionSave();
}
}
/**
* The action that has to happen when the ActionListener registrated an
* action in the Combobox. It sets the field to either a Single or Range
* Value. It uses the Min value as value when switching from range to single
* and the value as Min when switching from single to range value.
*/
private void actionCombobox() {
if (activeType != comboboxValueTypes.getSelectedIndex()) {
double activeValue = 0;
if (activeType == 0) {
try {
activeValue = Double.parseDouble(textfieldValue.getText());
} catch (NumberFormatException ex) {
System.out.println(Arrays.toString(ex.getStackTrace()));
}
this.remove(singlePanel);
this.add(rangePanel, cc.xyw(2, 4, 5));
textfieldMin.setText(activeValue + "");
} else {
try {
activeValue = Double.parseDouble(textfieldMin.getText());
} catch (NumberFormatException ex) {
System.out.println(Arrays.toString(ex.getStackTrace()));
}
this.remove(rangePanel);
this.add(singlePanel, cc.xyw(2, 4, 5));
textfieldValue.setText(activeValue + "");
}
labelError.setText("");
activeType = comboboxValueTypes.getSelectedIndex();
this.revalidate();
this.repaint();
}
}
/**
* The action that happens when the save-button was pressed. Tries to parse
* the textfields to Double values. If it works it gets saved in the given
* DialogListener. Sets the error label otherwise.
*/
private void actionSave() {
shouldSafe = true;
if (activeType == 0) {
try {
SingleValue changedValue = new SingleValue(Double.parseDouble(textfieldValue.getText()));
procedureValue = changedValue;
} catch (NumberFormatException ex) {
labelError.setText(LIMOResourceBundle.getString("NOT_A_NUMBER"));
}
} else {
try {
double min = Double.parseDouble(textfieldMin.getText());
double max = Double.parseDouble(textfieldMax.getText());
if (max > min) {
RangeValue changedValue = new RangeValue(min, max);
procedureValue = changedValue;
} else {
labelError.setText(LIMOResourceBundle.getString("MAX_BIGGER_MIN"));
}
} catch (NumberFormatException ex) {
labelError.setText(LIMOResourceBundle.getString("NOT_A_NUMBER"));
}
}
for (WindowListener wl : getWindowListeners()) {
wl.windowClosing(null);
}
// Close window
setVisible(false);
dispose();
}
}
}