Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
PaSiMapPanel | 67 | 247 | 94 | ||
PaSiMapPanel.PaSiMapPrinter | 430 | 18 | 7 |
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.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 GPaSiMapPanel | |
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 | 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 | @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 | 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 | @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 | @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 | @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 | @Override |
234 | public boolean cancelActivity(long id) | |
235 | { | |
236 | 0 | getPasimapModel().cancel(); |
237 | 0 | return true; |
238 | } | |
239 | ||
240 | 0 | @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 | @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 | 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 | @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 | @Override |
343 | protected void showLabels_actionPerformed() | |
344 | { | |
345 | 0 | getRotatableCanvas().showLabels(showLabels.getState()); |
346 | } | |
347 | ||
348 | 0 | @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 | @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 | 0 | Object[] alAndColsel = getPasimapModel().getInputData() |
386 | .getAlignmentView(false).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 | @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 | @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 | 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 | @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 | @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 | 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 | @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 | @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 | @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 | @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 | @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 | public void setProgressBar(String message, long id) |
655 | { | |
656 | 0 | progressBar.setProgressBar(message, id); |
657 | } | |
658 | ||
659 | 0 | public String getMessage(long id) |
660 | { | |
661 | 0 | return progressBar.getMessage(id); |
662 | } | |
663 | ||
664 | 0 | 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 | 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 | 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 | 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 | 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 | public void addProgressListenerFor(Container pap) |
746 | { | |
747 | 0 | pap.addPropertyChangeListener(new PropertyChangeListener() |
748 | { | |
749 | 0 | @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 | @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 | @Override |
788 | public boolean operationInProgress() | |
789 | { | |
790 | 0 | return progressBar.operationInProgress(); |
791 | } | |
792 | ||
793 | 0 | @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 | 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 | 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 | 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 | public void setInputData(AlignmentViewport data) |
847 | { | |
848 | 0 | getPasimapModel().setInputData(data); |
849 | 0 | originalSeqData.setVisible(data != null); |
850 | } | |
851 | ||
852 | 0 | public AlignViewportI getAlignViewport() |
853 | { | |
854 | 0 | return av; |
855 | } | |
856 | ||
857 | 0 | public PaSiMapModel getPasimapModel() |
858 | { | |
859 | 0 | return pasimapModel; |
860 | } | |
861 | ||
862 | 0 | public void setPasimapModel(PaSiMapModel pasimapModel) |
863 | { | |
864 | 0 | this.pasimapModel = pasimapModel; |
865 | } | |
866 | ||
867 | 0 | public RotatableCanvas getRotatableCanvas() |
868 | { | |
869 | 0 | return rc; |
870 | } | |
871 | ||
872 | 0 | public void setRotatableCanvas(RotatableCanvas rc) |
873 | { | |
874 | 0 | this.rc = rc; |
875 | } | |
876 | ||
877 | 0 | public int getTop() |
878 | { | |
879 | 0 | return top; |
880 | } | |
881 | ||
882 | 0 | 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 | 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 | @Override |
905 | public JProgressBar getProgressBar(long id) | |
906 | { | |
907 | 0 | return progressBar.getProgressBar(id); |
908 | } | |
909 | } |