+
+ /**
+ * close the panel - deregisters all listeners and nulls any references to
+ * alignment data.
+ */
+ public void closePanel()
+ {
+ PaintRefresher.RemoveComponent(getSeqPanel().seqCanvas);
+ PaintRefresher.RemoveComponent(getIdPanel().getIdCanvas());
+ PaintRefresher.RemoveComponent(this);
+
+ closeChildFrames();
+
+ /*
+ * try to ensure references are nulled
+ */
+ if (annotationPanel != null)
+ {
+ annotationPanel.dispose();
+ annotationPanel = null;
+ }
+
+ if (av != null)
+ {
+ av.removePropertyChangeListener(propertyChangeListener);
+ propertyChangeListener = null;
+ StructureSelectionManager ssm = av.getStructureSelectionManager();
+ ssm.removeStructureViewerListener(getSeqPanel(), null);
+ ssm.removeSelectionListener(getSeqPanel());
+ ssm.removeCommandListener(av);
+ ssm.removeStructureViewerListener(getSeqPanel(), null);
+ ssm.removeSelectionListener(getSeqPanel());
+ av.dispose();
+ av = null;
+ }
+ else
+ {
+ if (Console.isDebugEnabled())
+ {
+ Console.warn("Closing alignment panel which is already closed.");
+ }
+ }
+ }
+
+ /**
+ * Close any open dialogs that would be orphaned when this one is closed
+ */
+ protected void closeChildFrames()
+ {
+ if (overviewPanel != null)
+ {
+ overviewPanel.dispose();
+ overviewPanel = null;
+ }
+ if (calculationDialog != null)
+ {
+ calculationDialog.closeFrame();
+ calculationDialog = null;
+ }
+ }
+
+ /**
+ * hides or shows dynamic annotation rows based on groups and av state flags
+ */
+ public void updateAnnotation()
+ {
+ updateAnnotation(false, false);
+ }
+
+ public void updateAnnotation(boolean applyGlobalSettings)
+ {
+ updateAnnotation(applyGlobalSettings, false);
+ }
+
+ public void updateAnnotation(boolean applyGlobalSettings,
+ boolean preserveNewGroupSettings)
+ {
+ av.updateGroupAnnotationSettings(applyGlobalSettings,
+ preserveNewGroupSettings);
+ adjustAnnotationHeight();
+ }
+
+ @Override
+ public AlignmentI getAlignment()
+ {
+ return av == null ? null : av.getAlignment();
+ }
+
+ @Override
+ public String getViewName()
+ {
+ return av.getViewName();
+ }
+
+ /**
+ * Make/Unmake this alignment panel the current input focus
+ *
+ * @param b
+ */
+ public void setSelected(boolean b)
+ {
+ try
+ {
+ if (alignFrame.getSplitViewContainer() != null)
+ {
+ /*
+ * bring enclosing SplitFrame to front first if there is one
+ */
+ ((SplitFrame) alignFrame.getSplitViewContainer()).setSelected(b);
+ }
+ alignFrame.setSelected(b);
+ } catch (Exception ex)
+ {
+ }
+ if (b)
+ {
+ setAlignFrameView();
+ }
+ }
+
+ public void setAlignFrameView()
+ {
+ alignFrame.setDisplayedView(this);
+ }
+
+ @Override
+ public StructureSelectionManager getStructureSelectionManager()
+ {
+ return av.getStructureSelectionManager();
+ }
+
+ @Override
+ public void raiseOOMWarning(String string, OutOfMemoryError error)
+ {
+ new OOMWarning(string, error, this);
+ }
+
+ @Override
+ public jalview.api.FeatureRenderer cloneFeatureRenderer()
+ {
+
+ return new FeatureRenderer(this);
+ }
+
+ @Override
+ public jalview.api.FeatureRenderer getFeatureRenderer()
+ {
+ return seqPanel.seqCanvas.getFeatureRenderer();
+ }
+
+ public void updateFeatureRenderer(
+ jalview.renderer.seqfeatures.FeatureRenderer fr)
+ {
+ fr.transferSettings(getSeqPanel().seqCanvas.getFeatureRenderer());
+ }
+
+ public void updateFeatureRendererFrom(jalview.api.FeatureRenderer fr)
+ {
+ if (getSeqPanel().seqCanvas.getFeatureRenderer() != null)
+ {
+ getSeqPanel().seqCanvas.getFeatureRenderer().transferSettings(fr);
+ }
+ }
+
+ public ScalePanel getScalePanel()
+ {
+ return scalePanel;
+ }
+
+ public void setScalePanel(ScalePanel scalePanel)
+ {
+ this.scalePanel = scalePanel;
+ }
+
+ public SeqPanel getSeqPanel()
+ {
+ return seqPanel;
+ }
+
+ public void setSeqPanel(SeqPanel seqPanel)
+ {
+ this.seqPanel = seqPanel;
+ }
+
+ public AnnotationPanel getAnnotationPanel()
+ {
+ return annotationPanel;
+ }
+
+ public void setAnnotationPanel(AnnotationPanel annotationPanel)
+ {
+ this.annotationPanel = annotationPanel;
+ }
+
+ public AnnotationLabels getAlabels()
+ {
+ return alabels;
+ }
+
+ public void setAlabels(AnnotationLabels alabels)
+ {
+ this.alabels = alabels;
+ }
+
+ public IdPanel getIdPanel()
+ {
+ return idPanel;
+ }
+
+ public void setIdPanel(IdPanel idPanel)
+ {
+ this.idPanel = idPanel;
+ }
+
+ /**
+ * Follow a scrolling change in the (cDNA/Protein) complementary alignment.
+ * The aim is to keep the two alignments 'lined up' on their centre columns.
+ *
+ * @param sr
+ * holds mapped region(s) of this alignment that we are scrolling
+ * 'to'; may be modified for sequence offset by this method
+ * @param verticalOffset
+ * the number of visible sequences to show above the mapped region
+ */
+ protected void scrollToCentre(SearchResultsI sr, int verticalOffset)
+ {
+ scrollToPosition(sr, verticalOffset, true);
+ }
+
+ /**
+ * Set a flag to say do not scroll any (cDNA/protein) complement.
+ *
+ * @param b
+ */
+ protected void setToScrollComplementPanel(boolean b)
+ {
+ this.scrollComplementaryPanel = b;
+ }
+
+ /**
+ * Get whether to scroll complement panel
+ *
+ * @return true if cDNA/protein complement panels should be scrolled
+ */
+ protected boolean isSetToScrollComplementPanel()
+ {
+ return this.scrollComplementaryPanel;
+ }
+
+ /**
+ * Redraw sensibly.
+ *
+ * @adjustHeight if true, try to recalculate panel height for visible
+ * annotations
+ */
+ protected void refresh(boolean adjustHeight)
+ {
+ validateAnnotationDimensions(adjustHeight);
+ addNotify();
+ if (adjustHeight)
+ {
+ // sort, repaint, update overview
+ paintAlignment(true, false);
+ }
+ else
+ {
+ // lightweight repaint
+ repaint();
+ }
+ }
+
+ @Override
+ /**
+ * Property change event fired when a change is made to the viewport ranges
+ * object associated with this alignment panel's viewport
+ */
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // update this panel's scroll values based on the new viewport ranges values
+ ViewportRanges ranges = av.getRanges();
+ int x = ranges.getStartRes();
+ int y = ranges.getStartSeq();
+ setScrollValues(x, y);
+
+ // now update any complementary alignment (its viewport ranges object
+ // is different so does not get automatically updated)
+ if (isSetToScrollComplementPanel())
+ {
+ setToScrollComplementPanel(false);
+ av.scrollComplementaryAlignment();
+ setToScrollComplementPanel(true);
+ }
+ }
+
+ /**
+ * Set the reference to the PCA/Tree chooser dialog for this panel. This
+ * reference should be nulled when the dialog is closed.
+ *
+ * @param calculationChooser
+ */
+ public void setCalculationDialog(CalculationChooser calculationChooser)
+ {
+ calculationDialog = calculationChooser;
+ }
+
+ /**
+ * Returns the reference to the PCA/Tree chooser dialog for this panel (null
+ * if none is open)
+ */
+ public CalculationChooser getCalculationDialog()
+ {
+ return calculationDialog;
+ }
+
+ /**
+ * Constructs and sets the title for the Overview window (if there is one),
+ * including the align frame's title, and view name (if applicable). Returns
+ * the title, or null if this panel has no Overview window open.
+ *
+ * @param alignFrame
+ * @return
+ */
+ public String setOverviewTitle(AlignFrame alignFrame)
+ {
+ if (this.overviewPanel == null)
+ {
+ return null;
+ }
+ String overviewTitle = MessageManager
+ .formatMessage("label.overview_params", new Object[]
+ { alignFrame.getTitle() });
+ String viewName = getViewName();
+ if (viewName != null)
+ {
+ overviewTitle += (" " + viewName);
+ }
+ overviewPanel.setTitle(overviewTitle);
+ return overviewTitle;
+ }
+
+ /**
+ * If this alignment panel has an Overview panel open, closes it
+ */
+ public void closeOverviewPanel()
+ {
+ if (overviewPanel != null)
+ {
+ overviewPanel.close();
+ overviewPanel = null;
+ }
+ }
+