Clover icon

Coverage Report

  1. Project Clover database Thu Nov 7 2024 17:01:39 GMT
  2. Package jalview.gui

File PaSiMapPanel.java

 

Coverage histogram

../../img/srcFileCovDistChart0.png
0% of files have more coverage

Code metrics

68
265
50
2
909
658
101
0.38
5.3
25
2.02

Classes

Class Line # Actions
PaSiMapPanel 67 247 94
0.00%
PaSiMapPanel.PaSiMapPrinter 430 18 7
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

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.api.AlignViewportI;
25    import jalview.api.analysis.ScoreModelI;
26    import jalview.api.analysis.SimilarityParamsI;
27    import jalview.bin.Console;
28    import jalview.datamodel.Alignment;
29    import jalview.datamodel.AlignmentI;
30    import jalview.datamodel.AlignmentView;
31    import jalview.datamodel.HiddenColumns;
32    import jalview.datamodel.SequenceGroup;
33    import jalview.datamodel.SequenceI;
34    import jalview.gui.ImageExporter.ImageWriterI;
35    import jalview.gui.JalviewColourChooser.ColourChooserListener;
36    import jalview.jbgui.GPCAPanel;
37    import jalview.math.RotatableMatrix.Axis;
38    import jalview.util.ImageMaker;
39    import jalview.util.MessageManager;
40    import jalview.viewmodel.AlignmentViewport;
41    import jalview.viewmodel.PaSiMapModel;
42   
43    import java.awt.BorderLayout;
44    import java.awt.Color;
45    import java.awt.Container;
46    import java.awt.Dimension;
47    import java.awt.Graphics;
48    import java.awt.event.ActionEvent;
49    import java.awt.event.ActionListener;
50    import java.awt.print.PageFormat;
51    import java.awt.print.Printable;
52    import java.awt.print.PrinterException;
53    import java.awt.print.PrinterJob;
54    import java.beans.PropertyChangeEvent;
55    import java.beans.PropertyChangeListener;
56   
57    import javax.swing.ButtonGroup;
58    import javax.swing.JMenuItem;
59    import javax.swing.JProgressBar;
60    import javax.swing.JRadioButtonMenuItem;
61    import javax.swing.event.InternalFrameAdapter;
62    import javax.swing.event.InternalFrameEvent;
63   
64    /**
65    * The panel holding the Pairwise Similarity Map 3-D visualisation
66    */
 
