1 /* AlignMatchViewer.java
2  *
3  * created: Tue Feb 13 2001
4  *
5  * This file is part of Artemis
6  *
7  * Copyright (C) 2001  Genome Research Limited
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/AlignMatchViewer.java,v 1.3 2008-05-29 14:18:48 tjc Exp $
24  */
25 
26 package uk.ac.sanger.artemis.components;
27 
28 import uk.ac.sanger.artemis.*;
29 
30 import java.awt.*;
31 import java.awt.event.*;
32 import java.io.File;
33 import java.io.FileWriter;
34 import java.io.IOException;
35 import java.io.PrintWriter;
36 
37 import javax.swing.*;
38 import javax.swing.event.ListSelectionListener;
39 import javax.swing.event.ListSelectionEvent;
40 import java.util.Comparator;
41 import java.util.Collections;
42 
43 /**
44  *  A component for viewing AlignMatchVectors selected in an AlignmentViewer.
45  *
46  *  @author Kim Rutherford
47  *  @version $Id: AlignMatchViewer.java,v 1.3 2008-05-29 14:18:48 tjc Exp $
48  **/
49 
50 public class AlignMatchViewer extends JFrame
51 {
52 
53   /**
54    *  The AlignmentViewer to call alignAt () and setSelection () on when the
55    *  user clicks on a match.
56    **/
57   private AlignmentViewer alignment_viewer = null;
58 
59   /**
60    *  The Vector of AlignMatch objects that was passed to the constructor.
61    **/
62   private AlignMatchVector matches = null;
63 
64   /**
65    *  The list that contains the matches.
66    **/
67   private JList list;
68 
69   /**
70    *  If selected the list items will be sorted by score.
71    **/
72   private JCheckBoxMenuItem sort_by_score_menu_item =
73     new JCheckBoxMenuItem ("Sort by Score");
74 
75   /**
76    *  If selected the list items will be sorted by percent identity.
77    **/
78   private JCheckBoxMenuItem sort_by_percent_id_menu_item =
79     new JCheckBoxMenuItem ("Sort by Percent Identity");
80 
81   /**
82    *  If selected the list items will be sorted by the start position of the
83    *  query.
84    **/
85   private JCheckBoxMenuItem sort_by_query_start =
86     new JCheckBoxMenuItem ("Sort by Hit Query Start");
87 
88   /**
89    *  If selected the list items will be sorted by the start position of the
90    *  subject.
91    **/
92   private JCheckBoxMenuItem sort_by_subject_start =
93     new JCheckBoxMenuItem ("Sort by Hit Subject start");
94 
95   /**
96    *  Create a new AlignMatchViewer which shows the given matches.
97    *  @param alignment_viewer The AlignmentViewer to call alignAt () and
98    *    setSelection () on when the user clicks on a match.
99    *  @param matches The Vector of AlignMatch objects to show.
100    **/
AlignMatchViewer(final AlignmentViewer alignment_viewer, final AlignMatchVector matches)101   public AlignMatchViewer(final AlignmentViewer alignment_viewer,
102                           final AlignMatchVector matches)
103   {
104     this.alignment_viewer = alignment_viewer;
105     this.matches = matches;
106 
107     final JMenuBar menu_bar = new JMenuBar();
108     final JMenu file_menu = new JMenu("File");
109 
110     final JMenuItem save = new JMenuItem("Save List to File...");
111     save.addActionListener(new ActionListener()
112     {
113       public void actionPerformed(ActionEvent arg0)
114       {
115         saveMatchList();
116       }
117     });
118 
119     final JMenuItem close = new JMenuItem("Close");
120     close.addActionListener(new ActionListener ()
121     {
122       public void actionPerformed (ActionEvent event)
123       {
124         setVisible (false);
125         AlignMatchViewer.this.dispose ();
126       }
127     });
128 
129     file_menu.add (save);
130     file_menu.add (close);
131     menu_bar.add (file_menu);
132 
133     final JMenu sort_menu = new JMenu("Sort");
134     sort_menu.add(sort_by_score_menu_item);
135 
136     sort_by_score_menu_item.addItemListener(new ItemListener ()
137     {
138       public void itemStateChanged(ItemEvent e)
139       {
140         if (sort_by_score_menu_item.getState())
141         {
142           sort_by_percent_id_menu_item.setState (false);
143           sort_by_query_start.setState (false);
144           sort_by_subject_start.setState (false);
145         }
146         setList ();
147       }
148     });
149 
150     sort_menu.add (sort_by_percent_id_menu_item);
151 
152     sort_by_percent_id_menu_item.addItemListener(new ItemListener()
153     {
154       public void itemStateChanged(ItemEvent e)
155       {
156         if(sort_by_percent_id_menu_item.getState())
157         {
158           sort_by_score_menu_item.setState(false);
159           sort_by_query_start.setState(false);
160           sort_by_subject_start.setState (false);
161         }
162         setList ();
163       }
164     });
165 
166     sort_menu.add (sort_by_query_start);
167 
168     sort_by_query_start.addItemListener(new ItemListener()
169     {
170       public void itemStateChanged(ItemEvent e)
171       {
172         if(sort_by_query_start.getState())
173         {
174           sort_by_percent_id_menu_item.setState(false);
175           sort_by_score_menu_item.setState(false);
176           sort_by_subject_start.setState(false);
177         }
178 
179         setList();
180       }
181     });
182 
183     sort_menu.add(sort_by_subject_start);
184 
185     sort_by_subject_start.addItemListener(new ItemListener()
186     {
187       public void itemStateChanged(ItemEvent e)
188       {
189         if(sort_by_subject_start.getState())
190         {
191           sort_by_percent_id_menu_item.setState(false);
192           sort_by_score_menu_item.setState(false);
193           sort_by_query_start.setState(false);
194         }
195         setList ();
196       }
197     });
198 
199     menu_bar.add(sort_menu);
200 
201     setJMenuBar(menu_bar);
202 
203     list = new JList();
204 
205     list.setBackground(Color.white);
206 
207     getContentPane().add(new JScrollPane(list), "Center");
208 
209     final JPanel panel = new JPanel();
210 
211     final JButton close_button = new JButton("Close");
212 
213     panel.add(close_button);
214     close_button.addActionListener(new ActionListener()
215     {
216       public void actionPerformed(ActionEvent e)
217       {
218         AlignMatchViewer.this.dispose ();
219       }
220     });
221 
222     close_button.addActionListener(new ActionListener()
223     {
224       public void actionPerformed(ActionEvent e)
225       {
226         AlignMatchViewer.this.dispose();
227       }
228     });
229 
230     getContentPane().add(panel, "South");
231 
232     addWindowListener(new WindowAdapter()
233     {
234       public void windowClosing(WindowEvent event)
235       {
236         AlignMatchViewer.this.dispose();
237       }
238     });
239 
240     pack();
241 
242     setList();
243 
244     final Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
245 
246     int screen_height = screen.height;
247     int screen_width  = screen.width;
248 
249     if(screen_height <= 600)
250       setSize (350, screen_height * 9 / 10);
251     else
252       setSize (350, screen_height - 200);
253 
254     setLocation(new Point (screen.width - getSize ().width - 5,
255                            (screen.height - getSize ().height) / 2));
256   }
257 
258   /**
259    *  Sort the matches depending on the setting of sort_by_score_menu_item and
260    *  sort_by_percent_id_menu_item.
261    **/
getSortedMatches()262   private AlignMatchVector getSortedMatches()
263   {
264     final AlignMatchVector matches_copy = (AlignMatchVector)matches.clone();
265 
266     final Comparator comparator;
267 
268     if(sort_by_score_menu_item.getState())
269     {
270       comparator =
271         new Comparator ()
272         {
273           public int compare (Object fst, Object snd)
274           {
275             final int fst_score = ((AlignMatch)fst).getScore();
276             final int snd_score = ((AlignMatch)snd).getScore();
277 
278             if (fst_score < snd_score)
279               return 1;
280             else
281             {
282               if (fst_score > snd_score)
283                 return -1;
284               else
285                 return 0;
286             }
287           }
288         };
289     }
290     else
291     {
292       if(sort_by_percent_id_menu_item.getState())
293       {
294         comparator =
295           new Comparator()
296           {
297             public int compare (Object fst, Object snd)
298             {
299               final int fst_value = ((AlignMatch)fst).getPercentID();
300               final int snd_value = ((AlignMatch)snd).getPercentID();
301 
302               if (fst_value < snd_value)
303                 return 1;
304               else
305               {
306                 if(fst_value > snd_value)
307                   return -1;
308                 else
309                   return 0;
310               }
311             }
312           };
313       }
314       else
315       {
316         if(sort_by_query_start.getState())
317         {
318           comparator =
319             new Comparator()
320             {
321               public int compare(Object fst, Object snd)
322               {
323                 final int fst_value =
324                   ((AlignMatch)fst).getQuerySequenceStart();
325                 final int snd_value =
326                   ((AlignMatch)snd).getQuerySequenceStart();
327 
328                 if(fst_value > snd_value)
329                   return 1;
330                 else
331                 {
332                   if (fst_value < snd_value)
333                     return -1;
334                   else
335                     return 0;
336                 }
337               }
338             };
339         }
340         else
341         {
342           if(sort_by_subject_start.getState())
343           {
344             comparator =
345               new Comparator()
346               {
347                 public int compare (Object fst, Object snd)
348                 {
349                   final int fst_value =
350                     ((AlignMatch)fst).getSubjectSequenceStart();
351                   final int snd_value =
352                     ((AlignMatch)snd).getSubjectSequenceStart();
353 
354                   if (fst_value > snd_value)
355                     return 1;
356                   else
357                   {
358                     if (fst_value < snd_value)
359                       return -1;
360                     else
361                       return 0;
362                   }
363                 }
364               };
365           }
366           else
367             return matches;
368         }
369       }
370     }
371 
372     matches_copy.sort(comparator);
373     return matches_copy;
374   }
375 
376   /**
377    *  Clear the List and then fill it with the matches in the order
378    **/
setList()379   private void setList ()
380   {
381     final AlignMatchVector sorted_matches = getSortedMatches();
382 
383     list.setEnabled(false);
384     list.setVisible(false);
385     list.removeAll();
386 
387     String listItems[] = new String[sorted_matches.size()];
388 
389     for(int i = 0 ; i<sorted_matches.size() ; ++i)
390     {
391       final AlignMatch this_align_match = sorted_matches.elementAt(i);
392 
393       listItems[i] = new String(
394         this_align_match.getQuerySequenceStart() + ".." +
395         this_align_match.getQuerySequenceEnd() + " -> " +
396         this_align_match.getSubjectSequenceStart() + ".." +
397         this_align_match.getSubjectSequenceEnd() + " " +
398         (this_align_match.isRevMatch() ? "rev " : "") +
399         this_align_match.getPercentID() + "% id score " +
400         this_align_match.getScore() );
401 
402     }
403 
404     list.setListData(listItems);
405 
406     list.addListSelectionListener(new ListSelectionListener()
407     {
408       public void valueChanged(ListSelectionEvent e)
409       {
410         final int item_number = list.getSelectedIndex();
411 
412         final AlignMatch selected_match = matches.elementAt(item_number);
413 
414         alignment_viewer.setSelection(selected_match);
415         alignment_viewer.alignAt(selected_match);
416       }
417     });
418 
419     list.setEnabled(true);
420     list.setVisible(true);
421   }
422 
423 
424   /**
425    *  Save the text of the match list to a file.
426    **/
saveMatchList()427   private void saveMatchList()
428   {
429     final StickyFileChooser file_dialog = new StickyFileChooser();
430 
431     file_dialog.setDialogTitle("Choose save file ...");
432     file_dialog.setDialogType(JFileChooser.SAVE_DIALOG);
433     final int status = file_dialog.showSaveDialog(this);
434 
435     if(status != JFileChooser.APPROVE_OPTION ||
436        file_dialog.getSelectedFile() == null)
437       return;
438 
439     final File write_file =
440       new File(file_dialog.getCurrentDirectory(),
441                 file_dialog.getSelectedFile().getName());
442 
443     if(write_file.exists())
444     {
445       final YesNoDialog yes_no_dialog =
446         new YesNoDialog(this,
447                          "this file exists: " + write_file +
448                          " overwrite it?");
449       if(yes_no_dialog.getResult())
450       {
451         // yes - continue
452       }
453       else
454         return;
455     }
456 
457     try
458     {
459       final PrintWriter writer =
460         new PrintWriter(new FileWriter(write_file));
461 
462       for(int i = 0 ; i < list.getModel().getSize() ; ++i)
463         writer.println(list.getModel().getElementAt(i));
464       writer.close();
465     }
466     catch(IOException e)
467     {
468       new MessageDialog(this, "error while writing: " + e.getMessage());
469     }
470   }
471 
472 
473 }
474