Finish implementation of ObjectArrayEditor
This commit is contained in:
parent
2242367832
commit
ef6033c303
@ -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);
|
||||
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -401,7 +401,6 @@ public class ArrayEditor extends JPanel implements PropertyEditor {
|
||||
}
|
||||
}
|
||||
|
||||
//setPreferredSize(new Dimension(400,500));
|
||||
|
||||
if (withAddButton && !(upperButtonList.contains(addButton))) {
|
||||
upperButtonList.add(addButton);
|
||||
@ -415,9 +414,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 +427,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 +463,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 +489,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 +527,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 +568,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 +634,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;
|
||||
|
213
src/main/java/eva2/gui/editor/ObjectArrayEditor.java
Normal file
213
src/main/java/eva2/gui/editor/ObjectArrayEditor.java
Normal file
@ -0,0 +1,213 @@
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
JButton configButton;
|
||||
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 = ((Item) 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;
|
||||
}
|
||||
if (true == false) {
|
||||
return true;
|
||||
} else {
|
||||
// Convert the listmodel to an array of strings 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);
|
||||
}
|
||||
}
|
33
src/main/java/eva2/tools/Primitives.java
Normal file
33
src/main/java/eva2/tools/Primitives.java
Normal 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;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user