Remove start end for now??
[jalview.git] / src / jalview / gui / DasSourceBrowser.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.gui;\r
20 \r
21 import jalview.jbgui.*;\r
22 import javax.swing.table.AbstractTableModel;\r
23 import javax.swing.event.*;\r
24 import jalview.util.TableSorter;\r
25 import java.awt.event.*;\r
26 import javax.swing.*;\r
27 import java.util.*;\r
28 \r
29 \r
30 import org.biojava.dasobert.dasregistry.DasCoordinateSystem;\r
31 import org.biojava.dasobert.dasregistry.DasSource;\r
32 import org.biojava.dasobert.dasregistry.Das1Source;\r
33 import java.awt.BorderLayout;\r
34 \r
35 public class DasSourceBrowser extends GDasSourceBrowser\r
36     implements Runnable, ListSelectionListener\r
37 {\r
38   static DasSource[] dasSources = null;\r
39 \r
40   Hashtable localSources = null;\r
41 \r
42   Vector selectedSources;\r
43 \r
44   public DasSourceBrowser()\r
45   {\r
46     registryURL.setText(jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",\r
47         "http://das.sanger.ac.uk/registry/das1/sources/") );\r
48 \r
49     setSelectedFromProperties();\r
50 \r
51     displayFullDetails(null);\r
52     table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\r
53 \r
54     filter1.addListSelectionListener(this);\r
55     filter2.addListSelectionListener(this);\r
56     filter3.addListSelectionListener(this);\r
57 \r
58     //Ask to be notified of selection changes.\r
59     ListSelectionModel rowSM = table.getSelectionModel();\r
60     rowSM.addListSelectionListener(new ListSelectionListener()\r
61     {\r
62       public void valueChanged(ListSelectionEvent e)\r
63       {\r
64         //Ignore extra messages.\r
65         if (e.getValueIsAdjusting())\r
66           return;\r
67 \r
68         ListSelectionModel lsm = (ListSelectionModel) e.getSource();\r
69         if (!lsm.isSelectionEmpty())\r
70         {\r
71           int selectedRow = lsm.getMinSelectionIndex();\r
72           displayFullDetails(table.getValueAt(selectedRow, 0).toString());\r
73         }\r
74       }\r
75     });\r
76 \r
77     table.addMouseListener(new MouseAdapter()\r
78         {\r
79           public void mouseClicked(MouseEvent evt)\r
80           {\r
81             if(evt.getClickCount()==2\r
82                || SwingUtilities.isRightMouseButton(evt))\r
83               editRemoveLocalSource(evt);\r
84           }\r
85         });\r
86 \r
87     if(dasSources==null)\r
88     {\r
89     Thread worker = new Thread(this);\r
90     worker.start();\r
91     }\r
92     else\r
93      {\r
94        init();\r
95      }\r
96   }\r
97 \r
98   void init()\r
99   {\r
100     int dSize = dasSources.length;\r
101     Object[][] data = new Object[dSize][2];\r
102     for (int i = 0; i < dSize; i++)\r
103     {\r
104       data[i][0] = dasSources[i].getNickname();\r
105       data[i][1] = new Boolean(selectedSources.contains(dasSources[i].\r
106           getNickname()));\r
107     }\r
108 \r
109     refreshTableData(data);\r
110     setCapabilities(dasSources);\r
111 \r
112     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
113         {\r
114           public void run()\r
115           {\r
116             TableSorter sorter = (TableSorter)table.getModel();\r
117             sorter.setSortingStatus(1, TableSorter.DESCENDING);\r
118             sorter.setSortingStatus(1, TableSorter.NOT_SORTED);\r
119           }\r
120         });\r
121 \r
122     progressBar.setIndeterminate(false);\r
123     progressBar.setVisible(false);\r
124     addLocal.setVisible(true);\r
125     refresh.setVisible(true);\r
126   }\r
127 \r
128 \r
129   public void refreshTableData(Object[][] data)\r
130   {\r
131     TableSorter sorter = new TableSorter(new DASTableModel(data));\r
132     sorter.setTableHeader(table.getTableHeader());\r
133     table.setModel(sorter);\r
134   }\r
135 \r
136   void displayFullDetails(String nickName)\r
137   {\r
138 \r
139     StringBuffer text = new StringBuffer(\r
140         "<HTML><font size=\"2\" face=\"Verdana, Arial, Helvetica, sans-serif\">");\r
141 \r
142     if (nickName == null)\r
143     {\r
144       fullDetails.setText(text +\r
145                           "Select a DAS service from the table"\r
146                           + " to read a full description here.</font></html>");\r
147       return;\r
148     }\r
149 \r
150     int dSize = dasSources.length;\r
151     for (int i = 0; i < dSize; i++)\r
152     {\r
153       if (!dasSources[i].getNickname().equals(nickName))\r
154         continue;\r
155 \r
156       DasSource ds = dasSources[i];\r
157 \r
158       text.append("<font color=\"#0000FF\">Id:</font> " + dasSources[i].getId() +\r
159                   "<br>");\r
160       text.append("<font color=\"#0000FF\">Nickname:</font> " +\r
161                   dasSources[i].getNickname() + "<br>");\r
162       text.append("<font color=\"#0000FF\">URL:</font> " + dasSources[i].getUrl() +\r
163                   "<br>");\r
164 \r
165       text.append("<font color=\"#0000FF\">Admin Email:</font> <a href=\"mailto:"\r
166                   +dasSources[i].getAdminemail()\r
167                   +"\">"+dasSources[i].getAdminemail()+"</a>" +\r
168                   "<br>");\r
169 \r
170 \r
171       text.append("<font color=\"#0000FF\">Registered at:</font> " + dasSources[i].getRegisterDate() +\r
172                         "<br>");\r
173 \r
174       text.append("<font color=\"#0000FF\">Last successful test:</font> " + dasSources[i].getLeaseDate() +\r
175                         "<br>");\r
176 \r
177       text.append("<font color=\"#0000FF\">Labels:</font> ");\r
178       for(int s=0; s<dasSources[i].getLabels().length; s++)\r
179       {\r
180         text.append( dasSources[i].getLabels()[s]);\r
181         if(s<dasSources[i].getLabels().length-1)\r
182           text.append(",");\r
183         text.append(" ");\r
184       }\r
185       text.append("<br>");\r
186 \r
187 \r
188 \r
189       text.append("<font color=\"#0000FF\">Capabilities:</font> ");\r
190       String[] scap = dasSources[i].getCapabilities();\r
191       for (int j = 0; j < scap.length; j++)\r
192       {\r
193         text.append(scap[j]);\r
194         if (j < scap.length - 1)\r
195           text.append(", ");\r
196       }\r
197       text.append("<br>");\r
198 \r
199       text.append("<font color=\"#0000FF\">Coordinates:</font> ");\r
200       DasCoordinateSystem[] dcs = ds.getCoordinateSystem();\r
201       for (int j = 0; j < dcs.length; j++)\r
202       {\r
203         text.append("(" + dcs[j].getUniqueId() + ") "\r
204                     + dcs[j].getCategory() + ", " + dcs[j].getName());\r
205         if (dcs[j].getNCBITaxId() != 0)\r
206           text.append(", " + dcs[j].getNCBITaxId());\r
207         if (dcs[j].getOrganismName().length() > 0)\r
208           text.append(", " + dcs[j].getOrganismName());\r
209 \r
210         text.append("<br>");\r
211       }\r
212 \r
213       text.append("<font color=\"#0000FF\">Description:</font> " +\r
214                   dasSources[i].getDescription() + "<br>");\r
215 \r
216 \r
217       if (dasSources[i].getHelperurl()!=null\r
218           && dasSources[i].getHelperurl().length() > 0)\r
219       {\r
220         text.append("<font color=\"#0000FF\"><a href=\"" +\r
221                     dasSources[i].getHelperurl()\r
222                     + "\">Go to site</a></font<br>");\r
223       }\r
224 \r
225       text.append("</font></html>");\r
226 \r
227       break;\r
228     }\r
229 \r
230     fullDetails.setText(text.toString());\r
231     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
232     {\r
233       public void run()\r
234       {\r
235         fullDetailsScrollpane.getVerticalScrollBar().setValue(0);\r
236       }\r
237     });\r
238   }\r
239 \r
240 \r
241   public void run()\r
242   {\r
243 \r
244     addLocal.setVisible(false);\r
245     refresh.setVisible(false);\r
246     progressBar.setVisible(true);\r
247     progressBar.setIndeterminate(true);\r
248 \r
249     dasSources = jalview.io.DasSequenceFeatureFetcher.getDASSources();\r
250 \r
251     appendLocalSources();\r
252 \r
253     init();\r
254   }\r
255 \r
256   public Vector getSelectedSources()\r
257   {\r
258     Vector selected = new Vector();\r
259     for (int r = 0; r < selectedSources.size(); r++)\r
260     {\r
261         for (int i = 0; i < dasSources.length; i++)\r
262         {\r
263           if (dasSources[i].getNickname().equals(\r
264               selectedSources.elementAt(r)))\r
265           {\r
266             selected.addElement(dasSources[i]);\r
267             break;\r
268           }\r
269         }\r
270     }\r
271 \r
272     return selected;\r
273   }\r
274 \r
275   public DasSource[] getDASSource()\r
276   {\r
277     if(dasSources==null)\r
278     {\r
279      dasSources = jalview.io.DasSequenceFeatureFetcher.getDASSources();\r
280      appendLocalSources();\r
281     }\r
282 \r
283     return dasSources;\r
284   }\r
285 \r
286   public void refresh_actionPerformed(ActionEvent e)\r
287   {\r
288     saveProperties(jalview.bin.Cache.applicationProperties);\r
289 \r
290     Thread worker = new Thread(this);\r
291     worker.start();\r
292   }\r
293 \r
294   private void setCapabilities(DasSource[] sources)\r
295   {\r
296     Vector authority = new Vector();\r
297     Vector type = new Vector();\r
298     Vector label = new Vector();\r
299 \r
300     authority.addElement("Any");\r
301     type.addElement("Any");\r
302     label.addElement("Any");\r
303 \r
304     for (int i = 0; i < sources.length; i++)\r
305     {\r
306       DasSource ds = sources[i];\r
307 \r
308       DasCoordinateSystem[] dcs = ds.getCoordinateSystem();\r
309 \r
310       for (int j = 0; j < dcs.length; j++)\r
311       {\r
312         if (!type.contains(dcs[j].getCategory()))\r
313           type.addElement(dcs[j].getCategory());\r
314 \r
315         if (!authority.contains(dcs[j].getName()))\r
316           authority.addElement(dcs[j].getName());\r
317       }\r
318 \r
319       String[] slabels = ds.getLabels();\r
320       for (int s = 0; s < slabels.length; s++)\r
321       {\r
322         if (!label.contains(slabels[s]))\r
323         {\r
324           label.addElement(slabels[s]);\r
325         }\r
326       }\r
327 \r
328     }\r
329 \r
330     filter1.setListData(authority);\r
331     filter2.setListData(type);\r
332     filter3.setListData(label);\r
333 \r
334     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
335     {\r
336       public void run()\r
337       {\r
338         filter1.setSelectedIndex(0);\r
339         filter2.setSelectedIndex(0);\r
340         filter3.setSelectedIndex(0);\r
341       }\r
342     });\r
343   }\r
344 \r
345   public void amendLocal(boolean newSource)\r
346   {\r
347     String url = "http://localhost:8080/", nickname = "";\r
348 \r
349     if(!newSource)\r
350     {\r
351       int selectedRow = table.getSelectionModel().getMinSelectionIndex();\r
352       nickname = table.getValueAt(selectedRow, 0).toString();\r
353       url = ((DasSource)localSources.get(nickname)).getUrl();\r
354     }\r
355 \r
356     JTextField nametf = new JTextField(nickname, 40);\r
357     JTextField urltf = new JTextField(url, 40);\r
358 \r
359     JPanel panel = new JPanel(new BorderLayout());\r
360     JPanel pane12 = new JPanel(new BorderLayout());\r
361     pane12.add(new JLabel("Nickname: "), BorderLayout.CENTER);\r
362     pane12.add(nametf, BorderLayout.EAST);\r
363     panel.add(pane12, BorderLayout.NORTH);\r
364     pane12 = new JPanel(new BorderLayout());\r
365     pane12.add(new JLabel("URL: "), BorderLayout.CENTER);\r
366     pane12.add(urltf, BorderLayout.EAST);\r
367     panel.add(pane12, BorderLayout.SOUTH);\r
368 \r
369 \r
370     int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,\r
371         panel, "Enter Nickname & URL of Local DAS Source",\r
372         JOptionPane.OK_CANCEL_OPTION);\r
373 \r
374        if (reply != JOptionPane.OK_OPTION )\r
375        {\r
376            return;\r
377        }\r
378 \r
379        if(!urltf.getText().endsWith("/"))\r
380          urltf.setText(urltf.getText()+"/");\r
381 \r
382        Das1Source local = new Das1Source();\r
383 \r
384        local.setUrl(urltf.getText());\r
385        local.setNickname(nametf.getText());\r
386 \r
387 \r
388        if(localSources==null)\r
389          localSources = new Hashtable();\r
390 \r
391        localSources.put(local.getNickname(), local);\r
392 \r
393        if(!newSource && !nickname.equals(nametf.getText()))\r
394        {\r
395          localSources.remove(nickname);\r
396        }\r
397 \r
398        int size = dasSources.length;\r
399        int adjust = newSource ? 1 : 0;\r
400 \r
401        Object[][] data = new Object[size+adjust][2];\r
402        for (int i = 0; i < size; i++)\r
403        {\r
404          if(!newSource && dasSources[i].getNickname().equals(nickname))\r
405          {\r
406            ((DasSource)dasSources[i]).setNickname(local.getNickname());\r
407            ((DasSource)dasSources[i]).setUrl(local.getUrl());\r
408            data[i][0] = local.getNickname();\r
409            data[i][1] = new Boolean(true);\r
410          }\r
411          else\r
412          {\r
413            data[i][0] = dasSources[i].getNickname();\r
414            data[i][1] = new Boolean(selectedSources.contains(dasSources[i].\r
415                getNickname()));\r
416          }\r
417        }\r
418 \r
419        if(newSource)\r
420        {\r
421          data[size][0] = local.getNickname();\r
422          data[size][1] = new Boolean(true);\r
423          selectedSources.add(local.getNickname());\r
424        }\r
425 \r
426        DasSource [] tmp = new DasSource[size+adjust];\r
427 \r
428        System.arraycopy(dasSources, 0, tmp, 0, size);\r
429 \r
430        if(newSource)\r
431          tmp[size] = local;\r
432 \r
433        dasSources = tmp;\r
434 \r
435        refreshTableData(data);\r
436 \r
437        SwingUtilities.invokeLater(new Runnable()\r
438        {\r
439          public void run()\r
440          {\r
441            scrollPane.getVerticalScrollBar().setValue(\r
442                scrollPane.getVerticalScrollBar().getMaximum()\r
443                );\r
444          }\r
445        });\r
446 \r
447        displayFullDetails(local.getNickname());\r
448      }\r
449 \r
450     public void editRemoveLocalSource(MouseEvent evt)\r
451     {\r
452       int selectedRow = table.getSelectionModel().getMinSelectionIndex();\r
453       if(selectedRow==-1)\r
454         return;\r
455 \r
456       String nickname = table.getValueAt(selectedRow, 0).toString();\r
457 \r
458       if (!localSources.containsKey(nickname))\r
459       {\r
460         JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
461         "You can only edit or remove local DAS Sources!",\r
462          "Public DAS source - not editable",\r
463          JOptionPane.WARNING_MESSAGE);\r
464         return;\r
465       }\r
466 \r
467 \r
468       Object[] options = {"Edit", "Remove", "Cancel"};\r
469       int choice = JOptionPane.showInternalOptionDialog(Desktop.desktop,\r
470     "Do you want to edit or remove "+nickname+"?",\r
471     "Edit / Remove Local DAS Source",\r
472     JOptionPane.YES_NO_CANCEL_OPTION,\r
473     JOptionPane.QUESTION_MESSAGE,\r
474     null,\r
475     options,\r
476     options[2]);\r
477 \r
478       switch(choice)\r
479       {\r
480         case 0: amendLocal(false);   break;\r
481         case 1:\r
482           localSources.remove(nickname);\r
483           selectedSources.remove(nickname);\r
484           Object[][] data = new Object[dasSources.length-1][2];\r
485           DasSource [] tmp = new DasSource[dasSources.length-1];\r
486           int index = 0;\r
487           for (int i = 0; i < dasSources.length; i++)\r
488           {\r
489             if (dasSources[i].getNickname().equals(nickname))\r
490             {\r
491               continue;\r
492             }\r
493             else\r
494             {\r
495               tmp[index] = dasSources[i];\r
496               data[index][0] = dasSources[i].getNickname();\r
497               data[index][1] = new Boolean(selectedSources.contains(dasSources[i].\r
498                   getNickname()));\r
499               index++;\r
500             }\r
501           }\r
502            dasSources = tmp;\r
503            refreshTableData(data);\r
504            SwingUtilities.invokeLater(new Runnable()\r
505            {\r
506              public void run()\r
507              {\r
508                scrollPane.getVerticalScrollBar().setValue(\r
509                    scrollPane.getVerticalScrollBar().getMaximum()\r
510                    );\r
511              }\r
512            });\r
513 \r
514           break;\r
515       }\r
516     }\r
517 \r
518     void appendLocalSources()\r
519     {\r
520       if(localSources==null)\r
521         return;\r
522 \r
523       int size = dasSources!=null ? dasSources.length : 0;\r
524       int lsize = localSources.size();\r
525 \r
526       Object[][] data = new Object[size+lsize][2];\r
527       for (int i = 0; i < size; i++)\r
528       {\r
529         data[i][0] = dasSources[i].getNickname();\r
530         data[i][1] = new Boolean(selectedSources.contains(dasSources[i].\r
531             getNickname()));\r
532       }\r
533 \r
534       DasSource [] tmp = new DasSource[size+lsize];\r
535       if(dasSources!=null)\r
536         System.arraycopy(dasSources, 0, tmp, 0, size);\r
537 \r
538       Enumeration en = localSources.keys();\r
539       int index = size;\r
540       while(en.hasMoreElements())\r
541       {\r
542         String key = en.nextElement().toString();\r
543         data[index][0] = key;\r
544         data[index][1] = new Boolean(false);\r
545         tmp[index] = new Das1Source();\r
546         tmp[index].setNickname(key);\r
547         tmp[index].setUrl( ((DasSource)localSources.get(key)).getUrl() );\r
548 \r
549         index++;\r
550       }\r
551 \r
552          dasSources = tmp;\r
553 \r
554          refreshTableData(data);\r
555   }\r
556 \r
557   public void valueChanged(ListSelectionEvent evt)\r
558   {\r
559     //Called when the MainTable selection changes\r
560     if (evt.getValueIsAdjusting())\r
561     {\r
562       return;\r
563     }\r
564 \r
565     displayFullDetails(null);\r
566 \r
567     // Filter the displayed data sources\r
568     int dSize = dasSources.length;\r
569     ArrayList names = new ArrayList();\r
570     ArrayList selected = new ArrayList();\r
571     DasSource ds;\r
572 \r
573     //The features filter is not visible, but we must still\r
574     //filter the das source list here.\r
575     //July 2006 - only 6 sources fo not serve features\r
576     Object [] dummyFeatureList = new Object[]{"features"};\r
577 \r
578     // capabilities.get\r
579     for (int i = 0; i < dSize; i++)\r
580     {\r
581       ds = dasSources[i];\r
582 \r
583       if (!selectedInList(dummyFeatureList, ds.getCapabilities())\r
584       ||  !selectedInList(filter3.getSelectedValues(),\r
585                           ds.getLabels()))\r
586       {\r
587         continue;\r
588       }\r
589 \r
590       DasCoordinateSystem[] dcs = ds.getCoordinateSystem();\r
591       for (int j = 0; j < dcs.length; j++)\r
592       {\r
593         if (selectedInList(dummyFeatureList,ds.getCapabilities())\r
594         &&\r
595             selectedInList(filter1.getSelectedValues(),\r
596                            new String[]\r
597                            {dcs[j].getName()})\r
598             && selectedInList(filter2.getSelectedValues(),\r
599                               new String[]\r
600                               {dcs[j].getCategory()}))\r
601         {\r
602           names.add(ds.getNickname());\r
603           selected.add(new Boolean(\r
604               selectedSources.contains(ds.getNickname())));\r
605           break;\r
606         }\r
607       }\r
608     }\r
609 \r
610     dSize = names.size();\r
611     Object[][] data = new Object[dSize][2];\r
612     for (int d = 0; d < dSize; d++)\r
613     {\r
614       data[d][0] = names.get(d);\r
615       data[d][1] = selected.get(d);\r
616     }\r
617 \r
618     refreshTableData(data);\r
619   }\r
620 \r
621   boolean selectedInList(Object [] selection, String[] items)\r
622   {\r
623     for (int i = 0; i < selection.length; i++)\r
624     {\r
625       if (selection[i].equals("Any"))\r
626         return true;\r
627 \r
628       for (int j = 0; j < items.length; j++)\r
629       {\r
630         if (selection[i].equals(items[j]))\r
631           return true;\r
632       }\r
633     }\r
634 \r
635     return false;\r
636   }\r
637 \r
638   void setSelectedFromProperties()\r
639   {\r
640      String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE", "uniprot");\r
641      StringTokenizer st = new StringTokenizer(active, "\t");\r
642      selectedSources = new Vector();\r
643      while(st.hasMoreTokens())\r
644      {\r
645        selectedSources.addElement(st.nextToken());\r
646      }\r
647 \r
648      String local = jalview.bin.Cache.getProperty("DAS_LOCAL_SOURCE");\r
649      if(local!=null)\r
650      {\r
651        if(localSources == null)\r
652          localSources = new Hashtable();\r
653 \r
654        st = new StringTokenizer(local, "\t");\r
655        while(st.hasMoreTokens())\r
656        {\r
657          String token = st.nextToken();\r
658          int bar = token.indexOf("|");\r
659          Das1Source source = new Das1Source();\r
660 \r
661          source.setUrl(token.substring(bar + 1));\r
662          source.setNickname(token.substring(0, bar));\r
663 \r
664          localSources.put(source.getNickname(), source);\r
665        }\r
666      }\r
667   }\r
668 \r
669   public void saveProperties(Properties properties)\r
670   {\r
671     properties.setProperty("DAS_REGISTRY_URL", registryURL.getText());\r
672 \r
673     StringBuffer sb = new StringBuffer();\r
674     for(int r=0; r<table.getModel().getRowCount(); r++)\r
675     {\r
676       if( ((Boolean)table.getValueAt(r,1)).booleanValue())\r
677       {\r
678         sb.append(table.getValueAt(r,0)+"\t");\r
679       }\r
680     }\r
681 \r
682     properties.setProperty("DAS_ACTIVE_SOURCE", sb.toString() );\r
683 \r
684     if(localSources!=null)\r
685     {\r
686       sb = new StringBuffer();\r
687       Enumeration en = localSources.keys();\r
688       while(en.hasMoreElements())\r
689       {\r
690         String token = en.nextElement().toString();\r
691         sb.append(token+"|"\r
692                   + ((DasSource)localSources.get(token)).getUrl()\r
693                   +"\t");\r
694       }\r
695 \r
696       properties.setProperty("DAS_LOCAL_SOURCE", sb.toString());\r
697     }\r
698 \r
699   }\r
700 \r
701   class DASTableModel\r
702       extends AbstractTableModel\r
703   {\r
704 \r
705     public DASTableModel(Object[][] data)\r
706     {\r
707       this.data = data;\r
708     }\r
709 \r
710     private String[] columnNames = new String[]  {"Nickname", "Use Source"};\r
711 \r
712     private Object[][] data;\r
713 \r
714     public int getColumnCount()\r
715     {\r
716       return columnNames.length;\r
717     }\r
718 \r
719     public int getRowCount()\r
720     {\r
721       return data.length;\r
722     }\r
723 \r
724     public String getColumnName(int col)\r
725     {\r
726       return columnNames[col];\r
727     }\r
728 \r
729     public Object getValueAt(int row, int col)\r
730     {\r
731       return data[row][col];\r
732     }\r
733 \r
734     /*\r
735      * JTable uses this method to determine the default renderer/\r
736      * editor for each cell.  If we didn't implement this method,\r
737      * then the last column would contain text ("true"/"false"),\r
738      * rather than a check box.\r
739      */\r
740     public Class getColumnClass(int c)\r
741     {\r
742       return getValueAt(0, c).getClass();\r
743     }\r
744 \r
745     /*\r
746      * Don't need to implement this method unless your table's\r
747      * editable.\r
748      */\r
749     public boolean isCellEditable(int row, int col)\r
750     {\r
751       //Note that the data/cell address is constant,\r
752       //no matter where the cell appears onscreen.\r
753       return col == 1;\r
754 \r
755     }\r
756 \r
757     /*\r
758      * Don't need to implement this method unless your table's\r
759      * data can change.\r
760      */\r
761     public void setValueAt(Object value, int row, int col)\r
762     {\r
763       data[row][col] = value;\r
764       fireTableCellUpdated(row, col);\r
765 \r
766       String name = getValueAt(row,0).toString();\r
767       boolean selected = ((Boolean)value).booleanValue();\r
768 \r
769       if(selectedSources.contains(name) && !selected)\r
770         selectedSources.remove(name);\r
771 \r
772       if(!selectedSources.contains(name) && selected)\r
773         selectedSources.add(name);\r
774     }\r
775   }\r
776 }\r
777 \r
778 \r