[MOBY-guts] biomoby commit

Martin Senger senger at pub.open-bio.org
Sat Sep 24 17:51:52 UTC 2005


senger
Sat Sep 24 13:51:52 EDT 2005
Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard
In directory pub.open-bio.org:/tmp/cvs-serv30711/src/main/org/biomoby/service/dashboard

Modified Files:
	AbstractPanel.java CommonTree.java ConsolePanel.java 
	Dashboard.java DashboardPanel.java DashboardProperties.java 
	EventGeneratorPanel.java NOTES RegistryModel.java 
	RegistryPanel.java 
Added Files:
	CommonConsole.java CommonNode.java PropertyChannel.java 
	SwingWorker.java 
Log Message:


moby-live/Java/src/main/org/biomoby/service/dashboard CommonConsole.java,NONE,1.1 CommonNode.java,NONE,1.1 PropertyChannel.java,NONE,1.1 SwingWorker.java,NONE,1.1 AbstractPanel.java,1.5,1.6 CommonTree.java,1.1,1.2 ConsolePanel.java,1.3,1.4 Dashboard.java,1.3,1.4 DashboardPanel.java,1.3,1.4 DashboardProperties.java,1.2,1.3 EventGeneratorPanel.java,1.2,1.3 NOTES,1.5,1.6 RegistryModel.java,1.1,1.2 RegistryPanel.java,1.6,1.7
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/AbstractPanel.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/AbstractPanel.java	2005/09/18 14:09:42	1.5
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/AbstractPanel.java	2005/09/24 17:51:51	1.6
@@ -20,6 +20,7 @@
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
 import javax.swing.JTextField;
+import javax.swing.JComboBox;
 import javax.swing.JFileChooser;
 import javax.swing.AbstractButton;
 import javax.swing.BorderFactory;
@@ -49,6 +50,7 @@
 
 import java.io.File;
 import java.util.prefs.Preferences;
+import java.util.Map;
 
 /**
  * WORK IN PROGRESS. <p>
@@ -81,11 +83,13 @@
     // something need to be done only once - keep it here
     protected Icon panelIcon;
     protected JComponent pComponent;
-    protected Icon confirmIcon;
+    protected static Icon confirmIcon;
 
     // re-use "style" components
     protected static final Insets BREATH_TOP = new Insets (10,0,0,0);
 
+    //
+    protected PropertyChannel propertyChannel;
 
     /*********************************************************************
      * Default constructor (just for the sub-classes).
@@ -139,6 +143,14 @@
     public void propertyChange (PropertyChangeEvent event) {
     }
 
+    /**************************************************************************
+     * Remember a property channel and register itself to it as a listener.
+     **************************************************************************/
+    protected void setPropertyChannel (PropertyChannel propertyChannel) {
+	this.propertyChannel = propertyChannel;
+	propertyChannel.addPropertyChangeListener (this);
+    }
+
     //
     // Abstract methods
     //
@@ -146,7 +158,7 @@
     /**************************************************************************
      *
      **************************************************************************/
-    abstract public JComponent getComponent();
+    abstract public JComponent getComponent (PropertyChannel propertyChannel);
 
     /**************************************************************************
      *
@@ -228,23 +240,16 @@
     /*********************************************************************
      * Create a panel with given text field and with a directory/file
      * browser button attached.
-     *
-     * @param chooserMode should be one of
-     * JFileChooser.DIRECTORIES_ONLY, JFileChooser.FILES_ONLY, and
-     * JFileChooser.FILES_AND_DIRECTORIES (but it is not tested)
      ********************************************************************/
     protected JFileChooserWithHistory createFileSelector (String chooserTitle,
 							  String approveButtonText,
-							  int chooserMode,
 							  String defaultValue,
-							  FileFilter filter) {
+							  String preferenceNode,
+							  String eventName) {
 	JFileChooserWithHistory chooser =
-	    new JFileChooserWithHistory (null, this, "cacheDirectory");
+	    new JFileChooserWithHistory (null, this, preferenceNode);
 
 	JFileChooser ch = chooser.getFileChooser();
-	ch.setFileSelectionMode (chooserMode);
-	if (filter != null)
-	    ch.setFileFilter (filter);
 	ch.setApproveButtonText (approveButtonText);
 	ch.setDialogTitle (chooserTitle);
 
@@ -252,10 +257,57 @@
  	    chooser.getSelectedFile() == null)
  	    chooser.setSelectedFile (new File (defaultValue));
 
