Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 14:43:25 GMT
  2. Package jalview.gui

File PaSiMapPanel.java

 

Coverage histogram

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

Code metrics

68
268
52
2
923
670
103
0.38
5.15
26
1.98

Classes

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