67    public class PaSiMapPanel extends SpatialPanel
68    implements Runnable, IProgressIndicator
69    {
70    private static final int MIN_WIDTH = 470;
71   
72    private static final int MIN_HEIGHT = 250;
73   
74    private static final int MAX_PASIMAP_SEQ = 20000;
75   
76    private final int GAP_OPEN_COST = 100;
77   
78    private final int GAP_EXTEND_COST = 5;
79   
80    private RotatableCanvas rc;
81   
82    AlignmentPanel ap;
83   
84    AlignmentViewport av;
85   
86    private PaSiMapModel pasimapModel;
87   
88    private int top = 0;
89   
90    private IProgressIndicator progressBar;
91   
92    private long progId;
93   
94    private boolean working;
95   
96    private String newPasimapTitle;
97   
98    /**
99    * Constructor given sequence data, a similarity (or distance) score model
100    * name, and score calculation parameters
101    *
102    * @param alignPanel
103    * @param modelName
104    */
 
105  0 toggle public PaSiMapPanel(AlignmentPanel alignPanel, String modelName)
106    {
107  0 super(8); // dim = 8
108  0 this.av = alignPanel.av;
109  0 this.ap = alignPanel;
110  0 boolean nucleotide = av.getAlignment().isNucleotide();
111   
112    // progressBar = new ProgressBar(statusPanel, statusBar);
113   
114  0 addInternalFrameListener(new InternalFrameAdapter()
115    {
 
116  0 toggle @Override
117    public void internalFrameClosed(InternalFrameEvent e)
118    {
119  0 close_actionPerformed();
120    }
121    });
122   
123  0 boolean selected = av.getSelectionGroup() != null
124    && av.getSelectionGroup().getSize() > 0;
125  0 SequenceI[] seqs;
126  0 if (!selected)
127    {
128  0 seqs = av.getAlignment().getSequencesArray();
129    }
130    else
131    {
132  0 seqs = av.getSelectionGroup().getSequencesInOrder(av.getAlignment());
133    }
134   
135  0 ScoreModelI scoreModel = ScoreModels.getInstance()
136    .getScoreModel(modelName, ap);
137  0 setPasimapModel(new PaSiMapModel(av, seqs, nucleotide, scoreModel));
138   
139  0 newPasimapTitle = alignPanel.alignFrame.formCalculationTitle(
140    MessageManager.formatMessage("label.calc_title", "PaSiMap",
141    scoreModel.getName()),
142    selected, ap.alignFrame.getTitle());
143   
144  0 PaintRefresher.Register(this, av.getSequenceSetId());
145   
146  0 setRotatableCanvas(new RotatableCanvas(alignPanel));
147  0 this.getContentPane().add(getRotatableCanvas(), BorderLayout.CENTER);
148   
149  0 addKeyListener(getRotatableCanvas());
150  0 validate();
151    }
152   
153    /**
154    * Ensure references to potentially very large objects (the PaSiMap matrices)
155    * are nulled when the frame is closed
156    */
 
157  0 toggle protected void close_actionPerformed()
158    {
159  0 setPasimapModel(null);
160  0 if (this.rc != null)
161    {
162  0 this.rc.sequencePoints = null;
163  0 this.rc.setAxisEndPoints(null);
164  0 this.rc = null;
165    }
166    }
167   
 
168  0 toggle @Override
169    protected void bgcolour_actionPerformed()
170    {
171  0 String ttl = MessageManager.getString("label.select_background_colour");
172  0 ColourChooserListener listener = new ColourChooserListener()
173    {
 
174  0 toggle @Override
175    public void colourSelected(Color c)
176    {
177  0 rc.setBgColour(c);
178  0 rc.repaint();
179    }
180    };
181  0 JalviewColourChooser.showColourChooser(this, ttl, rc.getBgColour(),
182    listener);
183    }
184   
185    /**
186    * Calculates the PaSiMap and displays the results
187    */
 
188  0 toggle @Override
189    public void run()
190    {
191  0 working = true;
192  0 progId = System.currentTimeMillis();
193  0 progressBar = new jalview.gui.ProgressBar(statusPanel, statusBar);
194  0 String message = MessageManager
195    .getString("label.pasimap_recalculating");
196  0 if (getParent() == null)
197    {
198  0 progressBar = ap.alignFrame;
199  0 message = MessageManager.getString("label.pasimap_calculating");
200    }
201  0 progressBar.setProgressBar(message, progId);
202  0 try
203    {
204  0 SequenceGroup selGroup = av.getSelectionGroup();
205   
206  0 if (selGroup == null)
207    {
208  0 selGroup = new SequenceGroup(av.getAlignment().getSequences());
209  0 selGroup.setStartRes(0);
210  0 selGroup.setEndRes(av.getAlignment().getWidth() - 1);
211    }
212   
213  0 if (selGroup.getSize() > MAX_PASIMAP_SEQ)
214    {
215  0 int start = selGroup.getStartRes(), end = selGroup.getEndRes();
216  0 selGroup = new SequenceGroup(
217    selGroup.getSequences().subList(0, MAX_PASIMAP_SEQ));
218  0 selGroup.setStartRes(start);
219  0 selGroup.setEndRes(end);
220  0 Console.warn("Truncated input sequences for PASIMAP analysis to "
221    + MAX_PASIMAP_SEQ);
222    }
223   
224  0 final PairwiseAlignPanel pap = new PairwiseAlignPanel(av, selGroup, true,
225    GAP_OPEN_COST, GAP_EXTEND_COST, false, null);
226  0 pap.setDiscardAlignments(true);
227  0 pap.setQuiet(true);
228   
229  0 System.out.println(pap != null);
230  0 addProgressListenerFor(pap);
231  0 progressBar.registerHandler(progId, new IProgressIndicatorHandler()
232    {
 
233  0 toggle @Override
234    public boolean cancelActivity(long id)
235    {
236  0 getPasimapModel().cancel();
237  0 return true;
238    }
239   
 
240  0 toggle @Override
241    public boolean canCancel()
242    {
243  0 return getPasimapModel().canCancel();
244    }
245    });
246  0 getPasimapModel().calculate(pap);
247  0 if (!getPasimapModel().isCancelled())
248    {
249    // TODO: fix outputAlignment so it uses the compact form if no text report is available
250  0 outputAlignment.setVisible(!pap.isDiscardAlignments() && !pap.isQuiet());
251  0 xCombobox.setSelectedIndex(0);
252  0 yCombobox.setSelectedIndex(1);
253  0 zCombobox.setSelectedIndex(2);
254   
255  0 getPasimapModel().updateRc(getRotatableCanvas());
256    // rc.invalidate();
257  0 setTop(getPasimapModel().getTop());
258    }
259    } catch (OutOfMemoryError er)
260    {
261  0 new OOMWarning("calculating PaSiMap", er);
262  0 working = false;
263  0 return;
264    } finally
265    {
266  0 if (!getPasimapModel().isCancelled()) {
267    // finish up the progress bar if we weren't cancelled.
268  0 progressBar.setProgressBar("", progId);
269    }
270    }
271   
272  0 repaint();
273  0 if (!getPasimapModel().isCancelled() && getParent() == null)
274    {
275  0 Desktop.addInternalFrame(this,
276    newPasimapTitle,
277    475, 450);
278  0 this.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
279    }
280  0 working = false;
281    }
282   
283    /**
284    * Updates the PaSiMap display after a change of component to use for x, y or
285    * z axis
286    */
 
287  0 toggle @Override
288    protected void doDimensionChange()
289    {
290  0 if (getTop() == 0)
291    {
292  0 return;
293    }
294   
295  0 int dim1 = getTop() - xCombobox.getSelectedIndex();
296  0 int dim2 = getTop() - yCombobox.getSelectedIndex();
297  0 int dim3 = getTop() - zCombobox.getSelectedIndex();
298  0 getPasimapModel().updateRcView(dim1, dim2, dim3);
299  0 getRotatableCanvas().resetView();
300    }
301   
302    /**
303    * Sets the selected checkbox item index for PaSiMap dimension (1, 2, 3...)
304    * for the given axis (X/Y/Z)
305    *
306    * @param index
307    * @param axis
308    */
 
309  0 toggle public void setSelectedDimensionIndex(int index, Axis axis)
310    {
311  0 switch (axis)
312    {
313  0 case X:
314  0 xCombobox.setSelectedIndex(index);
315  0 break;
316  0 case Y:
317  0 yCombobox.setSelectedIndex(index);
318  0 break;
319  0 case Z:
320  0 zCombobox.setSelectedIndex(index);
321  0 break;
322  0 default:
323    }
324    }
325   
 
326  0 toggle @Override
327    protected void outputValues_actionPerformed()
328    {
329  0 CutAndPasteTransfer cap = new CutAndPasteTransfer();
330  0 try
331    {
332  0 cap.setText(getPasimapModel().getDetails());
333  0 Desktop.addInternalFrame(cap,
334    MessageManager.getString("label.pasimap_details"), 500, 500);
335    } catch (OutOfMemoryError oom)
336    {
337  0 new OOMWarning("opening PaSiMap details", oom);
338  0 cap.dispose();
339    }
340    }
341   
 
342  0 toggle @Override
343    protected void showLabels_actionPerformed()
344    {
345  0 getRotatableCanvas().showLabels(showLabels.getState());
346    }
347   
 
348  0 toggle @Override
349    protected void print_actionPerformed()
350    {
351  0 PaSiMapPrinter printer = new PaSiMapPrinter();
352  0 printer.start();
353    }
354   
355    /**
356    * If available, shows the data which formed the inputs for the PaSiMap as a
357    * new alignment
358    */
 
359  0 toggle @Override
360    public void originalSeqData_actionPerformed()
361    {
362    // JAL-2647 disabled after load from project (until save to project done)
363  0 if (getPasimapModel().getInputData() == null)
364    {
365  0 Console.info(
366    "Unexpected call to originalSeqData_actionPerformed - should have hidden this menu action.");
367  0 return;
368    }
369    // decide if av alignment is sufficiently different to original data to
370    // warrant a new window to be created
371    // create new alignment window with hidden regions (unhiding hidden regions
372    // yields unaligned seqs)
373    // or create a selection box around columns in alignment view
374    // test Alignment(SeqCigar[])
375  0 char gc = '-';
376  0 try
377    {
378    // we try to get the associated view's gap character
379    // but this may fail if the view was closed...
380  0 gc = av.getGapCharacter();
381    } catch (Exception ex)
382    {
383    }
384   
385    // TODO - this possibly now does compeltely the wrong thing - returns the alignment view for the model, which may be spurious
386  0 Object[] alAndColsel = getPasimapModel().getInputData().getAlignmentAndHiddenColumns(gc);
387   
388  0 if (alAndColsel != null && alAndColsel[0] != null)
389    {
390    // AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);
391   
392  0 AlignmentI al = new Alignment((SequenceI[]) alAndColsel[0]);
393  0 AlignmentI dataset = (av != null && av.getAlignment() != null)
394    ? av.getAlignment().getDataset()
395    : null;
396  0 if (dataset != null)
397    {
398  0 al.setDataset(dataset);
399    }
400   
401  0 if (true)
402    {
403    // make a new frame!
404  0 AlignFrame af = new AlignFrame(al, (HiddenColumns) alAndColsel[1],
405    AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
406   
407    // >>>This is a fix for the moment, until a better solution is
408    // found!!<<<
409    // af.getFeatureRenderer().transferSettings(alignFrame.getFeatureRenderer());
410   
411    // af.addSortByOrderMenuItem(ServiceName + " Ordering",
412    // msaorder);
413   
414  0 Desktop.addInternalFrame(af, MessageManager.formatMessage(
415    "label.original_data_for_params", new String[]
416    { this.title }), AlignFrame.DEFAULT_WIDTH,
417    AlignFrame.DEFAULT_HEIGHT);
418    }
419    }
420    /*
421    * CutAndPasteTransfer cap = new CutAndPasteTransfer(); for (int i = 0; i <
422    * seqs.length; i++) { cap.appendText(new jalview.util.Format("%-" + 15 +
423    * "s").form( seqs[i].getName())); cap.appendText(" " + seqstrings[i] +
424    * "\n"); }
425    *
426    * Desktop.addInternalFrame(cap, "Original Data", 400, 400);
427    */
428    }
429   
 
430    class PaSiMapPrinter extends Thread implements Printable
431    {
 
432  0 toggle @Override
433    public void run()
434    {
435  0 PrinterJob printJob = PrinterJob.getPrinterJob();
436  0 PageFormat defaultPage = printJob.defaultPage();
437  0 PageFormat pf = printJob.pageDialog(defaultPage);
438   
439  0 if (defaultPage == pf)
440    {
441    /*
442    * user cancelled
443    */
444  0 return;
445    }
446   
447  0 printJob.setPrintable(this, pf);
448   
449  0 if (printJob.printDialog())
450    {
451  0 try
452    {
453  0 printJob.print();
454    } catch (Exception PrintException)
455    {
456  0 PrintException.printStackTrace();
457    }
458    }
459    }
460   
 
461  0 toggle @Override
462    public int print(Graphics pg, PageFormat pf, int pi)
463    throws PrinterException
464    {
465  0 pg.translate((int) pf.getImageableX(), (int) pf.getImageableY());
466   
467  0 getRotatableCanvas().drawBackground(pg);
468  0 getRotatableCanvas().drawScene(pg);
469  0 if (getRotatableCanvas().drawAxes)
470    {
471  0 getRotatableCanvas().drawAxes(pg);
472    }
473   
474  0 if (pi == 0)
475    {
476  0 return Printable.PAGE_EXISTS;
477    }
478    else
479    {
480  0 return Printable.NO_SUCH_PAGE;
481    }
482    }
483    }
484   
 
485  0 toggle public void makePaSiMapImage(ImageMaker.TYPE type) throws Exception
486    {
487  0 int width = getRotatableCanvas().getWidth();
488  0 int height = getRotatableCanvas().getHeight();
489  0 ImageWriterI writer = new ImageWriterI()
490    {
 
491  0 toggle @Override
492    public void exportImage(Graphics g) throws Exception
493    {
494  0 RotatableCanvas canvas = getRotatableCanvas();
495  0 canvas.drawBackground(g);
496  0 canvas.drawScene(g);
497  0 if (canvas.drawAxes)
498    {
499  0 canvas.drawAxes(g);
500    }
501    }
502    };
503  0 String pasimap = MessageManager.getString("label.pasimap");
504  0 ImageExporter exporter = new ImageExporter(writer, null, type, pasimap);
505  0 exporter.doExport(null, this, width, height, pasimap);
506    }
507   
 
508  0 toggle @Override
509    protected void viewMenu_menuSelected()
510    {
511  0 buildAssociatedViewMenu();
512    }
513   
514    /**
515    * Builds the menu showing the choice of possible views (for the associated
516    * sequence data) to which the PaSiMap may be linked
517    */
 
518  0 toggle void buildAssociatedViewMenu()
519    {
520  0 AlignmentPanel[] aps = PaintRefresher
521    .getAssociatedPanels(av.getSequenceSetId());
522  0 if (aps.length == 1 && getRotatableCanvas().av == aps[0].av)
523    {
524  0 associateViewsMenu.setVisible(false);
525  0 return;
526    }
527   
528  0 associateViewsMenu.setVisible(true);
529   
530  0 if ((viewMenu
531    .getItem(viewMenu.getItemCount() - 2) instanceof JMenuItem))
532    {
533  0 viewMenu.insertSeparator(viewMenu.getItemCount() - 1);
534    }
535   
536  0 associateViewsMenu.removeAll();
537   
538  0 JRadioButtonMenuItem item;
539  0 ButtonGroup buttonGroup = new ButtonGroup();
540  0 int iSize = aps.length;
541   
542  0 for (int i = 0; i < iSize; i++)
543    {
544  0 final AlignmentPanel panel = aps[i];
545  0 item = new JRadioButtonMenuItem(panel.av.getViewName(),
546    panel.av == getRotatableCanvas().av);
547  0 buttonGroup.add(item);
548  0 item.addActionListener(new ActionListener()
549    {
 
550  0 toggle @Override
551    public void actionPerformed(ActionEvent evt)
552    {
553  0 selectAssociatedView(panel);
554    }
555    });
556   
557  0 associateViewsMenu.add(item);
558    }
559   
560  0 final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem(
561    "All Views");
562   
563  0 buttonGroup.add(itemf);
564   
565  0 itemf.setSelected(getRotatableCanvas().isApplyToAllViews());
566  0 itemf.addActionListener(new ActionListener()
567    {
 
568  0 toggle @Override
569    public void actionPerformed(ActionEvent evt)
570    {
571  0 getRotatableCanvas().setApplyToAllViews(itemf.isSelected());
572    }
573    });
574  0 associateViewsMenu.add(itemf);
575   
576    }
577   
578    /*
579    * (non-Javadoc)
580    *
581    * @see
582    * jalview.jbgui.GPaSiMapPanel#outputPoints_actionPerformed(java.awt.event.ActionEvent
583    * )
584    */
 
585  0 toggle @Override
586    protected void outputPoints_actionPerformed()
587    {
588  0 CutAndPasteTransfer cap = new CutAndPasteTransfer();
589  0 try
590    {
591  0 cap.setText(getPasimapModel().getPointsasCsv(false,
592    xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(),
593    zCombobox.getSelectedIndex()));
594  0 Desktop.addInternalFrame(cap, MessageManager
595    .formatMessage("label.points_for_params", new String[]
596    { this.getTitle() }), 500, 500);
597    } catch (OutOfMemoryError oom)
598    {
599  0 new OOMWarning("exporting PaSiMap points", oom);
600  0 cap.dispose();
601    }
602    }
603   
604    /*
605    * (non-Javadoc)
606    *
607    * @see
608    * jalview.jbgui.GPaSiMapPanel#outputProjPoints_actionPerformed(java.awt.event
609    * .ActionEvent)
610    */
 
611  0 toggle @Override
612    protected void outputProjPoints_actionPerformed()
613    {
614  0 CutAndPasteTransfer cap = new CutAndPasteTransfer();
615  0 try
616    {
617  0 cap.setText(getPasimapModel().getPointsasCsv(true,
618    xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(),
619    zCombobox.getSelectedIndex()));
620  0 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
621    "label.transformed_points_for_params", new String[]
622    { this.getTitle() }), 500, 500);
623    } catch (OutOfMemoryError oom)
624    {
625  0 new OOMWarning("exporting transformed PaSiMap points", oom);
626  0 cap.dispose();
627    }
628    }
629   
630    /*
631    * (non-Javadoc)
632    *
633    * @see
634    * jalview.jbgui.GPaSiMapPanel#outputAlignment_actionPerformed(java.awt.event
635    * .ActionEvent)
636    */
 
