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