From 4c81ca651ee2d79d63756af2697800269e268a23 Mon Sep 17 00:00:00 2001 From: Marcel Kronfeld Date: Wed, 9 Feb 2011 13:33:11 +0000 Subject: [PATCH] Adding a basic implementation of an EvATreeView - to test, use the command line argument --treeView --- src/eva2/client/EvAClient.java | 59 +++- src/eva2/gui/EvATabbedFrameMaker.java | 22 +- src/eva2/gui/EvATreeNode.java | 85 ++++++ src/eva2/gui/EvATreeSelectionListener.java | 66 +++++ src/eva2/gui/GOEPanel.java | 157 ++++------ src/eva2/gui/GenericObjectEditor.java | 4 +- src/eva2/gui/JParaPanel.java | 20 +- src/eva2/gui/PropertySheetPanel.java | 272 ++++++++++++------ .../server/modules/GenericModuleAdapter.java | 14 +- 9 files changed, 474 insertions(+), 225 deletions(-) create mode 100644 src/eva2/gui/EvATreeNode.java create mode 100644 src/eva2/gui/EvATreeSelectionListener.java diff --git a/src/eva2/client/EvAClient.java b/src/eva2/client/EvAClient.java index 81ff44ef..7972e063 100644 --- a/src/eva2/client/EvAClient.java +++ b/src/eva2/client/EvAClient.java @@ -33,6 +33,7 @@ import java.util.Vector; import javax.swing.ButtonGroup; import javax.swing.ImageIcon; +import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenuBar; @@ -41,7 +42,9 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JRadioButtonMenuItem; +import javax.swing.JScrollPane; import javax.swing.JSeparator; +import javax.swing.JTree; import javax.swing.JWindow; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; @@ -49,15 +52,19 @@ import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; +import javax.swing.tree.DefaultMutableTreeNode; import eva2.EvAInfo; import eva2.gui.BeanInspector; import eva2.gui.EvATabbedFrameMaker; +import eva2.gui.EvATreeNode; +import eva2.gui.EvATreeSelectionListener; import eva2.gui.ExtAction; import eva2.gui.HtmlDemo; import eva2.gui.JEFrame; import eva2.gui.JEFrameRegister; import eva2.gui.JExtMenu; +import eva2.gui.JParaPanel; import eva2.gui.LogPanel; import eva2.server.EvAServer; import eva2.server.go.InterfaceGOParameters; @@ -133,7 +140,8 @@ public class EvAClient implements RemoteStateListener, Serializable { private transient String currentModule = null; Vector superListenerList = null; - private boolean withGUI = true ; + private boolean withGUI = true; + private boolean withTreeView = false; private EvATabbedFrameMaker frmMkr = null; public void addRemoteStateListener(RemoteStateListener l) { @@ -170,7 +178,7 @@ public class EvAClient implements RemoteStateListener, Serializable { * @param nosplash */ public EvAClient(final String hostName, final String paramsFile, boolean autorun, boolean nosplash) { - this(hostName, null, paramsFile, null, autorun, nosplash, false); + this(hostName, null, paramsFile, null, autorun, nosplash, false, false); } /** @@ -199,8 +207,8 @@ public class EvAClient implements RemoteStateListener, Serializable { * @param noSplash * @param noGui */ - public EvAClient(final String hostName, String paramsFile, boolean autorun, boolean noSplash, boolean noGui) { - this(hostName, null, paramsFile, null, autorun, noSplash, noGui); + public EvAClient(final String hostName, String paramsFile, boolean autorun, boolean noSplash, boolean noGui, boolean withTreeView) { + this(hostName, null, paramsFile, null, autorun, noSplash, noGui, withTreeView); } /** @@ -217,7 +225,7 @@ public class EvAClient implements RemoteStateListener, Serializable { * @param noGui */ public EvAClient(final String hostName, InterfaceGOParameters goParams, boolean autorun, boolean noSplash, boolean noGui) { - this(hostName, null, null, goParams, autorun, noSplash, noGui); + this(hostName, null, null, goParams, autorun, noSplash, noGui, false); } /** @@ -236,7 +244,7 @@ public class EvAClient implements RemoteStateListener, Serializable { * @param noSplash * @param noGui */ - public EvAClient(final String hostName, final Window parent, final String paramsFile, final InterfaceGOParameters goParams, final boolean autorun, final boolean noSplash, final boolean noGui) { + public EvAClient(final String hostName, final Window parent, final String paramsFile, final InterfaceGOParameters goParams, final boolean autorun, final boolean noSplash, final boolean noGui, final boolean showTreeView) { clientInited = false; final SplashScreenShell fSplashScreen = new SplashScreenShell(EvAInfo.splashLocation); @@ -244,6 +252,7 @@ public class EvAClient implements RemoteStateListener, Serializable { preloadClasses(); withGUI = !noGui; + withTreeView = showTreeView; // activate the splash screen (show later using SwingUtilities) if (!noSplash && withGUI) { try { @@ -370,7 +379,7 @@ public class EvAClient implements RemoteStateListener, Serializable { m_Frame = new JEFrame(EvAInfo.productName + " workbench"); m_Frame.setCloseAllOnClosed(true); m_Frame.setName(this.getClass().getSimpleName()); // the name is set to recognize the client window - + BasicResourceLoader loader = BasicResourceLoader.instance(); byte[] bytes = loader.getBytesFromResourceLocation(EvAInfo.iconLocation, true); m_Frame.setIconImage(Toolkit.getDefaultToolkit().createImage(bytes)); @@ -462,9 +471,9 @@ public class EvAClient implements RemoteStateListener, Serializable { System.out.println(EVAHELP.getSystemPropertyString()); } - String[] keys= new String[]{"--help", "--autorun", "--nosplash", "--nogui", "--remotehost", "--params"}; - int[] arities = new int[]{0, 0, 0, 0, 1, 1}; - Object[] values = new Object[6]; + String[] keys= new String[]{"--help", "--autorun", "--nosplash", "--nogui", "--remotehost", "--params", "--treeView"}; + int[] arities = new int[]{0, 0, 0, 0, 1, 1, 0}; + Object[] values = new Object[keys.length]; Integer[] unknownArgs = StringTools.parseArguments(args, keys, arities, values, true); @@ -480,13 +489,14 @@ public class EvAClient implements RemoteStateListener, Serializable { boolean autorun=(values[1]!=null); boolean nosplash=(values[2]!=null); boolean nogui=(values[3]!=null); + boolean treeView=(values[6]!=null); String hostName=StringTools.checkSingleStringArg(keys[4], values[4], arities[4]-1); String paramsFile=StringTools.checkSingleStringArg(keys[5], values[5], arities[5]-1); if (TRACE) System.out.println("Command line arguments were: "); if (TRACE) System.out.println(" " + BeanInspector.toString(keys)); if (TRACE) System.out.println(" " + BeanInspector.toString(values)); - EvAClient Client = new EvAClient(hostName, paramsFile, autorun, nosplash, nogui); + EvAClient Client = new EvAClient(hostName, paramsFile, autorun, nosplash, nogui, treeView); } } @@ -505,7 +515,7 @@ public class EvAClient implements RemoteStateListener, Serializable { EvAClient evaClient; evaClient = new EvAClient(null, parent, null, goParams, - false, true, false); // initializes GUI in the background + false, true, false, false); // initializes GUI in the background // important: wait for GUI initialization before accessing any internal // settings: evaClient.awaitClientInitialized(); // this returns as soon as the @@ -917,7 +927,12 @@ public class EvAClient implements RemoteStateListener, Serializable { infoPanel.setLayout(new BorderLayout()); infoPanel.add(m_ProgressBar, BorderLayout.SOUTH); infoPanel.add(m_LogPanel, BorderLayout.NORTH); + JComponent tree=null; + if (withTreeView && (newModuleAdapter instanceof AbstractModuleAdapter)) { + tree = getEvATreeView(frmMkr.getGOPanel(), "GOParameters", ((AbstractModuleAdapter)newModuleAdapter).getGOParameters()); + m_Frame.add(tree, BorderLayout.WEST); + } m_Frame.add(frmMkr.getToolBar(), BorderLayout.NORTH); m_Frame.add(moduleContainer, BorderLayout.CENTER); //m_Frame.add(m_ProgressBar, BorderLayout.CENTER); @@ -951,6 +966,26 @@ public class EvAClient implements RemoteStateListener, Serializable { } } + /** + * Create a tree view of an object based on EvATreeNode. It is encapsulated + * in a JScrollPane. + * + * @see EvATreeNode + * @param title + * @param object + * @return + */ + public JComponent getEvATreeView(JParaPanel goPanel, String title, Object object) { + EvATreeNode root = new EvATreeNode(title, object); // the root of the tree + JTree jtree = new JTree(root); + JScrollPane treeView = new JScrollPane(jtree); + + EvATreeSelectionListener treeListener = new EvATreeSelectionListener(root, goPanel.getEditor(), jtree); + // hooks itself up as the tree listener. It reacts both to changes in the selection + // state of the tree (to update the parameter panel) and to changes in the + // parameters to update the tree + return treeView; + } /** * */ diff --git a/src/eva2/gui/EvATabbedFrameMaker.java b/src/eva2/gui/EvATabbedFrameMaker.java index aa70fb96..66ab404c 100644 --- a/src/eva2/gui/EvATabbedFrameMaker.java +++ b/src/eva2/gui/EvATabbedFrameMaker.java @@ -114,7 +114,7 @@ public class EvATabbedFrameMaker implements Serializable, PanelMaker, InterfaceN List informers) { // if the informers have changed, update the GUI element which displays them try { - JParaPanel statsPan = (JParaPanel) pmContainer.get(2); + JParaPanel statsPan = getStatsPanel(); if (statsPan.m_Editor!=null) { statsPan.m_Editor.setValue(statsPan.m_Editor.getValue()); // really update the contents of the stats panel // System.out.println("OOO setting informers to stats panel succeeded!"); @@ -125,4 +125,24 @@ public class EvATabbedFrameMaker implements Serializable, PanelMaker, InterfaceN e.printStackTrace(System.err); } } + + public JParaPanel getGOPanel() { + try { + JParaPanel sP = (JParaPanel) pmContainer.get(1); + return sP; + } catch(Exception e) { + System.err.println("Failed to get GO panel from " + this.getClass()); + } + return null; + } + + public JParaPanel getStatsPanel() { + try { + JParaPanel sP = (JParaPanel) pmContainer.get(2); + return sP; + } catch(Exception e) { + System.err.println("Failed to get statistics panel from " + this.getClass()); + } + return null; + } } diff --git a/src/eva2/gui/EvATreeNode.java b/src/eva2/gui/EvATreeNode.java new file mode 100644 index 00000000..a7094cc1 --- /dev/null +++ b/src/eva2/gui/EvATreeNode.java @@ -0,0 +1,85 @@ +package eva2.gui; + +import javax.swing.tree.DefaultMutableTreeNode; + +/** + * The node class for the EvA2 tree view panel. Each node contains a parameter object. + * Typically, the tree hierarchy starts with a + * GOParameters object, however this is not necessary. + * The tree is constructed using the reflection functionality of PropertySheetPanel + * which is also used to generate the nested panels for parameter configuration. + * + * @see PropertySheetPanel + * @see GOParameters + * @author mkron + * + */ +public class EvATreeNode extends DefaultMutableTreeNode { + private String[] childrenNames = null; + private Object[] childrenValues = null; + private String myName="EvATreeNode"; + private boolean doListPrimitives=false; + + /** + * A default constructor setting the name and target object of + * the tree. The children are generated immediately. + * The node label is constructed from the name String and the + * information retrieved from the target object if it implements the getName method. + * + * @param name title of the node + * @param target + */ + public EvATreeNode(String name, Object target) { + super(target); + myName = name; + setObject(target, true); + } + + /** + * Set the target object of the tree. Note that the name is not automatically + * updated and may be out of date if the new target object is incompatible to the + * old name. + * + * @param target the new target object + * @param expand should be true to generate child nodes immediately + */ + public void setObject(Object target, boolean expand) { + super.setUserObject(target); + childrenNames = PropertySheetPanel.getPropertyNames(target); + childrenValues = PropertySheetPanel.getPropertyValues(target, true, true, true); + super.removeAllChildren(); + if (expand) initChildren(); + } + + public void setName(String name) { + myName=name; + } + + public String getName() { + return myName; + } + + /** + * Actually create child nodes. + */ + private void initChildren() { + for (int i=0; i=0; i--) { + System.out.println("* " + i + " " + tp.getPathComponent(i)); + } + EvATreeNode leafNode = (EvATreeNode)tp.getLastPathComponent(); +// goe.setValue(leafNode.getUserObject()); + Component editComp = goe.getCustomEditor(); + if (editComp instanceof GOEPanel) { + // update the object in the main GOEPanel + ((GOEPanel)editComp).setTarget(leafNode.getUserObject()); + } else { + System.err.println("Error, unable to notify custom editor of type " + editComp.getClass() + ", expected GOEPanel (EvATreeSelectionListener)"); + } + } + + public void propertyChange(PropertyChangeEvent evt) { + if (TRACE) System.out.println("EvATreeNode received change event " + evt); + root.setObject(evt.getNewValue(), true); + if (jtree !=null) jtree.setModel(new DefaultTreeModel(root)); // TODO this should be done differently so that the tree is not collapsed on each change! + } +} diff --git a/src/eva2/gui/GOEPanel.java b/src/eva2/gui/GOEPanel.java index 721bcb32..d8012f92 100644 --- a/src/eva2/gui/GOEPanel.java +++ b/src/eva2/gui/GOEPanel.java @@ -52,7 +52,7 @@ public class GOEPanel extends JPanel implements ItemListener { /** Save object to disk */ private JButton m_SaveBut; /** ok button */ - public JButton m_okBut; + private JButton m_okBut; /** cancel button */ private JButton m_cancelBut; /** edit source button */ @@ -62,20 +62,24 @@ public class GOEPanel extends JPanel implements ItemListener { private GenericObjectEditor m_goe = null; private boolean withComboBoxToolTips = true; // should tool tips for the combo box be created? private int tipMaxLen = 100; // maximum length of tool tip -// private String[] m_ClassesShortName; -// private SourceCodeEditor m_SourceCodeEditor; -// private PropertyDialog m_SourceCodeEditorFrame; /** * */ public GOEPanel(Object target, Object backup, PropertyChangeSupport support, GenericObjectEditor goe) { + this(target, backup, support, goe, false); + } + + /** + * + */ + public GOEPanel(Object target, Object backup, PropertyChangeSupport support, GenericObjectEditor goe, boolean withCancel) { Object m_Object = target; m_Backup = backup; m_Support = support; m_goe = goe; - //System.out.println("GOEPanel.Constructor !!"); +// System.out.println("GOEPanel.Constructor !! " + this); try { if (!(Proxy.isProxyClass(m_Object.getClass()))) m_Backup = copyObject(m_Object); } catch(OutOfMemoryError err) { @@ -90,10 +94,11 @@ public class GOEPanel extends JPanel implements ItemListener { m_ChildPropertySheet.addPropertyChangeListener( new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { + if (TRACE) System.out.println("GOE Property Change Listener: " + evt); m_Support.firePropertyChange("", m_Backup, m_goe.getValue()); } }); - m_OpenBut = new JButton("Open..."); + m_OpenBut = new JButton("Open"); m_OpenBut.setToolTipText("Load a configured object"); m_OpenBut.setEnabled(true); m_OpenBut.addActionListener(new ActionListener() { @@ -111,7 +116,7 @@ public class GOEPanel extends JPanel implements ItemListener { } }); - m_SaveBut = new JButton("Save..."); + m_SaveBut = new JButton("Save"); m_SaveBut.setToolTipText("Save the current configured object"); m_SaveBut.setEnabled(true); m_SaveBut.addActionListener(new ActionListener() { @@ -120,39 +125,13 @@ public class GOEPanel extends JPanel implements ItemListener { // saveObject(m_goe.getValue()); } }); -// -// m_editSourceBut = new JButton("Edit Source"); -// m_editSourceBut.setToolTipText("Edit the Source"); -// m_editSourceBut.setEnabled(false); -// m_editSourceBut.addActionListener(new ActionListener() { -// public void actionPerformed(ActionEvent e) { -// m_editSourceBut.setEnabled(false); -// m_SourceCodeEditor = new SourceCodeEditor(); -// String className = m_Object.getClass().getName(); -// m_SourceCodeEditor.editSource(EvAClient.DYNAMICCLASSES_PROPERTIES.getProperty(className)); -// m_SourceCodeEditorFrame = new PropertyDialog(m_SourceCodeEditor, "test", 50, 50); -// m_SourceCodeEditorFrame.pack(); -// m_SourceCodeEditorFrame.addWindowListener(new WindowAdapter() { -// public void windowClosing (WindowEvent e) { -// m_SourceCodeEditor = null; -// m_editSourceBut.setEnabled(true); -// } -// }); -// m_SourceCodeEditor.addPropertyChangeListener(new -// PropertyChangeListener() { -// public void propertyChange(PropertyChangeEvent evt) { -// sourceChanged(); -// } -// } -// ); -// } -// }); m_okBut = new JButton("OK"); m_okBut.setEnabled(true); m_okBut.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { m_Backup = copyObject(m_goe.getValue()); +// System.out.println("Backup is now " + BeanInspector.toString(m_Backup)); if ((getTopLevelAncestor() != null) && (getTopLevelAncestor() instanceof Window)) { Window w = (Window) getTopLevelAncestor(); w.dispose(); @@ -161,12 +140,13 @@ public class GOEPanel extends JPanel implements ItemListener { }); m_cancelBut = new JButton("Cancel"); - m_cancelBut.setEnabled(false); + m_cancelBut.setEnabled(true); m_cancelBut.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (m_Backup != null) { // m_Object = copyObject(m_Backup); // TODO m_goe.setObject(m_Object); +// System.out.println("Backup was " + BeanInspector.toString(m_Backup)); m_goe.setValue(copyObject(m_Backup)); updateClassType(); updateChooser(); @@ -197,9 +177,10 @@ public class GOEPanel extends JPanel implements ItemListener { okcButs.setLayout(new GridLayout(1, 4, 5, 5)); okcButs.add(m_OpenBut); okcButs.add(m_SaveBut); - okcButs.add(m_okBut); // okcButs.add(m_editSourceBut); - //okcButs.add(m_cancelBut); + if (withCancel) okcButs.add(m_cancelBut); + okcButs.add(m_okBut); + add(okcButs, BorderLayout.SOUTH); if (m_goe.getClassType() != null) { @@ -210,6 +191,11 @@ public class GOEPanel extends JPanel implements ItemListener { m_ObjectChooser.addItemListener(this); } + public void setEnabledOkCancelButtons(boolean enabled) { + m_okBut.setEnabled(enabled); + m_cancelBut.setEnabled(enabled); + } + /** * Makes a copy of an object using serialization * @param source the object to copy @@ -261,6 +247,11 @@ public class GOEPanel extends JPanel implements ItemListener { public void removeCancelListener(ActionListener a) { m_cancelBut.removeActionListener(a); } + + public void setTarget(Object o) { + m_ChildPropertySheet.setTarget(o); + } + /** * */ @@ -330,34 +321,6 @@ public class GOEPanel extends JPanel implements ItemListener { } } -// -// public void sourceChanged() { -// -// //System.out.println("SOURCESTATECHANGED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! "); -// String className = (String) m_ObjectChooser.getSelectedItem(); -// -//// @todohannes: hack! ausbessern -// className = (String) m_ObjectChooser.getSelectedItem(); -// try { -// if (m_userdefclasses == true) { -// className = m_Object.getClass().getName(); -// Object[] para = new Object[] {}; -// Object n = (Object) CompileAndLoad.getInstanceFull( -// EvAClient.DYNAMICCLASSES_PROPERTIES.getProperty(className), -// className, -// para); -// setObject(n); -// } -// else { -// System.out.println("m_userdefclasses == false!!!!!"); -// } -// } -// catch (Exception ex) { -// } -// -// } - - /** * When the chooser selection is changed, ensures that the Object * is changed appropriately. @@ -367,40 +330,16 @@ public class GOEPanel extends JPanel implements ItemListener { public void itemStateChanged(ItemEvent e) { String className = (String)m_ObjectChooser.getSelectedItem(); -// m_editSourceBut.setEnabled(false); -// @todohannes: hack! ausbessern -// try { -// if (EvAClient.DYNAMICCLASSES_PROPERTIES.containsKey(className) && m_userdefclasses) { -// m_editSourceBut.setEnabled(true); -// } -// } catch (Exception e1) { -// System.out.println("Fehler !!! " + e1); -// } - -// @todohannes: hack! ausbessern -// -// if (this.m_SourceCodeEditorFrame != null) { -// m_SourceCodeEditorFrame.setVisible(false); -// m_SourceCodeEditorFrame = null; -// m_SourceCodeEditor = null; -// } if (TRACE) System.out.println("Event-Quelle: " + e.getSource().toString()); if ((e.getSource() == m_ObjectChooser) && (e.getStateChange() == ItemEvent.SELECTED)){ className = (String)m_ObjectChooser.getSelectedItem(); try { -// if (EvAClient.DYNAMICCLASSES_PROPERTIES.containsKey(className) && m_userdefclasses) { -// Object[] para = new Object[] {}; -// String source = EvAClient.DYNAMICCLASSES_PROPERTIES.getProperty(className); -// Object dummy = CompileAndLoad.getInstanceFull(source,className,para); -// setObject(dummy); -// } else { if (TRACE) System.out.println(className); // Object n = (Object)Class.forName(className, true, this.getClass().getClassLoader()).newInstance(); Object n = (Object)Class.forName(className).newInstance(); m_goe.setValue(n); // TODO ? setObject(n); -// } } catch (Exception ex) { System.err.println("Exeption in itemStateChanged "+ex.getMessage()); System.err.println("Classpath is " + System.getProperty("java.class.path")); @@ -422,27 +361,27 @@ public class GOEPanel extends JPanel implements ItemListener { class ToolTipComboBoxRenderer extends BasicComboBoxRenderer { private static final long serialVersionUID = -5781643352198561208L; String[] toolTips = null; - + public ToolTipComboBoxRenderer(String[] tips) { super(); toolTips=tips; } - - @Override - public Component getListCellRendererComponent(JList list, Object value, - int index, boolean isSelected, boolean cellHasFocus) { - if (isSelected) { - setBackground(list.getSelectionBackground()); - setForeground(list.getSelectionForeground()); - if ((toolTips!=null) && (index >= 0)) { - if (toolTips[index]!=null) list.setToolTipText(toolTips[index]); - } - } else { - setBackground(list.getBackground()); - setForeground(list.getForeground()); - } - setFont(list.getFont()); - setText((value == null) ? "" : value.toString()); - return this; - } - } + + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + if ((toolTips!=null) && (index >= 0)) { + if (toolTips[index]!=null) list.setToolTipText(toolTips[index]); + } + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + setFont(list.getFont()); + setText((value == null) ? "" : value.toString()); + return this; + } +} diff --git a/src/eva2/gui/GenericObjectEditor.java b/src/eva2/gui/GenericObjectEditor.java index bd1aaf8d..0bc7bd3b 100644 --- a/src/eva2/gui/GenericObjectEditor.java +++ b/src/eva2/gui/GenericObjectEditor.java @@ -485,10 +485,10 @@ public class GenericObjectEditor implements PropertyEditor { /** * */ - public void disableOK() { + public void disableOKCancel() { if (m_EditorComponent == null) m_EditorComponent = new GOEPanel(m_Object, m_Backup, m_Support, this); - m_EditorComponent.m_okBut.setEnabled(false); + m_EditorComponent.setEnabledOkCancelButtons(false); } public void addPropertyChangeListener(PropertyChangeListener l) { if (m_Support == null) m_Support = new PropertyChangeSupport(this); diff --git a/src/eva2/gui/JParaPanel.java b/src/eva2/gui/JParaPanel.java index a3bf580a..e8fe3e75 100644 --- a/src/eva2/gui/JParaPanel.java +++ b/src/eva2/gui/JParaPanel.java @@ -11,19 +11,25 @@ package eva2.gui; * IMPORTS *==========================================================================*/ -import javax.swing.*; -import java.awt.*; -import java.beans.PropertyEditor; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.GridBagLayout; import java.beans.PropertyEditorManager; import java.io.Serializable; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.JComponent; +import javax.swing.JPanel; + public class JParaPanel implements Serializable, PanelMaker { public static boolean TRACE = false; protected String m_Name = "undefined"; protected Object m_LocalParameter; protected Object m_ProxyParameter; - protected PropertyEditor m_Editor; + protected GenericObjectEditor m_Editor; private JPanel m_Panel; public JParaPanel() { @@ -47,7 +53,7 @@ public class JParaPanel implements Serializable, PanelMaker { ((GenericObjectEditor) (m_Editor)).setClassType(m_LocalParameter. getClass()); ((GenericObjectEditor) (m_Editor)).setValue(m_LocalParameter); - ((GenericObjectEditor) (m_Editor)).disableOK(); + ((GenericObjectEditor) (m_Editor)).disableOKCancel(); m_Panel.setLayout(new BorderLayout()); m_Panel.add(m_Editor.getCustomEditor(), BorderLayout.CENTER); @@ -65,6 +71,10 @@ public class JParaPanel implements Serializable, PanelMaker { return m_Name; } + public GenericObjectEditor getEditor() { + return m_Editor; + } + /** This method will allow you to add a new Editor to a given class * @param object * @param editor diff --git a/src/eva2/gui/PropertySheetPanel.java b/src/eva2/gui/PropertySheetPanel.java index 18351af0..c54d9348 100644 --- a/src/eva2/gui/PropertySheetPanel.java +++ b/src/eva2/gui/PropertySheetPanel.java @@ -234,13 +234,12 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener // Now lets search for the individual properties, their // values, views and editors... m_Editors = new PropertyEditor[m_Properties.length]; - m_Values = new Object[m_Properties.length]; + m_Values = getValues(m_Target, m_Properties, true, false, true); // collect property values if possible m_Views = new JComponent[m_Properties.length]; m_ViewWrapper= new JComponent[m_Properties.length]; m_Labels = new JLabel[m_Properties.length]; m_TipTexts = new String[m_Properties.length]; -// boolean firstTip = true; for (int i = 0; i < m_Properties.length; i++) { // For each property do this // Don't display hidden or expert properties. @@ -248,53 +247,19 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener // we now look at hidden properties, they can be shown or hidden dynamically (MK) String name = m_Properties[i].getDisplayName(); if (TRACE) System.out.println("PSP looking at "+ name); - - if (m_Properties[i].isExpert()) continue; - Method getter = m_Properties[i].getReadMethod(); - Method setter = m_Properties[i].getWriteMethod(); - // Only display read/write properties. - if (getter == null || setter == null) continue; + if (m_Values[i]==null) continue; // expert, hidden, or no getter/setter available JComponent newView = null; try { - Object args[] = { }; - Object value = getter.invoke(m_Target, args); - PropertyEditor editor = null; - //Class pec = m_Properties[i].getPropertyEditorClass(); - m_Values[i] = value; -// ////////////////// refactored by MK - editor = PropertyEditorProvider.findEditor(m_Properties[i], value); - m_Editors[i] = editor; - if (editor == null) continue; - - //////////////////// + m_Editors[i] = makeEditor(m_Properties[i], name, m_Values[i]); + if (m_Editors[i]==null) continue; + m_TipTexts[i] = BeanInspector.getToolTipText(name, m_Methods, m_Target, stripToolTipToFirstPoint, tipTextLineLen); - - // Don't try to set null values: - if (value == null) { - // If it's a user-defined property we give a warning. - String getterClass = m_Properties[i].getReadMethod().getDeclaringClass().getName(); - if (getterClass.indexOf("java.") != 0) System.out.println("Warning: Property \"" + name+ "\" of class " + targ.getClass() + " has null initial value. Skipping."); - continue; + newView = getView(m_Editors[i]); + if (newView==null) { + System.err.println("Warning: Property \"" + name + "\" has non-displayabale editor. Skipping."); + continue; } - editor.setValue(value); - - m_TipTexts[i] = BeanInspector.getToolTipText(name, m_Methods, m_Target, stripToolTipToFirstPoint, tipTextLineLen); - -// System.out.println("PSP editor class: " + editor.getClass()); - newView = getView(editor); - if (newView==null) { - System.err.println("Warning: Property \"" + name + "\" has non-displayabale editor. Skipping."); - continue; - } - - editor.addPropertyChangeListener(this); - } catch (InvocationTargetException ex) { - System.out.println("InvocationTargetException " + name - + " on target: " - + ex.getTargetException()); - ex.getTargetException().printStackTrace(); - continue; } catch (Exception ex) { System.out.println("Skipping property "+name+" ; exception: " + ex); ex.printStackTrace(); @@ -304,65 +269,186 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener // Add some specific display for some greeks here name = translateGreek(name); - m_Labels[i] = new JLabel(name, SwingConstants.RIGHT); - m_Labels[i].setBorder(BorderFactory.createEmptyBorder(10,10,0,5)); - m_Views[i] = newView; - m_ViewWrapper[i] = new JPanel(); - m_ViewWrapper[i].setLayout(new BorderLayout()); - GridBagConstraints gbConstraints = new GridBagConstraints(); - gbConstraints.anchor = GridBagConstraints.EAST; - gbConstraints.fill = GridBagConstraints.HORIZONTAL; - gbConstraints.gridy = i+componentOffset; - gbConstraints.gridx = 0; - gbLayout.setConstraints(m_Labels[i], gbConstraints); - add(m_Labels[i]); - JPanel newPanel = new JPanel(); - if (m_TipTexts[i] != null) { - m_Views[i].setToolTipText(m_TipTexts[i]); - m_Labels[i].setToolTipText(m_TipTexts[i]); - } - newPanel.setBorder(BorderFactory.createEmptyBorder(10,5,0,10)); - newPanel.setLayout(new BorderLayout()); - // @todo: Streiche here i could add the ViewWrapper - m_ViewWrapper[i].add(m_Views[i], BorderLayout.CENTER); - newPanel.add(m_ViewWrapper[i], BorderLayout.CENTER); - gbConstraints = new GridBagConstraints(); - gbConstraints.anchor = GridBagConstraints.WEST; - gbConstraints.fill = GridBagConstraints.BOTH; - gbConstraints.gridy = i+componentOffset; - gbConstraints.gridx = 1; - gbConstraints.weightx = 100; - gbLayout.setConstraints(newPanel, gbConstraints); - add(newPanel); + addLabelView(componentOffset, gbLayout, i, name, newView); m_NumEditable++; if (m_Properties[i].isHidden()) { m_ViewWrapper[i].setVisible(false); + m_Views[i].setVisible(false); m_Labels[i].setVisible(false); } - } + } // end for each property if (m_NumEditable == 0) { - JLabel empty = new JLabel("No editable properties",SwingConstants.CENTER); - Dimension d = empty.getPreferredSize(); - empty.setPreferredSize(new Dimension(d.width * 2, d.height * 2)); - empty.setBorder(BorderFactory.createEmptyBorder(10, 5, 0, 10)); - GridBagConstraints gbConstraints = new GridBagConstraints(); - gbConstraints.anchor = GridBagConstraints.CENTER; - gbConstraints.fill = GridBagConstraints.HORIZONTAL; - gbConstraints.gridy = componentOffset; - gbConstraints.gridx = 0; - gbLayout.setConstraints(empty, gbConstraints); - add(empty); + add(createDummyLabel(componentOffset, gbLayout)); } -// Container p=this; -// while (p != null) { -// p.setSize(p.getPreferredSize()); -// p = p.getParent(); -// } validate(); setVisible(true); } - + + public static PropertyDescriptor[] getProperties(Object target) { + BeanInfo bi; + try { + bi = Introspector.getBeanInfo(target.getClass()); + } catch (IntrospectionException e) { + e.printStackTrace(); + return null; + } + return bi.getPropertyDescriptors(); + } + + public static String[] getPropertyNames(Object target) { + return getNames(getProperties(target)); + } + + public static Object[] getPropertyValues(Object target, boolean omitExpert, boolean omitHidden, boolean onlySetAndGettable) { + return getValues(target, getProperties(target), omitExpert, omitHidden, onlySetAndGettable); + } + + public static String[] getNames(PropertyDescriptor[] props) { + String[] names=new String[props.length]; + for (int i = 0; i