637  0 toggle @Override
638    protected void outputAlignment_actionPerformed()
639    {
640  0 CutAndPasteTransfer cap = new CutAndPasteTransfer();
641  0 try
642    {
643  0 cap.setText(getPasimapModel().getAlignmentOutput());
644  0 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
645    "label.pairwise_alignment_for_params", new String[]
646    { this.getTitle() }), 500, 500);
647    } catch (OutOfMemoryError oom)
648    {
649  0 new OOMWarning("exporting pairwise alignments", oom);
650  0 cap.dispose();
651    }
652    }
653   
 
654  0 toggle public void setProgressBar(String message, long id)
655    {
656  0 progressBar.setProgressBar(message, id);
657    }
658   
 
659  0 toggle public String getMessage(long id)
660    {
661  0 return progressBar.getMessage(id);
662    }
663   
 
664  0 toggle public void setProgressBarMessage(long id, String message)
665    {
666  0 progressBar.setProgressBarMessage(id, message);
667    }
668   
669    /*
670    * make the progressBar determinate and update its progress
671    * or indeterminate if progress<-1 or lengthOfTask < 0
672    */
 
673  0 toggle public void updateProgressBar(int lengthOfTask, int progress)
674    {
675  0 JProgressBar pBar = progressBar.getProgressBar(progId);
676  0 if (pBar == null)
677    {
678  0 return;
679    }
680  0 if (pBar.isIndeterminate())
681    {
682  0 pBar.setMaximum(lengthOfTask);
683  0 pBar.setValue(0);
684  0 pBar.setIndeterminate(false);
685    }
686   
687  0 if (progress<-1 || lengthOfTask<=0)
688    {
689  0 pBar.setIndeterminate(true);
690  0 pBar.repaint();
691  0 return;
692    }
693  0 updateProgressBar(progress);
694    }
695   
 
