Merge branch 'object-array-editor' into 'master'

Object array editor

This introduces a new generic ObjectArrayEditor which allows adding assignable classes of a type T to a list (shown in a JList) and configuring those objects in a GenericObjectEditor instance. 

![Screen_Shot_2015-12-16_at_20.05.56](/uploads/6175a0ca3fb67db382d32353a6b5fd6c/Screen_Shot_2015-12-16_at_20.05.56.png)

This thing is useful in multiple instances:

- MetaEvA
  - To select problems and configure them (dimension, init range, etc.)
  - To select optimizers (configuration will be ignored)
- Experiment Generator (future project)
  - To select problems and configure optimizer to be executed in a run matrix

ToDo:

- [x] Allow deactivating/hiding the "Config" button
- [x] Make sure this will automatically be used for objects that have an `Anything[]`
- [x] Find a way to get a better `toString()` (CEC2005 for some reason looks fine)

See merge request !10
This commit is contained in:
Fabian Becker 2015-12-18 16:50:09 +01:00
commit 6a24e01e45
13 changed files with 529 additions and 198 deletions

View File

@ -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<Item> 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<Item> 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<String> classesLongNames;
ArrayList<Class<?>> 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<Item> 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<Class<?>> 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;
}
}

View File

@ -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();

View File

@ -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);

View File

@ -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("<html><b>" + 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 {

View File

@ -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;

View File

@ -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("<html><b>" + title), gbConstraints);
gbConstraints.gridx = 1;
gbConstraints.gridy = 0;
gbConstraints.weightx = 1.0;
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
add(new JSeparator(JSeparator.HORIZONTAL), gbConstraints);
}
}

View File

@ -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<TypeSelectorItem> {
private static final Logger LOGGER = Logger.getLogger(TypeSelector.class.getName());
/**
* The model containing the list of names to select from
*/
private DefaultComboBoxModel<TypeSelectorItem> comboBoxModel;
public TypeSelector() {
comboBoxModel = new DefaultComboBoxModel<>(new Vector<>());
}
public void updateClassType(String classTypeName) {
java.util.List<String> classesLongNames;
ArrayList<Class<?>> instances = new ArrayList<>(5);
classesLongNames = GenericObjectEditor.getClassesFromProperties(classTypeName, instances);
LOGGER.finest("Selected type for OptimizationEditorPanel: " + classTypeName);
if (classesLongNames.size() > 1) {
Vector<TypeSelectorItem> 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<Class<?>> 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;
}
}

View File

@ -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;
}
}

View File

@ -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<JButton> 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;

View File

@ -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<T> extends JPanel implements PropertyEditor {
private T[] value;
private JList<T> objectList;
private DefaultListModel<T> listModel;
private PropertyChangeSupport propChangeSupport;
private JButton configButton;
public ObjectArrayEditor(Class<T> 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());
}
}

View File

@ -162,11 +162,8 @@ public class OptimizationJobList extends PropertySelectableList<OptimizationJob>
(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);

View File

@ -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<?>, Class<?>> getWrapperTypes()
{
Map<Class<?>, 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;
}
}

View File

@ -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());
}
}