JAL-1075 tweak layout and test display for tree based sequence source browser
[jalview.git] / src / jalview / gui / JDatabaseTree.java
1 package jalview.gui;
2
3 import jalview.bin.Cache;
4 import jalview.ws.seqfetcher.DbSourceProxy;
5
6 import java.awt.BorderLayout;
7 import java.awt.Component;
8 import java.awt.Container;
9 import java.awt.Dimension;
10 import java.awt.FlowLayout;
11 import java.awt.event.ActionEvent;
12 import java.awt.event.ActionListener;
13 import java.util.ArrayList;
14 import java.util.Hashtable;
15 import java.util.List;
16 import java.util.Vector;
17
18 import javax.swing.JButton;
19 import javax.swing.JFrame;
20 import javax.swing.JLabel;
21 import javax.swing.JPanel;
22 import javax.swing.JScrollPane;
23 import javax.swing.JTree;
24 import javax.swing.JViewport;
25 import javax.swing.tree.DefaultMutableTreeNode;
26 import javax.swing.tree.DefaultTreeCellRenderer;
27 import javax.swing.tree.DefaultTreeModel;
28 import javax.swing.tree.MutableTreeNode;
29 import javax.swing.tree.TreeCellRenderer;
30 import javax.swing.tree.TreeModel;
31 import javax.swing.tree.TreePath;
32 import javax.swing.tree.TreeSelectionModel;
33
34 import com.sun.java.help.search.DBPartParameters;
35
36 public class JDatabaseTree extends JalviewDialog
37 {
38   JButton getDatabaseSelectorButton()
39   {
40     final JButton viewdbs = new JButton("--- Select Database ---");
41     viewdbs.addActionListener(new ActionListener()
42     {
43
44       @Override
45       public void actionPerformed(ActionEvent arg0)
46       {
47         showDialog(null);
48       }
49     });
50     return viewdbs;
51   }
52
53   JScrollPane svp;
54
55   JTree dbviews;
56
57   private jalview.ws.SequenceFetcher sfetcher;
58
59   public JDatabaseTree(jalview.ws.SequenceFetcher sfetch)
60   {
61     super();
62     /*
63      * Dynamically generated database list will need a translation function from
64      * internal source to externally distinct names. UNIPROT and UP_NAME are
65      * identical DB sources, and should be collapsed.
66      */
67     DefaultMutableTreeNode tn = null, root = new DefaultMutableTreeNode();
68     Hashtable<DbSourceProxy, DefaultMutableTreeNode> tns = new Hashtable<DbSourceProxy, DefaultMutableTreeNode>();
69     Hashtable<String, DefaultMutableTreeNode> source = new Hashtable<String, DefaultMutableTreeNode>();
70     sfetcher = sfetch;
71     String dbs[] = sfetch.getSupportedDb();
72     Hashtable ht = new Hashtable();
73     for (int i = 0; i < dbs.length; i++)
74     {
75       tn = source.get(dbs[i]);
76       List<DbSourceProxy> srcs = sfetch.getSourceProxy(dbs[i]);
77       if (tn == null)
78       {
79         source.put(dbs[i], tn = new DefaultMutableTreeNode(dbs[i], true));
80       }
81       for (DbSourceProxy dbp : srcs)
82       {
83         if (ht.get(dbp.getDbName()) == null)
84         {
85           tn.add(new DefaultMutableTreeNode(dbp, false));
86           ht.put(dbp.getDbName(), dbp.getDbName());
87         } else {
88           System.err.println("dupe ig for : "+dbs[i]+" \t"+dbp.getDbName());
89         }
90       }
91     }
92     for (int i = 0; i < dbs.length; i++)
93     {
94       tn = source.get(dbs[i]);
95       if (tn == null)
96       {
97         continue;
98       }
99       if (tn.getChildCount() == 1)
100       {
101         // remove nodes with only one child
102         source.put(dbs[i], tn = (DefaultMutableTreeNode) tn.getChildAt(0));
103       }
104       root.add(tn);
105     }
106     initDialogFrame(this, true, false, "Select Database Retrieval Source",
107             400, 300);
108     svp = new JScrollPane();
109     //svp.setAutoscrolls(true);
110     dbviews = new JTree(new DefaultTreeModel(root, false));
111     dbviews.setCellRenderer(new DbTreeRenderer(this));
112
113     dbviews.getSelectionModel().setSelectionMode(
114             TreeSelectionModel.SINGLE_TREE_SELECTION);
115     svp.getViewport().setView(dbviews);
116     svp.getViewport().setMinimumSize(new Dimension(300,250));
117     //svp.setSize(300,250);
118 //    JPanel panel=new JPanel();
119 //    panel.setSize(new Dimension(350,220));
120 //    panel.add(svp);
121     
122     add(svp, BorderLayout.NORTH);
123     JPanel j = new JPanel(new FlowLayout());
124     j.setPreferredSize(new Dimension(300,50));
125     j.add(ok);
126     j.add(cancel);
127     add(j, BorderLayout.CENTER);
128     validate();
129   }
130
131   private class DbTreeRenderer extends DefaultTreeCellRenderer implements
132           TreeCellRenderer
133   {
134     JDatabaseTree us;
135
136     public DbTreeRenderer(JDatabaseTree me)
137     {
138       us = me;
139     }
140
141     private Component returnLabel(String txt)
142     {
143       JLabel jl = new JLabel(txt);
144       jl.setFont(JvSwingUtils.getLabelFont());
145       return jl;
146     }
147
148     @Override
149     public Component getTreeCellRendererComponent(JTree tree, Object value,
150             boolean selected, boolean expanded, boolean leaf, int row,
151             boolean hasFocus)
152     {
153       String val = "";
154       if (value != null && value instanceof DefaultMutableTreeNode)
155       {
156         DefaultMutableTreeNode vl = (DefaultMutableTreeNode) value;
157         value = vl.getUserObject();
158         if (value instanceof DbSourceProxy)
159         {
160           val = (((DbSourceProxy) value).getDbName());
161         }
162         else
163         {
164           if (value instanceof String)
165           {
166             val = ((String) value);
167           }
168         }
169       }
170       if (value == null)
171       {
172         val = ("");
173       }
174       return super.getTreeCellRendererComponent(tree, val, selected,
175               expanded, leaf, row, hasFocus);
176
177     }
178   }
179
180   List<DbSourceProxy> selection = null;
181
182   @Override
183   protected void raiseClosed()
184   {
185     for (ActionListener al : lstners)
186     {
187       al.actionPerformed(null);
188     }
189   }
190
191   @Override
192   protected void okPressed()
193   {
194     _setSelectionState();
195     closeDialog();
196   }
197
198   @Override
199   protected void cancelPressed()
200   {
201     closeDialog();
202   }
203
204   private void showDialog(Container parent)
205   {
206     validate();
207     waitForInput();
208   }
209
210   public boolean hasSelection()
211   {
212     return selection == null ? false : selection.size() == 0 ? false : true;
213   }
214
215   public List<DbSourceProxy> getSelectedSources()
216   {
217     return selection;
218   }
219
220   private void _setSelectionState()
221   {
222     if (dbviews.getSelectionCount() == 0)
223     {
224       selection = null;
225     }
226     List<DbSourceProxy> srcs = new ArrayList<DbSourceProxy>();
227     for (TreePath tp : dbviews.getSelectionPaths())
228     {
229       DefaultMutableTreeNode dmt = (DefaultMutableTreeNode) tp
230               .getLastPathComponent();
231       if (dmt.getUserObject() != null)
232       {
233         if (dmt.getUserObject() instanceof DbSourceProxy)
234         {
235           srcs.add((DbSourceProxy) dmt.getUserObject());
236         }
237         else
238         {
239           srcs.addAll(sfetcher.getSourceProxy((String) dmt.getUserObject()));
240         }
241       }
242     }
243     selection = srcs;
244   }
245
246   public String getSelectedItem()
247   {
248     if (hasSelection())
249     {
250       return getSelectedSources().get(0).getDbName();
251     }
252     return null;
253   }
254
255   public String getExampleQueries()
256   {
257     if (!hasSelection())
258     {
259       return null;
260     }
261     StringBuffer sb = new StringBuffer();
262     for (DbSourceProxy dbs : getSelectedSources())
263     {
264       if (sb.length() > 0)
265       {
266         sb.append(";");
267       }
268       sb.append(dbs.getTestQuery());
269     }
270     return sb.toString();
271   }
272
273   List<ActionListener> lstners = new Vector<ActionListener>();
274
275   public void addActionListener(ActionListener actionListener)
276   {
277     lstners.add(actionListener);
278   }
279
280   public void removeActionListener(ActionListener actionListener)
281   {
282     lstners.remove(actionListener);
283   }
284
285   public static void main(String args[])
286   {
287     Cache.getDasSourceRegistry();
288     JDatabaseTree jdt = new JDatabaseTree(new jalview.ws.SequenceFetcher());
289     JFrame foo = new JFrame();
290     foo.setLayout(new BorderLayout());
291     foo.add(jdt.getDatabaseSelectorButton(), BorderLayout.CENTER);
292     foo.pack();
293     foo.setVisible(true);
294     int nultimes = 5;
295     final Thread us = Thread.currentThread();
296     jdt.addActionListener(new ActionListener()
297     {
298
299       @Override
300       public void actionPerformed(ActionEvent e)
301       {
302         us.interrupt();
303       }
304     });
305     do
306     {
307       try
308       {
309         Thread.sleep(50);
310       } catch (InterruptedException x)
311       {
312         nultimes--;
313         if (!jdt.hasSelection())
314         {
315           System.out.println("No Selection");
316         }
317         else
318         {
319           System.out.println("Selection: " + jdt.getSelectedItem());
320           int s = 1;
321           for (DbSourceProxy pr : jdt.getSelectedSources())
322           {
323             System.out.println("Source " + s++ + ": " + pr.getDbName()
324                     + " (" + pr.getDbSource() + ") Version "
325                     + pr.getDbVersion() + ". Test:\t" + pr.getTestQuery());
326           }
327           System.out.println("Test queries: " + jdt.getExampleQueries());
328         }
329       }
330     } while (nultimes > 0 && foo.isVisible());
331     foo.setVisible(false);
332   }
333 }