696  0 toggle public void updateProgressBarWithEta(int progress, double minutes)
697    {
698  0 JProgressBar pBar = progressBar.getProgressBar(progId);
699   
700  0 if (pBar == null)
701    {
702  0 return;
703    }
704  0 int max=pBar.getMaximum();
705  0 updateProgressBarEta(minutes);
706  0 pBar.setMaximum(max);
707  0 pBar.setValue(progress);
708    }
709   
 
710  0 toggle public void updateProgressBarEta(double minutes)
711    {
712  0 JProgressBar pBar = progressBar.getProgressBar(progId);
713   
714  0 if (pBar == null)
715    {
716  0 return;
717    }
718  0 progressBar.setProgressBarMessage(progId,
719    progressBar.getMessage(progId) + " ("
720  0 + (Double.isNaN(minutes) ? " .. working ..)"
721  0 : (minutes < 1.0 ? "Less than a minute)"
722    : ((int) Math.ceil(minutes))
723    + " mins. to go)")));
724    }
725   
 
726  0 toggle public void updateProgressBar(int progress)
727    {
728  0 JProgressBar pBar = progressBar.getProgressBar(progId);
729   
730  0 if (pBar == null)
731    {
732  0 return;
733    }
734   
735  0 pBar.setValue(progress);
736  0 pBar.repaint();
737    }
738   
739    /**
740    * adds a listener for a pairwise alignment panel's progress TODO: generalise
741    * for anything that can report progress ?
742    *
743    * @param pap
744    */
 
