/* IterationSetupDialog.java created 2007-12-05
*
*/
package org.signalml.app.method.iterate;
import static org.signalml.app.util.i18n.SvarogI18n._;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.GroupLayout.Alignment;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.signalml.app.method.ApplicationMethodDescriptor;
import org.signalml.app.method.ApplicationMethodManager;
import org.signalml.app.method.MethodConfigurer;
import org.signalml.app.model.components.validation.ValidationErrors;
import org.signalml.app.util.IconUtils;
import org.signalml.app.util.SwingUtils;
import org.signalml.app.view.common.components.ResolvableComboBox;
import org.signalml.app.view.common.dialogs.AbstractDialog;
import org.signalml.app.view.common.dialogs.errors.Dialogs;
import org.signalml.exception.SanityCheckException;
import org.signalml.method.iterator.IterableMethod;
import org.signalml.method.iterator.IterableNumericParameter;
import org.signalml.method.iterator.IterableParameter;
import org.signalml.method.iterator.MethodIteratorData;
import org.signalml.method.iterator.ParameterIterationSettings;
import org.signalml.plugin.export.SignalMLException;
import org.springframework.validation.Errors;
/** IterationSetupDialog
*
*
* @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o.
*/
public class IterationSetupDialog extends AbstractDialog {
private static final Dimension SPINNER_DIMENSION = new Dimension(250,25);
private static final long serialVersionUID = 1L;
private ApplicationMethodManager methodManager;
private Action editBaseConfigurationAction;
private JButton editBaseConfigurationButton;
private JSpinner iterationCountSpinner;
private ResolvableComboBox parameterComboBox;
private JCheckBox iterateCheckBox;
private SpinnerNumberModel startSpinnerNumberModel;
private SpinnerNumberModel endSpinnerNumberModel;
private JSpinner startSpinner;
private JSpinner endSpinner;
private MethodIteratorData currentData;
private IterableMethod currentMethod;
private ParameterIterationSettings[] currentParameters;
public IterationSetupDialog() {
super();
}
public IterationSetupDialog(Window w, boolean isModal) {
super(w, isModal);
}
@Override
protected void initialize() {
setTitle(_("Method iteration"));
setIconImage(IconUtils.loadClassPathImage("org/signalml/app/icon/iteratemethod.png"));
setResizable(false);
super.initialize();
}
@Override
public JComponent createInterface() {
JPanel interfacePanel = new JPanel(new BorderLayout());
JPanel baseConfigurationPanel = new JPanel();
baseConfigurationPanel.setLayout(new BoxLayout(baseConfigurationPanel, BoxLayout.X_AXIS));
baseConfigurationPanel.setBorder(new CompoundBorder(
new TitledBorder(_("Base method configuration")),
new EmptyBorder(3,3,3,3)
));
baseConfigurationPanel.add(new JLabel(_("Edit base configuration")));
baseConfigurationPanel.add(Box.createHorizontalStrut(5));
baseConfigurationPanel.add(Box.createHorizontalGlue());
baseConfigurationPanel.add(getEditBaseConfigurationButton());
JPanel iterationPanel = new JPanel();
iterationPanel.setBorder(new CompoundBorder(
new TitledBorder(_("Iteration configuration")),
new EmptyBorder(3,3,3,3)
));
GroupLayout layout = new GroupLayout(iterationPanel);
iterationPanel.setLayout(layout);
layout.setAutoCreateContainerGaps(false);
layout.setAutoCreateGaps(true);
JLabel iterationCountLabel = new JLabel(_("Iteration count"));
JLabel parameterLabel = new JLabel(_("Parameter"));
JLabel iterateLabel = new JLabel(_("Iterate this parameter"));
JLabel iterationStartLabel = new JLabel(_("Iteration start value"));
JLabel iterationEndLabel = new JLabel(_("Iteration end value"));
GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
hGroup.addGroup(
layout.createParallelGroup()
.addComponent(iterationCountLabel)
.addComponent(parameterLabel)
.addComponent(iterateLabel)
.addComponent(iterationStartLabel)
.addComponent(iterationEndLabel)
);
hGroup.addGroup(
layout.createParallelGroup(Alignment.TRAILING)
.addComponent(getIterationCountSpinner())
.addComponent(getParameterComboBox())
.addComponent(getIterateCheckBox())
.addComponent(getStartSpinner())
.addComponent(getEndSpinner())
);
layout.setHorizontalGroup(hGroup);
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
vGroup.addGroup(
layout.createParallelGroup(Alignment.BASELINE)
.addComponent(iterationCountLabel)
.addComponent(getIterationCountSpinner())
);
vGroup.addGroup(
layout.createParallelGroup(Alignment.BASELINE)
.addComponent(parameterLabel)
.addComponent(getParameterComboBox())
);
vGroup.addGroup(
layout.createParallelGroup(Alignment.BASELINE)
.addComponent(iterateLabel)
.addComponent(getIterateCheckBox())
);
vGroup.addGroup(
layout.createParallelGroup(Alignment.BASELINE)
.addComponent(iterationStartLabel)
.addComponent(getStartSpinner())
);
vGroup.addGroup(
layout.createParallelGroup(Alignment.BASELINE)
.addComponent(iterationEndLabel)
.addComponent(getEndSpinner())
);
layout.setVerticalGroup(vGroup);
interfacePanel.add(baseConfigurationPanel, BorderLayout.NORTH);
interfacePanel.add(iterationPanel, BorderLayout.CENTER);
return interfacePanel;
}
private ParameterIterationSettings[] getNewParameters(IterableParameter[] iterableParameters, ParameterIterationSettings[] oldParameters) {
ParameterIterationSettings[] parameters = new ParameterIterationSettings[iterableParameters.length];
int i, e;
boolean copied;
for (i=0; i<parameters.length; i++) {
parameters[i] = new ParameterIterationSettings(iterableParameters[i]);
copied = false;
if (oldParameters != null) {
for (e=0; e<oldParameters.length; e++) {
if (iterableParameters[i].equals(oldParameters[e].getParameter())) {
parameters[i].setIterated(oldParameters[e].isIterated());
parameters[i].setStartValue(oldParameters[e].getStartValue());
parameters[i].setEndValue(oldParameters[e].getEndValue());
copied = true;
break;
}
}
}
if (!copied) {
parameters[i].setIterated(false);
parameters[i].setStartValue(iterableParameters[i].getDefaultStartValue());
parameters[i].setEndValue(iterableParameters[i].getDefaultEndValue());
}
}
return parameters;
}
private void fillDialogFromCurrentParameters() {
DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel(currentParameters);
getParameterComboBox().setModel(comboBoxModel);
if (currentParameters.length > 0) {
getParameterComboBox().setSelectedIndex(0);
}
}
@Override
public void fillDialogFromModel(Object model) throws SignalMLException {
IterationSetupDescriptor descriptor = (IterationSetupDescriptor) model;
currentMethod = descriptor.getMethod();
currentData = descriptor.getData();
Object subjectData = currentData.getSubjectMethodData();
getIterationCountSpinner().setValue(new Integer(currentData.getTotalIterations()));
IterableParameter[] iterableParameters = currentMethod.getIterableParameters(subjectData);
ParameterIterationSettings[] parameters = currentData.getParameters();
currentParameters = getNewParameters(iterableParameters, parameters);
fillDialogFromCurrentParameters();
}
@Override
public void fillModelFromDialog(Object model) throws SignalMLException {
IterationSetupDescriptor descriptor = (IterationSetupDescriptor) model;
MethodIteratorData data = descriptor.getData();
data.setTotalIterations((Integer) getIterationCountSpinner().getValue());
data.setParameters(currentParameters);
}
@Override
public void validateDialog(Object model, ValidationErrors errors) throws SignalMLException {
super.validateDialog(model, errors);
boolean anyIterated = false;
for (int i=0; i<currentParameters.length; i++) {
if (currentParameters[i].isIterated()) {
anyIterated = true;
break;
}
}
if (!anyIterated) {
errors.addError(_("You must choose at least one parameter to iterate over"));
}
}
public Action getEditBaseConfigurationAction() {
if (editBaseConfigurationAction == null) {
editBaseConfigurationAction = new EditBaseConfiguration();
}
return editBaseConfigurationAction;
}
public JButton getEditBaseConfigurationButton() {
if (editBaseConfigurationButton == null) {
editBaseConfigurationButton = new JButton(getEditBaseConfigurationAction());
}
return editBaseConfigurationButton;
}
public JSpinner getIterationCountSpinner() {
if (iterationCountSpinner == null) {
iterationCountSpinner = new JSpinner(new SpinnerNumberModel(new Integer(2), new Integer(2), null, new Integer(1)));
iterationCountSpinner.setPreferredSize(SPINNER_DIMENSION);
iterationCountSpinner.setMinimumSize(SPINNER_DIMENSION);
iterationCountSpinner.setMaximumSize(SPINNER_DIMENSION);
iterationCountSpinner.setFont(iterationCountSpinner.getFont().deriveFont(Font.PLAIN));
}
return iterationCountSpinner;
}
public ResolvableComboBox getParameterComboBox() {
if (parameterComboBox == null) {
parameterComboBox = new ResolvableComboBox();
parameterComboBox.setModel(new DefaultComboBoxModel());
parameterComboBox.setPreferredSize(SPINNER_DIMENSION);
parameterComboBox.setMinimumSize(SPINNER_DIMENSION);
parameterComboBox.setMaximumSize(SPINNER_DIMENSION);
parameterComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ParameterIterationSettings selected = (ParameterIterationSettings) parameterComboBox.getSelectedItem();
if (selected == null) {
return;
}
IterableParameter parameter = selected.getParameter();
if (parameter instanceof IterableNumericParameter) {
IterableNumericParameter numeric = (IterableNumericParameter) parameter;
SpinnerNumberModel spinnerModel;
spinnerModel = new SpinnerNumberModel((Number) selected.getStartValue(), numeric.getMinimum(), numeric.getMaximum(), numeric.getStepSize());
SwingUtils.replaceSpinnerModel(getStartSpinner(), spinnerModel);
spinnerModel = new SpinnerNumberModel((Number) selected.getEndValue(), numeric.getMinimum(), numeric.getMaximum(), numeric.getStepSize());
SwingUtils.replaceSpinnerModel(getEndSpinner(), spinnerModel);
} else {
throw new SanityCheckException("Unuspported parameter type [" + parameter.getClass() + "]");
}
getIterateCheckBox().setSelected(selected.isIterated());
}
});
}
return parameterComboBox;
}
public JCheckBox getIterateCheckBox() {
if (iterateCheckBox == null) {
iterateCheckBox = new JCheckBox();
iterateCheckBox.setPreferredSize(SPINNER_DIMENSION);
iterateCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
boolean iterated = iterateCheckBox.isSelected();
getStartSpinner().setEnabled(iterated);
getEndSpinner().setEnabled(iterated);
ParameterIterationSettings selected = (ParameterIterationSettings) getParameterComboBox().getSelectedItem();
if (selected == null) {
return;
}
selected.setIterated(iterated);
}
});
}
return iterateCheckBox;
}
public SpinnerNumberModel getStartSpinnerNumberModel() {
if (startSpinnerNumberModel == null) {
startSpinnerNumberModel = new SpinnerNumberModel();
}
return startSpinnerNumberModel;
}
public SpinnerNumberModel getEndSpinnerNumberModel() {
if (endSpinnerNumberModel == null) {
endSpinnerNumberModel = new SpinnerNumberModel();
}
return endSpinnerNumberModel;
}
public JSpinner getStartSpinner() {
if (startSpinner == null) {
startSpinner = new JSpinner(new SpinnerNumberModel(50,1,100,1));
startSpinner.setPreferredSize(SPINNER_DIMENSION);
startSpinner.setMinimumSize(SPINNER_DIMENSION);
startSpinner.setMaximumSize(SPINNER_DIMENSION);
startSpinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
ParameterIterationSettings selected = (ParameterIterationSettings) getParameterComboBox().getSelectedItem();
if (selected == null) {
return;
}
selected.setStartValue(startSpinner.getValue());
}
});
startSpinner.setEnabled(false);
startSpinner.setFont(startSpinner.getFont().deriveFont(Font.PLAIN));
}
return startSpinner;
}
public JSpinner getEndSpinner() {
if (endSpinner == null) {
endSpinner = new JSpinner(new SpinnerNumberModel(50,1,100,1));
endSpinner.setPreferredSize(SPINNER_DIMENSION);
endSpinner.setMinimumSize(SPINNER_DIMENSION);
endSpinner.setMaximumSize(SPINNER_DIMENSION);
endSpinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
ParameterIterationSettings selected = (ParameterIterationSettings) getParameterComboBox().getSelectedItem();
if (selected == null) {
return;
}
selected.setEndValue(endSpinner.getValue());
}
});
endSpinner.setEnabled(false);
endSpinner.setFont(endSpinner.getFont().deriveFont(Font.PLAIN));
}
return endSpinner;
}
@Override
public boolean supportsModelClass(Class<?> clazz) {
return IterationSetupDescriptor.class.isAssignableFrom(clazz);
}
public ApplicationMethodManager getMethodManager() {
return methodManager;
}
public void setMethodManager(ApplicationMethodManager methodManager) {
this.methodManager = methodManager;
}
protected class EditBaseConfiguration extends AbstractAction {
private static final long serialVersionUID = 1L;
public EditBaseConfiguration() {
super(_("Edit..."));
putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/baseconfiguration.png"));
putValue(AbstractAction.SHORT_DESCRIPTION,_("Reconfigure basic method parameters"));
}
public void actionPerformed(ActionEvent ev) {
ApplicationMethodDescriptor descriptor = methodManager.getMethodData(currentMethod);
MethodConfigurer configurer = descriptor.getConfigurer(methodManager);
Object subjectData = currentData.getSubjectMethodData();
try {
boolean ok = configurer.configure(currentMethod, subjectData);
if (!ok) {
return;
}
} catch (SignalMLException ex) {
logger.error("Failed to configure base data", ex);
Dialogs.showExceptionDialog(IterationSetupDialog.this, ex);
return;
}
IterableParameter[] iterableParameters = currentMethod.getIterableParameters(subjectData);
currentParameters = getNewParameters(iterableParameters, currentParameters);
fillDialogFromCurrentParameters();
}
}
}