+	if (eventName != null) {
+	    JTextFieldWithHistory textField = chooser.getTextField();
+	    textField.addActionListener (getTextFieldListener (eventName));
+	    String text = textField.getText();
+	    if (UUtils.notEmpty (text))
+		propertyChannel.put (eventName, text);
+	}
+
 	return chooser;
     }
 
     /*********************************************************************
+     * Create a text field (possibly with an 'initValue' with history
+     * taken from given 'preferenceNode'. If 'evenName' is not null
+     * (which means that the contens of this text filed may be of
+     * interest of someone outside), add an action event that will
+     * update the shared property storage (a global variable
+     * 'propertyChannel') when the text field changes its value.
+     ********************************************************************/
+    protected JTextFieldWithHistory createText (String initValue,
+						String preferenceNode,
+						String eventName) {
+	JTextFieldWithHistory textField =
+	    new JTextFieldWithHistory (initValue,
+				       this,
+				       preferenceNode);
+	if (eventName != null) {
+	    textField.addActionListener (getTextFieldListener (eventName));
+	    String text = textField.getText();
+	    if (UUtils.notEmpty (text))
+		propertyChannel.put (eventName, text);
+	}
+
+	return textField;
+    }
+
+    /*********************************************************************
+     * 
+     ********************************************************************/
+    private ActionListener getTextFieldListener (String eventName) {
+	final String name = eventName;
+	return new ActionListener() {
+		public void actionPerformed (ActionEvent e) {
+		    String contents =  ((JTextFieldWithHistory)e.getSource()).getText();
+		    propertyChannel.put (name, contents);
+		}
+	    };
+    }
+
+
+    /*********************************************************************
      * 
      ********************************************************************/
     protected boolean getPrefValue (String key,
@@ -276,11 +328,11 @@
     /*********************************************************************
      * Return true if confirmation dialog passed.
      ********************************************************************/
-    public boolean confirm (Object msg) {
+    public static boolean confirm (Object msg) {
 	if (confirmIcon == null)
 	    confirmIcon =
 		SwingUtils.createIcon ("images/confirmButton.gif", Dashboard.class);
-        return SwingUtils.confirm (this, msg, confirmIcon);
+        return SwingUtils.confirm (null, msg, confirmIcon);
     }
 
 }

===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/CommonTree.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/CommonTree.java	2005/09/18 08:46:26	1.1
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/CommonTree.java	2005/09/24 17:51:51	1.2
@@ -8,20 +8,35 @@
 
 package org.biomoby.service.dashboard;
 
+import org.tulsoft.shared.UUtils;
+import org.tulsoft.tools.gui.SwingUtils;
+
 import javax.swing.JTree;
 import javax.swing.JLabel;
 import javax.swing.JScrollPane;
 import javax.swing.Icon;
+import javax.swing.JPopupMenu;
+import javax.swing.JOptionPane;
+import javax.swing.JMenuItem;
+import javax.swing.ToolTipManager;
+import javax.swing.AbstractAction;
 import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.DefaultTreeModel;
 import javax.swing.tree.DefaultTreeCellRenderer;
 import javax.swing.tree.TreeSelectionModel;
 import javax.swing.tree.TreePath;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.event.TreeSelectionEvent;
 
 import java.awt.Component;
 import java.awt.Font;
+import java.awt.event.ActionEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+import java.util.HashSet;
+import java.util.Enumeration;
 
 // import java.beans.PropertyChangeListener;
 // import java.beans.PropertyChangeEvent;
@@ -40,6 +55,15 @@
 public class CommonTree
     extends JTree {
 
+    // some shared constants
+    final static protected int SORTED_BY_NAME      = 0;
+    final static protected int SORTED_BY_AUTHORITY = 1;
+
+    // tree components
+    protected JPopupMenu popup;
+    protected Icon searchIcon;
+    protected String lastSearchText = "";
+
 //     protected PropertyChangeSupport support;
 //     protected boolean expanded = true;   // the status of the application list
 
@@ -47,34 +71,48 @@
      * Constructor
      ********************************************************************/
     public CommonTree (String rootNode) {
-        super (new DefaultTreeModel (new DefaultMutableTreeNode (rootNode)));
+        super (new DefaultTreeModel (new DefaultMutableTreeNode (new CommonNode (rootNode))));
 
 	// create an almost empty tree, only with a root node that
 	// contains just a String holding the name of the root node;
-	// the tree will be populated later by calling 'updateTree()'
-        setFont (new Font ("Dialog",  Font.PLAIN, 10));
+//         setFont (new Font ("Dialog",  Font.PLAIN, 10));
         putClientProperty ("JTree.lineStyle", "Angled");
 	setCellRenderer (new CommonTreeCellRenderer());
 	getSelectionModel().setSelectionMode
 	    (TreeSelectionModel.SINGLE_TREE_SELECTION);
 
-  	addMouseListener (new MouseAdapter() {
-		public void mouseClicked (MouseEvent e) {
-		    TreePath selPath = getPathForLocation (e.getX(), e.getY());
-		    if (e.getClickCount() == 1)
-			onSelected (selPath);
+//   	addMouseListener (new MouseAdapter() {
+// 		public void mouseClicked (MouseEvent e) {
+// 		    TreePath selPath = getPathForLocation (e.getX(), e.getY());
+// 		    if (e.getClickCount() == 1)
+// 			onSelected (selPath);
+// 		}
+// 	    });
+
+	// listen for when the selection changes
+	addTreeSelectionListener ( new TreeSelectionListener() {
+		public void valueChanged (TreeSelectionEvent e) {
+		    DefaultMutableTreeNode node =
+			(DefaultMutableTreeNode)getLastSelectedPathComponent();
+		    if (node == null) return;
+		    selected (node);
 		}
 	    });
+
+	// enable tool tips
+	ToolTipManager.sharedInstance().registerComponent (this);
     }
 
     //
-    // I want to display the empty modules with the same icon as
-    // 'closed' tree branches - therefore I need my own cell renderer
-    // (also it is suitable for new leaf icon)
-    //
     class CommonTreeCellRenderer
 	extends DefaultTreeCellRenderer {
 
+	HashSet toBeHighlighted;
+
+	public void setToBeHighlighted (HashSet toBeHighlighted) {
+	    this.toBeHighlighted = toBeHighlighted;
+	}
+
 	public Component getTreeCellRendererComponent (JTree tree,
 						       java.lang.Object value,
 						       boolean selected,
@@ -88,40 +126,170 @@
 	    //
 	    Component c = super.getTreeCellRendererComponent (tree, value, selected,
 							      expanded, leaf, row, hasFocus);
+	    // add a tool-tip for the root node
+	    if (row == 0) {
+		setToolTipText ("Right-click will show other options");
+		setFont (new Font ("Dialog",  Font.BOLD, 12));
+	    } else {
+		setToolTipText (null);
+		setFont (new Font ("Dialog",  Font.PLAIN, 10));
+	    }
+
 	    // TBD: whale icon?
 // 	    if (leaf)
 // 		((JLabel)c).setIcon (icons [COMPUTER]);
 
+
+	    // do highlight
+	    Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
+	    CommonNode nodeObject = (CommonNode)userObject;
+	    if (toBeHighlighted != null && toBeHighlighted.contains (nodeObject.getValue()))
+		setText ("<html><font color='red'>" + nodeObject + "</font></html>");
+
 	    return c;
 	}
     }
 
+    /*********************************************************************
+     * Put this tree in a scrollable pane.
+     ********************************************************************/
     public JScrollPane scrollable() {
  	return new JScrollPane (this);
     }
 
 
     /*********************************************************************
-     * onAppSelected()
-     *    When an application name is selected it will fire a
-     *    PropertyChange event with SELECTED_BY_NAME property. The value of
-     *    the property will be an instance of Hashtable carrying:
-     *    - module name as MODULE_NAME,
-     *    - application name as APP_NAME, and
-     *    - an this instance as ALBEAN_LIST
-     ********************************************************************/
-    protected void onSelected (TreePath path) {
-//         if (path == null) return;
-//         DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
-//         if (path.getPathCount() < 3) return;   // we need to be on an application name
-//         String appName = (String)node.getUserObject();
-//         DefaultMutableTreeNode parent = (DefaultMutableTreeNode)node.getParent();
-//         String module = (String)parent.getUserObject();
-// 	Hashtable result = new Hashtable();
-// 	result.put (ALBeanListWithGUI.MODULE_NAME, module);
-// 	result.put (ALBeanListWithGUI.APP_NAME, appName);
-// 	result.put (ALBeanListWithGUI.ALBEAN_LIST, this);
-// 	support.firePropertyChange (ALBeanListWithGUI.SELECTED_BY_NAME, null, result);
+     * Called when a tree node is selected. Does nothing here
+     ********************************************************************/
+    protected void selected (DefaultMutableTreeNode node) {
+    }
+
+    /*********************************************************************
+     * Create a popup object with common items. Subclasses can (and
+     * usually do) add more items, or re-created the whole popup. <p>
+     *
+     * @param title is given to the popups
+     ********************************************************************/
+    protected void createPopups (String title) {
+	popup = new JPopupMenu (title);
+	popup.add
+	    (new JMenuItem (new AbstractAction ("Search") {
+		    public void actionPerformed (ActionEvent e) {
+			String searchText = searchDialog();
+			if (searchText != null)
+			    search (searchText);
+		    }
+		}));
+	popup.add
+	    (new JMenuItem (new AbstractAction ("Expand all nodes") {
+		    public void actionPerformed (ActionEvent e) {
+			expand();
+		    }
+		}));
+	popup.add
+	    (new JMenuItem (new AbstractAction ("Collaps all nodes") {
+		    public void actionPerformed (ActionEvent e) {
+			collapse();
+		    }
+		}));
+
+	// add listener to this tree to bring up popup menus
+	MouseListener popupListener = new PopupListener();
+	addMouseListener (popupListener);
+    }
+
+    class PopupListener extends MouseAdapter {
+	public void mousePressed (MouseEvent e) {
+	    maybeShowPopup (e);
+	}
+	public void mouseReleased (MouseEvent e) {
+	    maybeShowPopup (e);
+	}
+	private void maybeShowPopup (MouseEvent e) {
+	    if (e.isPopupTrigger() && popup.isEnabled()) {
+		popup.show (e.getComponent(),
+			    e.getX(), e.getY());
+	    }
+	}
+    }
+
+    /*********************************************************************
+     * Collapse all nodes, starting from the root. <p>
+     ********************************************************************/
+    protected void collapse() {
+ 	SwingUtils.collapseTree (this, (DefaultMutableTreeNode)getModel().getRoot());
+    }
+
+    /*********************************************************************
+     * Expand all nodes, starting from the root. <p>
+     ********************************************************************/
+    protected void expand() {
+//  	SwingUtils.expandTree (this, (DefaultMutableTreeNode)getModel().getRoot());
+
+
+	final SwingWorker worker = new SwingWorker() {
+		public Object construct() {
+		    SwingUtils.expandTree (CommonTree.this, (DefaultMutableTreeNode)getModel().getRoot());
+		    return null;  // not used here
+		}
+		// runs on the event-dispatching thread.
+		public void finished() {
+		    repaint();
+		}
+	    };
+	worker.start(); 
+
+    }
+
+    /*********************************************************************
+     * Search underlying objects and highligh nodes corresponding to
+     * the found objects. But it does nothing here - it is supposed to
+     * be overwritten by a concrete tree.
+     ********************************************************************/
+    protected void search (String searchText) {
+	System.out.println ("Search text: " + searchText);
+    }
+
+    /*********************************************************************
+     * Show a dialog asking for a search string, and return it. Or
+     * return null if user cancel the dialog.
+     ********************************************************************/
+    protected String searchDialog() {
+	if (searchIcon == null)
+	    searchIcon = 
+		SwingUtils.createIcon ("images/viewerButton.gif", Dashboard.class);
+
+	String result = (String)JOptionPane.showInputDialog
+	    (null,
+	     "The search will highlight nodes in this tree that\n" +
+	     "contain (or are related to) the text you enter here.\n"  +
+	     "Text is treated as a regular expression. The case-\n" +
+	     "insensitivity is, however, always added by default.\n \n" +
+	     "For example, try: germplasm or mark|kawas.\n \n",
+	     "Search",
+	     JOptionPane.OK_CANCEL_OPTION,
+	     searchIcon,
+	     null,
+	     lastSearchText);
+	if (result != null)
+	    lastSearchText = result;
+	return result;
+    }
+    
+    protected void highlightAndJumpTo (HashSet toBeHighlighted) {
+
+	CommonTreeCellRenderer r = (CommonTreeCellRenderer)getCellRenderer();
+	r.setToBeHighlighted (toBeHighlighted);
+	collapse ();
+	DefaultTreeModel tModel = (DefaultTreeModel)getModel();
+	DefaultMutableTreeNode root = (DefaultMutableTreeNode)tModel.getRoot(); 
+	Enumeration en = root.depthFirstEnumeration();
+	while (en.hasMoreElements()) {
+	    DefaultMutableTreeNode node = (DefaultMutableTreeNode)en.nextElement();
+	    if (toBeHighlighted.contains (node.getUserObject().toString())) {
+		makeVisible (new TreePath (tModel.getPathToRoot (node)));
+	    }
+	}
     }
 
 }

===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/ConsolePanel.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/ConsolePanel.java	2005/09/18 14:09:42	1.3
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/ConsolePanel.java	2005/09/24 17:51:51	1.4
@@ -15,7 +15,7 @@
 import javax.swing.Icon;
 import javax.swing.JComponent;
 import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
+// import javax.swing.JTextArea;
 import javax.swing.JPanel;
 import javax.swing.text.html.HTMLDocument;
 
@@ -28,6 +28,7 @@
 import java.beans.PropertyChangeEvent;
 
 import java.util.Date;
+import java.util.Map;
 
 /**
  * A debugging panel. It tries to listen to as many events it can, and
@@ -42,13 +43,13 @@
 public class ConsolePanel
     extends AbstractPanel {
 
-    JTextArea textArea = null;
+    CommonConsole console;
 
     /*********************************************************************
      * propertyChange()
      ********************************************************************/
     public void propertyChange (PropertyChangeEvent e) {
-	if (textArea == null) return;  // I am not yet ready
+	if (console == null) return;  // I am not yet ready
 
         String prop = e.getPropertyName();
         if (prop == null) return;     // no interest in non-specific changes
@@ -57,8 +58,7 @@
         if (value == null) return;   // no interest in non-defined  new values
 
 	if (prop.equalsIgnoreCase (DP_LOG_MSG)) {
-	    textArea.append (value.toString());
-	    textArea.append ("\n");
+	    console.setText (value.toString() + "\n");
 	} else {
 	    StringBuffer buf = new StringBuffer();
 	    Object source = e.getSource();
@@ -69,38 +69,43 @@
 	    }
 	    buf.append (" at ");
 	    buf.append (new Date().toString());
-	    textArea.append ("PROPERTY: " + prop + buf + "\n");
-	    textArea.append ("VALUE:    " + value.toString() + "\n\n");
+	    console.setText ("PROPERTY: " + prop + buf + "\n" +
+			     "VALUE:    " + value.toString() + "\n\n");
 	}
     }
 
     /**************************************************************************
      *
      **************************************************************************/
-    public JComponent getComponent() {
-	JPanel p = new JPanel (new GridBagLayout(), true);
+    public JComponent getComponent (PropertyChannel propertyChannel) {
+ 	setPropertyChannel (propertyChannel);
 
-        textArea = new JTextArea (24, 80);
-        textArea.setFont (new Font ("Courier", Font.PLAIN, 10));
-	textArea.setEditable (false);
-	JScrollPane scroller = new JScrollPane (textArea);
-
-	JButton cleanButton =
-	    createButton (" Clean ",
-			  "Remove all messages from the console area",
-			  KeyEvent.VK_C,
-			  new ActionListener() {
-			      public void actionPerformed (ActionEvent e) {
-				  if (! "".equals (textArea.getText()) && confirm ("Remove all messages?"))
-				      textArea.setText ("");
-			      }
-			  });
-
-	// put it together
- 	SwingUtils.addComponent (p, scroller,    0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0);
- 	SwingUtils.addComponent (p, cleanButton, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0);
+	console = new CommonConsole();
+	return console;
 
-	return p;
+// 	JPanel p = new JPanel (new GridBagLayout(), true);
+
+//         textArea = new JTextArea (24, 80);
+//         textArea.setFont (new Font ("Courier", Font.PLAIN, 10));
+// 	textArea.setEditable (false);
+// 	JScrollPane scroller = new JScrollPane (textArea);
+
+// 	JButton cleanButton =
+// 	    createButton (" Clean ",
+// 			  "Remove all messages from the console area",
+// 			  KeyEvent.VK_C,
+// 			  new ActionListener() {
+// 			      public void actionPerformed (ActionEvent e) {
+// 				  if (! "".equals (textArea.getText()) && confirm ("Remove all messages?"))
+// 				      textArea.setText ("");
+// 			      }
+// 			  });
+
+// 	// put it together
+//  	SwingUtils.addComponent (p, scroller,    0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0);
+//  	SwingUtils.addComponent (p, cleanButton, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0);
+
+// 	return p;
     }
 
     /**************************************************************************

===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/Dashboard.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/Dashboard.java	2005/09/18 14:09:42	1.3
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/Dashboard.java	2005/09/24 17:51:51	1.4
@@ -34,6 +34,7 @@
 import java.util.Vector;
 import java.util.Enumeration;
 import java.util.Properties;
+import java.util.Hashtable;
 import java.util.Date;
 import java.net.URL;
 import java.text.DateFormat;
@@ -54,6 +55,7 @@
     public static boolean useLoadMonitor = true;
     protected JTabbedPane tabbedPane;
     protected DashboardPanel[] panels;
+    protected PropertyChannel propertyChannel;
     protected static Properties dashboardProperties;
 
     static {
@@ -84,7 +86,8 @@
      **************************************************************************/
     public Dashboard() {
 	loadPanels();
-	dashboard = getComponent();
+	propertyChannel = new PropertyChannel();
+	dashboard = getComponent (propertyChannel);
 	connectPanels();
     }
 
@@ -103,14 +106,14 @@
 
     /**************************************************************************
      * Connect all available Dashboard panels: a) together, and b)
-     * with the status bar.
+     * with the status bar. TBD: It changed... It uses now a PropertyChannel...
      **************************************************************************/
     public void connectPanels() {
 	for (int i = 0; i < panels.length; i++) {
-	    for (int j = 0; j < i; j++)
-		panels[i].addPropertyChangeListener (panels[j]);
-	    for (int j = i+1; j < panels.length; j++)
-		panels[i].addPropertyChangeListener (panels[j]);
+// 	    for (int j = 0; j < i; j++)
+// 		panels[i].addPropertyChangeListener (panels[j]);
+// 	    for (int j = i+1; j < panels.length; j++)
+// 		panels[i].addPropertyChangeListener (panels[j]);
 	    if (statusBar != null)
 		panels[i].addPropertyChangeListener (statusBar);
 	}
@@ -120,7 +123,8 @@
      * Show the main frame.
      **************************************************************************/
     public void show() {
-  	JFrame frame = SwingUtils.createMainFrame (getComponent(), getName());
+  	JFrame frame = SwingUtils.createMainFrame (getComponent (propertyChannel),
+						   getName());
   	SwingUtils.showMainFrame (frame, dashboard.getPreferredSize());
     }
 
@@ -182,7 +186,7 @@
     /**************************************************************************
      *
      **************************************************************************/
-    public JComponent getComponent() {
+    public JComponent getComponent (PropertyChannel propertyChannel) {
 
 	if (dashboard != null)
 	    return dashboard;
@@ -202,7 +206,9 @@
 	    String name = panels[i].getName();
 	    if (useLoadMonitor)
 		ProgressView.monitor.setTextAndAdd ("Loading " + name + "...");
-	    tabbedPane.addTab (name, panels[i].getIcon(), panels[i].getComponent());
+	    tabbedPane.addTab (name,
+			       panels[i].getIcon(),
+			       panels[i].getComponent (propertyChannel));
 	}
         statusBar = getStatusBar();
 

===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardPanel.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardPanel.java	2005/09/18 08:46:26	1.3
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardPanel.java	2005/09/24 17:51:51	1.4
@@ -32,9 +32,12 @@
     extends PropertyChangeListener, DashboardProperties {
 
     /**************************************************************************
-     * Return a graphical representation of this panel.
+     * Return a graphical representation of this panel. <p>
+     *
+     * @param propertyChannel is a shared storage for properties
+     * @return a GUI representing this panel
      **************************************************************************/
-    JComponent getComponent();
+    JComponent getComponent (PropertyChannel propertyChannel);
 
     /**************************************************************************
      * A name identifies a panel in the dashboard's tabs. It should be

===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardProperties.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardProperties.java	2005/09/18 08:46:26	1.2
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardProperties.java	2005/09/24 17:51:51	1.3
@@ -27,11 +27,17 @@
 
 public interface DashboardProperties {
 
+    // names of properties used in property change events
     static final String DP_LOG_MSG = "log-msg";
     static final String DP_STATUS_MSG = "status-msg";
     static final String DP_SERVICE_NAME = "dp-service-name";
     static final String DP_DATATYPE_NAME = "dp-datatype-name";
 
+    // names of properties used in property channel storage
+    static final String DP_REGISTRY_ENDPOINT = "dp-registry-endpoint";
+    static final String DP_REGISTRY_NAMESPACE = "dp-registry-namespace";
+    static final String DP_CACHE_DIR = "dp-cache-dir";
+
     /** A filename containing Java properties that configure the
 	dashboard. */
     static final String DASHBOARD_PROPERTIES_FILE = "dashboard.properties";

===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/EventGeneratorPanel.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/EventGeneratorPanel.java	2005/09/18 08:46:26	1.2
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/EventGeneratorPanel.java	2005/09/24 17:51:51	1.3
@@ -25,6 +25,8 @@
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeEvent;
 
+import java.util.Map;
+
 /**
  * A debugging panel. It generates some events. <p>
  *
@@ -40,7 +42,9 @@
     /**************************************************************************
      *
      **************************************************************************/
-    public JComponent getComponent() {
+    public JComponent getComponent (PropertyChannel propertyChannel) {
+ 	setPropertyChannel (propertyChannel);
+
 	JPanel p = new JPanel (new GridBagLayout(), true);
 
 	JLabel desc =
@@ -81,7 +85,8 @@
 
     //
     private void onFire (String propertyName, String value) {
-	support.firePropertyChange (propertyName, null, value);
+	propertyChannel.put (propertyName, value);
+// 	support.firePropertyChange (propertyName, null, value);
     }
 
     /**************************************************************************

===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/NOTES,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/NOTES	2005/09/22 16:07:09	1.5
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/NOTES	2005/09/24 17:51:51	1.6
@@ -1,3 +1,123 @@
+invokeLater()
+-------------
+/**
+ * Create the GUI and show it.  For thread safety,
+ * this method should be invoked from the
+ * event-dispatching thread.
+ */
+private static void createAndShowGUI() {
+    //Make sure we have nice window decorations.
+    JFrame.setDefaultLookAndFeelDecorated(true);
+
+    //Create and set up the window.
+    frame = new JFrame("FocusConceptsDemo");
+    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+    //Create and set up the content pane.
+    JComponent newContentPane = new FocusConceptsDemo();
+    newContentPane.setOpaque(true); //content panes must be opaque
+    frame.setContentPane(newContentPane);
+
+    //Display the window.
+    frame.pack();
+    frame.setVisible(true);
+}
+public static void main(String[] args) {
+    //Schedule a job for the event-dispatching thread:
+    //creating and showing this application's GUI.
+    javax.swing.SwingUtilities.invokeLater(new Runnable() {
+        public void run() {
+            createAndShowGUI();
+        }
+    });
+
+invokeAndWait():
+----------------
+void printTextField() throws Exception {
+    final String[] myStrings = new String[2];
+
+    Runnable getTextFieldText = new Runnable() {
+        public void run() {
+            myStrings[0] = textField0.getText();
+            myStrings[1] = textField1.getText();
+        }
+    };
+    SwingUtilities.invokeAndWait(getTextFieldText);
+
+    System.out.println(myStrings[0] + " " + myStrings[1]);
+}
+
+SwingWorker:
+------------
+
+//BETTER CODE:
+public void actionPerformed(ActionEvent e) {
+    ...
+    final SwingWorker worker = new SwingWorker() {
+        public Object construct() {
+            //...code that might take a while to execute is here...
+            return someValue;
+        }
+    };
+    worker.start();  //required for SwingWorker 3
+    ...
+}
+
+using finished:
+
+public void actionPerformed(ActionEvent e) {
+    ...
+    if (icon == null) {     //haven't viewed this photo before
+        loadImage(imagedir + pic.filename, current);
+    } else {
+        updatePhotograph(current, pic);
+    }
+}
+...
+//Load an image in a separate thread.
+private void loadImage(final String imagePath, final int index) {
+    final SwingWorker worker = new SwingWorker() {
+        ImageIcon icon = null;
+
+        public Object construct() {
+            icon = new ImageIcon(getURL(imagePath));
+            return icon; //return value not used by this program
+        }
+
+        //Runs on the event-dispatching thread.
+        public void finished() {
+            Photo pic = (Photo)pictures.elementAt(index);
+            pic.setIcon(icon);
+            if (index == current)
+                updatePhotograph(index, pic);
+        }
+    };
+    worker.start(); 
+}
+
+
+----
+
+* error messages (dialog window, or a text-area window/save button, something on sterrr?)
+? logging (LogPanel and/or usual logging to a file?)
+* communication with StatusBar (incl. progress bar, cancel button)
+* disabling things during a long-time operation
+* general Console panel (save button; various renderes?)
+* graphics to trees
+
+
+TODO generally:
+---------------
+
+* notice that the dasboard is used the first time and offer ti create
+a list of wanted panels (some of them are suggested as default)
+
+* notice that user does not use cache (and that he did not select "do
+not check it at startup") and tell him "do you want a cache?"
+
+* BUG: not sure why so many (repeated) changes from the actionlistener
+in JFieldTextWithHistory
+
 TODO with views:
 ----------------
 * change onMethods() to be protected or even private...

===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/RegistryModel.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/RegistryModel.java	2005/09/19 08:09:22	1.1
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/RegistryModel.java	2005/09/24 17:51:51	1.2
@@ -8,8 +8,18 @@
 
 package org.biomoby.service.dashboard;
 
+import org.biomoby.shared.MobyException;
+import org.biomoby.shared.MobyDataType;
+import org.biomoby.shared.CentralAll;
+import org.biomoby.client.CentralDigestCachedImpl;
+
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeSupport;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.regex.Pattern;
 
 /**
  * A real worker that supplies all data to the {@link
@@ -20,17 +30,108 @@
  * @version $Id$
  */
 
-public class RegistryModel {
+public class RegistryModel
+    extends AbstractModel {
+
+    CentralAll worker;
+    Hashtable dataTypesTable;
 
     /*********************************************************************
      * Default constructor.
      ********************************************************************/
     public RegistryModel() {
+	super();
+    }
+
+    /*********************************************************************
+     * Usual constructor that shares support for property changes with
+     * its creator.
+     ********************************************************************/
+    public RegistryModel (PropertyChangeSupport support) {
+	super (support);
+    }
+
+    /*********************************************************************
+     *
+     ********************************************************************/
+    public MobyDataType[] getDataTypesByNames()
+	throws MobyException {
+
+	if (worker == null)
+	    initWorker();
+
+	MobyDataType[] dataTypes = worker.getDataTypes();
+	return dataTypes;
     }
 
     /*********************************************************************
      *
      ********************************************************************/
+    public MobyDataType getDataType (String dataTypeName)
+	throws MobyException {
+	if (dataTypeName == null)
+	    return null;
+
+	MobyDataType[] dataTypes = getDataTypesByNames();
+
+	if (dataTypesTable == null) {
+	    dataTypesTable = new Hashtable();
+	    for (int i = 0; i < dataTypes.length; i++) {
+		dataTypesTable.put (dataTypes[i].getName(), dataTypes[i]);
+	    }
+	}
+	return (MobyDataType)dataTypesTable.get (dataTypeName);
+    }
+
+    /*********************************************************************
+     * Return a HashSet filled with names of data types that have
+     * somewhere given 'searchText'. Add case-insensitivity to the
+     * regular expression in 'searchText'.
+     ********************************************************************/
+    public HashSet find (String searchText)
+	throws MobyException {
+	HashSet found = new HashSet();
+	MobyDataType[] dataTypes = getDataTypesByNames();
+	if (! searchText.startsWith ("(?i)"))
+	    searchText = "(?i)" + searchText;
+	Pattern pattern = Pattern.compile (searchText);
+	for (int i = 0; i < dataTypes.length; i++) {
+	    if (pattern.matcher (dataTypes[i].toString()).find())
+		found.add (dataTypes[i].getName());
+	}
+	return found;
+    }
+
+
+//     /*********************************************************************
+//      *
+//      ********************************************************************/
+//     public MobyDataType[] getDataTypesByAuthority()
+// 	throws MobyException {
+
+// 	if (worker == null)
+// 	    initWorker();
+
+// 	MobyDataType[] dataTypes = worker.getDataTypes();
+// 	java.util.Arrays.sort (dataTypes);
+// 	return dataTypes;
+//     }
+
+    /*********************************************************************
+     *
+     ********************************************************************/
+    protected void initWorker()
+	throws MobyException {
+	String registryURL = propertyChannel.getString (DP_REGISTRY_ENDPOINT);
+	String registryNS = propertyChannel.getString (DP_REGISTRY_NAMESPACE);
+//  	String cacheDir = propertyChannel.getString (DP_CACHE_DIR);
+ 	String cacheDir = "/home/senger/jMoby/myCache";
+//  	cacheDir = null;
+
+	worker = new CentralDigestCachedImpl (registryURL,
+					      registryNS,
+					      cacheDir);
+    }
 
 
 }

===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/RegistryPanel.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/RegistryPanel.java	2005/09/19 08:08:32	1.6
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/RegistryPanel.java	2005/09/24 17:51:51	1.7
@@ -8,6 +8,13 @@
 
 package org.biomoby.service.dashboard;
 
+import org.biomoby.shared.MobyException;
+import org.biomoby.shared.Central;
+import org.biomoby.shared.MobyDataType;
+import org.biomoby.shared.MobyRelationship;
+import org.biomoby.service.generator.DataTypesGenerator;
+
+import org.tulsoft.shared.UUtils;
 import org.tulsoft.tools.gui.SwingUtils;
 import org.tulsoft.tools.gui.JTextFieldWithHistory;
 import org.tulsoft.tools.gui.JFileChooserWithHistory;
@@ -21,19 +28,33 @@
 import javax.swing.JSplitPane;
 import javax.swing.JScrollPane;
 import javax.swing.JTextArea;
+import javax.swing.JPopupMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.AbstractAction;
 import javax.swing.JComponent;
 import javax.swing.text.html.HTMLDocument;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
 
 import java.awt.GridBagLayout;
 import java.awt.Font;
-
 import java.awt.event.KeyEvent;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseAdapter;
+
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeEvent;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Enumeration;
+import java.util.Vector;
 
 /**
  * A panel displaying contents of a Biomoby registry. It also select
@@ -58,6 +79,7 @@
     // components that are used from more methods
     JFileChooserWithHistory cacheDir;
     JLabel labelCacheDir;
+    CommonConsole console;
 
     /*********************************************************************
      * propertyChange()
@@ -78,14 +100,16 @@
      ********************************************************************/
     public RegistryPanel() {
 	super();
-// 	registryModel = new RegistryModel (this);
-	registryModel = new RegistryModel();
+ 	registryModel = new RegistryModel (support);
     }
 
     /**************************************************************************
      *
      **************************************************************************/
-    public JComponent getComponent() {
+    public JComponent getComponent (PropertyChannel propertyChannel) {
+ 	setPropertyChannel (propertyChannel);
+	registryModel.setPropertyChannel (propertyChannel);
+
 	if (pComponent != null)
 	    return pComponent;
 
@@ -94,6 +118,7 @@
 	// ontology trees
 	ServicesTree servicesTree = new ServicesTree();
 	DataTypesTree dataTypesTree = new DataTypesTree();
+	dataTypesTree.update (CommonTree.SORTED_BY_NAME);
 	NamespacesTree namespacesTree = new NamespacesTree();
 
 	JSplitPane split1 = new JSplitPane (JSplitPane.HORIZONTAL_SPLIT,
@@ -110,7 +135,8 @@
 	split2.setOneTouchExpandable (true);
 
 	// console panel
-	JPanel console = getConsole();
+	console = new CommonConsole();
+	console.setAppendMode (false);
 
 	JSplitPane split3 = new JSplitPane (JSplitPane.VERTICAL_SPLIT,
 					    split2,
@@ -177,10 +203,10 @@
     protected JPanel getRegistryLocation() {
    	JLabel labelRegistryURL = new JLabel("Endpoint");
 	JTextFieldWithHistory registryURL =
-	    new JTextFieldWithHistory ("", this, "registryEndpoint");
+	    createText ("", "registryEndpoint", DP_REGISTRY_ENDPOINT);
    	JLabel labelRegistryNS = new JLabel("Namespace (URI)");
 	JTextFieldWithHistory registryNS =
-	    new JTextFieldWithHistory ("", this, "registryNamespace");
+	    createText ("", "registryNamespace", DP_REGISTRY_NAMESPACE);
 	JButton reloadAllButton =
 	    createButton (" Reload all ",
 			  "Reload all ontology trees from the Biomoby registry",
@@ -226,9 +252,11 @@
    	labelCacheDir = new JLabel("Cache directory");
 	cacheDir = createFileSelector ("Select directory for/with local cache",
 				       "Select",
-				       JFileChooser.DIRECTORIES_ONLY,
 				       System.getProperty ("java.io.tmpdir"),
-				       null);
+				       "cacheDirectory",
+				       DP_CACHE_DIR);
+	cacheDir.getFileChooser().setFileSelectionMode (JFileChooser.DIRECTORIES_ONLY);
+
 	onUseCache (usingCache);
 	JButton infoButton =
 	    createButton (" Info ",
@@ -273,13 +301,13 @@
     /**************************************************************************
      *
      **************************************************************************/
-    protected JPanel getConsole() {
-	JPanel p = new JPanel (new GridBagLayout());
+//     protected JPanel getConsole() {
+// 	JPanel p = new JPanel (new GridBagLayout());
 
-        JTextArea textArea = new JTextArea();
-        textArea.setFont (new Font ("Courier", Font.PLAIN, 10));
-	textArea.setEditable (false);
-	JScrollPane scroller = new JScrollPane (textArea);
+//         JTextArea textArea = new JTextArea();
+//         textArea.setFont (new Font ("Courier", Font.PLAIN, 10));
+// 	textArea.setEditable (false);
+// 	JScrollPane scroller = new JScrollPane (textArea);
 
 // 	JButton cleanButton =
 // 	    createButton (" Clean ",
@@ -292,12 +320,12 @@
 // 			      }
 // 			  });
 
-	// put it together
- 	SwingUtils.addComponent (p, scroller,    0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0);
-//  	SwingUtils.addComponent (p, cleanButton, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0);
+// 	// put it together
+//  	SwingUtils.addComponent (p, scroller,    0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0);
+// //  	SwingUtils.addComponent (p, cleanButton, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0);
 
-	return p;
-    }
+// 	return p;
+//     }
 
     /**************************************************************************
      *
@@ -312,11 +340,277 @@
      *
      **************************************************************************/
     class DataTypesTree extends CommonTree {
+	MobyDataType[] dataTypes = null;
+	int lastSorted = SORTED_BY_NAME;
+	boolean hideBadGuys = false;
+	boolean showMembers = false;
+	JCheckBoxMenuItem hideBox;
+
 	public DataTypesTree() {
 	    super ("DataTypes");
+	    createPopups ("Data Types Menu");
+	}
+
+	protected void createPopups (String title) {
+	    super.createPopups (title);
+	    popup.addSeparator();
+	    popup.add
+		(new JMenuItem (new AbstractAction ("Sort by names") {
+			public void actionPerformed (ActionEvent e) {
+			    update (lastSorted = SORTED_BY_NAME);
+			    hideBox.setEnabled (true);
+			}
+		    }));
+	    popup.add
+		(new JMenuItem (new AbstractAction ("Sort by authorities") {
+			public void actionPerformed (ActionEvent e) {
+			    update (lastSorted = SORTED_BY_AUTHORITY);
+			    hideBox.setEnabled (false);
+			}
+		    }));
+	    popup.addSeparator();
+
+	    JCheckBoxMenuItem showBox = new JCheckBoxMenuItem ("Show HAS/HASA members");
+	    showBox.addItemListener (new ItemListener() {
+		    public void itemStateChanged  (ItemEvent e) {
+			showMembers = (e.getStateChange() == ItemEvent.SELECTED);
+			update (lastSorted);
+		    }
+		});
+	    popup.add (showBox);
+
+	    hideBox = new JCheckBoxMenuItem ("Hide deprecated objects");
+	    hideBox.addItemListener (new ItemListener() {
+		    public void itemStateChanged  (ItemEvent e) {
+			hideBadGuys = (e.getStateChange() == ItemEvent.SELECTED);
+			if (hideBadGuys)
+			    removeBadGuys();
+			else
+			    update (lastSorted);
+		    }
+		});
+	    popup.add (hideBox);
+	}
+
+	void update (int howSorted) {
+	    popup.setEnabled (false);
+	    final int sorted = howSorted;
+	    final SwingWorker worker = new SwingWorker() {
+		    public Object construct() {
+			try {
+			    dataTypes = registryModel.getDataTypesByNames();
+			} catch (MobyException e) {
+			    // TBD: what to do here?
+			    System.err.println ("ERROR: " + e.getMessage());
+			}
+			return dataTypes;  // not used here
+		    }
+
+		    // runs on the event-dispatching thread.
+		    public void finished() {
+			if (dataTypes != null) {
+			    if (sorted == SORTED_BY_AUTHORITY)
+				onUpdateDataTreeByAuth (dataTypes);
+			    else
+				onUpdateDataTree (dataTypes);
+			    popup.setEnabled (true);
+			}
+		    }
+		};
+	    worker.start(); 
+	}
+
+	void onUpdateDataTree (MobyDataType[] dataTypes) {
+	    DefaultTreeModel tModel = (DefaultTreeModel)getModel();
+	    DefaultMutableTreeNode root = (DefaultMutableTreeNode)tModel.getRoot();
+	    root.removeAllChildren();   // does not harm if no children exist
+	    HashMap nodes = new HashMap (dataTypes.length);
+	    for (int i = 0; i < dataTypes.length; i++) {
+		String thisName = dataTypes[i].getName();
+		DefaultMutableTreeNode thisNode = (DefaultMutableTreeNode)nodes.get (thisName);
+		if (thisNode == null) {
+		    thisNode = new DefaultMutableTreeNode (new CommonNode (thisName));
+		    nodes.put (thisName, thisNode);
+		}
+		String[] parents = dataTypes[i].getParentNames();
+		if (parents.length == 0) {   // we have a top-level object
+		    root.add (thisNode);
+		} else {
+		    String parentName = parents[0];
+		    DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)nodes.get (parentName);
+		    if (parentNode == null) {
+			parentNode = new DefaultMutableTreeNode (new CommonNode (parentName));
+			nodes.put (parentName, parentNode);
+		    }
+		    if (showMembers)
+			addMembers (thisNode, dataTypes[i]);
+		    parentNode.add (thisNode);
+		}
+	    }
+	    if (hideBadGuys)
+		removeBadGuys();
+	    else
+		tModel.reload();
+	}
+
+
+	void onUpdateDataTreeByAuth (MobyDataType[] dataTypes) {
+	    DefaultTreeModel tModel = (DefaultTreeModel)getModel();
+	    DefaultMutableTreeNode root = (DefaultMutableTreeNode)tModel.getRoot();
+	    root.removeAllChildren();   // does not harm if no children exist
+	    HashMap nodes = new HashMap (dataTypes.length);
+	    for (int i = 0; i < dataTypes.length; i++) {
+		String thisName = dataTypes[i].getName();
+		DefaultMutableTreeNode thisNode = (DefaultMutableTreeNode)nodes.get (thisName);
+		if (thisNode == null) {
+		    thisNode = new DefaultMutableTreeNode (new CommonNode (thisName));
+		    nodes.put (thisName, thisNode);
+		}
+		String authority = dataTypes[i].getAuthority();
+		if (UUtils.isEmpty (authority))
+		    authority = "<unknown>";
+		DefaultMutableTreeNode authNode = (DefaultMutableTreeNode)nodes.get (authority);
+		if (authNode == null) {
+		    authNode = new DefaultMutableTreeNode (new CommonNode (authority));
+		    nodes.put (authority, authNode);
+		    root.add (authNode);
+		}
+		if (showMembers)
+		    addMembers (thisNode, dataTypes[i]);
+		authNode.add (thisNode);
+	    }
+	    tModel.reload();
 	}
+
+	void removeBadGuys() {
+	    DefaultTreeModel tModel = (DefaultTreeModel)getModel();
+	    DefaultMutableTreeNode root = (DefaultMutableTreeNode)tModel.getRoot();
+	 
+	    Vector removeFromParent = new Vector();   // nodes that will be removed   
+	    Vector removeAllChildren = new Vector();  // nodes whose children will be removed
+	    for (Enumeration en = root.children(); en.hasMoreElements(); ) {
+		DefaultMutableTreeNode node = (DefaultMutableTreeNode)en.nextElement();
+		String value = ((CommonNode)node.getUserObject()).getValue();
+		if (value.equals ("Object")) {
+		    // primitive type should not have children
+		    for (Enumeration en2 = node.children(); en2.hasMoreElements(); ) {
+			DefaultMutableTreeNode node2 = (DefaultMutableTreeNode)en2.nextElement();
+			String value2 = ((CommonNode)node2.getUserObject()).getValue();
+			if (DataTypesGenerator.isPrimitiveType (value2))
+			    removeAllChildren.addElement (node2);
+		    }
+		} else {
+		    // only Object can be a root object
+		    removeFromParent.addElement (node);
+		}
+	    }
+	    for (Enumeration en = removeFromParent.elements(); en.hasMoreElements(); ) {
+		DefaultMutableTreeNode node = (DefaultMutableTreeNode)en.nextElement();
+		node.removeFromParent();
+	    }
+	    for (Enumeration en = removeAllChildren.elements(); en.hasMoreElements(); ) {
+		DefaultMutableTreeNode node = (DefaultMutableTreeNode)en.nextElement();
+		node.removeAllChildren();
+	    }
+	    tModel.reload();
+	}
+
+	void addMembers (DefaultMutableTreeNode node, MobyDataType dataType) {
+	    MobyRelationship[] rels = dataType.getChildren();
+	    for (int i = 0; i < rels.length; i++) {
+		String memberName = rels[i].getName();
+		String memberType = rels[i].getDataTypeName();
+		int memberRel = rels[i].getRelationshipType();
+		node.add (new DefaultMutableTreeNode (new MemberNode (rels[i])));
+	    }
+	}
+
+	/*********************************************************************
+	 * Search underlying objects and highligh nodes corresponding to
+	 * the found objects.
+	 ********************************************************************/
+	protected void search (String searchText) {
+	    final String regex = searchText;
+	    final SwingWorker worker = new SwingWorker() {
+		    HashSet found = new HashSet();
+		    public Object construct() {
+			try {
+			    if (UUtils.notEmpty (regex))
+				found = registryModel.find (regex);
+			} catch (MobyException e) {
+			    // TBD: what to do here?
+			    System.err.println ("ERROR: " + e.getMessage());
+			}
+			return found;  // not used here
+		    }
+
+		    // runs on the event-dispatching thread.
+		    public void finished() {
+			if (found != null)
+			    highlightAndJumpTo (found);
+		    }
+		};
+	    worker.start(); 
+	}
+
+	/*********************************************************************
+	 *
+	 ********************************************************************/
+	protected void selected (DefaultMutableTreeNode node) {
+ 	    final CommonNode nodeObject = (CommonNode)node.getUserObject();
+	    final SwingWorker worker = new SwingWorker() {
+		    MobyDataType dataType;
+		    public Object construct() {
+			try {
+			    dataType = registryModel.getDataType (nodeObject.getValue());
+			} catch (MobyException e) {
+			    // TBD: what to do here?
+			    System.err.println ("ERROR: " + e.getMessage());
+			}
+			return dataType;  // not used here
+		    }
+
+		    // runs on the event-dispatching thread.
+		    public void finished() {
+			if (dataType != null)
+// 			    System.out.println (dataType);
+			    console.setText (dataType.toString());
+		    }
+		};
+	    worker.start(); 
+	}
+
+	class MemberNode extends CommonNode {
+	    MobyRelationship rel;
+	    public MemberNode (MobyRelationship rel) {
+		this.rel = rel;
+	    }
+	    public String getValue() {
+		return rel.getDataTypeName();
+	    }
+	    public String toString() {
+		String memberName = rel.getName();
+		String memberType = rel.getDataTypeName();
+		int memberRel = rel.getRelationshipType();
+		StringBuffer buf = new StringBuffer (100);
+		buf.append ("<html><b>");
+		buf.append (memberRel == Central.iHAS ? "HAS" : "HASA");
+		buf.append (": </b>");
+		buf.append (memberType);
+		if (UUtils.notEmpty (memberName)) {
+		    buf.append (" (<font color='blue'>");
+		    buf.append (memberName);
+		    buf.append ("</font>)");
+		}
+		return buf.toString();
+	    }
+	}
+
+
     }
 
+
+
     /**************************************************************************
      *
      **************************************************************************/
@@ -342,35 +636,4 @@
 	return panelIcon;
     }
 
-
-// public void actionPerformed(ActionEvent e) {
-//     ...
-//     if (icon == null) {     //haven't viewed this photo before
-//         loadImage(imagedir + pic.filename, current);
-//     } else {
-//         updatePhotograph(current, pic);
-//     }
-// }
-// ...
-// //Load an image in a separate thread.
-// private void loadImage(final String imagePath, final int index) {
-//     final SwingWorker worker = new SwingWorker() {
-//         ImageIcon icon = null;
-
-//         public Object construct() {
-//             icon = new ImageIcon(getURL(imagePath));
-//             return icon; //return value not used by this program
-//         }
-
-//         //Runs on the event-dispatching thread.
-//         public void finished() {
-//             Photo pic = (Photo)pictures.elementAt(index);
-//             pic.setIcon(icon);
-//             if (index == current)
-//                 updatePhotograph(index, pic);
-//         }
-//     };
-//     worker.start(); 
-// }
-
 }




More information about the MOBY-guts mailing list