745  0 toggle public void addProgressListenerFor(Container pap)
746    {
747  0 pap.addPropertyChangeListener(new PropertyChangeListener()
748    {
 
749  0 toggle @Override
750    public void propertyChange(PropertyChangeEvent pcEvent)
751    {
752  0 if (PairwiseAlignPanel.PROGRESS.equals(pcEvent.getPropertyName()))
753    {
754  0 updateProgressBar((int) pcEvent.getNewValue());
755    }
756  0 else if (PairwiseAlignPanel.TOTAL.equals(pcEvent.getPropertyName()))
757    {
758  0 updateProgressBar((int) pcEvent.getNewValue(), 0);
759    }
760  0 else if (PairwiseAlignPanel.ETA.equals(pcEvent.getPropertyName()))
761    {
762  0 updateProgressBarEta((double) pcEvent.getNewValue());
763    }
764  0 else if (PairwiseAlignPanel.PROGRESSMESSAGE.equals(pcEvent.getPropertyName()))
765    {
766  0 setProgressBarMessage(progId, (String) pcEvent.getNewValue());
767    }
768  0 else if (PairwiseAlignPanel.PROGRESSCOMPLETE.equals(pcEvent.getPropertyName()))
769    {
770  0 setProgressBarMessage(progId, (String) pcEvent.getNewValue());
771    }
772    }
773    });
774    }
775   
 
