summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/gui/configurator
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/gui/configurator')
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractParameterConfigurator.java153
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractSingleParameterConfigurator.java47
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java238
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java134
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java167
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java126
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java70
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ParameterConfigurator.java39
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java72
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/package-info.java29
10 files changed, 1075 insertions, 0 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractParameterConfigurator.java
new file mode 100644
index 00000000..7fbc0049
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractParameterConfigurator.java
@@ -0,0 +1,153 @@
+package de.lmu.ifi.dbs.elki.gui.configurator;
+/*
+This file is part of ELKI:
+Environment for Developing KDD-Applications Supported by Index-Structures
+
+Copyright (C) 2011
+Ludwig-Maximilians-Universität München
+Lehr- und Forschungseinheit für Datenbanksysteme
+ELKI Development Team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+
+import de.lmu.ifi.dbs.elki.gui.icons.StockIcon;
+import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
+
+/**
+ * Abstract class to produce a configurator for a particular parameter.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has StockIcon
+ *
+ * @param <T> parameter type
+ */
+public abstract class AbstractParameterConfigurator<T extends Parameter<?, ?>> implements ParameterConfigurator {
+ /**
+ * The parameter to configure
+ */
+ final T param;
+
+ /**
+ * The parent container
+ */
+ final JComponent parent;
+
+ /**
+ * The event listeners for this parameter.
+ */
+ protected EventListenerList listenerList = new EventListenerList();
+
+ /**
+ * Constructor.
+ *
+ * @param param Parameter
+ * @param parent Parent
+ */
+ public AbstractParameterConfigurator(T param, JComponent parent) {
+ super();
+ this.param = param;
+ this.parent = parent;
+ }
+
+ /**
+ * Complete the current grid row, adding the icon at the end
+ */
+ protected void finishGridRow() {
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ constraints.weightx = 0;
+ final JLabel icon;
+ if(param.isOptional()) {
+ if(param.isDefined() && param.tookDefaultValue() && !(param instanceof Flag)) {
+ // TODO: better icon for default value?
+ icon = new JLabel(StockIcon.getStockIcon(StockIcon.DIALOG_INFORMATION));
+ icon.setToolTipText("Default value: "+param.getDefaultValueAsString());
+ }
+ else {
+ icon = new JLabel();
+ icon.setMinimumSize(new Dimension(16, 16));
+ }
+ }
+ else {
+ if(!param.isDefined()) {
+ icon = new JLabel(StockIcon.getStockIcon(StockIcon.DIALOG_ERROR));
+ icon.setToolTipText("Missing value.");
+ }
+ else {
+ icon = new JLabel();
+ icon.setMinimumSize(new Dimension(16, 16));
+ }
+ }
+ parent.add(icon, constraints);
+ }
+
+ @Override
+ public void addParameter(@SuppressWarnings("unused") Object owner, @SuppressWarnings("unused") Parameter<?, ?> param, @SuppressWarnings("unused") TrackParameters track) {
+ LoggingUtil.warning(this.getClass() + " does not support sub-parameters!");
+ }
+
+ @Override
+ public void addChangeListener(ChangeListener listener) {
+ listenerList.add(ChangeListener.class, listener);
+ }
+
+ @Override
+ public void removeChangeListener(ChangeListener listener) {
+ listenerList.remove(ChangeListener.class, listener);
+ }
+
+ /**
+ * Notify listeners of a changed value.
+ */
+ protected void fireValueChanged() {
+ // FIXME: compare with previous value?
+ ChangeEvent evt = new ChangeEvent(this);
+ for(ChangeListener listener : listenerList.getListeners(ChangeListener.class)) {
+ listener.stateChanged(evt);
+ }
+ }
+
+ @Override
+ public void appendParameters(ListParameterization params) {
+ Object val = getUserInput();
+ if(val instanceof String && ((String) val).length() == 0) {
+ val = null;
+ }
+ if(val != null) {
+ params.addParameter(param.getOptionID(), val);
+ }
+ }
+
+ /**
+ * Get the value given by the user.
+ *
+ * @return value for parameter
+ */
+ public abstract Object getUserInput();
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractSingleParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractSingleParameterConfigurator.java
new file mode 100644
index 00000000..fa2146de
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractSingleParameterConfigurator.java
@@ -0,0 +1,47 @@
+package de.lmu.ifi.dbs.elki.gui.configurator;
+/*
+This file is part of ELKI:
+Environment for Developing KDD-Applications Supported by Index-Structures
+
+Copyright (C) 2011
+Ludwig-Maximilians-Universität München
+Lehr- und Forschungseinheit für Datenbanksysteme
+ELKI Development Team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import java.awt.GridBagConstraints;
+
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
+
+public abstract class AbstractSingleParameterConfigurator<T extends Parameter<?, ?>> extends AbstractParameterConfigurator<T> {
+ final JLabel label;
+
+ public AbstractSingleParameterConfigurator(T param, JComponent parent) {
+ super(param, parent);
+ // Label
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.weightx = 0;
+ label = new JLabel(param.getName());
+ label.setAlignmentX(0.0f);
+ label.setToolTipText(param.getShortDescription());
+ parent.add(label, constraints);
+ // subclasses will add a second component to the row!
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java
new file mode 100644
index 00000000..c40cad99
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java
@@ -0,0 +1,238 @@
+package de.lmu.ifi.dbs.elki.gui.configurator;
+/*
+This file is part of ELKI:
+Environment for Developing KDD-Applications Supported by Index-Structures
+
+Copyright (C) 2011
+Ludwig-Maximilians-Universität München
+Lehr- und Forschungseinheit für Datenbanksysteme
+ELKI Development Team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.basic.BasicComboPopup;
+
+import de.lmu.ifi.dbs.elki.gui.icons.StockIcon;
+import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassListParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
+
+public class ClassListParameterConfigurator extends AbstractSingleParameterConfigurator<ClassListParameter<?>> implements ActionListener, ChangeListener {
+ final ConfiguratorPanel child;
+
+ /**
+ * We need a panel to put our components on.
+ */
+ final JPanel panel;
+
+ /**
+ * Text field to store the name
+ */
+ final JTextField textfield;
+
+ /**
+ * The button to open the file selector
+ */
+ final JButton button;
+
+ /**
+ * The combobox we are abusing to produce the popup
+ */
+ final JComboBox combo;
+
+ /**
+ * The popup menu.
+ */
+ final SuperPopup popup;
+
+ public ClassListParameterConfigurator(ClassListParameter<?> cp, JComponent parent) {
+ super(cp, parent);
+ textfield = new JTextField();
+ textfield.setToolTipText(param.getShortDescription());
+ if(cp.isDefined() && !cp.tookDefaultValue()) {
+ textfield.setText(cp.getValueAsString());
+ }
+ textfield.setPreferredSize(new Dimension(400, textfield.getPreferredSize().height));
+
+ button = new JButton(StockIcon.getStockIcon(StockIcon.LIST_ADD));
+ button.setToolTipText(param.getShortDescription());
+ button.addActionListener(this);
+ // So the first item doesn't get automatically selected
+ combo = new JComboBox();
+ combo.setEditable(true);
+ combo.setPrototypeDisplayValue(cp.getRestrictionClass().getSimpleName());
+ popup = new SuperPopup(combo);
+
+ // fill dropdown menu
+ {
+ // Offer the shorthand version of class names.
+ String prefix = cp.getRestrictionClass().getPackage().getName() + ".";
+ for(Class<?> impl : cp.getKnownImplementations()) {
+ String name = impl.getName();
+ if(name.startsWith(prefix)) {
+ name = name.substring(prefix.length());
+ }
+ combo.addItem(name);
+ }
+ }
+ combo.addActionListener(this);
+
+ // setup panel
+ {
+ panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+ panel.add(textfield, BorderLayout.CENTER);
+ panel.add(button, BorderLayout.EAST);
+
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.weightx = 1.0;
+ parent.add(panel, constraints);
+ finishGridRow();
+ }
+
+ // Child options
+ {
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.weightx = 1.0;
+ constraints.insets = new Insets(0, 10, 0, 0);
+ child = new ConfiguratorPanel();
+ child.addChangeListener(this);
+ parent.add(child, constraints);
+ }
+
+ textfield.addActionListener(this);
+ }
+
+ @Override
+ public void addParameter(Object owner, Parameter<?, ?> param, TrackParameters track) {
+ child.addParameter(owner, param, track);
+ }
+
+ /**
+ * Callback to show the popup menu
+ */
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(e.getSource() == button) {
+ popup.show(panel);
+ }
+ else if(e.getSource() == combo) {
+ String newClass = (String) combo.getSelectedItem();
+ if(newClass != null && newClass.length() > 0) {
+ String val = textfield.getText();
+ if(val.length() > 0) {
+ val = val + ClassListParameter.LIST_SEP + newClass;
+ }
+ else {
+ val = newClass;
+ }
+ textfield.setText(val);
+ popup.hide();
+ fireValueChanged();
+ }
+ }
+ else if(e.getSource() == textfield) {
+ fireValueChanged();
+ }
+ else {
+ LoggingUtil.warning("actionPerformed triggered by unknown source: " + e.getSource());
+ }
+ }
+
+ // FIXME: Refactor - duplicate code.
+ /** @apiviz.exclude */
+ class SuperPopup extends BasicComboPopup {
+ /**
+ * Serial version
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor.
+ *
+ * @param combo Combo box used for data storage.
+ */
+ public SuperPopup(JComboBox combo) {
+ super(combo);
+ }
+
+ /**
+ * Show the menu on a particular panel.
+ *
+ * This code is mostly copied from {@link BasicComboPopup#getPopupLocation}
+ *
+ * @param parent Parent element to show at.
+ */
+ public void show(JPanel parent) {
+ Dimension popupSize = parent.getSize();
+ Insets insets = getInsets();
+
+ // reduce the width of the scrollpane by the insets so that the popup
+ // is the same width as the combo box.
+ popupSize.setSize(popupSize.width - (insets.right + insets.left), getPopupHeightForRowCount(comboBox.getMaximumRowCount()));
+ Rectangle popupBounds = computePopupBounds(0, comboBox.getBounds().height, popupSize.width, popupSize.height);
+ Dimension scrollSize = popupBounds.getSize();
+
+ scroller.setMaximumSize(scrollSize);
+ scroller.setPreferredSize(scrollSize);
+ scroller.setMinimumSize(scrollSize);
+
+ list.revalidate();
+
+ super.show(parent, 0, parent.getBounds().height);
+ }
+ }
+
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ if(e.getSource() == child) {
+ fireValueChanged();
+ }
+ else {
+ LoggingUtil.warning("stateChanged triggered by unknown source: " + e.getSource());
+ }
+ }
+
+ @Override
+ public String getUserInput() {
+ return textfield.getText();
+ }
+
+ @Override
+ public void appendParameters(ListParameterization params) {
+ super.appendParameters(params);
+ child.appendParameters(params);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
new file mode 100644
index 00000000..656cd380
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
@@ -0,0 +1,134 @@
+package de.lmu.ifi.dbs.elki.gui.configurator;
+/*
+This file is part of ELKI:
+Environment for Developing KDD-Applications Supported by Index-Structures
+
+Copyright (C) 2011
+Ludwig-Maximilians-Universität München
+Lehr- und Forschungseinheit für Datenbanksysteme
+ELKI Development Team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import de.lmu.ifi.dbs.elki.gui.util.DynamicParameters;
+import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
+
+public class ClassParameterConfigurator extends AbstractSingleParameterConfigurator<ClassParameter<?>> implements ActionListener, ChangeListener {
+ final JComboBox value;
+
+ final ConfiguratorPanel child;
+
+ public ClassParameterConfigurator(ClassParameter<?> cp, JComponent parent) {
+ super(cp, parent);
+ // Input field
+ {
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.weightx = 1.0;
+ value = new JComboBox();
+ value.setToolTipText(param.getShortDescription());
+ value.setPrototypeDisplayValue(cp.getRestrictionClass().getSimpleName());
+ parent.add(value, constraints);
+ finishGridRow();
+ }
+
+ if(!param.tookDefaultValue() && param.isDefined() && param.getGivenValue() != null) {
+ value.addItem(param.getValueAsString());
+ value.setSelectedIndex(0);
+ }
+
+ // For parameters with a default value, offer using the default
+ // For optional parameters, offer not specifying them.
+ if(cp.hasDefaultValue()) {
+ value.addItem(DynamicParameters.STRING_USE_DEFAULT + " " + cp.getDefaultValueAsString());
+ }
+ else if(cp.isOptional()) {
+ value.addItem(DynamicParameters.STRING_OPTIONAL);
+ }
+ // Offer the shorthand version of class names.
+ for(Class<?> impl : cp.getKnownImplementations()) {
+ value.addItem(ClassParameter.canonicalClassName(impl, cp.getRestrictionClass()));
+ }
+ // Child options
+ {
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.weightx = 1.0;
+ constraints.insets = new Insets(0, 10, 0, 0);
+ child = new ConfiguratorPanel();
+ child.addChangeListener(this);
+ parent.add(child, constraints);
+ }
+ value.addActionListener(this);
+ }
+
+ @Override
+ public void addParameter(Object owner, Parameter<?, ?> param, TrackParameters track) {
+ child.addParameter(owner, param, track);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(e.getSource() == value) {
+ fireValueChanged();
+ }
+ else {
+ LoggingUtil.warning("actionPerformed triggered by unknown source: " + e.getSource());
+ }
+ }
+
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ if(e.getSource() == child) {
+ fireValueChanged();
+ }
+ else {
+ LoggingUtil.warning("stateChanged triggered by unknown source: " + e.getSource());
+ }
+ }
+
+ @Override
+ public String getUserInput() {
+ String val = (String) value.getSelectedItem();
+ if(val.startsWith(DynamicParameters.STRING_USE_DEFAULT)) {
+ return null;
+ }
+ if(val == DynamicParameters.STRING_OPTIONAL) {
+ return null;
+ }
+ return val;
+ }
+
+ @Override
+ public void appendParameters(ListParameterization params) {
+ super.appendParameters(params);
+ child.appendParameters(params);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java
new file mode 100644
index 00000000..30016a8f
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java
@@ -0,0 +1,167 @@
+package de.lmu.ifi.dbs.elki.gui.configurator;
+/*
+This file is part of ELKI:
+Environment for Developing KDD-Applications Supported by Index-Structures
+
+Copyright (C) 2011
+Ludwig-Maximilians-Universität München
+Lehr- und Forschungseinheit für Datenbanksysteme
+ELKI Development Team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import java.awt.GridBagLayout;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.JPanel;
+import javax.swing.border.SoftBevelBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+
+import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassListParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
+
+/**
+ * A panel that contains configurators for parameters.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.landmark
+ * @apiviz.has de.lmu.ifi.dbs.elki.gui.configurator.ParameterConfigurator
+ */
+public class ConfiguratorPanel extends JPanel implements ChangeListener {
+ /**
+ * Serial version
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Keep a map of parameter
+ */
+ private Map<Object, ParameterConfigurator> childconfig = new HashMap<Object, ParameterConfigurator>();
+
+ /**
+ * Child options
+ */
+ private java.util.Vector<ParameterConfigurator> children = new java.util.Vector<ParameterConfigurator>();
+
+ /**
+ * The event listeners for this panel.
+ */
+ protected EventListenerList listenerList = new EventListenerList();
+
+ /**
+ * Constructor.
+ */
+ public ConfiguratorPanel() {
+ super(new GridBagLayout());
+ }
+
+ /**
+ * Add parameter to this panel.
+ *
+ * @param param Parameter to add
+ * @param track Parameter tracking object
+ */
+ public void addParameter(Object owner, Parameter<?, ?> param, TrackParameters track) {
+ this.setBorder(new SoftBevelBorder(SoftBevelBorder.LOWERED));
+ ParameterConfigurator cfg = null;
+ {
+ Object cur = owner;
+ while(cfg == null && cur != null) {
+ cfg = childconfig.get(cur);
+ if(cfg != null) {
+ break;
+ }
+ cur = track.getParent(cur);
+ }
+ }
+ if(cfg != null) {
+ cfg.addParameter(owner, param, track);
+ return;
+ }
+ else {
+ cfg = makeConfigurator(param);
+ cfg.addChangeListener(this);
+ children.add(cfg);
+ }
+ }
+
+ private ParameterConfigurator makeConfigurator(Parameter<?, ?> param) {
+ if(param instanceof Flag) {
+ return new FlagParameterConfigurator((Flag) param, this);
+ }
+ if(param instanceof ClassListParameter) {
+ ParameterConfigurator cfg = new ClassListParameterConfigurator((ClassListParameter<?>) param, this);
+ childconfig.put(param, cfg);
+ return cfg;
+ }
+ if(param instanceof ClassParameter) {
+ ParameterConfigurator cfg = new ClassParameterConfigurator((ClassParameter<?>) param, this);
+ childconfig.put(param, cfg);
+ return cfg;
+ }
+ if(param instanceof FileParameter) {
+ return new FileParameterConfigurator((FileParameter) param, this);
+ }
+ return new TextParameterConfigurator(param, this);
+ }
+
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ if(e.getSource() instanceof ParameterConfigurator) {
+ // TODO: check that e is in children?
+ fireValueChanged();
+ }
+ else {
+ LoggingUtil.warning("stateChanged triggered by unknown source: " + e.getSource());
+ }
+ }
+
+ public void addChangeListener(ChangeListener listener) {
+ listenerList.add(ChangeListener.class, listener);
+ }
+
+ public void removeChangeListener(ChangeListener listener) {
+ listenerList.remove(ChangeListener.class, listener);
+ }
+
+ protected void fireValueChanged() {
+ ChangeEvent evt = new ChangeEvent(this);
+ for(ChangeListener listener : listenerList.getListeners(ChangeListener.class)) {
+ listener.stateChanged(evt);
+ }
+ }
+
+ public void appendParameters(ListParameterization params) {
+ for(ParameterConfigurator cfg : children) {
+ cfg.appendParameters(params);
+ }
+ }
+
+ public void clear() {
+ removeAll();
+ childconfig.clear();
+ children.clear();
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java
new file mode 100644
index 00000000..e27d8155
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java
@@ -0,0 +1,126 @@
+package de.lmu.ifi.dbs.elki.gui.configurator;
+/*
+This file is part of ELKI:
+Environment for Developing KDD-Applications Supported by Index-Structures
+
+Copyright (C) 2011
+Ludwig-Maximilians-Universität München
+Lehr- und Forschungseinheit für Datenbanksysteme
+ELKI Development Team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import java.awt.BorderLayout;
+import java.awt.GridBagConstraints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JFileChooser;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import de.lmu.ifi.dbs.elki.gui.icons.StockIcon;
+import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
+
+public class FileParameterConfigurator extends AbstractSingleParameterConfigurator<FileParameter> implements ActionListener {
+ /**
+ * The panel to store the components
+ */
+ final JPanel panel;
+
+ /**
+ * Text field to store the name
+ */
+ final JTextField textfield;
+
+ /**
+ * The button to open the file selector
+ */
+ final JButton button;
+
+ /**
+ * The actual file chooser
+ */
+ final JFileChooser fc = new JFileChooser();
+
+ public FileParameterConfigurator(FileParameter fp, JComponent parent) {
+ super(fp, parent);
+ // create components
+ textfield = new JTextField();
+ textfield.setToolTipText(param.getShortDescription());
+ textfield.addActionListener(this);
+ button = new JButton(StockIcon.getStockIcon(StockIcon.DOCUMENT_OPEN));
+ button.setToolTipText(param.getShortDescription());
+ button.addActionListener(this);
+ // fill with value
+ File f = null;
+ if(fp.isDefined()) {
+ f = fp.getValue();
+ }
+ if(f != null) {
+ String fn = f.getPath();
+ textfield.setText(fn);
+ fc.setSelectedFile(f);
+ }
+ else {
+ textfield.setText("");
+ fc.setSelectedFile(null);
+ }
+
+ // make a panel
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.weightx = 1.0;
+ panel = new JPanel(new BorderLayout());
+ panel.add(textfield, BorderLayout.CENTER);
+ panel.add(button, BorderLayout.EAST);
+
+ parent.add(panel, constraints);
+ finishGridRow();
+ }
+
+ /**
+ * Button callback to show the file selector
+ */
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(e.getSource() == button) {
+ int returnVal = fc.showOpenDialog(button);
+
+ if(returnVal == JFileChooser.APPROVE_OPTION) {
+ textfield.setText(fc.getSelectedFile().getPath());
+ fireValueChanged();
+ }
+ else {
+ // Do nothing on cancel.
+ }
+ }
+ else if(e.getSource() == textfield) {
+ fireValueChanged();
+ }
+ else {
+ LoggingUtil.warning("actionPerformed triggered by unknown source: " + e.getSource());
+ }
+ }
+
+ @Override
+ public String getUserInput() {
+ return textfield.getText();
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java
new file mode 100644
index 00000000..01b2cb62
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java
@@ -0,0 +1,70 @@
+package de.lmu.ifi.dbs.elki.gui.configurator;
+/*
+This file is part of ELKI:
+Environment for Developing KDD-Applications Supported by Index-Structures
+
+Copyright (C) 2011
+Ludwig-Maximilians-Universität München
+Lehr- und Forschungseinheit für Datenbanksysteme
+ELKI Development Team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import java.awt.GridBagConstraints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+
+import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
+
+public class FlagParameterConfigurator extends AbstractParameterConfigurator<Flag> implements ActionListener {
+ final JCheckBox value;
+
+ public FlagParameterConfigurator(Flag param, JComponent parent) {
+ super(param, parent);
+
+ // Input field
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.gridwidth = 2;
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.weightx = 1.0;
+ value = new JCheckBox(param.getName());
+ if(param.isDefined() && !param.tookDefaultValue()) {
+ value.setSelected(param.getValue());
+ }
+ value.setToolTipText(param.getShortDescription());
+ parent.add(value, constraints);
+ finishGridRow();
+
+ value.addActionListener(this);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == value) {
+ fireValueChanged();
+ } else {
+ LoggingUtil.warning("actionPerformed triggered by unknown source: "+e.getSource());
+ }
+ }
+
+ @Override
+ public Boolean getUserInput() {
+ return value.isSelected() ? true : null;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/ParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ParameterConfigurator.java
new file mode 100644
index 00000000..020ba2c2
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ParameterConfigurator.java
@@ -0,0 +1,39 @@
+package de.lmu.ifi.dbs.elki.gui.configurator;
+/*
+This file is part of ELKI:
+Environment for Developing KDD-Applications Supported by Index-Structures
+
+Copyright (C) 2011
+Ludwig-Maximilians-Universität München
+Lehr- und Forschungseinheit für Datenbanksysteme
+ELKI Development Team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import javax.swing.event.ChangeListener;
+
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
+
+public interface ParameterConfigurator {
+ public void addParameter(Object owner, Parameter<?, ?> param, TrackParameters track);
+
+ public void addChangeListener(ChangeListener listener);
+
+ public void removeChangeListener(ChangeListener listener);
+
+ public void appendParameters(ListParameterization params);
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java
new file mode 100644
index 00000000..4662484a
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java
@@ -0,0 +1,72 @@
+package de.lmu.ifi.dbs.elki.gui.configurator;
+/*
+This file is part of ELKI:
+Environment for Developing KDD-Applications Supported by Index-Structures
+
+Copyright (C) 2011
+Ludwig-Maximilians-Universität München
+Lehr- und Forschungseinheit für Datenbanksysteme
+ELKI Development Team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JComponent;
+import javax.swing.JTextField;
+
+import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
+
+// FIXME: update on focus loss?
+// FIXME: restrictions for number input?
+public class TextParameterConfigurator extends AbstractSingleParameterConfigurator<Parameter<?, ?>> implements ActionListener {
+ final JTextField value;
+
+ public TextParameterConfigurator(Parameter<?, ?> param, JComponent parent) {
+ super(param, parent);
+
+ // Input field
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.weightx = 1.0;
+ value = new JTextField();
+ if(param.isDefined() && !param.tookDefaultValue()) {
+ value.setText(param.getValueAsString());
+ }
+ value.setPreferredSize(new Dimension(400, value.getPreferredSize().height));
+ parent.add(value, constraints);
+ finishGridRow();
+
+ value.addActionListener(this);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == value) {
+ fireValueChanged();
+ } else {
+ LoggingUtil.warning("actionPerformed triggered by unknown source: "+e.getSource());
+ }
+ }
+
+ @Override
+ public String getUserInput() {
+ return value.getText();
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/package-info.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/package-info.java
new file mode 100644
index 00000000..4c42582b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/package-info.java
@@ -0,0 +1,29 @@
+/**
+ * <p>Configurator components</p>
+ *
+ * @apiviz.exclude javax.swing.event.*
+ * @apiviz.exclude javax.awt.event.*
+ */
+/*
+This file is part of ELKI:
+Environment for Developing KDD-Applications Supported by Index-Structures
+
+Copyright (C) 2011
+Ludwig-Maximilians-Universität München
+Lehr- und Forschungseinheit für Datenbanksysteme
+ELKI Development Team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+package de.lmu.ifi.dbs.elki.gui.configurator; \ No newline at end of file