diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java')
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java | 148 |
1 files changed, 56 insertions, 92 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java index 182c7a0a..a49ec23f 100644 --- a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java +++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.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 @@ -27,20 +27,24 @@ 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.Icon; 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 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.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; @@ -54,8 +58,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter; * @author Erich Schubert * * @apiviz.uses ClassListParameter + * @apiviz.uses ClassTree */ public class ClassListParameterConfigurator extends AbstractSingleParameterConfigurator<ClassListParameter<?>> implements ActionListener, ChangeListener { + /** + * Configurator for children + */ final ConfiguratorPanel child; /** @@ -74,15 +82,16 @@ public class ClassListParameterConfigurator extends AbstractSingleParameterConfi final JButton button; /** - * The combobox we are abusing to produce the popup + * The popup we use. */ - final JComboBox<String> combo; + final TreePopup popup; /** - * The popup menu. + * Constructor. + * + * @param cp Class list parameter + * @param parent Parent component */ - final SuperPopup popup; - public ClassListParameterConfigurator(ClassListParameter<?> cp, JComponent parent) { super(cp, parent); textfield = new JTextField(); @@ -95,26 +104,20 @@ public class ClassListParameterConfigurator extends AbstractSingleParameterConfi 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); + 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(); @@ -156,82 +159,43 @@ public class ClassListParameterConfigurator extends AbstractSingleParameterConfi public void actionPerformed(ActionEvent e) { if(e.getSource() == button) { popup.show(panel); + return; } - 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) { + if(e.getSource() == textfield) { fireValueChanged(); + return; } - 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<String> 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); + 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) { + String val = textfield.getText(); + val = (val.length() > 0) ? val + ClassListParameter.LIST_SEP + newClass : newClass; + textfield.setText(val); + 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 |