776  0 toggle @Override
777    public void registerHandler(final long id,
778    final IProgressIndicatorHandler handler)
779    {
780  0 progressBar.registerHandler(id, handler);
781    }
782   
783    /**
784    *
785    * @return true if any progress bars are still active
786    */
 
787  0 toggle @Override
788    public boolean operationInProgress()
789    {
790  0 return progressBar.operationInProgress();
791    }
792   
 
793  0 toggle @Override
794    protected void resetButton_actionPerformed()
795    {
796  0 int t = getTop();
797  0 setTop(0); // ugly - prevents dimensionChanged events from being processed
798  0 xCombobox.setSelectedIndex(0);
799  0 yCombobox.setSelectedIndex(1);
800  0 setTop(t);
801  0 zCombobox.setSelectedIndex(2);
802    }
803   
804    /**
805    * Answers true if PaSiMap calculation is in progress, else false
806    *
807    * @return
808    */
 
809  0 toggle public boolean isWorking()
810    {
811  0 return working;
812    }
813   
814    /**
815    * Answers the selected checkbox item index for PaSiMap dimension for the X, Y
816    * or Z axis of the display
817    *
818    * @param axis
819    * @return
820    */
 
821  0 toggle public int getSelectedDimensionIndex(Axis axis)
822    {
823  0 switch (axis)
824    {
825  0 case X:
826  0 return xCombobox.getSelectedIndex();
827  0 case Y:
828  0 return yCombobox.getSelectedIndex();
829  0 default:
830  0 return zCombobox.getSelectedIndex();
831    }
832    }
833   
 
