JAL-1632 dialog to calculate either Tree or PCA
[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       // create an entry for this score matrix for use in PCA
199       JCheckBoxMenuItem jm = new JCheckBoxMenuItem();
200       jm.setText(MessageManager.getStringOrReturn("label.score_model_",
201               name));
202       jm.setSelected(pcaModel.getScoreModelName().equals(name));
203       if ((pcaModel.isNucleotide() && sm.isDNA())
204               || (!pcaModel.isNucleotide() && sm.isProtein()))
205       {
206         jm.addActionListener(new ActionListener()
207         {
208           @Override
209           public void actionPerformed(ActionEvent e)
210           {
211             if (!pcaModel.getScoreModelName().equals(name))
212             {
213               ScoreModelI sm2 = configureScoreModel(sm);
214               pcaModel.setScoreModel(sm2);
215               Thread worker = new Thread(PCAPanel.this);
216               worker.start();
217             }
218           }
219         });
220         scoreModelMenu.add(jm);
221       }
222     }
223   }
224
225   @Override
226   public void bgcolour_actionPerformed(ActionEvent e)
227   {
228     Color col = JColorChooser.showDialog(this,
229             MessageManager.getString("label.select_background_colour"),
230             rc.bgColour);
231
232     if (col != null)
233     {
234       rc.bgColour = col;
235     }
236     rc.repaint();
237   }
238
239   /**
240    * DOCUMENT ME!
241    */
242   @Override
243   public void run()
244   {
245     long progId = System.currentTimeMillis();
246     IProgressIndicator progress = this;
247     String message = MessageManager.getString("label.pca_recalculating");
248     if (getParent() == null)
249     {
250       progress = ap.alignFrame;
251       message = MessageManager.getString("label.pca_calculating");
252     }
253     progress.setProgressBar(message, progId);
254     try
255     {
256       calcSettings.setEnabled(false);
257       pcaModel.run();
258       // ////////////////
259       xCombobox.setSelectedIndex(0);
260       yCombobox.setSelectedIndex(1);
261       zCombobox.setSelectedIndex(2);
262
263       pcaModel.updateRc(rc);
264       // rc.invalidate();
265       nuclSetting.setSelected(pcaModel.isNucleotide());
266       protSetting.setSelected(!pcaModel.isNucleotide());
267       jvVersionSetting.setSelected(pcaModel.isJvCalcMode());
268       top = pcaModel.getTop();
269
270     } catch (OutOfMemoryError er)
271     {
272       new OOMWarning("calculating PCA", er);
273       return;
274     } finally
275     {
276       progress.setProgressBar("", progId);
277     }
278     calcSettings.setEnabled(true);
279     repaint();
280     if (getParent() == null)
281     {
282       addKeyListener(rc);
283       Desktop.addInternalFrame(this, MessageManager
284               .getString("label.principal_component_analysis"), 475, 450);
285     }
286   }
287
288   @Override
289   protected void nuclSetting_actionPerfomed(ActionEvent arg0)
290   {
291     if (!pcaModel.isNucleotide())
292     {
293       pcaModel.setNucleotide(true);
294       pcaModel.setScoreModel(ScoreModels.getInstance().getDefaultModel(
295               false));
296       Thread worker = new Thread(this);
297       worker.start();
298     }
299
300   }
301
302   @Override
303   protected void protSetting_actionPerfomed(ActionEvent arg0)
304   {
305
306     if (pcaModel.isNucleotide())
307     {
308       pcaModel.setNucleotide(false);
309       pcaModel.setScoreModel(ScoreModels.getInstance()
310               .getDefaultModel(true));
311       Thread worker = new Thread(this);
312       worker.start();
313     }
314   }
315
316   @Override
317   protected void jvVersionSetting_actionPerfomed(ActionEvent arg0)
318   {
319     pcaModel.setJvCalcMode(jvVersionSetting.isSelected());
320     Thread worker = new Thread(this);
321     worker.start();
322   }
323
324   /**
325    * DOCUMENT ME!
326    */
327   void doDimensionChange()
328   {
329     if (top == 0)
330     {
331       return;
332     }
333
334     int dim1 = top - xCombobox.getSelectedIndex();
335     int dim2 = top - yCombobox.getSelectedIndex();
336     int dim3 = top - zCombobox.getSelectedIndex();
337     pcaModel.updateRcView(dim1, dim2, dim3);
338     rc.img = null;
339     rc.rotmat.setIdentity();
340     rc.initAxes();
341     rc.paint(rc.getGraphics());
342   }
343
344   /**
345    * DOCUMENT ME!
346    * 
347    * @param e
348    *          DOCUMENT ME!
349    */
350   @Override
351   protected void xCombobox_actionPerformed(ActionEvent e)
352   {
353     doDimensionChange();
354   }
355
356   /**
357    * DOCUMENT ME!
358    * 
359    * @param e
360    *          DOCUMENT ME!
361    */
362   @Override
363   protected void yCombobox_actionPerformed(ActionEvent e)
364   {
365     doDimensionChange();
366   }
367
368   /**
369    * DOCUMENT ME!
370    * 
371    * @param e
372    *          DOCUMENT ME!
373    */
374   @Override
375   protected void zCombobox_actionPerformed(ActionEvent e)
376   {
377     doDimensionChange();
378   }
379
380   @Override
381   public void outputValues_actionPerformed(ActionEvent e)
382   {
383     CutAndPasteTransfer cap = new CutAndPasteTransfer();
384     try
385     {
386       cap.setText(pcaModel.getDetails());
387       Desktop.addInternalFrame(cap,
388               MessageManager.getString("label.pca_details"), 500, 500);
389     } catch (OutOfMemoryError oom)
390     {
391       new OOMWarning("opening PCA details", oom);
392       cap.dispose();
393     }
394   }
395
396   @Override
397   public void showLabels_actionPerformed(ActionEvent e)
398   {
399     rc.showLabels(showLabels.getState());
400   }
401
402   @Override
403   public void print_actionPerformed(ActionEvent e)
404   {
405     PCAPrinter printer = new PCAPrinter();
406     printer.start();
407   }
408
409   @Override
410   public void originalSeqData_actionPerformed(ActionEvent e)
411   {
412     // this was cut'n'pasted from the equivalent TreePanel method - we should
413     // make this an abstract function of all jalview analysis windows
414     if (pcaModel.getSeqtrings() == null)
415     {
416       jalview.bin.Cache.log
417               .info("Unexpected call to originalSeqData_actionPerformed - should have hidden this menu action.");
418       return;
419     }
420     // decide if av alignment is sufficiently different to original data to
421     // warrant a new window to be created
422     // create new alignmnt window with hidden regions (unhiding hidden regions
423     // yields unaligned seqs)
424     // or create a selection box around columns in alignment view
425     // test Alignment(SeqCigar[])
426     char gc = '-';
427     try
428     {
429       // we try to get the associated view's gap character
430       // but this may fail if the view was closed...
431       gc = av.getGapCharacter();
432     } catch (Exception ex)
433     {
434     }
435     ;
436     Object[] alAndColsel = pcaModel.getSeqtrings()
437             .getAlignmentAndColumnSelection(gc);
438
439     if (alAndColsel != null && alAndColsel[0] != null)
440     {
441       // AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);
442
443       AlignmentI al = new Alignment((SequenceI[]) alAndColsel[0]);
444       AlignmentI dataset = (av != null && av.getAlignment() != null) ? av
445               .getAlignment().getDataset() : null;
446       if (dataset != null)
447       {
448         al.setDataset(dataset);
449       }
450
451       if (true)
452       {
453         // make a new frame!
454         AlignFrame af = new AlignFrame(al,
455                 (ColumnSelection) alAndColsel[1], AlignFrame.DEFAULT_WIDTH,
456                 AlignFrame.DEFAULT_HEIGHT);
457
458         // >>>This is a fix for the moment, until a better solution is
459         // found!!<<<
460         // af.getFeatureRenderer().transferSettings(alignFrame.getFeatureRenderer());
461
462         // af.addSortByOrderMenuItem(ServiceName + " Ordering",
463         // msaorder);
464
465         Desktop.addInternalFrame(af, MessageManager.formatMessage(
466                 "label.original_data_for_params",
467                 new String[] { this.title }), AlignFrame.DEFAULT_WIDTH,
468                 AlignFrame.DEFAULT_HEIGHT);
469       }
470     }
471     /*
472      * CutAndPasteTransfer cap = new CutAndPasteTransfer(); for (int i = 0; i <
473      * seqs.length; i++) { cap.appendText(new jalview.util.Format("%-" + 15 +
474      * "s").form( seqs[i].getName())); cap.appendText(" " + seqstrings[i] +
475      * "\n"); }
476      * 
477      * Desktop.addInternalFrame(cap, "Original Data", 400, 400);
478      */
479   }
480
481   class PCAPrinter extends Thread implements Printable
482   {
483     @Override
484     public void run()
485     {
486       PrinterJob printJob = PrinterJob.getPrinterJob();
487       PageFormat pf = printJob.pageDialog(printJob.defaultPage());
488
489       printJob.setPrintable(this, pf);
490
491       if (printJob.printDialog())
492       {
493         try
494         {
495           printJob.print();
496         } catch (Exception PrintException)
497         {
498           PrintException.printStackTrace();
499         }
500       }
501     }
502
503     @Override
504     public int print(Graphics pg, PageFormat pf, int pi)
505             throws PrinterException
506     {
507       pg.translate((int) pf.getImageableX(), (int) pf.getImageableY());
508
509       rc.drawBackground(pg, rc.bgColour);
510       rc.drawScene(pg);
511       if (rc.drawAxes == true)
512       {
513         rc.drawAxes(pg);
514       }
515
516       if (pi == 0)
517       {
518         return Printable.PAGE_EXISTS;
519       }
520       else
521       {
522         return Printable.NO_SUCH_PAGE;
523       }
524     }
525   }
526
527   /**
528    * DOCUMENT ME!
529    * 
530    * @param e
531    *          DOCUMENT ME!
532    */
533   @Override
534   public void eps_actionPerformed(ActionEvent e)
535   {
536     makePCAImage(jalview.util.ImageMaker.TYPE.EPS);
537   }
538
539   /**
540    * DOCUMENT ME!
541    * 
542    * @param e
543    *          DOCUMENT ME!
544    */
545   @Override
546   public void png_actionPerformed(ActionEvent e)
547   {
548     makePCAImage(jalview.util.ImageMaker.TYPE.PNG);
549   }
550
551   void makePCAImage(jalview.util.ImageMaker.TYPE type)
552   {
553     int width = rc.getWidth();
554     int height = rc.getHeight();
555
556     jalview.util.ImageMaker im;
557
558     if (type == jalview.util.ImageMaker.TYPE.PNG)
559     {
560       im = new jalview.util.ImageMaker(this,
561               jalview.util.ImageMaker.TYPE.PNG, "Make PNG image from PCA",
562               width, height, null, null, null, 0, false);
563     }
564     else if (type == jalview.util.ImageMaker.TYPE.EPS)
565     {
566       im = new jalview.util.ImageMaker(this,
567               jalview.util.ImageMaker.TYPE.EPS, "Make EPS file from PCA",
568               width, height, null, this.getTitle(), null, 0, false);
569     }
570     else
571     {
572       im = new jalview.util.ImageMaker(this,
573               jalview.util.ImageMaker.TYPE.SVG, "Make SVG file from PCA",
574               width, height, null, this.getTitle(), null, 0, false);
575
576     }
577
578     if (im.getGraphics() != null)
579     {
580       rc.drawBackground(im.getGraphics(), Color.black);
581       rc.drawScene(im.getGraphics());
582       if (rc.drawAxes == true)
583       {
584         rc.drawAxes(im.getGraphics());
585       }
586       im.writeImage();
587     }
588   }
589
590   @Override
591   public void viewMenu_menuSelected()
592   {
593     buildAssociatedViewMenu();
594   }
595
596   void buildAssociatedViewMenu()
597   {
598     AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(av
599             .getSequenceSetId());
600     if (aps.length == 1 && rc.av == aps[0].av)
601     {
602       associateViewsMenu.setVisible(false);
603       return;
604     }
605
606     associateViewsMenu.setVisible(true);
607
608     if ((viewMenu.getItem(viewMenu.getItemCount() - 2) instanceof JMenuItem))
609     {
610       viewMenu.insertSeparator(viewMenu.getItemCount() - 1);
611     }
612
613     associateViewsMenu.removeAll();
614
615     JRadioButtonMenuItem item;
616     ButtonGroup buttonGroup = new ButtonGroup();
617     int i, iSize = aps.length;
618     final PCAPanel thisPCAPanel = this;
619     for (i = 0; i < iSize; i++)
620     {
621       final AlignmentPanel ap = aps[i];
622       item = new JRadioButtonMenuItem(ap.av.viewName, ap.av == rc.av);
623       buttonGroup.add(item);
624       item.addActionListener(new ActionListener()
625       {
626         @Override
627         public void actionPerformed(ActionEvent evt)
628         {
629           rc.applyToAllViews = false;
630           rc.av = ap.av;
631           rc.ap = ap;
632           PaintRefresher.Register(thisPCAPanel, ap.av.getSequenceSetId());
633         }
634       });
635
636       associateViewsMenu.add(item);
637     }
638
639     final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem("All Views");
640
641     buttonGroup.add(itemf);
642
643     itemf.setSelected(rc.applyToAllViews);
644     itemf.addActionListener(new ActionListener()
645     {
646       @Override
647       public void actionPerformed(ActionEvent evt)
648       {
649         rc.applyToAllViews = itemf.isSelected();
650       }
651     });
652     associateViewsMenu.add(itemf);
653
654   }
655
656   /*
657    * (non-Javadoc)
658    * 
659    * @see
660    * jalview.jbgui.GPCAPanel#outputPoints_actionPerformed(java.awt.event.ActionEvent
661    * )
662    */
663   @Override
664   protected void outputPoints_actionPerformed(ActionEvent e)
665   {
666     CutAndPasteTransfer cap = new CutAndPasteTransfer();
667     try
668     {
669       cap.setText(pcaModel.getPointsasCsv(false,
670               xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(),
671               zCombobox.getSelectedIndex()));
672       Desktop.addInternalFrame(cap, MessageManager.formatMessage(
673               "label.points_for_params", new String[] { this.getTitle() }),
674               500, 500);
675     } catch (OutOfMemoryError oom)
676     {
677       new OOMWarning("exporting PCA points", oom);
678       cap.dispose();
679     }
680   }
681
682   /*
683    * (non-Javadoc)
684    * 
685    * @see
686    * jalview.jbgui.GPCAPanel#outputProjPoints_actionPerformed(java.awt.event
687    * .ActionEvent)
688    */
689   @Override
690   protected void outputProjPoints_actionPerformed(ActionEvent e)
691   {
692     CutAndPasteTransfer cap = new CutAndPasteTransfer();
693     try
694     {
695       cap.setText(pcaModel.getPointsasCsv(true,
696               xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(),
697               zCombobox.getSelectedIndex()));
698       Desktop.addInternalFrame(cap, MessageManager.formatMessage(
699               "label.transformed_points_for_params",
700               new String[] { this.getTitle() }), 500, 500);
701     } catch (OutOfMemoryError oom)
702     {
703       new OOMWarning("exporting transformed PCA points", oom);
704       cap.dispose();
705     }
706   }
707
708   /*
709    * (non-Javadoc)
710    * 
711    * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
712    */
713   @Override
714   public void setProgressBar(String message, long id)
715   {
716     progressBar.setProgressBar(message, id);
717     // if (progressBars == null)
718     // {
719     // progressBars = new Hashtable();
720     // progressBarHandlers = new Hashtable();
721     // }
722     //
723     // JPanel progressPanel;
724     // Long lId = new Long(id);
725     // GridLayout layout = (GridLayout) statusPanel.getLayout();
726     // if (progressBars.get(lId) != null)
727     // {
728     // progressPanel = (JPanel) progressBars.get(new Long(id));
729     // statusPanel.remove(progressPanel);
730     // progressBars.remove(lId);
731     // progressPanel = null;
732     // if (message != null)
733     // {
734     // statusBar.setText(message);
735     // }
736     // if (progressBarHandlers.contains(lId))
737     // {
738     // progressBarHandlers.remove(lId);
739     // }
740     // layout.setRows(layout.getRows() - 1);
741     // }
742     // else
743     // {
744     // progressPanel = new JPanel(new BorderLayout(10, 5));
745     //
746     // JProgressBar progressBar = new JProgressBar();
747     // progressBar.setIndeterminate(true);
748     //
749     // progressPanel.add(new JLabel(message), BorderLayout.WEST);
750     // progressPanel.add(progressBar, BorderLayout.CENTER);
751     //
752     // layout.setRows(layout.getRows() + 1);
753     // statusPanel.add(progressPanel);
754     //
755     // progressBars.put(lId, progressPanel);
756     // }
757     // // update GUI
758     // // setMenusForViewport();
759     // validate();
760   }
761
762   @Override
763   public void registerHandler(final long id,
764           final IProgressIndicatorHandler handler)
765   {
766     progressBar.registerHandler(id, handler);
767     // if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
768     // {
769     // throw new
770     // Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
771     // }
772     // progressBarHandlers.put(new Long(id), handler);
773     // final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
774     // if (handler.canCancel())
775     // {
776     // JButton cancel = new JButton(
777     // MessageManager.getString("action.cancel"));
778     // final IProgressIndicator us = this;
779     // cancel.addActionListener(new ActionListener()
780     // {
781     //
782     // @Override
783     // public void actionPerformed(ActionEvent e)
784     // {
785     // handler.cancelActivity(id);
786     // us.setProgressBar(MessageManager.formatMessage("label.cancelled_params",
787     // new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
788     // }
789     // });
790     // progressPanel.add(cancel, BorderLayout.EAST);
791     // }
792   }
793
794   /**
795    * 
796    * @return true if any progress bars are still active
797    */
798   @Override
799   public boolean operationInProgress()
800   {
801     return progressBar.operationInProgress();
802   }
803
804   @Override
805   protected void resetButton_actionPerformed(ActionEvent e)
806   {
807     int t = top;
808     top = 0; // ugly - prevents dimensionChanged events from being processed
809     xCombobox.setSelectedIndex(0);
810     yCombobox.setSelectedIndex(1);
811     top = t;
812     zCombobox.setSelectedIndex(2);
813   }
814
815   /**
816    * If the score model is one that requires to get state data from the current
817    * view, allow it to do so
818    * 
819    * @param sm
820    * @return
821    */
822   protected ScoreModelI configureScoreModel(ScoreModelI sm)
823   {
824     if (sm instanceof ViewBasedAnalysisI)
825     {
826       try
827       {
828         sm = sm.getClass().newInstance();
829         ((ViewBasedAnalysisI) sm).configureFromAlignmentView(ap);
830       } catch (Exception q)
831       {
832         Cache.log.error("Couldn't create a scoremodel instance for "
833                 + sm.getName());
834       }
835     }
836     return sm;
837   }
838 }