1 /********************************************************************
2 *
3 *  This library is free software; you can redistribute it and/or
4 *  modify it under the terms of the GNU Library General Public
5 *  License as published by the Free Software Foundation; either
6 *  version 2 of the License, or (at your option) any later version.
7 *
8 *  This library is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 *  Library General Public License for more details.
12 *
13 *  You should have received a copy of the GNU Library General Public
14 *  License along with this library; if not, write to the
15 *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 *  Boston, MA  02111-1307, USA.
17 *
18 *  @author: Copyright (C) Tim Carver
19 *
20 ********************************************************************/
21 
22 package org.emboss.jemboss.gui;
23 
24 import java.awt.*;
25 import java.io.*;
26 import java.util.*;
27 import java.util.prefs.Preferences;
28 
29 import javax.swing.*;
30 import javax.swing.event.*;
31 import javax.swing.table.*;
32 import java.awt.event.*;
33 import java.net.MalformedURLException;
34 import java.net.URL;
35 import java.awt.datatransfer.*;
36 import java.awt.dnd.*;
37 
38 import org.emboss.jemboss.parser.*;
39 import org.emboss.jemboss.soap.*;
40 import org.emboss.jemboss.JembossParams;
41 import org.emboss.jemboss.gui.filetree.*;
42 import org.emboss.jemboss.programs.RunEmbossApplication2;
43 
44 /**
45 *
46 * SequenceList extends JFrame to display a set of sequences
47 * that the user is working on in a session. The sequence list
48 * can be stored and read back in by the application. This allows
49 * the user to usefully maintain a list of sequence that are
50 * being worked on and easily drag and drop them into sequence
51 * fields of applications.
52 *
53 */
54 public class SequenceList extends JFrame implements TableModelListener
55 {
56 
57   /** drag and drop table containing the list of sequences */
58   private DragJTable table;
59   /** model for the sequence table */
60   private SequenceListTableModel seqModel;
61   /** select to save the sequence list between sessions */
62   protected static JCheckBoxMenuItem storeSeqList;
63   final Cursor cbusy = new Cursor(Cursor.WAIT_CURSOR);
64   final Cursor cdone = new Cursor(Cursor.DEFAULT_CURSOR);
65   final boolean withSoap;
66   final JembossParams mysettings;
67   Preferences myPreferences;
68 
69   protected static JCheckBoxMenuItem getSeqLength;
70   private final static String GET_SEQUENCE_LENGTH_AUTO ="GET_SEQUENCE_LENGTH_AUTOMATICALLY";
71   private final static String STORE_SEQUENCE_LIST ="STORE_SEQUENCE_LIST";
72   // Keys for this frame's preferences
73   private static final String WINDOW_X_KEY = "WINDOW_X";
74   private static final String WINDOW_Y_KEY = "WINDOW_Y";
75   private static final String WINDOW_WIDTH_KEY = "WINDOW_WIDTH";
76   private static final String WINDOW_HEIGHT_KEY = "WINDOW_HEIGHT";
77 
78 
79   /**
80   *
81   * @param withSoap	true if in client-server mode
82   * @param mysettings	jemboss properties
83   *
84   */
SequenceList(final boolean withSoap,final JembossParams mysettings)85   public SequenceList(final boolean withSoap,final JembossParams mysettings)
86   {
87     super("Sequence List");
88     this.withSoap = withSoap;
89     this.mysettings = mysettings;
90     myPreferences = Preferences.userNodeForPackage(SequenceList.class);
91     setSize(400,155);
92     getSeqLength = new JCheckBoxMenuItem("Get sequence lengths automatically");
93     if(myPreferences.getBoolean(GET_SEQUENCE_LENGTH_AUTO, false))
94         getSeqLength.setSelected(true);
95     getSeqLength.addItemListener(new ItemListener(){
96         public void itemStateChanged(ItemEvent e) {
97             myPreferences.putBoolean(GET_SEQUENCE_LENGTH_AUTO,
98                     getSeqLength.isSelected());
99         }
100     });
101     storeSeqList = new JCheckBoxMenuItem("Save Sequence List");
102     if(myPreferences.getBoolean(STORE_SEQUENCE_LIST, false))
103         storeSeqList.setSelected(true);
104     storeSeqList.addItemListener(new ItemListener(){
105         public void itemStateChanged(ItemEvent e) {
106             myPreferences.putBoolean(STORE_SEQUENCE_LIST,
107                     isStoreSequenceList());
108         }
109     });
110     seqModel = new SequenceListTableModel();
111     table = new DragJTable(seqModel);
112     table.setModel(seqModel);
113     table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
114 
115     //column width
116     for(int i=0;i<SequenceListTableModel.modelColumns.length;i++)
117     {
118       TableColumn column = table.getColumn(
119             SequenceListTableModel.modelColumns[i].title);
120       column.setPreferredWidth(
121              SequenceListTableModel.modelColumns[i].width);
122     }
123 
124     JScrollPane scrollpane = new JScrollPane(table);
125     scrollpane.setSize(300,100);
126     getContentPane().add(scrollpane, BorderLayout.CENTER);
127 
128 //setup menu bar
129     JMenuBar menuPanel = new JMenuBar();
130     new BoxLayout(menuPanel,BoxLayout.X_AXIS);
131     setJMenuBar(menuPanel);
132 
133     JMenu fileMenu = new JMenu("File");
134     fileMenu.setMnemonic(KeyEvent.VK_F);
135     menuPanel.add(fileMenu);
136     JMenu toolMenu = new JMenu("Tools");
137     toolMenu.setMnemonic(KeyEvent.VK_T);
138     menuPanel.add(toolMenu);
139 
140     JMenuItem openMenuItem = new JMenuItem("Open");
141     openMenuItem.addActionListener(new ActionListener()
142     {
143       public void actionPerformed(ActionEvent e)
144       {
145         int nrow = table.getSelectedRow();
146         String fileName = (String)table.getValueAt(nrow,
147                 table.convertColumnIndexToView(SequenceListTableModel.COL_NAME));
148 
149         SequenceData row = (SequenceData)SequenceListTableModel.modelVector.elementAt(nrow);
150 
151         if(!(row.s_remote.booleanValue()))
152           DragTree.showFilePane(fileName,mysettings);        //local file
153         else
154           RemoteDragTree.showFilePane(fileName,mysettings);  //remote file
155       }
156     });
157     fileMenu.add(openMenuItem);
158 
159     toolMenu.add(getSeqLength);
160 
161 
162     JMenuItem addSeq = new JMenuItem("Add sequence");
163     addSeq.addActionListener(new ActionListener()
164     {
165       public void actionPerformed(ActionEvent e)
166       {
167         int row = table.getSelectedRow();
168         seqModel.insertRow(row+1);
169         table.tableChanged(new TableModelEvent(seqModel, row+1, row+1,
170                 TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
171       }
172     });
173     toolMenu.add(addSeq);
174 
175     JMenuItem deleteSeq = new JMenuItem("Delete sequence");
176     deleteSeq.addActionListener(new ActionListener()
177     {
178       public void actionPerformed(ActionEvent e)
179       {
180         int row = table.getSelectedRow();
181         if(seqModel.deleteRow(row))
182           table.tableChanged(new TableModelEvent(seqModel, row, row,
183                 TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE));
184 
185       }
186     });
187     toolMenu.add(deleteSeq);
188 
189 
190     JMenuItem reset = new JMenuItem("Remove all sequences");
191     reset.addActionListener(new ActionListener()
192     {
193       public void actionPerformed(ActionEvent e)
194       {
195         seqModel.setDefaultData();
196         table.repaint();
197       }
198     });
199     toolMenu.add(reset);
200 
201     toolMenu.addSeparator();
202 
203     File fseq = new File(System.getProperty("user.home")
204                            + System.getProperty("file.separator")
205                            + ".jembossSeqList");
206     if (!fseq.exists()){
207     	try {
208 			fseq.createNewFile();
209 		} catch (IOException e1) {
210 			//
211 		}
212     }
213     if(!fseq.canWrite())
214     {
215       storeSeqList.setSelected(false);
216       storeSeqList.setEnabled(false);
217     }
218     toolMenu.add(storeSeqList);
219 
220     fileMenu.addSeparator();
221 
222     JMenuItem closeFrame = new JMenuItem("Close");
223     closeFrame.setAccelerator(KeyStroke.getKeyStroke(
224                     KeyEvent.VK_E, ActionEvent.CTRL_MASK));
225 
226     closeFrame.addActionListener(new ActionListener()
227     {
228       public void actionPerformed(ActionEvent e)
229       {
230         setVisible(false);
231       }
232     });
233     fileMenu.add(closeFrame);
234 
235     // help menu
236    JMenu helpMenu = new JMenu("Help");
237    helpMenu.setMnemonic(KeyEvent.VK_H);
238    JMenuItem fmh = new JMenuItem("About Sequence List");
239    fmh.addActionListener(new ActionListener()
240    {
241      public void actionPerformed(ActionEvent e)
242      {
243         ClassLoader cl = this.getClass().getClassLoader();
244         try
245         {
246           URL inURL = cl.getResource("resources/seqList.html");
247           new Browser(inURL,"resources/seqList.html");
248         }
249         catch (MalformedURLException mex)
250         {
251           System.out.println("Didn't find resources/seqList.html");
252         }
253         catch (IOException iex)
254         {
255           System.out.println("Didn't find resources/seqList.html");
256         }
257       }
258     });
259     helpMenu.add(fmh);
260     menuPanel.add(helpMenu);
261     table.getModel().addTableModelListener(this);
262     setBounds();
263   }
264 
265 
setBounds()266   private void setBounds(){
267       int x = myPreferences.getInt(WINDOW_X_KEY, 10);
268       int y = myPreferences.getInt(WINDOW_Y_KEY, 10);
269       int width = myPreferences.getInt(WINDOW_WIDTH_KEY, 400);
270       int height = myPreferences.getInt(WINDOW_HEIGHT_KEY, 200);
271       this.setBounds(x,y,width, height);
272   }
273 
saveBounds()274   public void saveBounds(){
275       myPreferences.putInt(WINDOW_X_KEY, getX());
276       myPreferences.putInt(WINDOW_Y_KEY, getY());
277       myPreferences.putInt(WINDOW_WIDTH_KEY, getWidth());
278       myPreferences.putInt(WINDOW_HEIGHT_KEY, getHeight());
279   }
280 
281   /**
282      *
283      * Look for first set to default in the table.
284      *
285      * @return index to row
286      *
287      */
getDefaultRow(int h)288   private int getDefaultRow(int h)
289   {
290     int nrow = seqModel.getRowCount();
291     int j = 0;
292     for(int i =0;i<nrow;i++)
293     {
294       Boolean isDef = (Boolean)seqModel.getValueAt(i,
295                         SequenceListTableModel.COL_DEF);
296       if(isDef.booleanValue() && (j++ == h) )
297         return i;
298     }
299     return -1;
300   }
301 
302   /**
303   *
304   * Cygwin uses infoseq to get sequence length and type
305   * and uses infoalign to get the sequence weight.
306   *
307   */
cygwinSeqAttr(String fc, JembossParams mysettings)308   private int cygwinSeqAttr(String fc, JembossParams mysettings)
309   {
310     String[] envp = new String[2];  /* environment vars */
311     String ps = new String(System.getProperty("path.separator"));
312     String embossPath = mysettings.getEmbossPath();
313     embossPath = new String("PATH" + ps +
314                       embossPath + ps + mysettings.getEmbossBin() + ps);
315     envp[0] = "PATH=" + embossPath;
316     envp[1] = "EMBOSS_DATA=" + mysettings.getEmbossData();
317 
318     String command = mysettings.getEmbossBin().concat(
319                 "infoseq -only -type -length -nohead -auto "+fc);
320     RunEmbossApplication2 rea = new RunEmbossApplication2(command,envp,null);
321     rea.waitFor();
322 
323     String stdout = rea.getProcessStdout();
324     if(stdout.trim().equals(""))
325       return -1;
326 
327     StringTokenizer stok = new StringTokenizer(stdout,"\n ");
328     stok.nextToken();
329     return Integer.parseInt(stok.nextToken().trim());
330   }
331 
332 
333   /**
334    * Returns length of the inputs sequence, fc,
335    * executes the infoseq application to retrieve the length
336    * @param fc is the input sequence
337    * @param mysettings is the jemboss configuration parameters
338    * @return length of the input sequence
339  */
getSeqAttr(String fc, JembossParams mysettings)340 public static int getSeqAttr(String fc, JembossParams mysettings)
341   {
342 
343     String[] envp = BuildProgramMenu.getEnvp();
344     String command = mysettings.getEmbossBin().concat(
345                 "infoseq -only -type -length -nohead -auto "+fc);
346     RunEmbossApplication2 rea = new RunEmbossApplication2(command,envp,null);
347     rea.waitFor();
348 
349     String stdout = rea.getProcessStdout();
350     if(stdout.trim().equals(""))
351       return -1;
352 
353     StringTokenizer stok = new StringTokenizer(stdout,"\n ");
354     int l=0;
355     while (stok.hasMoreElements()){
356     stok.nextToken();
357     l += Integer.parseInt(stok.nextToken().trim());
358     }
359     return l;
360   }
361 
362   /**
363   *
364   * Get the default Sequence name
365   * @return 	default sequence name or null if no default
366   *
367   */
getDefaultSequenceName(int h)368   public String getDefaultSequenceName(int h)
369   {
370     int ndef = getDefaultRow(h);
371     if(ndef<0)
372       return null;
373 
374     String seqName = (String)seqModel.getValueAt(ndef,
375              SequenceListTableModel.COL_NAME);
376 
377     if(table.isListFile(ndef).booleanValue())
378       seqName = "@".concat(seqName);
379 
380     return seqName;
381   }
382 
383   /**
384   *
385   * Return the number of rows in the table
386   * @return 	number of rows in the table
387   *
388   */
getRowCount()389   public int getRowCount()
390   {
391     return seqModel.getRowCount();
392   }
393 
394   /**
395   *
396   * The <code>SequenceData</code> for a given row
397   * number.
398   * @param row 	number
399   * @return 	<code>SequenceData</code> for the row
400   *
401   */
getSequenceData(int nrow)402   public SequenceData getSequenceData(int nrow)
403   {
404     return seqModel.getSequenceData(nrow);
405   }
406 
getSequenceLength()407   private void getSequenceLength(){
408       int row = table.getSelectedRow();
409       String fileOrEntryName = (String)seqModel.getValueAt(row,
410                       SequenceListTableModel.COL_NAME);
411 
412       if(fileOrEntryName!=null && !fileOrEntryName.equals("") && !(new File(fileOrEntryName).exists()))
413       {
414         setCursor(cbusy);
415 
416         String fc = Util.getFileOrDatabaseForAjax(fileOrEntryName,
417                     BuildProgramMenu.getDatabaseList(),
418                     null,withSoap);
419 
420         boolean ok = false;
421         int length=0;
422 
423         if(!withSoap && fc!=null)    //Ajax without SOAP
424         {
425           if(JembossParams.isCygwin())
426           {
427             length = cygwinSeqAttr(fc,mysettings);
428             if(length > -1)
429               ok = true;
430           }
431           else
432           {
433               length = getSeqAttr(fc, mysettings);
434               if (length > -1)
435                   ok = true;
436           }
437         }
438         else if(fc!=null)    //Ajax with SOAP
439         {
440           try
441           {
442             CallAjax ca = new CallAjax(fc,"sequence",mysettings);
443             if(ca.getStatus().equals("0"))
444             {
445               length  = ca.getLength();
446               ok = true;
447             }
448           }
449           catch (JembossSoapException eae)
450           {
451             System.out.println("Call to Ajax library failed");
452             setCursor(cdone);
453           }
454         }
455 
456         if(!ok && fc!=null)                          //Ajax failed
457         {
458           if( mysettings.getServicePasswdByte()!=null ||
459               mysettings.getUseAuth() == false )
460           {
461             JOptionPane.showMessageDialog(null,
462                    "Sequence not found!", "Error Message",
463                    JOptionPane.ERROR_MESSAGE);
464           }
465           else
466           {
467             AuthPopup ap = new AuthPopup(mysettings,null);
468             ap.setBottomPanel();
469             ap.setSize(380,170);
470             ap.pack();
471             ap.setVisible(true);
472           }
473         }
474         else
475         {
476           seqModel.setValueAt(new Integer(1),row,
477                     SequenceListTableModel.COL_BEG);
478           seqModel.setValueAt(new Integer(length),row,
479                     SequenceListTableModel.COL_END);
480           seqModel.fireTableDataChanged();
481         }
482         setCursor(cdone);
483       }
484   }
485 
486   /**
487   *
488   * Determines whether the 'store sequence list' menu item selected
489   * ("~/.jembossSeqList")
490   * @return 	true if the menu item was selected
491   *
492   */
isStoreSequenceList()493   public boolean isStoreSequenceList()
494   {
495     return storeSeqList.isSelected();
496   }
497 
tableChanged(TableModelEvent e)498   public void tableChanged(TableModelEvent e) {
499       if (getSeqLength.isSelected() == false)
500           return;
501       int row = e.getFirstRow();
502       int column = e.getColumn();
503       if ( row == -1 || column == -1 )
504           return;
505       getSequenceLength();
506   }
507 
508 }
509 
510 
511 /**
512 *
513 * Extend JTable to implement a drag and drop table for
514 * storing sequence lists (SequenceList)
515 *
516 */
517 class DragJTable extends JTable implements DragGestureListener,
518              DragSourceListener, DropTargetListener
519 {
520 
521   /** model for the sequence table */
522   private SequenceListTableModel seqModel;
523 
524   /**
525   *
526   * @param seqModel	model for the sequence table
527   *
528   */
DragJTable(SequenceListTableModel seqModel)529   public DragJTable(SequenceListTableModel seqModel)
530   {
531     super();
532     this.seqModel = seqModel;
533     DragSource dragSource = DragSource.getDefaultDragSource();
534     dragSource.createDefaultDragGestureRecognizer(
535            this,                              // component where drag originates
536            DnDConstants.ACTION_COPY_OR_MOVE,  // actions
537            this);
538     setDropTarget(new DropTarget(this,this));
539   }
540 
541 // drag source
dragGestureRecognized(DragGestureEvent e)542   public void dragGestureRecognized(DragGestureEvent e)
543   {
544     Point p = e.getDragOrigin();
545     int ncol = columnAtPoint(p);
546 
547     if(ncol == convertColumnIndexToView(SequenceListTableModel.COL_NAME))
548     {
549       int nrow = getSelectedRow();
550       e.startDrag(DragSource.DefaultCopyDrop,             // cursor
551             (Transferable)seqModel.getSequenceData(nrow), // transferable data
552                   this);                                  // drag source listener
553     }
554   }
dragDropEnd(DragSourceDropEvent e)555   public void dragDropEnd(DragSourceDropEvent e) {}
dragEnter(DragSourceDragEvent e)556   public void dragEnter(DragSourceDragEvent e) {}
dragExit(DragSourceEvent e)557   public void dragExit(DragSourceEvent e) {}
dragOver(DragSourceDragEvent e)558   public void dragOver(DragSourceDragEvent e) {}
dropActionChanged(DragSourceDragEvent e)559   public void dropActionChanged(DragSourceDragEvent e) {}
560 
561 
562   /**
563   *
564   * Determine if a row in the table contains a list file
565   * @param row	row in the table
566   * @return 	true if row contains a list file
567   *
568   */
isListFile(int row)569   protected Boolean isListFile(int row)
570   {
571     return (Boolean)seqModel.getValueAt(row,
572                   SequenceListTableModel.COL_LIST);
573   }
574 
575 
576 // drop sink
dragEnter(DropTargetDragEvent e)577   public void dragEnter(DropTargetDragEvent e)
578   {
579     if(e.isDataFlavorSupported(RemoteFileNode.REMOTEFILENODE) ||
580        e.isDataFlavorSupported(FileNode.FILENODE) ||
581        e.isDataFlavorSupported(DataFlavor.stringFlavor) ||
582        e.isDataFlavorSupported(SequenceData.SEQUENCEDATA) )
583       e.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
584   }
585 
drop(DropTargetDropEvent e)586   public void drop(DropTargetDropEvent e)
587   {
588     Transferable t = e.getTransferable();
589 
590     if(t.isDataFlavorSupported(FileNode.FILENODE))
591     {
592       try
593       {
594         final FileNode fn =
595            (FileNode)t.getTransferData(FileNode.FILENODE);
596         insertData(seqModel,e.getLocation(),fn.getFile().getCanonicalPath(),
597                    "","",new Boolean(false),new Boolean(false),
598                    new Boolean(false));
599         e.getDropTargetContext().dropComplete(true);
600       }
601       catch(UnsupportedFlavorException ufe){}
602       catch(IOException ioe){}
603     }
604     else if(t.isDataFlavorSupported(RemoteFileNode.REMOTEFILENODE))
605     {
606       try
607       {
608         String dropS = (String)t.getTransferData(DataFlavor.stringFlavor);
609         insertData(seqModel,e.getLocation(),dropS,
610                    "","",new Boolean(false),new Boolean(false),
611                    new Boolean(true));
612         e.getDropTargetContext().dropComplete(true);
613       }
614       catch (Exception exp)
615       {
616         e.rejectDrop();
617       }
618     }
619     else if(t.isDataFlavorSupported(SequenceData.SEQUENCEDATA))
620     {
621       try
622       {
623         SequenceData seqData = (SequenceData)
624            t.getTransferData(SequenceData.SEQUENCEDATA);
625 
626 
627         insertData(seqModel,e.getLocation(),seqData.s_name,
628                    seqData.s_beg,seqData.s_end,
629                    seqData.s_listFile,seqData.s_default,
630                    seqData.s_remote);
631       }
632       catch (UnsupportedFlavorException ufe){}
633       catch (IOException ioe){}
634     }
635 
636   }
637 
638   /**
639   *
640   * Inser sequence data into the sequence table
641   * @param seqModel 	model for the sequence table
642   * @param ploc		point location to insert
643   * @param fileName	name of file
644   * @param sbeg		start of sequence
645   * @param send		end of sequence
646   * @param lis		true if a list file
647   * @param def		true if the default sequence
648   * @param bremote	true if a sequence on the server
649   *
650   */
insertData(SequenceListTableModel seqModel, Point ploc, String fileName, String sbeg, String send, Boolean lis, Boolean def, Boolean bremote)651   public void insertData(SequenceListTableModel seqModel, Point ploc,
652                          String fileName, String sbeg, String send,
653                          Boolean lis, Boolean def, Boolean bremote)
654   {
655     int row = rowAtPoint(ploc);
656     SequenceListTableModel.modelVector.insertElementAt(new SequenceData(fileName,
657                                    sbeg,send,lis,def,bremote),row);
658 
659     tableChanged(new TableModelEvent(seqModel, row+1, row+1,
660             TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
661   }
662 
dragOver(DropTargetDragEvent e)663   public void dragOver(DropTargetDragEvent e)
664   {
665     Point ploc = e.getLocation();
666     int row = rowAtPoint(ploc);
667     setRowSelectionInterval(row,row);
668   }
dropActionChanged(DropTargetDragEvent e)669   public void dropActionChanged(DropTargetDragEvent e) {}
dragExit(DropTargetEvent e)670   public void dragExit(DropTargetEvent e){}
671 
672 
673 }
674 
675 /**
676 *
677 * Content of each column in the DragJTable
678 *
679 */
680 class ColumnData
681 {
682   protected String title;
683   protected int width;
684   protected int alignment;
ColumnData(String title, int width, int alignment)685   public ColumnData(String title, int width, int alignment)
686   {
687     this.title = title;
688     this.width = width;
689     this.alignment = alignment;
690   }
691 }
692 
693 /**
694 *
695 * Model for the sequence table
696 *
697 */
698 class SequenceListTableModel extends AbstractTableModel
699 {
700 
701   protected static Vector modelVector;
702   public static final int COL_NAME = 0;
703   public static final int COL_BEG  = 1;
704   public static final int COL_END  = 2;
705   public static final int COL_LIST = 3;
706   public static final int COL_DEF  = 4;
707 
SequenceListTableModel()708   public SequenceListTableModel()
709   {
710     modelVector = new Vector();
711     File fseq = new File(System.getProperty("user.home")
712                   + System.getProperty("file.separator")
713                   + ".jembossSeqList");
714 
715     setDefaultData();
716 
717     if(fseq.canRead())
718       loadStoredSeqList(fseq);
719   }
720 
721   /**
722   *
723   * Define the columns as file/start/end/list and default
724   *
725   */
726   public static final ColumnData modelColumns[] =
727   {
728     new ColumnData("File / Database Entry",170,JLabel.LEFT),
729     new ColumnData("Start",45,JLabel.LEFT),
730     new ColumnData("End",45,JLabel.LEFT),
731     new ColumnData("List File",15,JLabel.LEFT),
732     new ColumnData("Default",15,JLabel.LEFT)
733   };
734 
735   /**
736   *
737   * DragJTable uses this method to determine the default renderer/
738   * editor for each cell.  If we didn't implement this method,
739   * then the last column would contain text ("true"/"false"),
740   * rather than a check box.
741   * @param c	column index
742   * @return 	class represented in that column
743   *
744   */
getColumnClass(int c)745   public Class getColumnClass(int c)
746   {
747     return getValueAt(0, c).getClass();
748   }
749 
750   /**
751   *
752   * Load from stored file the SequenceList created from
753   * a previous session.
754   * @param fseq 	contains stored sequence list
755   *
756   */
loadStoredSeqList(File fseq)757   protected void loadStoredSeqList(File fseq)
758   {
759     try
760     {
761       BufferedReader in = new BufferedReader(new FileReader(fseq));
762       String line;
763       int nrow = 0;
764 
765       while((line = in.readLine()) != null)
766       {
767         if(!line.equals(""))
768         {
769           line = line.trim();
770           StringTokenizer st = new StringTokenizer(line, " ");
771           for(int i=0;i<getColumnCount();i++)
772           {
773             if(!st.hasMoreTokens())
774               break;
775 
776             if(nrow >= getRowCount())
777             {
778               Boolean bdef = new Boolean(false);
779               modelVector.addElement(new SequenceData("","","",bdef,bdef,bdef));
780             }
781 
782             String value = st.nextToken();
783             if(value.equals("-"))
784               value = "";
785             if(value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false"))
786               setValueAt(new Boolean(value),nrow,i);
787             else
788               setValueAt(value,nrow,i);
789           }
790           nrow++;
791         }
792       }
793     }
794     catch (ArrayIndexOutOfBoundsException ai)
795     {
796       System.out.println("ArrayIndexOutOfBoundsException in SequenceList");
797       setDefaultData();
798     }
799     catch (IOException ioe)
800     {
801       setDefaultData();
802     }
803 
804   }
805 
806   /**
807   *
808   * Setup a blank square table
809   *
810   */
setDefaultData()811   protected void setDefaultData()
812   {
813     modelVector.removeAllElements();
814     Boolean bdef = new Boolean(false);
815     for(int i=0;i<getColumnCount();i++)
816       modelVector.addElement(new SequenceData("","","",bdef,bdef,bdef));
817 
818   }
819 
820 
821   /**
822   *
823   * The <code>SequenceData</code> for a given row
824   * number.
825   * @param row 	number
826   * @return 	<code>SequenceData</code> for the row
827   *
828   */
getSequenceData(int nrow)829   protected SequenceData getSequenceData(int nrow)
830   {
831     return (SequenceData)modelVector.get(nrow);
832   }
833 
834   /**
835   *
836   * Return the number of rows in the table
837   * @return 	number of rows in the table
838   *
839   */
getRowCount()840   public int getRowCount()
841   {
842     return modelVector==null ? 0 : modelVector.size();
843   }
844 
845   /**
846   *
847   * Return the number of columns in the table
848   * @return 	number of columns in the table
849   *
850   */
getColumnCount()851   public int getColumnCount()
852   {
853     return modelColumns.length;
854   }
855 
856   /**
857   *
858   * Return the name columns in the table
859   * @param c	column index
860   * @return 	name columns in the table
861   *
862   */
getColumnName(int c)863   public String getColumnName(int c)
864   {
865     return modelColumns[c].title;
866   }
867 
868   /**
869   *
870   * Define if a cell is editable by the user
871   * @param nRow	row number
872   * @param nCol	column number
873   * @return 	true if editable
874   *
875   */
isCellEditable(int nRow, int nCol)876   public boolean isCellEditable(int nRow, int nCol)
877   {
878     return true;
879   }
880 
881 
882   /**
883   *
884   * Get the Object in a cell in the table
885   * @param nRow	row number
886   * @param nCol	column number
887   * @return 	value of a cell in the table
888   *
889   */
getValueAt(int nRow, int nCol)890   public Object getValueAt(int nRow, int nCol)
891   {
892     if(nRow < 0 || nCol>=getRowCount())
893       return "";
894 
895     SequenceData row = (SequenceData)modelVector.elementAt(nRow);
896     switch(nCol)
897     {
898       case COL_NAME: return row.s_name;
899       case COL_BEG: return row.s_beg;
900       case COL_END: return row.s_end;
901       case COL_DEF:  return row.s_default;
902       case COL_LIST:  return row.s_listFile;
903     }
904     return "";
905   }
906 
907   /**
908   *
909   * Set the Object in a cell in the table
910   * @param value to set
911   * @param row number
912   * @param column number
913   *
914   */
setValueAt(Object value, int nRow, int nCol)915   public void setValueAt(Object value, int nRow, int nCol)
916   {
917     if(nRow < 0 || nCol>=getRowCount())
918       return ;
919 
920     SequenceData row = (SequenceData)modelVector.elementAt(nRow);
921     String svalue = value.toString();
922 
923     switch(nCol)
924     {
925       case COL_NAME:
926           if (!row.s_name.equals(svalue)){
927               row.s_name = svalue;
928               this.fireTableCellUpdated(nRow, nCol);
929           }
930         break;
931       case COL_BEG:
932         row.s_beg = svalue;
933         break;
934       case COL_END:
935         row.s_end = svalue;
936         break;
937       case COL_DEF:
938         row.s_default = (Boolean)value;
939         break;
940       case COL_LIST:
941         row.s_listFile = (Boolean)value;
942         break;
943     }
944   }
945 
946   /**
947   *
948   * Insert a blank row
949   * @param row index to insert at
950   *
951   */
insertRow(int row)952   public void insertRow(int row)
953   {
954     if(row < 0)
955       row = 0;
956     if(row > modelVector.size())
957       row = modelVector.size();
958     modelVector.insertElementAt(new SequenceData(), row);
959   }
960 
961 
962   /**
963   *
964   * Delete a row from the table
965   * @param row 	number to delete
966   * @return 	true if deleted
967   *
968   */
deleteRow(int row)969   public boolean deleteRow(int row)
970   {
971     if(row < 0 || row>=modelVector.size())
972       return false;
973     modelVector.remove(row);
974 
975 //add in blank row so there is always at least
976 //same number of rows as there is columns
977     if(getRowCount() < getColumnCount())
978     {
979       Boolean bdef = new Boolean(false);
980       modelVector.addElement(new SequenceData("","","",bdef,bdef,bdef));
981     }
982 
983     return true;
984   }
985 
986 }
987 
988 
989