435 lines
13 KiB
Java
435 lines
13 KiB
Java
package javaeva.gui;
|
|
/*
|
|
* Title: JavaEvA
|
|
* Description:
|
|
* Copyright: Copyright (c) 2003
|
|
* Company: University of Tuebingen, Computer Architecture
|
|
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher
|
|
* @version: $Revision: 235 $
|
|
* $Date: 2007-11-08 13:53:51 +0100 (Thu, 08 Nov 2007) $
|
|
* $Author: mkron $
|
|
*/
|
|
/*==========================================================================*
|
|
* IMPORTS
|
|
*==========================================================================*/
|
|
|
|
import javaeva.tools.EVAHELP;
|
|
import javaeva.tools.SelectedTag;
|
|
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.JLabel;
|
|
import javax.swing.JList;
|
|
import javax.swing.JButton;
|
|
import javax.swing.event.ListSelectionListener;
|
|
|
|
import javax.swing.ListCellRenderer;
|
|
import javax.swing.event.ListSelectionEvent;
|
|
import javax.swing.SwingConstants;
|
|
import javax.swing.JOptionPane;
|
|
import javax.swing.DefaultListModel;
|
|
import javax.swing.JScrollPane;
|
|
import javax.swing.DefaultListCellRenderer;
|
|
import java.beans.PropertyEditor;
|
|
import java.beans.PropertyChangeSupport;
|
|
import java.beans.PropertyChangeListener;
|
|
import java.beans.PropertyChangeEvent;
|
|
import java.beans.PropertyEditorManager;
|
|
import java.lang.reflect.Array;
|
|
/*==========================================================================*
|
|
* CLASS DECLARATION
|
|
*==========================================================================*/
|
|
public class GenericArrayEditor extends JPanel
|
|
implements PropertyEditor {
|
|
/** Handles property change notification */
|
|
private PropertyChangeSupport m_Support = new PropertyChangeSupport(this);
|
|
/** The label for when we can't edit that type */
|
|
private JLabel m_Label = new JLabel("Can't edit", SwingConstants.CENTER);
|
|
/** The list component displaying current values */
|
|
private JList m_ElementList = new JList();
|
|
/** The class of objects allowed in the array */
|
|
private Class m_ElementClass = String.class;
|
|
/** The defaultlistmodel holding our data */
|
|
private DefaultListModel m_ListModel;
|
|
/** The property editor for the class we are editing */
|
|
private PropertyEditor m_ElementEditor;
|
|
/** Click this to delete the selected array values */
|
|
private JButton m_DeleteBut = new JButton("Delete");
|
|
/** Click to add the current object configuration to the array */
|
|
private JButton m_AddBut = new JButton("Add");
|
|
/** Listens to buttons being pressed and taking the appropriate action */
|
|
private ActionListener m_InnerActionListener =
|
|
new ActionListener() {
|
|
//
|
|
public void actionPerformed(ActionEvent e) {
|
|
if (e.getSource() == m_DeleteBut) {
|
|
int [] selected = m_ElementList.getSelectedIndices();
|
|
if (selected != null) {
|
|
for (int i = 0; i < selected.length; i++) {
|
|
int current = selected[i];
|
|
m_ListModel.removeElementAt(current);
|
|
if (m_ListModel.size() > current) {
|
|
m_ElementList.setSelectedIndex(current);
|
|
}
|
|
}
|
|
m_Support.firePropertyChange("", null, null);
|
|
}
|
|
if (m_ElementList.getSelectedIndex() == -1) {
|
|
m_DeleteBut.setEnabled(false);
|
|
}
|
|
} else if (e.getSource() == m_AddBut) {
|
|
int selected = m_ElementList.getSelectedIndex();
|
|
Object addObj = m_ElementEditor.getValue();
|
|
|
|
// Make a full copy of the object using serialization
|
|
try {
|
|
SerializedObject so = new SerializedObject(addObj);
|
|
addObj = so.getObject();
|
|
if (selected != -1) {
|
|
m_ListModel.insertElementAt(addObj, selected);
|
|
} else {
|
|
m_ListModel.addElement(addObj);
|
|
}
|
|
m_Support.firePropertyChange("", null, null);
|
|
} catch (Exception ex) {
|
|
JOptionPane.showMessageDialog(GenericArrayEditor.this,"Could not create an object copy",null,JOptionPane.ERROR_MESSAGE);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/** Listens to list items being selected and takes appropriate action */
|
|
private ListSelectionListener m_InnerSelectionListener =
|
|
new ListSelectionListener() {
|
|
//
|
|
public void valueChanged(ListSelectionEvent e) {
|
|
|
|
if (e.getSource() == m_ElementList) {
|
|
// Enable the delete button
|
|
//System.out.println("m_ElementList.getSelectedIndex()"+m_ElementList.getSelectedIndex());
|
|
if (m_ElementList.getSelectedIndex() != -1) {
|
|
m_DeleteBut.setEnabled(true);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* Sets up the array editor.
|
|
*/
|
|
public GenericArrayEditor() {
|
|
setLayout(new BorderLayout());
|
|
add(m_Label, BorderLayout.CENTER);
|
|
m_DeleteBut.addActionListener(m_InnerActionListener);
|
|
m_AddBut.addActionListener(m_InnerActionListener);
|
|
m_ElementList.addListSelectionListener(m_InnerSelectionListener);
|
|
m_AddBut.setToolTipText("Add the current item to the list");
|
|
m_DeleteBut.setToolTipText("Delete the selected list item");
|
|
}
|
|
|
|
/* This class handles the creation of list cell renderers from the
|
|
* property editors.
|
|
*/
|
|
private class EditorListCellRenderer implements ListCellRenderer {
|
|
/** The class of the property editor for array objects */
|
|
private Class m_EditorClass;
|
|
/** The class of the array values */
|
|
private Class m_ValueClass;
|
|
/**
|
|
* Creates the list cell renderer.
|
|
*
|
|
* @param editorClass The class of the property editor for array objects
|
|
* @param valueClass The class of the array values
|
|
*/
|
|
public EditorListCellRenderer(Class editorClass, Class valueClass) {
|
|
m_EditorClass = editorClass;
|
|
m_ValueClass = valueClass;
|
|
}
|
|
/**
|
|
* Creates a cell rendering component.
|
|
*
|
|
* @param JList the list that will be rendered in
|
|
* @param Object the cell value
|
|
* @param int which element of the list to render
|
|
* @param boolean true if the cell is selected
|
|
* @param boolean true if the cell has the focus
|
|
* @return the rendering component
|
|
*/
|
|
public Component getListCellRendererComponent(final JList list,
|
|
final Object value,
|
|
final int index,
|
|
final boolean isSelected,
|
|
final boolean cellHasFocus) {
|
|
try {
|
|
final PropertyEditor e = (PropertyEditor)m_EditorClass.newInstance();
|
|
if (e instanceof GenericObjectEditor) {
|
|
// ((GenericObjectEditor) e).setDisplayOnly(true);
|
|
((GenericObjectEditor) e).setClassType(m_ValueClass);
|
|
}
|
|
e.setValue(value);
|
|
return new JPanel() {
|
|
/**
|
|
*
|
|
*/
|
|
public void paintComponent(Graphics g) {
|
|
Insets i = this.getInsets();
|
|
Rectangle box = new Rectangle(i.left,i.top,
|
|
this.getWidth(), //- i.right,
|
|
this.getHeight() );//- i.bottom +20);
|
|
g.setColor(isSelected ? list.getSelectionBackground() : list.getBackground());
|
|
g.fillRect(0, 0, this.getWidth(), this.getHeight());
|
|
g.setColor(isSelected ? list.getSelectionForeground(): list.getForeground());
|
|
e.paintValue(g, box);
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
public Dimension getPreferredSize() {
|
|
// Dimension newPref = getPreferredSize();
|
|
// newPref.height = getFontMetrics(getFont()).getHeight() * 6 / 4; //6 / 4;
|
|
// newPref.width = newPref.height * 6; //5
|
|
// setPreferredSize(newPref);
|
|
|
|
|
|
// Font f = this.getFont();
|
|
// FontMetrics fm = this.getFontMetrics(f);
|
|
// return new Dimension(0, fm.getHeight());
|
|
|
|
Font f = this.getFont();
|
|
FontMetrics fm = this.getFontMetrics(f);
|
|
Dimension newPref = new Dimension(0, fm.getHeight());
|
|
newPref.height = getFontMetrics(getFont()).getHeight() * 6 / 4; //6 / 4;
|
|
newPref.width = newPref.height * 6; //5
|
|
return newPref;
|
|
}
|
|
};
|
|
} catch (Exception ex) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the type of object being edited, so attempts to find an
|
|
* appropriate propertyeditor.
|
|
*
|
|
* @param o a value of type 'Object'
|
|
*/
|
|
private void updateEditorType(Object o) {
|
|
|
|
// Determine if the current object is an array
|
|
m_ElementEditor = null; m_ListModel = null;
|
|
removeAll();
|
|
|
|
if ((o != null) && (o.getClass().isArray())) {
|
|
Class elementClass = o.getClass().getComponentType();
|
|
PropertyEditor editor = PropertyEditorProvider.findEditor(elementClass);
|
|
Component view = null;
|
|
ListCellRenderer lcr = new DefaultListCellRenderer();
|
|
if (editor != null) {
|
|
if (editor instanceof GenericObjectEditor) {
|
|
((GenericObjectEditor) editor).setClassType(elementClass);
|
|
}
|
|
if (editor.isPaintable() && editor.supportsCustomEditor()) {
|
|
view = new PropertyPanel(editor);
|
|
lcr = new EditorListCellRenderer(editor.getClass(), elementClass);
|
|
} else if (editor.getTags() != null) {
|
|
view = new PropertyValueSelector(editor);
|
|
} else if (editor.getAsText() != null) {
|
|
view = new PropertyText(editor);
|
|
}
|
|
}
|
|
if (view == null) {
|
|
System.err.println("No property editor for class: "
|
|
+ elementClass.getName());
|
|
} else {
|
|
m_ElementEditor = editor;
|
|
|
|
// Create the ListModel and populate it
|
|
m_ListModel = new DefaultListModel();
|
|
m_ElementClass = elementClass;
|
|
for (int i = 0; i < Array.getLength(o); i++) {
|
|
m_ListModel.addElement(Array.get(o,i));
|
|
}
|
|
m_ElementList.setCellRenderer(lcr);
|
|
m_ElementList.setModel(m_ListModel);
|
|
if (m_ListModel.getSize() > 0) {
|
|
m_ElementList.setSelectedIndex(0);
|
|
m_DeleteBut.setEnabled(true);
|
|
} else {
|
|
m_DeleteBut.setEnabled(false);
|
|
}
|
|
|
|
try {
|
|
if (m_ListModel.getSize() > 0) {
|
|
m_ElementEditor.setValue(m_ListModel.getElementAt(0));
|
|
} else {
|
|
if (m_ElementEditor instanceof GenericObjectEditor) {
|
|
((GenericObjectEditor)m_ElementEditor).setDefaultValue();
|
|
} else {
|
|
m_ElementEditor.setValue(m_ElementClass.newInstance());
|
|
}
|
|
}
|
|
|
|
JPanel panel = new JPanel();
|
|
panel.setLayout(new BorderLayout());
|
|
panel.add(view, BorderLayout.CENTER);
|
|
panel.add(m_AddBut, BorderLayout.EAST);
|
|
add(panel, BorderLayout.NORTH);
|
|
add(new JScrollPane(m_ElementList), BorderLayout.CENTER);
|
|
add(m_DeleteBut, BorderLayout.SOUTH);
|
|
m_ElementEditor.addPropertyChangeListener(new PropertyChangeListener() {
|
|
public void propertyChange(PropertyChangeEvent e) {
|
|
repaint();
|
|
}
|
|
});
|
|
} catch (Exception ex) {
|
|
System.err.println(ex.getMessage());
|
|
m_ElementEditor = null;
|
|
}
|
|
}
|
|
}
|
|
if (m_ElementEditor == null) {
|
|
add(m_Label, BorderLayout.CENTER);
|
|
}
|
|
m_Support.firePropertyChange("", null, null);
|
|
validate();
|
|
}
|
|
/**
|
|
* Sets the current object array.
|
|
*
|
|
* @param o an object that must be an array.
|
|
*/
|
|
public void setValue(Object o) {
|
|
// Create a new list model, put it in the list and resize?
|
|
updateEditorType(o);
|
|
}
|
|
|
|
/**
|
|
* Gets the current object array.
|
|
*
|
|
* @return the current object array
|
|
*/
|
|
public Object getValue() {
|
|
|
|
if (m_ListModel == null) {
|
|
return null;
|
|
}
|
|
// Convert the listmodel to an array of strings and return it.
|
|
int length = m_ListModel.getSize();
|
|
Object result = Array.newInstance(m_ElementClass, length);
|
|
for (int i = 0; i < length; i++) {
|
|
Array.set(result, i, m_ListModel.elementAt(i));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Supposedly returns an initialization string to create a classifier
|
|
* identical to the current one, including it's state, but this doesn't
|
|
* appear possible given that the initialization string isn't supposed to
|
|
* contain multiple statements.
|
|
*
|
|
* @return the java source code initialisation string
|
|
*/
|
|
public String getJavaInitializationString() {
|
|
return "null";
|
|
}
|
|
|
|
/**
|
|
* Returns true to indicate that we can paint a representation of the
|
|
* string array
|
|
*
|
|
* @return true
|
|
*/
|
|
public boolean isPaintable() {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Paints a representation of the current classifier.
|
|
*
|
|
* @param gfx the graphics context to use
|
|
* @param box the area we are allowed to paint into
|
|
*/
|
|
public void paintValue(Graphics gfx, Rectangle box) {
|
|
FontMetrics fm = gfx.getFontMetrics();
|
|
int vpad = (box.height - fm.getAscent()) / 2;
|
|
// System.out.println(m_ListModel + " --- " + m_ElementClass);
|
|
String rep = m_ListModel.getSize() + " " + EVAHELP.cutClassName(m_ElementClass.getName());
|
|
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3 );
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
public String getAsText() {
|
|
return null;
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
public void setAsText(String text) throws IllegalArgumentException {
|
|
throw new IllegalArgumentException(text);
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
public String[] getTags() {
|
|
return null;
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
public boolean supportsCustomEditor() {
|
|
return true;
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
public Component getCustomEditor() {
|
|
return this;
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
public void addPropertyChangeListener(PropertyChangeListener l) {
|
|
m_Support.addPropertyChangeListener(l);
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
public void removePropertyChangeListener(PropertyChangeListener l) {
|
|
m_Support.removePropertyChangeListener(l);
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public static void main(String [] args) {
|
|
try {
|
|
java.beans.PropertyEditorManager.registerEditor(SelectedTag.class,TagEditor.class);
|
|
java.beans.PropertyEditorManager.registerEditor(String [].class,GenericArrayEditor.class);
|
|
java.beans.PropertyEditorManager.registerEditor(double [].class,GenericArrayEditor.class);
|
|
GenericArrayEditor editor = new GenericArrayEditor();
|
|
|
|
double [] initial = { 1, 2, 34,656,46 };
|
|
PropertyDialog pd = new PropertyDialog(editor,EVAHELP.cutClassName(editor.getClass().getName())
|
|
, 100, 100);
|
|
pd.setSize(200,200);
|
|
pd.addWindowListener(new WindowAdapter() {
|
|
public void windowClosing(WindowEvent e) {
|
|
System.exit(0);
|
|
}
|
|
});
|
|
editor.setValue(initial);
|
|
//ce.validate();
|
|
} catch (Exception ex) {
|
|
ex.printStackTrace();
|
|
System.err.println(ex.getMessage());
|
|
}
|
|
}
|
|
}
|
|
|