summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java')
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java150
1 files changed, 115 insertions, 35 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
index cbe03a4f..8deb72ed 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
@@ -4,7 +4,7 @@ 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) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,17 +23,31 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
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.event.ActionEvent;
import java.awt.event.ActionListener;
-import javax.swing.JComboBox;
+import javax.swing.Icon;
+import javax.swing.JButton;
import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-
+import javax.swing.plaf.basic.BasicArrowButton;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+
+import de.lmu.ifi.dbs.elki.gui.icons.StockIcon;
+import de.lmu.ifi.dbs.elki.gui.util.ClassTree;
+import de.lmu.ifi.dbs.elki.gui.util.ClassTree.ClassNode;
import de.lmu.ifi.dbs.elki.gui.util.DynamicParameters;
+import de.lmu.ifi.dbs.elki.gui.util.TreePopup;
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;
@@ -49,41 +63,91 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
* @apiviz.uses ClassParameter
*/
public class ClassParameterConfigurator extends AbstractSingleParameterConfigurator<ClassParameter<?>> implements ActionListener, ChangeListener {
- final JComboBox<String> value;
-
+ /**
+ * 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 popup we use.
+ */
+ final TreePopup popup;
+
+ /**
+ * Configuration panel for child.
+ */
final ConfiguratorPanel child;
+ /**
+ * Constructor.
+ *
+ * @param cp Class parameter
+ * @param parent Parent component.
+ */
public ClassParameterConfigurator(ClassParameter<?> cp, JComponent parent) {
super(cp, parent);
- // Input field
+ textfield = new JTextField();
+ textfield.setToolTipText(param.getShortDescription());
+ if(cp.isDefined() && !cp.tookDefaultValue()) {
+ textfield.setText(cp.getValueAsString());
+ }
+ textfield.setPreferredSize(new Dimension(400, textfield.getPreferredSize().height));
+ if(!param.tookDefaultValue() && param.isDefined() && param.getGivenValue() != null) {
+ textfield.setText(param.getValueAsString());
+ // FIXME: pre-select the current / default value in tree!
+ }
+
+ // This is a hack, but the BasicArrowButton looks very odd on GTK.
+ if(UIManager.getLookAndFeel().getName().indexOf("GTK") >= 0) {
+ // This is not optimal either, but looks more consistent at least.
+ button = new JButton(StockIcon.getStockIcon(StockIcon.EDIT_FIND));
+ }
+ else {
+ button = new BasicArrowButton(BasicArrowButton.SOUTH);
+ }
+ button.setToolTipText(param.getShortDescription());
+ button.addActionListener(this);
+
+ TreeNode root = ClassTree.build(cp.getKnownImplementations(), cp.getRestrictionClass().getPackage().getName());
+
+ popup = new TreePopup(new DefaultTreeModel(root));
+ popup.getTree().setRootVisible(false);
+ // popup.setPrototypeDisplayValue(cp.getRestrictionClass().getSimpleName());
+ popup.addActionListener(this);
+
+ Icon classIcon = StockIcon.getStockIcon(StockIcon.GO_NEXT);
+ Icon packageIcon = StockIcon.getStockIcon(StockIcon.PACKAGE);
+ TreePopup.Renderer renderer = (TreePopup.Renderer) popup.getTree().getCellRenderer();
+ renderer.setLeafIcon(classIcon);
+ renderer.setFolderIcon(packageIcon);
+
+ // 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;
- value = new JComboBox<>();
- value.setToolTipText(param.getShortDescription());
- value.setPrototypeDisplayValue(cp.getRestrictionClass().getSimpleName());
- parent.add(value, constraints);
+ parent.add(panel, constraints);
finishGridRow();
}
- if(!param.tookDefaultValue() && param.isDefined() && param.getGivenValue() != null) {
- value.addItem(param.getValueAsString());
- value.setSelectedIndex(0);
- }
+ // FIXME: re-add "none" option for optional parameters!
+ // FIXME: re-highlight default value!
- // 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();
@@ -95,7 +159,6 @@ public class ClassParameterConfigurator extends AbstractSingleParameterConfigura
child.addChangeListener(this);
parent.add(child, constraints);
}
- value.addActionListener(this);
}
@Override
@@ -105,27 +168,44 @@ public class ClassParameterConfigurator extends AbstractSingleParameterConfigura
@Override
public void actionPerformed(ActionEvent e) {
- if(e.getSource() == value) {
- fireValueChanged();
+ if(e.getSource() == button) {
+ popup.show(panel);
+ return;
}
- else {
- LoggingUtil.warning("actionPerformed triggered by unknown source: " + e.getSource());
+ if(e.getSource() == popup) {
+ if (e.getActionCommand() == TreePopup.ACTION_CANCELED) {
+ popup.setVisible(false);
+ textfield.requestFocus();
+ return;
+ }
+ TreePath path = popup.getTree().getSelectionPath();
+ final Object comp = path != null ? path.getLastPathComponent() : null;
+ if(comp instanceof ClassNode) {
+ ClassNode sel = (path != null) ? (ClassNode) comp : null;
+ String newClass = (sel != null) ? sel.getClassName() : null;
+ if(newClass != null && newClass.length() > 0) {
+ textfield.setText(newClass);
+ popup.setVisible(false);
+ fireValueChanged();
+ }
+ }
+ return;
}
+ LoggingUtil.warning("actionPerformed triggered by unknown source: " + e.getSource());
}
@Override
public void stateChanged(ChangeEvent e) {
if(e.getSource() == child) {
fireValueChanged();
+ return;
}
- else {
- LoggingUtil.warning("stateChanged triggered by unknown source: " + e.getSource());
- }
+ LoggingUtil.warning("stateChanged triggered by unknown source: " + e.getSource());
}
@Override
public String getUserInput() {
- String val = (String) value.getSelectedItem();
+ String val = textfield.getText();
if(val.startsWith(DynamicParameters.STRING_USE_DEFAULT)) {
return null;
}