diff --git a/src/main/java/eva2/gui/OptimizationEditorPanel.java b/src/main/java/eva2/gui/OptimizationEditorPanel.java index 8a80fb58..34b6eb6c 100644 --- a/src/main/java/eva2/gui/OptimizationEditorPanel.java +++ b/src/main/java/eva2/gui/OptimizationEditorPanel.java @@ -4,23 +4,17 @@ import eva2.gui.editor.GenericObjectEditor; import eva2.optimization.tools.FileTools; import eva2.tools.BasicResourceLoader; import eva2.tools.SerializedObject; -import eva2.tools.StringTools; -import eva2.util.annotation.Description; import eva2.yaml.BeanSerializer; import javax.swing.*; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; -import javax.swing.plaf.basic.BasicComboBoxRenderer; import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.beans.PropertyChangeSupport; import java.lang.reflect.Proxy; -import java.util.ArrayList; -import java.util.List; -import java.util.Vector; import java.util.logging.Logger; /** @@ -34,15 +28,11 @@ public class OptimizationEditorPanel extends JPanel implements ItemListener { /** * The chooser component */ - private JComboBox objectChooser; + private TypeSelector typeSelector; /** * The component that performs classifier customization */ private PropertySheetPanel propertySheetPanel; - /** - * The model containing the list of names to select from - */ - private DefaultComboBoxModel comboBoxModel; /** * Open object from disk */ @@ -77,9 +67,8 @@ public class OptimizationEditorPanel extends JPanel implements ItemListener { } private void buildTypeSelectionPanel() { - comboBoxModel = new DefaultComboBoxModel<>(new Vector<>()); - objectChooser = new JComboBox<>(comboBoxModel); - objectChooser.setEditable(false); + typeSelector = new TypeSelector(); + typeSelector.setEditable(false); GridBagConstraints gbConstraints = new GridBagConstraints(); @@ -89,7 +78,7 @@ public class OptimizationEditorPanel extends JPanel implements ItemListener { gbConstraints.gridy = 0; JLabel typeLabel = new JLabel("Type:"); - typeLabel.setLabelFor(objectChooser); + typeLabel.setLabelFor(typeSelector); typeLabel.setDisplayedMnemonic('t'); typeSelectionPanel.add(typeLabel, gbConstraints); @@ -97,7 +86,7 @@ public class OptimizationEditorPanel extends JPanel implements ItemListener { gbConstraints.gridy = 0; gbConstraints.weightx = 1.0; gbConstraints.fill = GridBagConstraints.HORIZONTAL; - typeSelectionPanel.add(objectChooser, gbConstraints); + typeSelectionPanel.add(typeSelector, gbConstraints); } /** @@ -181,9 +170,6 @@ public class OptimizationEditorPanel extends JPanel implements ItemListener { ((JDialog) container).dispose(); }); - // 10px padding - setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - setLayout(new GridBagLayout()); GridBagConstraints gbConstraints = new GridBagConstraints(); @@ -225,7 +211,7 @@ public class OptimizationEditorPanel extends JPanel implements ItemListener { updateChooser(); updateChildPropertySheet(); } - objectChooser.addItemListener(this); + typeSelector.addItemListener(this); } /** @@ -317,59 +303,24 @@ public class OptimizationEditorPanel extends JPanel implements ItemListener { * */ public void updateClassType() { - List classesLongNames; - ArrayList> instances = new ArrayList<>(5); - classesLongNames = GenericObjectEditor.getClassesFromProperties(genericObjectEditor.getClassType().getName(), instances); - LOGGER.finest("Selected type for OptimizationEditorPanel: " + genericObjectEditor.getClassType().getName()); - if (classesLongNames.size() > 1) { - Vector classesList = new Vector<>(); - String[] toolTips = collectComboToolTips(instances, tipMaxLen); - int i = 0; - for (String className : classesLongNames) { - String displayName = StringTools.cutClassName(className); + typeSelector.updateClassType(genericObjectEditor.getClassType().getName()); - classesList.add(new Item(className, displayName, toolTips[i++])); - } - comboBoxModel = new DefaultComboBoxModel<>(classesList); - objectChooser.setModel(comboBoxModel); - objectChooser.setRenderer(new ToolTipComboBoxRenderer()); + if (typeSelector.getItemCount() > 1) { typeSelectionPanel.setVisible(true); } else { typeSelectionPanel.setVisible(false); } } - private String[] collectComboToolTips(List> instances, int maxLen) { - String[] tips = new String[instances.size()]; - for (int i = 0; i < tips.length; i++) { - tips[i] = null; - - String tip = null; - - Description description = instances.get(i).getAnnotation(Description.class); - if (description != null) { - tip = description.value(); - } - - if (tip != null) { - if (tip.length() <= maxLen) { - tips[i] = tip; - } else { - tips[i] = tip.substring(0, maxLen - 2) + ".."; - } - } - } - return tips; - } public void updateChooser() { String objectName = genericObjectEditor.getValue().getClass().getName(); - for (int i = 0; i < comboBoxModel.getSize(); i++) { - Item element = comboBoxModel.getElementAt(i); + for (int i = 0; i < typeSelector.getItemCount(); i++) { + TypeSelectorItem element = typeSelector.getItemAt(i); if (objectName.equals(element.getId())) { - objectChooser.getModel().setSelectedItem(element); + typeSelector.getModel().setSelectedItem(element); break; } } @@ -393,8 +344,8 @@ public class OptimizationEditorPanel extends JPanel implements ItemListener { public void itemStateChanged(ItemEvent e) { String className; - if ((e.getSource() == objectChooser) && (e.getStateChange() == ItemEvent.SELECTED)) { - className = ((Item)objectChooser.getSelectedItem()).getId(); + if ((e.getSource() == typeSelector) && (e.getStateChange() == ItemEvent.SELECTED)) { + className = ((TypeSelectorItem) typeSelector.getSelectedItem()).getId(); try { Object n = Class.forName(className).newInstance(); genericObjectEditor.setValue(n); @@ -403,8 +354,8 @@ public class OptimizationEditorPanel extends JPanel implements ItemListener { System.err.println("Exception in itemStateChanged " + ex.getMessage()); System.err.println("Classpath is " + System.getProperty("java.class.path")); ex.printStackTrace(); - objectChooser.hidePopup(); - objectChooser.setSelectedIndex(0); + typeSelector.hidePopup(); + typeSelector.setSelectedIndex(0); JOptionPane.showMessageDialog(this, "Could not create an example of\n" + className + "\n" @@ -415,75 +366,3 @@ public class OptimizationEditorPanel extends JPanel implements ItemListener { } } } - -class ToolTipComboBoxRenderer extends BasicComboBoxRenderer { - - private static final long serialVersionUID = -5781643352198561208L; - - public ToolTipComboBoxRenderer() { - super(); - } - - @Override - public Component getListCellRendererComponent(JList list, Object value, - int index, boolean isSelected, boolean cellHasFocus) { - - super.getListCellRendererComponent(list, value, index, - isSelected, cellHasFocus); - - if (value != null) { - Item item = (Item)value; - setText(item.getDisplayName()); - - if (isSelected) { - setBackground(list.getSelectionBackground()); - setForeground(list.getSelectionForeground()); - list.setToolTipText(item.getDescription()); - } else { - setBackground(list.getBackground()); - setForeground(list.getForeground()); - } - } - - if (index == -1) { - Item item = (Item)value; - setText(item.getDisplayName()); - } - - setFont(list.getFont()); - return this; - } -} - -class Item -{ - private String id; - private String displayName; - private String description; - - public Item(String id, String displayName, String description) - { - this.id = id; - this.displayName = displayName; - this.description = description; - } - - public String getId() - { - return id; - } - - public String getDescription() - { - return description; - } - - public String getDisplayName() { - return displayName; - } - - public String toString() - { - return id; - } -} diff --git a/src/main/java/eva2/gui/PropertyDialog.java b/src/main/java/eva2/gui/PropertyDialog.java index 773e9d00..e9bf7fef 100644 --- a/src/main/java/eva2/gui/PropertyDialog.java +++ b/src/main/java/eva2/gui/PropertyDialog.java @@ -26,6 +26,8 @@ public class PropertyDialog extends JDialog { setLayout(new BorderLayout()); propertyEditor = editor; editorComponent = editor.getCustomEditor(); + + ((JPanel)getContentPane()).setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); add(editorComponent, BorderLayout.CENTER); pack(); diff --git a/src/main/java/eva2/gui/PropertyEditorProvider.java b/src/main/java/eva2/gui/PropertyEditorProvider.java index 212530f3..34166a51 100644 --- a/src/main/java/eva2/gui/PropertyEditorProvider.java +++ b/src/main/java/eva2/gui/PropertyEditorProvider.java @@ -3,12 +3,17 @@ package eva2.gui; import eva2.gui.editor.*; import eva2.optimization.individuals.codings.gp.GPArea; import eva2.optimization.operator.terminators.InterfaceTerminator; +import eva2.tools.Primitives; import eva2.tools.SelectedTag; import eva2.tools.StringSelection; import java.beans.PropertyDescriptor; import java.beans.PropertyEditor; import java.beans.PropertyEditorManager; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; public class PropertyEditorProvider { // if true, we use the GenericObjectEditor whenever no specific one is registered, so keep it true @@ -23,13 +28,24 @@ public class PropertyEditorProvider { public static PropertyEditor findEditor(Class cls) { PropertyEditor editor = PropertyEditorManager.findEditor(cls); + // Try to unwrap primitives + if (editor == null && Primitives.isWrapperType(cls)) { + editor = PropertyEditorManager.findEditor(Primitives.unwrap(cls)); + } + if ((editor == null) && useDefaultGOE) { if (cls.isArray()) { - editor = new ArrayEditor(); + Class unwrapped = Primitives.isWrapperType(cls.getComponentType()) ? Primitives.unwrap(cls.getComponentType()) : cls; + if (unwrapped.isPrimitive()) { + editor = new ArrayEditor(); + } else { + editor = new ObjectArrayEditor<>(unwrapped.getComponentType()); + } } else if (cls.isEnum()) { editor = new EnumEditor(); } else { editor = new GenericObjectEditor(); + ((GenericObjectEditor)editor).setClassType(cls); } } return editor; @@ -42,6 +58,7 @@ public class PropertyEditorProvider { * @return */ public static PropertyEditor findEditor(PropertyDescriptor prop, Object value) { + PropertyEditor editor = null; Class pec = prop.getPropertyEditorClass(); Class type = prop.getPropertyType(); @@ -56,10 +73,9 @@ public class PropertyEditorProvider { if (editor == null) { if (value != null) { - - // ToDo: This should be handled by the registerEditor below. findEditor however always returns the sun.beans.editor stuff. - if (value instanceof Enum) { - editor = new EnumEditor(); + // Try to unwrap primitives + if (Primitives.isWrapperType(value.getClass())) { + editor = PropertyEditorManager.findEditor(Primitives.unwrap(value.getClass())); } else { editor = PropertyEditorManager.findEditor(value.getClass()); } @@ -84,11 +100,17 @@ public class PropertyEditorProvider { if ((editor == null) && useDefaultGOE) { if (type.isArray()) { - editor = new ArrayEditor(); + Class unwrapped = Primitives.isWrapperType(type.getComponentType()) ? Primitives.unwrap(type.getComponentType()) : type; + if (unwrapped.isPrimitive()) { + editor = new ArrayEditor(); + } else { + editor = new ObjectArrayEditor<>(unwrapped.getComponentType()); + } } else if (type.isEnum()) { editor = new EnumEditor(); } else { editor = new GenericObjectEditor(); + ((GenericObjectEditor)editor).setClassType(type); } } } @@ -116,6 +138,8 @@ public class PropertyEditorProvider { PropertyEditorManager.registerEditor(Enum.class, EnumEditor.class); PropertyEditorManager.registerEditor(int[].class, ArrayEditor.class); PropertyEditorManager.registerEditor(double[].class, ArrayEditor.class); + PropertyEditorManager.registerEditor(String[].class, ArrayEditor.class); + PropertyEditorManager.registerEditor(InterfaceTerminator[].class, ArrayEditor.class); diff --git a/src/main/java/eva2/gui/PropertySheetPanel.java b/src/main/java/eva2/gui/PropertySheetPanel.java index f1617e25..578696d0 100644 --- a/src/main/java/eva2/gui/PropertySheetPanel.java +++ b/src/main/java/eva2/gui/PropertySheetPanel.java @@ -227,7 +227,7 @@ public final class PropertySheetPanel extends JPanel implements PropertyChangeLi gbConstraints.fill = GridBagConstraints.HORIZONTAL; gbConstraints.anchor = GridBagConstraints.PAGE_START; - add(buildTitledSeperator("Info"), gbConstraints); + add(new TitledSeparator("Info"), gbConstraints); gbConstraints.gridy = 1; add(infoPanel, gbConstraints); @@ -307,9 +307,7 @@ public final class PropertySheetPanel extends JPanel implements PropertyChangeLi gbConstraints.gridy = 2; - - - add(buildTitledSeperator("Properties"), gbConstraints); + add(new TitledSeparator("Properties"), gbConstraints); JScrollPane scrollableTable = new JScrollPane(propertyTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); gbConstraints.gridx = 0; @@ -320,6 +318,8 @@ public final class PropertySheetPanel extends JPanel implements PropertyChangeLi scrollableTable.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); add(scrollableTable, gbConstraints); + setMinimumSize(new Dimension(350, 0)); + validate(); setVisible(true); } @@ -333,24 +333,6 @@ public final class PropertySheetPanel extends JPanel implements PropertyChangeLi return label; } - private static JPanel buildTitledSeperator(String title) { - JPanel titledSeperator = new JPanel(new GridBagLayout()); - - GridBagConstraints gbConstraints = new GridBagConstraints(); - gbConstraints.gridx = 0; - gbConstraints.gridy = 0; - - titledSeperator.add(new JLabel("" + title), gbConstraints); - - gbConstraints.gridx = 1; - gbConstraints.gridy = 0; - gbConstraints.weightx = 1.0; - gbConstraints.fill = GridBagConstraints.HORIZONTAL; - titledSeperator.add(new JSeparator(JSeparator.HORIZONTAL), gbConstraints); - - return titledSeperator; - } - public static PropertyDescriptor[] getProperties(Object target) { BeanInfo bi; try { diff --git a/src/main/java/eva2/gui/TabbedFrameMaker.java b/src/main/java/eva2/gui/TabbedFrameMaker.java index 868e2ac3..17125f96 100644 --- a/src/main/java/eva2/gui/TabbedFrameMaker.java +++ b/src/main/java/eva2/gui/TabbedFrameMaker.java @@ -59,6 +59,8 @@ public class TabbedFrameMaker implements Serializable, PanelMaker, InterfaceNoti for (PanelMaker element : pmContainer) { JComponent panel = element.makePanel(); + + panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); if (element instanceof ModuleButtonPanelMaker) { extToolBar.add(panel); butPanelMkr = (ModuleButtonPanelMaker) element; diff --git a/src/main/java/eva2/gui/TitledSeparator.java b/src/main/java/eva2/gui/TitledSeparator.java new file mode 100644 index 00000000..75e521a7 --- /dev/null +++ b/src/main/java/eva2/gui/TitledSeparator.java @@ -0,0 +1,25 @@ +package eva2.gui; + +import javax.swing.*; +import java.awt.*; + +/** + * Created by halfdan on 17/12/15. + */ +public final class TitledSeparator extends JPanel { + public TitledSeparator(String title) { + setLayout(new GridBagLayout()); + + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.gridx = 0; + gbConstraints.gridy = 0; + + add(new JLabel("" + title), gbConstraints); + + gbConstraints.gridx = 1; + gbConstraints.gridy = 0; + gbConstraints.weightx = 1.0; + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + add(new JSeparator(JSeparator.HORIZONTAL), gbConstraints); + } +} diff --git a/src/main/java/eva2/gui/TypeSelector.java b/src/main/java/eva2/gui/TypeSelector.java new file mode 100644 index 00000000..74926af0 --- /dev/null +++ b/src/main/java/eva2/gui/TypeSelector.java @@ -0,0 +1,114 @@ +package eva2.gui; + +import eva2.gui.editor.GenericObjectEditor; +import eva2.tools.StringTools; +import eva2.util.annotation.Description; + +import javax.swing.*; +import javax.swing.plaf.basic.BasicComboBoxRenderer; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; +import java.util.logging.Logger; + +/** + * Created by fabian on 16/12/15. + */ +public class TypeSelector extends JComboBox { + private static final Logger LOGGER = Logger.getLogger(TypeSelector.class.getName()); + /** + * The model containing the list of names to select from + */ + private DefaultComboBoxModel comboBoxModel; + + public TypeSelector() { + + comboBoxModel = new DefaultComboBoxModel<>(new Vector<>()); + } + + public void updateClassType(String classTypeName) { + java.util.List classesLongNames; + ArrayList> instances = new ArrayList<>(5); + classesLongNames = GenericObjectEditor.getClassesFromProperties(classTypeName, instances); + LOGGER.finest("Selected type for OptimizationEditorPanel: " + classTypeName); + if (classesLongNames.size() > 1) { + Vector classesList = new Vector<>(); + String[] toolTips = collectComboToolTips(instances, 100); + int i = 0; + for (String className : classesLongNames) { + String displayName = StringTools.cutClassName(className); + + classesList.add(new TypeSelectorItem(className, displayName, toolTips[i++])); + } + comboBoxModel = new DefaultComboBoxModel<>(classesList); + this.setModel(comboBoxModel); + this.setRenderer(new ToolTipComboBoxRenderer()); + } + } + + private String[] collectComboToolTips(List> instances, int maxLen) { + String[] tips = new String[instances.size()]; + + for (int i = 0; i < tips.length; i++) { + tips[i] = null; + + String tip = null; + + Description description = instances.get(i).getAnnotation(Description.class); + if (description != null) { + tip = description.value(); + } + + if (tip != null) { + if (tip.length() <= maxLen) { + tips[i] = tip; + } else { + tips[i] = tip.substring(0, maxLen - 2) + ".."; + } + } + } + return tips; + } +} + + +class ToolTipComboBoxRenderer extends BasicComboBoxRenderer { + + private static final long serialVersionUID = -5781643352198561208L; + + public ToolTipComboBoxRenderer() { + super(); + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + + super.getListCellRendererComponent(list, value, index, + isSelected, cellHasFocus); + + if (value != null) { + TypeSelectorItem item = (TypeSelectorItem)value; + setText(item.getDisplayName()); + + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + list.setToolTipText(item.getDescription()); + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + } + + if (index == -1) { + TypeSelectorItem item = (TypeSelectorItem)value; + setText(item.getDisplayName()); + } + + setFont(list.getFont()); + return this; + } +} + diff --git a/src/main/java/eva2/gui/TypeSelectorItem.java b/src/main/java/eva2/gui/TypeSelectorItem.java new file mode 100644 index 00000000..310b0a48 --- /dev/null +++ b/src/main/java/eva2/gui/TypeSelectorItem.java @@ -0,0 +1,34 @@ +package eva2.gui; + +public class TypeSelectorItem +{ + private String id; + private String displayName; + private String description; + + public TypeSelectorItem(String id, String displayName, String description) + { + this.id = id; + this.displayName = displayName; + this.description = description; + } + + public String getId() + { + return id; + } + + public String getDescription() + { + return description; + } + + public String getDisplayName() { + return displayName; + } + + public String toString() + { + return id; + } +} diff --git a/src/main/java/eva2/gui/editor/ArrayEditor.java b/src/main/java/eva2/gui/editor/ArrayEditor.java index 645b3c28..ecd34ad1 100644 --- a/src/main/java/eva2/gui/editor/ArrayEditor.java +++ b/src/main/java/eva2/gui/editor/ArrayEditor.java @@ -79,7 +79,7 @@ public class ArrayEditor extends JPanel implements PropertyEditor { @Override public void actionPerformed(ActionEvent e) { - boolean consistentView = true; // be optimistic... + boolean consistentView; if (view instanceof PropertyText) { // check consistency! consistentView = ((PropertyText) view).checkConsistency(); if (!consistentView) { @@ -238,7 +238,7 @@ public class ArrayEditor extends JPanel implements PropertyEditor { list.ensureIndexIsVisible(index); propPanel.getEditor().setValue(item); propPanel.showDialog(); - propPanel = null; + } } } @@ -291,7 +291,7 @@ public class ArrayEditor extends JPanel implements PropertyEditor { ((GenericObjectEditor) e).setClassType(valueClass); } e.setValue(value); - JPanel cellPanel = new JPanel() { + return new JPanel() { @Override public void paintComponent(Graphics g) { @@ -315,7 +315,6 @@ public class ArrayEditor extends JPanel implements PropertyEditor { return newPref; } }; - return cellPanel; } catch (Exception ex) { return null; } @@ -401,7 +400,6 @@ public class ArrayEditor extends JPanel implements PropertyEditor { } } - //setPreferredSize(new Dimension(400,500)); if (withAddButton && !(upperButtonList.contains(addButton))) { upperButtonList.add(addButton); @@ -415,9 +413,6 @@ public class ArrayEditor extends JPanel implements PropertyEditor { // Upper Button Panel JPanel combiUpperPanel = new JPanel(getButtonLayout(0, upperButtonList)); - // ToDo Figure out how to now show this on Job Pane - combiUpperPanel.add(view); - view.setVisible(withAddButton); for (JButton but : upperButtonList) { combiUpperPanel.add(but); @@ -431,6 +426,12 @@ public class ArrayEditor extends JPanel implements PropertyEditor { gbConstraints.gridy = 0; add(combiUpperPanel, gbConstraints); + gbConstraints.gridy++; + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.weightx = 1.0; + add(view, gbConstraints); + view.setVisible(withAddButton); + // Job List gbConstraints.gridy++; gbConstraints.fill = GridBagConstraints.BOTH; @@ -461,13 +462,7 @@ public class ArrayEditor extends JPanel implements PropertyEditor { add(additionalCenterComp, gbConstraints); } - elementEditor.addPropertyChangeListener(new PropertyChangeListener() { - - @Override - public void propertyChange(final PropertyChangeEvent event) { - repaint(); - } - }); + elementEditor.addPropertyChangeListener(event -> repaint()); addPopupMenu(); } catch (Exception ex) { @@ -493,8 +488,8 @@ public class ArrayEditor extends JPanel implements PropertyEditor { * @return */ private LayoutManager getButtonLayout(int additionalOffset, List bList) { - int lines = 1 + ((bList.size() + additionalOffset - 1) / 3); int cols = 3; + int lines = 1 + ((bList.size() + additionalOffset - 1) / cols); return new GridLayout(lines, cols); } @@ -531,15 +526,11 @@ public class ArrayEditor extends JPanel implements PropertyEditor { * @return */ private ActionListener makeSelectionKnownAL(final ActionListener al) { - return new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - if (selectableList != null) { - selectableList.setSelectionByIndices(elementList.getSelectedIndices()); - } - al.actionPerformed(e); + return e -> { + if (selectableList != null) { + selectableList.setSelectionByIndices(elementList.getSelectedIndices()); } + al.actionPerformed(e); }; } @@ -576,12 +567,7 @@ public class ArrayEditor extends JPanel implements PropertyEditor { } public boolean areAllSelected() { - for (int i = 0; i < elementList.getModel().getSize(); i++) { - if (!elementList.isSelectedIndex(i)) { - return false; - } - } - return true; + return elementList.getSelectedIndices().length == elementList.getModel().getSize(); } /** @@ -647,7 +633,6 @@ public class ArrayEditor extends JPanel implements PropertyEditor { private JMenuItem createMenuItem(String title, boolean enabled, ActionListener aListener) { JMenuItem item = new JMenuItem(title); - // if (bgColor!=null) item.setForeground(bgColor); item.addActionListener(aListener); item.setEnabled(enabled); return item; diff --git a/src/main/java/eva2/gui/editor/ObjectArrayEditor.java b/src/main/java/eva2/gui/editor/ObjectArrayEditor.java new file mode 100644 index 00000000..09032cef --- /dev/null +++ b/src/main/java/eva2/gui/editor/ObjectArrayEditor.java @@ -0,0 +1,214 @@ +package eva2.gui.editor; + +import eva2.gui.*; +import eva2.tools.StringTools; + +import javax.swing.*; +import java.awt.*; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.beans.PropertyEditor; +import java.lang.reflect.Array; + +/** + * Created by halfdan on 17/12/15. + */ +public class ObjectArrayEditor extends JPanel implements PropertyEditor { + private T[] value; + private JList objectList; + private DefaultListModel listModel; + private PropertyChangeSupport propChangeSupport; + private JButton configButton; + + public ObjectArrayEditor(Class type) { + listModel = new DefaultListModel<>(); + + setLayout(new GridBagLayout()); + GridBagConstraints c = new GridBagConstraints(); + c.gridwidth = 2; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1.0; + c.weighty = 0.0; + c.gridx = 0; + c.gridy = 0; + + TypeSelector typeSelector = new TypeSelector(); + typeSelector.updateClassType(type.getName()); + + add(typeSelector, c); + + JButton addButton = new JButton("Add"); + c.gridwidth = 1; + c.gridx = 2; + c.gridy = 0; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1.0; + c.weighty = 0.0; + add(addButton, c); + + JButton removeButton = new JButton("Remove"); + c.gridx = 2; + c.gridy = 1; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1.0; + c.weighty = 0.0; + add(removeButton, c); + + configButton = new JButton("Config"); + c.gridx = 2; + c.gridy = 2; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1.0; + c.weighty = 0.0; + + add(configButton, c); + + objectList = new JList<>(listModel); + objectList.setVisibleRowCount(10); + + c.gridwidth = 2; + c.gridheight = 5; + c.gridx = 0; + c.gridy = 1; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1.0; + c.weighty = 1.0; + + JScrollPane scrollPane = new JScrollPane(objectList); + add(scrollPane, c); + + addButton.addActionListener(event -> { + String className = ((TypeSelectorItem) typeSelector.getSelectedItem()).getId(); + try { + T n = (T) Class.forName(className).newInstance(); + listModel.addElement(n); + propChangeSupport.firePropertyChange("", null, null); + } catch (Exception ex) { + System.err.println("Exception in itemStateChanged " + ex.getMessage()); + System.err.println("Classpath is " + System.getProperty("java.class.path")); + ex.printStackTrace(); + + JOptionPane.showMessageDialog(this, + "Could not create an example of\n" + + className + "\n" + + "from the current classpath. Is the resource folder at the right place?\nIs the class abstract or the default constructor missing?", + "GenericObjectEditor", + JOptionPane.ERROR_MESSAGE); + } + }); + + removeButton.addActionListener(event -> { + if (!objectList.isSelectionEmpty()) { + listModel.remove(objectList.getSelectedIndex()); + propChangeSupport.firePropertyChange("", null, null); + } + }); + + configButton.addActionListener(event -> { + T selected = objectList.getSelectedValue(); + PropertyEditor editor = PropertyEditorProvider.findEditor(selected.getClass()); + editor.setValue(selected); + PropertyDialog propertyDialog = new PropertyDialog(null, editor, StringTools.cutClassName(editor.getClass().getName())); + propertyDialog.setPreferredSize(new Dimension(500, 300)); + propertyDialog.setModal(true); + propertyDialog.setVisible(true); + propChangeSupport.firePropertyChange("", null, null); + }); + } + + @Override + public void setValue(Object value) { + this.value = (T[])value; + listModel.removeAllElements(); + for(T i : this.value) { + listModel.addElement(i); + } + } + + @Override + public Object getValue() { + if (listModel == null) { + return null; + } else { + // Convert the listmodel to an array of T and return it. + int length = listModel.getSize(); + Object result = Array.newInstance(value.getClass().getComponentType(), length); + for (int i = 0; i < length; i++) { + Array.set(result, i, listModel.elementAt(i)); + } + return result; + } + } + + @Override + public boolean isPaintable() { + return true; + } + + @Override + public void paintValue(Graphics gfx, Rectangle box) { + FontMetrics fm = gfx.getFontMetrics(); + int vpad = (box.height - fm.getAscent()) / 2; + String rep; + if (listModel.getSize() == 0) { + rep = "Empty"; + } else { + rep = listModel.getSize() + " of " + StringTools.cutClassName(value.getClass().getComponentType().getName()); + Object maybeName = BeanInspector.callIfAvailable(listModel.get(0), "getName", new Object[]{}); + if (maybeName != null) { + rep = rep + " (" + maybeName + "...)"; + } + } + gfx.drawString(rep, 2, fm.getHeight() + vpad - 3); + } + + @Override + public String getJavaInitializationString() { + return null; + } + + @Override + public String getAsText() { + return null; + } + + @Override + public void setAsText(String text) throws IllegalArgumentException { + throw new IllegalArgumentException(text); + } + + @Override + public String[] getTags() { + return new String[0]; + } + + @Override + public Component getCustomEditor() { + return this; + } + + @Override + public boolean supportsCustomEditor() { + return true; + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener l) { + if (propChangeSupport == null) { + propChangeSupport = new PropertyChangeSupport(this); + } + propChangeSupport.addPropertyChangeListener(l); + } + + @Override + public void removePropertyChangeListener(PropertyChangeListener l) { + if (propChangeSupport == null) { + propChangeSupport = new PropertyChangeSupport(this); + } + propChangeSupport.removePropertyChangeListener(l); + } + + public void toggleConfigButton() { + this.configButton.setEnabled(!configButton.isEnabled()); + } +} diff --git a/src/main/java/eva2/optimization/statistics/OptimizationJobList.java b/src/main/java/eva2/optimization/statistics/OptimizationJobList.java index bf7a3c7d..fcc93292 100644 --- a/src/main/java/eva2/optimization/statistics/OptimizationJobList.java +++ b/src/main/java/eva2/optimization/statistics/OptimizationJobList.java @@ -162,11 +162,8 @@ public class OptimizationJobList extends PropertySelectableList (StatisticsOnTwoSampledData[]) StatisticalEvaluation.statsParams.getTwoSampledStats().getSelectedEnum(StatisticsOnTwoSampledData.values())); ActionListener sl = e -> arrayEditor.selectDeselectAll(); - ActionListener cliButtonListener = actionEvent -> System.out.println("Generating CLI call"); - ActionListener sal = e -> jobList.saveSelectedJobs(arrayEditor); - arrayEditor.addUpperActionButton("Get CLI", cliButtonListener); arrayEditor.addUpperActionButton("(De-)Sel. all", sl); arrayEditor.addUpperActionButton("Test Stats", al); diff --git a/src/main/java/eva2/tools/Primitives.java b/src/main/java/eva2/tools/Primitives.java new file mode 100644 index 00000000..3c271c1d --- /dev/null +++ b/src/main/java/eva2/tools/Primitives.java @@ -0,0 +1,33 @@ +package eva2.tools; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by halfdan on 17/12/15. + */ +public class Primitives { + public static Class unwrap(Class clazz) { + return getWrapperTypes().get(clazz); + } + + public static boolean isWrapperType(Class clazz) + { + return getWrapperTypes().containsKey(clazz); + } + + private static Map, Class> getWrapperTypes() + { + Map, Class> ret = new HashMap<>(); + ret.put(Boolean.class, boolean.class); + ret.put(Character.class, char.class); + ret.put(Byte.class, byte.class); + ret.put(Short.class, short.class); + ret.put(Integer.class, int.class); + ret.put(Long.class, long.class); + ret.put(Float.class, float.class); + ret.put(Double.class, double.class); + ret.put(Void.class, void.class); + return ret; + } +} diff --git a/src/test/java/eva2/gui/TypeSelectorItemTest.java b/src/test/java/eva2/gui/TypeSelectorItemTest.java new file mode 100644 index 00000000..4ac5e135 --- /dev/null +++ b/src/test/java/eva2/gui/TypeSelectorItemTest.java @@ -0,0 +1,40 @@ +package eva2.gui; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class TypeSelectorItemTest { + TypeSelectorItem item; + + @Before + public void setUp() throws Exception { + item = new TypeSelectorItem( + "eva2.problem.AbstractProblemDouble", + "AbstractProblemDouble", + "An abstract problem" + ); + } + + @Test + public void testGetId() throws Exception { + assertEquals("eva2.problem.AbstractProblemDouble", item.getId()); + } + + @Test + public void testGetDescription() throws Exception { + assertEquals("An abstract problem", item.getDescription()); + } + + @Test + public void testGetDisplayName() throws Exception { + assertEquals("AbstractProblemDouble", item.getDisplayName()); + } + + @Test + public void testToString() throws Exception { + // Should match the id + assertEquals("eva2.problem.AbstractProblemDouble", item.toString()); + } +} \ No newline at end of file