834  0 toggle public void setShowLabels(boolean show)
835    {
836  0 showLabels.setSelected(show);
837    }
838   
839    /**
840    * Sets the input data used to calculate the PaSiMap. This is provided for
841    * 'restore from project', which does not currently support this (AL-2647), so
842    * sets the value to null, and hides the menu option for "Input Data...". J
843    *
844    * @param data
845    */
 
846  0 toggle public void setInputData(AlignmentViewport data)
847    {
848  0 getPasimapModel().setInputData(data);
849  0 originalSeqData.setVisible(data != null);
850    }
851   
 
852  0 toggle public AlignViewportI getAlignViewport()
853    {
854  0 return av;
855    }
856   
 
857  0 toggle public PaSiMapModel getPasimapModel()
858    {
859  0 return pasimapModel;
860    }
861   
 
862  0 toggle public void setPasimapModel(PaSiMapModel pasimapModel)
863    {
864  0 this.pasimapModel = pasimapModel;
865    }
866   
 
867  0 toggle public RotatableCanvas getRotatableCanvas()
868    {
869  0 return rc;
870    }
871   
 
872  0 toggle public void setRotatableCanvas(RotatableCanvas rc)
873    {
874  0 this.rc = rc;
875    }
876   
 
877  0 toggle public int getTop()
878    {
879  0 return top;
880    }
881   
 
882  0 toggle public void setTop(int top)
883    {
884  0 this.top = top;
885    }
886   
887    /**
888    * set the associated view for this PaSiMap.
889    *
890    * @param panel
891    */
 
892  0 toggle public void selectAssociatedView(AlignmentPanel panel)
893    {
894  0 getRotatableCanvas().setApplyToAllViews(false);
895   
896  0 ap = panel;
897  0 av = panel.av;
898   
899  0 getRotatableCanvas().av = panel.av;
900  0 getRotatableCanvas().ap = panel;
901  0 PaintRefresher.Register(PaSiMapPanel.this, panel.av.getSequenceSetId());
902    }
903   
 
904  0 toggle @Override
905    public JProgressBar getProgressBar(long id)
906    {
907  0 return progressBar.getProgressBar(id);
908    }
909    }