885c3bf8a2026a9c05418479999d03e5103bf171
[jalview.git] / src / jalview / gui / PCAPanel.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import jalview.analysis.scoremodels.ScoreModels;
24 import jalview.analysis.scoremodels.SimilarityParams;
25 import jalview.api.analysis.ScoreModelI;
26 import jalview.api.analysis.SimilarityParamsI;
27 import jalview.api.analysis.ViewBasedAnalysisI;
28 import jalview.bin.Cache;
29 import jalview.datamodel.Alignment;
30 import jalview.datamodel.AlignmentI;
31 import jalview.datamodel.AlignmentView;
32 import jalview.datamodel.ColumnSelection;
33 import jalview.datamodel.SeqCigar;
34 import jalview.datamodel.SequenceI;
35 import jalview.jbgui.GPCAPanel;
36 import jalview.util.MessageManager;
37 import jalview.viewmodel.AlignmentViewport;
38 import jalview.viewmodel.PCAModel;
39
40 import java.awt.BorderLayout;
41 import java.awt.Color;
42 import java.awt.Graphics;
43 import java.awt.event.ActionEvent;
44 import java.awt.event.ActionListener;
45 import java.awt.print.PageFormat;
46 import java.awt.print.Printable;
47 import java.awt.print.PrinterException;
48 import java.awt.print.PrinterJob;
49
50 import javax.swing.ButtonGroup;
51 import javax.swing.JCheckBoxMenuItem;
52 import javax.swing.JColorChooser;
53 import javax.swing.JMenuItem;
54 import javax.swing.JRadioButtonMenuItem;
55 import javax.swing.event.InternalFrameAdapter;
56 import javax.swing.event.InternalFrameEvent;
57
58 /**
59  * DOCUMENT ME!
60  * 
61  * @author $author$
62  * @version $Revision$
63  */
64 public class PCAPanel extends GPCAPanel implements Runnable,
65         IProgressIndicator
66 {
67
68   private IProgressIndicator progressBar;
69
70   RotatableCanvas rc;
71
72   AlignmentPanel ap;
73
74   AlignmentViewport av;
75
76   PCAModel pcaModel;
77
78   int top = 0;
79
80   /**
81    * Creates a new PCAPanel object using default score model and parameters
82    * 
83    * @param alignPanel
84    */
85   public PCAPanel(AlignmentPanel alignPanel)
86   {
87     this(alignPanel, ScoreModels.getInstance().getDefaultModel(
88             !alignPanel.av.getAlignment().isNucleotide()),
89             SimilarityParams.SeqSpace);
90   }
91
92   /**
93    * Constructor given sequence data, a similarity (or distance) score model,
94    * and score calculation parameters
95    * 
96    * @param alignPanel
97    * @param scoreModel
98    * @param params
99    */
100   public PCAPanel(AlignmentPanel alignPanel, ScoreModelI scoreModel,
101           SimilarityParamsI params)
102   {
103     super();
104     this.av = alignPanel.av;
105     this.ap = alignPanel;
106     boolean nucleotide = av.getAlignment().isNucleotide();
107
108     progressBar = new ProgressBar(statusPanel, statusBar);
109
110     addInternalFrameListener(new InternalFrameAdapter()
111     {
112       @Override
113       public void internalFrameClosed(InternalFrameEvent e)
114       {
115         close_actionPerformed();
116       }
117     });
118
119     boolean selected = av.getSelectionGroup() != null
120             && av.getSelectionGroup().getSize() > 0;
121     AlignmentView seqstrings = av.getAlignmentView(selected);
122     SequenceI[] seqs;
123     if (!selected)
124     {
125       seqs = av.getAlignment().getSequencesArray();
126     }
127     else
128     {
129       seqs = av.getSelectionGroup().getSequencesInOrder(av.getAlignment());
130     }
131
132     // TODO can we allow PCA on unaligned data given choice of
133     // similarity measure parameters?
134     if (!checkAligned(seqstrings))
135     {
136       JvOptionPane.showMessageDialog(Desktop.desktop,
137               MessageManager.getString("label.pca_sequences_not_aligned"),
138               MessageManager.getString("label.sequences_not_aligned"),
139               JvOptionPane.WARNING_MESSAGE);
140
141       return;
142     }
143
144     pcaModel = new PCAModel(seqstrings, seqs, nucleotide, scoreModel,
145             params);
146     PaintRefresher.Register(this, av.getSequenceSetId());
147
148     rc = new RotatableCanvas(alignPanel);
149     this.getContentPane().add(rc, BorderLayout.CENTER);
150     Thread worker = new Thread(this);
151     worker.start();
152   }
153
154   /**
155    * Answers true if all sequences have the same aligned length, else false
156    * 
157    * @param seqstrings
158    * @return
159    */
160   protected boolean checkAligned(AlignmentView seqstrings)
161   {
162     SeqCigar sq[] = seqstrings.getSequences();
163     int length = sq[0].getWidth();
164     boolean sameLength = true;
165     for (int i = 0; i < sq.length; i++)
166     {
167       if (sq[i].getWidth() != length)
168       {
169         sameLength = false;
170         break;
171       }
172     }
173     return sameLength;
174   }
175
176   /**
177    * Ensure references to potentially very large objects (the PCA matrices) are
178    * nulled when the frame is closed
179    */
180   protected void close_actionPerformed()
181   {
182     pcaModel = null;
183   }
184
185   /**
186    * Repopulate the options and actions under the score model menu when it is
187    * selected. Options will depend on whether 'nucleotide' or 'peptide'
188    * modelling is selected (and also possibly on whether any additional score
189    * models have been added).
190    */
191   @Override
192   protected void scoreModel_menuSelected()
193   {
194     scoreModelMenu.removeAll();
195     for (final ScoreModelI sm : ScoreModels.getInstance().getModels())
196     {
197       final String name = sm.getName();
198       JCheckBoxMenuItem jm = new JCheckBoxMenuItem(name);
199
200       /*
201        * if the score model doesn't provide a description, try to look one
202        * up in the text bundle, falling back on its name
203        */
204       String tooltip = sm.getDescription();
205       if (tooltip == null)
206       {
207         tooltip = MessageManager.getStringOrReturn("label.score_model_",
208                 name);
209       }
210       jm.setToolTipText(tooltip);
211       jm.setSelected(pcaModel.getScoreModelName().equals(name));
212       if ((pcaModel.isNucleotide() && sm.isDNA())
213               || (!pcaModel.isNucleotide() && sm.isProtein()))
214       {
215         jm.addActionListener(new ActionListener()
216         {
217           @Override
218           public void actionPerformed(ActionEvent e)
219           {
220             if (!pcaModel.getScoreModelName().equals(name))
221             {
222               ScoreModelI sm2 = configureScoreModel(sm);
223               pcaModel.setScoreModel(sm2);
224               Thread worker = new Thread(PCAPanel.this);
225               worker.start();
226             }
227           }
228         });
229         scoreModelMenu.add(jm);
230       }
231     }
232   }
233
234   @Override
235   public void bgcolour_actionPerformed(ActionEvent e)
236   {
237     Color col = JColorChooser.showDialog(this,
238             MessageManager.getString("label.select_background_colour"),
239             rc.bgColour);
240
241     if (col != null)
242     {
243       rc.bgColour = col;
244     }
245     rc.repaint();
246   }
247
248   /**
249    * DOCUMENT ME!
250    */
251   @Override
252   public void run()
253   {
254     long progId = System.currentTimeMillis();
255     IProgressIndicator progress = this;
256     String message = MessageManager.getString("label.pca_recalculating");
257     if (getParent() == null)
258     {
259       progress = ap.alignFrame;
260       message = MessageManager.getString("label.pca_calculating");
261     }
262     progress.setProgressBar(message, progId);
263     try
264     {
265       calcSettings.setEnabled(false);
266       pcaModel.run();
267       // ////////////////
268       xCombobox.setSelectedIndex(0);
269       yCombobox.setSelectedIndex(1);
270       zCombobox.setSelectedIndex(2);
271
272       pcaModel.updateRc(rc);
273       // rc.invalidate();
274       nuclSetting.setSelected(pcaModel.isNucleotide());
275       protSetting.setSelected(!pcaModel.isNucleotide());
276       jvVersionSetting.setSelected(pcaModel.isJvCalcMode());
277       top = pcaModel.getTop();
278
279     } catch (OutOfMemoryError er)
280     {
281       new OOMWarning("calculating PCA", er);
282       return;
283     } finally
284     {
285       progress.setProgressBar("", progId);
286     }
287     calcSettings.setEnabled(true);
288     repaint();
289     if (getParent() == null)
290     {
291       addKeyListener(rc);
292       Desktop.addInternalFrame(this, MessageManager
293               .getString("label.principal_component_analysis"), 475, 450);
294     }
295   }
296
297   @Override
298   protected void nuclSetting_actionPerfomed(ActionEvent arg0)
299   {
300     if (!pcaModel.isNucleotide())
301     {
302       pcaModel.setNucleotide(true);
303       pcaModel.setScoreModel(ScoreModels.getInstance().getDefaultModel(
304               false));
305       Thread worker = new Thread(this);
306       worker.start();
307     }
308
309   }
310
311   @Override
312   protected void protSetting_actionPerfomed(ActionEvent arg0)
313   {
314
315     if (pcaModel.isNucleotide())
316     {
317       pcaModel.setNucleotide(false);
318       pcaModel.setScoreModel(ScoreModels.getInstance()
319               .getDefaultModel(true));
320       Thread worker = new Thread(this);
321       worker.start();
322     }
323   }
324
325   @Override
326   protected void jvVersionSetting_actionPerfomed(ActionEvent arg0)
327   {
328     pcaModel.setJvCalcMode(jvVersionSetting.isSelected());
329     Thread worker = new Thread(this);
330     worker.start();
331   }
332
333   /**
334    * DOCUMENT ME!
335    */
336   void doDimensionChange()
337   {
338     if (top == 0)
339     {
340       return;
341     }
342
343     int dim1 = top - xCombobox.getSelectedIndex();
344     int dim2 = top - yCombobox.getSelectedIndex();
345     int dim3 = top - zCombobox.getSelectedIndex();
346     pcaModel.updateRcView(dim1, dim2, dim3);
347     rc.img = null;
348     rc.rotmat.setIdentity();
349     rc.initAxes();
350     rc.paint(rc.getGraphics());
351   }
352
353   /**
354    * DOCUMENT ME!
355    * 
356    * @param e
357    *          DOCUMENT ME!
358    */
359   @Override
360   protected void xCombobox_actionPerformed(ActionEvent e)
361   {
362     doDimensionChange();
363   }
364
365   /**
366    * DOCUMENT ME!
367    * 
368    * @param e
369    *          DOCUMENT ME!
370    */
371   @Override
372   protected void yCombobox_actionPerformed(ActionEvent e)
373   {
374     doDimensionChange();
375   }
376
377   /**
378    * DOCUMENT ME!
379    * 
380    * @param e
381    *          DOCUMENT ME!
382    */
383   @Override
384   protected void zCombobox_actionPerformed(ActionEvent e)
385   {
386     doDimensionChange();
387   }
388
389   @Override
390   public void outputValues_actionPerformed(ActionEvent e)
391   {
392     CutAndPasteTransfer cap = new CutAndPasteTransfer();
393     try
394     {
395       cap.setText(pcaModel.getDetails());
396       Desktop.addInternalFrame(cap,
397               MessageManager.getString("label.pca_details"), 500, 500);
398     } catch (OutOfMemoryError oom)
399     {
400       new OOMWarning("opening PCA details", oom);
401       cap.dispose();
402     }
403   }
404
405   @Override
406   public void showLabels_actionPerformed(ActionEvent e)
407   {
408     rc.showLabels(showLabels.getState());
409   }
410
411   @Override
412   public void print_actionPerformed(ActionEvent e)
413   {
414     PCAPrinter printer = new PCAPrinter();
415     printer.start();
416   }
417
418   @Override
419   public void originalSeqData_actionPerformed(ActionEvent e)
420   {
421     // this was cut'n'pasted from the equivalent TreePanel method - we should
422     // make this an abstract function of all jalview analysis windows
423     if (pcaModel.getSeqtrings() == null)
424     {
425       jalview.bin.Cache.log
426               .info("Unexpected call to originalSeqData_actionPerformed - should have hidden this menu action.");
427       return;
428     }
429     // decide if av alignment is sufficiently different to original data to
430     // warrant a new window to be created
431     // create new alignmnt window with hidden regions (unhiding hidden regions
432     // yields unaligned seqs)
433     // or create a selection box around columns in alignment view
434     // test Alignment(SeqCigar[])
435     char gc = '-';
436     try
437     {
438       // we try to get the associated view's gap character
439       // but this may fail if the view was closed...
440       gc = av.getGapCharacter();
441     } catch (Exception ex)
442     {
443     }
444     ;
445     Object[] alAndColsel = pcaModel.getSeqtrings()
446             .getAlignmentAndColumnSelection(gc);
447
448     if (alAndColsel != null && alAndColsel[0] != null)
449     {
450       // AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);
451
452       AlignmentI al = new Alignment((SequenceI[]) alAndColsel[0]);
453       AlignmentI dataset = (av != null && av.getAlignment() != null) ? av
454               .getAlignment().getDataset() : null;
455       if (dataset != null)
456       {
457         al.setDataset(dataset);
458       }
459
460       if (true)
461       {
462         // make a new frame!
463         AlignFrame af = new AlignFrame(al,
464                 (ColumnSelection) alAndColsel[1], AlignFrame.DEFAULT_WIDTH,
465                 AlignFrame.DEFAULT_HEIGHT);
466
467         // >>>This is a fix for the moment, until a better solution is
468         // found!!<<<
469         // af.getFeatureRenderer().transferSettings(alignFrame.getFeatureRenderer());
470
471         // af.addSortByOrderMenuItem(ServiceName + " Ordering",
472         // msaorder);
473
474         Desktop.addInternalFrame(af, MessageManager.formatMessage(
475                 "label.original_data_for_params",
476                 new String[] { this.title }), AlignFrame.DEFAULT_WIDTH,
477                 AlignFrame.DEFAULT_HEIGHT);
478       }
479     }
480     /*
481      * CutAndPasteTransfer cap = new CutAndPasteTransfer(); for (int i = 0; i <
482      * seqs.length; i++) { cap.appendText(new jalview.util.Format("%-" + 15 +
483      * "s").form( seqs[i].getName())); cap.appendText(" " + seqstrings[i] +
484      * "\n"); }
485      * 
486      * Desktop.addInternalFrame(cap, "Original Data", 400, 400);
487      */
488   }
489
490   class PCAPrinter extends Thread implements Printable
491   {
492     @Override
493     public void run()
494     {
495       PrinterJob printJob = PrinterJob.getPrinterJob();
496       PageFormat pf = printJob.pageDialog(printJob.defaultPage());
497
498       printJob.setPrintable(this, pf);
499
500       if (printJob.printDialog())
501       {
502         try
503         {
504           printJob.print();
505         } catch (Exception PrintException)
506         {
507           PrintException.printStackTrace();
508         }
509       }
510     }
511
512     @Override
513     public int print(Graphics pg, PageFormat pf, int pi)
514             throws PrinterException
515     {
516       pg.translate((int) pf.getImageableX(), (int) pf.getImageableY());
517
518       rc.drawBackground(pg, rc.bgColour);
519       rc.drawScene(pg);
520       if (rc.drawAxes == true)
521       {
522         rc.drawAxes(pg);
523       }
524
525       if (pi == 0)
526       {
527         return Printable.PAGE_EXISTS;
528       }
529       else
530       {
531         return Printable.NO_SUCH_PAGE;
532       }
533     }
534   }
535
536   /**
537    * DOCUMENT ME!
538    * 
539    * @param e
540    *          DOCUMENT ME!
541    */
542   @Override
543   public void eps_actionPerformed(ActionEvent e)
544   {
545     makePCAImage(jalview.util.ImageMaker.TYPE.EPS);
546   }
547
548   /**
549    * DOCUMENT ME!
550    * 
551    * @param e
552    *          DOCUMENT ME!
553    */
554   @Override
555   public void png_actionPerformed(ActionEvent e)
556   {
557     makePCAImage(jalview.util.ImageMaker.TYPE.PNG);
558   }
559
560   void makePCAImage(jalview.util.ImageMaker.TYPE type)
561   {
562     int width = rc.getWidth();
563     int height = rc.getHeight();
564
565     jalview.util.ImageMaker im;
566
567     if (type == jalview.util.ImageMaker.TYPE.PNG)
568     {
569       im = new jalview.util.ImageMaker(this,
570               jalview.util.ImageMaker.TYPE.PNG, "Make PNG image from PCA",
571               width, height, null, null, null, 0, false);
572     }
573     else if (type == jalview.util.ImageMaker.TYPE.EPS)
574     {
575       im = new jalview.util.ImageMaker(this,
576               jalview.util.ImageMaker.TYPE.EPS, "Make EPS file from PCA",
577               width, height, null, this.getTitle(), null, 0, false);
578     }
579     else
580     {
581       im = new jalview.util.ImageMaker(this,
582               jalview.util.ImageMaker.TYPE.SVG, "Make SVG file from PCA",
583               width, height, null, this.getTitle(), null, 0, false);
584
585     }
586
587     if (im.getGraphics() != null)
588     {
589       rc.drawBackground(im.getGraphics(), Color.black);
590       rc.drawScene(im.getGraphics());
591       if (rc.drawAxes == true)
592       {
593         rc.drawAxes(im.getGraphics());
594       }
595       im.writeImage();
596     }
597   }
598
599   @Override
600   public void viewMenu_menuSelected()
601   {
602     buildAssociatedViewMenu();
603   }
604
605   void buildAssociatedViewMenu()
606   {
607     AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(av
608             .getSequenceSetId());
609     if (aps.length == 1 && rc.av == aps[0].av)
610     {
611       associateViewsMenu.setVisible(false);
612       return;
613     }
614
615     associateViewsMenu.setVisible(true);
616
617     if ((viewMenu.getItem(viewMenu.getItemCount() - 2) instanceof JMenuItem))
618     {
619       viewMenu.insertSeparator(viewMenu.getItemCount() - 1);
620     }
621
622     associateViewsMenu.removeAll();
623
624     JRadioButtonMenuItem item;
625     ButtonGroup buttonGroup = new ButtonGroup();
626     int i, iSize = aps.length;
627     final PCAPanel thisPCAPanel = this;
628     for (i = 0; i < iSize; i++)
629     {
630       final AlignmentPanel ap = aps[i];
631       item = new JRadioButtonMenuItem(ap.av.viewName, ap.av == rc.av);
632       buttonGroup.add(item);
633       item.addActionListener(new ActionListener()
634       {
635         @Override
636         public void actionPerformed(ActionEvent evt)
637         {
638           rc.applyToAllViews = false;
639           rc.av = ap.av;
640           rc.ap = ap;
641           PaintRefresher.Register(thisPCAPanel, ap.av.getSequenceSetId());
642         }
643       });
644
645       associateViewsMenu.add(item);
646     }
647
648     final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem("All Views");
649
650     buttonGroup.add(itemf);
651
652     itemf.setSelected(rc.applyToAllViews);
653     itemf.addActionListener(new ActionListener()
654     {
655       @Override
656       public void actionPerformed(ActionEvent evt)
657       {
658         rc.applyToAllViews = itemf.isSelected();
659       }
660     });
661     associateViewsMenu.add(itemf);
662
663   }
664
665   /*
666    * (non-Javadoc)
667    * 
668    * @see
669    * jalview.jbgui.GPCAPanel#outputPoints_actionPerformed(java.awt.event.ActionEvent
670    * )
671    */
672   @Override
673   protected void outputPoints_actionPerformed(ActionEvent e)
674   {
675     CutAndPasteTransfer cap = new CutAndPasteTransfer();
676     try
677     {
678       cap.setText(pcaModel.getPointsasCsv(false,
679               xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(),
680               zCombobox.getSelectedIndex()));
681       Desktop.addInternalFrame(cap, MessageManager.formatMessage(
682               "label.points_for_params", new String[] { this.getTitle() }),
683               500, 500);
684     } catch (OutOfMemoryError oom)
685     {
686       new OOMWarning("exporting PCA points", oom);
687       cap.dispose();
688     }
689   }
690
691   /*
692    * (non-Javadoc)
693    * 
694    * @see
695    * jalview.jbgui.GPCAPanel#outputProjPoints_actionPerformed(java.awt.event
696    * .ActionEvent)
697    */
698   @Override
699   protected void outputProjPoints_actionPerformed(ActionEvent e)
700   {
701     CutAndPasteTransfer cap = new CutAndPasteTransfer();
702     try
703     {
704       cap.setText(pcaModel.getPointsasCsv(true,
705               xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(),
706               zCombobox.getSelectedIndex()));
707       Desktop.addInternalFrame(cap, MessageManager.formatMessage(
708               "label.transformed_points_for_params",
709               new String[] { this.getTitle() }), 500, 500);
710     } catch (OutOfMemoryError oom)
711     {
712       new OOMWarning("exporting transformed PCA points", oom);
713       cap.dispose();
714     }
715   }
716
717   /*
718    * (non-Javadoc)
719    * 
720    * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
721    */
722   @Override
723   public void setProgressBar(String message, long id)
724   {
725     progressBar.setProgressBar(message, id);
726     // if (progressBars == null)
727     // {
728     // progressBars = new Hashtable();
729     // progressBarHandlers = new Hashtable();
730     // }
731     //
732     // JPanel progressPanel;
733     // Long lId = new Long(id);
734     // GridLayout layout = (GridLayout) statusPanel.getLayout();
735     // if (progressBars.get(lId) != null)
736     // {
737     // progressPanel = (JPanel) progressBars.get(new Long(id));
738     // statusPanel.remove(progressPanel);
739     // progressBars.remove(lId);
740     // progressPanel = null;
741     // if (message != null)
742     // {
743     // statusBar.setText(message);
744     // }
745     // if (progressBarHandlers.contains(lId))
746     // {
747     // progressBarHandlers.remove(lId);
748     // }
749     // layout.setRows(layout.getRows() - 1);
750     // }
751     // else
752     // {
753     // progressPanel = new JPanel(new BorderLayout(10, 5));
754     //
755     // JProgressBar progressBar = new JProgressBar();
756     // progressBar.setIndeterminate(true);
757     //
758     // progressPanel.add(new JLabel(message), BorderLayout.WEST);
759     // progressPanel.add(progressBar, BorderLayout.CENTER);
760     //
761     // layout.setRows(layout.getRows() + 1);
762     // statusPanel.add(progressPanel);
763     //
764     // progressBars.put(lId, progressPanel);
765     // }
766     // // update GUI
767     // // setMenusForViewport();
768     // validate();
769   }
770
771   @Override
772   public void registerHandler(final long id,
773           final IProgressIndicatorHandler handler)
774   {
775     progressBar.registerHandler(id, handler);
776     // if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
777     // {
778     // throw new
779     // Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
780     // }
781     // progressBarHandlers.put(new Long(id), handler);
782     // final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
783     // if (handler.canCancel())
784     // {
785     // JButton cancel = new JButton(
786     // MessageManager.getString("action.cancel"));
787     // final IProgressIndicator us = this;
788     // cancel.addActionListener(new ActionListener()
789     // {
790     //
791     // @Override
792     // public void actionPerformed(ActionEvent e)
793     // {
794     // handler.cancelActivity(id);
795     // us.setProgressBar(MessageManager.formatMessage("label.cancelled_params",
796     // new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
797     // }
798     // });
799     // progressPanel.add(cancel, BorderLayout.EAST);
800     // }
801   }
802
803   /**
804    * 
805    * @return true if any progress bars are still active
806    */
807   @Override
808   public boolean operationInProgress()
809   {
810     return progressBar.operationInProgress();
811   }
812
813   @Override
814   protected void resetButton_actionPerformed(ActionEvent e)
815   {
816     int t = top;
817     top = 0; // ugly - prevents dimensionChanged events from being processed
818     xCombobox.setSelectedIndex(0);
819     yCombobox.setSelectedIndex(1);
820     top = t;
821     zCombobox.setSelectedIndex(2);
822   }
823
824   /**
825    * If the score model is one that requires to get state data from the current
826    * view, allow it to do so
827    * 
828    * @param sm
829    * @return
830    */
831   protected ScoreModelI configureScoreModel(ScoreModelI sm)
832   {
833     if (sm instanceof ViewBasedAnalysisI)
834     {
835       try
836       {
837         sm = sm.getClass().newInstance();
838         ((ViewBasedAnalysisI) sm).configureFromAlignmentView(ap);
839       } catch (Exception q)
840       {
841         Cache.log.error("Couldn't create a scoremodel instance for "
842                 + sm.getName());
843       }
844     }
845     return sm;
846   }
847 }