From: Ben Soares Date: Thu, 27 Jul 2023 19:18:50 +0000 (+0100) Subject: Merge branch 'develop' into feature/JAL-244_Automatically_adjust_left_margin_to_avoid... X-Git-Tag: Release_2_11_3_0~8^2~47^2~8 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=078d3939810e3be7d0ed9452df7db6b29e7b8e70;hp=-c;p=jalview.git Merge branch 'develop' into feature/JAL-244_Automatically_adjust_left_margin_to_avoid_cropping_annotation_labels --- 078d3939810e3be7d0ed9452df7db6b29e7b8e70 diff --combined src/jalview/gui/AlignFrame.java index 7f9bfff,49bd4e9..3e24e67 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@@ -157,6 -157,7 +157,6 @@@ import jalview.viewmodel.AlignmentViewp import jalview.viewmodel.ViewportRanges; import jalview.ws.DBRefFetcher; import jalview.ws.DBRefFetcher.FetchFinishedListenerI; -import jalview.ws.datamodel.alphafold.PAEContactMatrix; import jalview.ws.jws1.Discoverer; import jalview.ws.jws2.Jws2Discoverer; import jalview.ws.jws2.jabaws2.Jws2Instance; @@@ -1455,11 -1456,9 +1455,11 @@@ public class AlignFrame extends GAlignF protected void htmlMenuItem_actionPerformed(ActionEvent e) { HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel); - try { + try + { htmlSVG.exportHTML(null); - } catch (ImageOutputException x) { + } catch (ImageOutputException x) + { // report problem to console and raise dialog } } @@@ -1468,64 -1467,51 +1468,64 @@@ public void bioJSMenuItem_actionPerformed(ActionEvent e) { BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel); - try { - bjs.exportHTML(null); - } catch (ImageOutputException x) { - // report problem to console and raise dialog - } + try + { + bjs.exportHTML(null); + } catch (ImageOutputException x) + { + // report problem to console and raise dialog + } } public void createImageMap(File file, String image) { - try { - alignPanel.makePNGImageMap(file, image); - } catch (ImageOutputException x) { + try + { + alignPanel.makePNGImageMap(file, image); + } catch (ImageOutputException x) + { // report problem to console and raise dialog } } @Override - public void createPNG_actionPerformed(ActionEvent e) { - try{ + public void createPNG_actionPerformed(ActionEvent e) + { + try + { createPNG(null); } catch (ImageOutputException ioex) { // raise dialog, and report via console } } + @Override - public void createEPS_actionPerformed(ActionEvent e) { - try{ + public void createEPS_actionPerformed(ActionEvent e) + { + try + { createEPS(null); } catch (ImageOutputException ioex) { // raise dialog, and report via console } - + } + @Override - public void createSVG_actionPerformed(ActionEvent e) { - try{ + public void createSVG_actionPerformed(ActionEvent e) + { + try + { createSVG(null); } catch (ImageOutputException ioex) { // raise dialog, and report via console } - + } + /** * Creates a PNG image of the alignment and writes it to the given file. If * the file is null, the user is prompted to choose a file. @@@ -1537,8 -1523,7 +1537,8 @@@ createPNG(f, null, BitmapImageSizing.nullBitmapImageSizing()); } - public void createPNG(File f, String renderer, BitmapImageSizing userBis) throws ImageOutputException + public void createPNG(File f, String renderer, BitmapImageSizing userBis) + throws ImageOutputException { alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis); } @@@ -1549,7 -1534,7 +1549,7 @@@ * * @param f */ - public void createEPS(File f) throws ImageOutputException + public void createEPS(File f) throws ImageOutputException { createEPS(f, null); } @@@ -1565,7 -1550,7 +1565,7 @@@ * * @param f */ - public void createSVG(File f) throws ImageOutputException + public void createSVG(File f) throws ImageOutputException { createSVG(f, null); } @@@ -2356,14 -2341,12 +2356,14 @@@ // annotation was duplicated earlier alignment.addAnnotation(sequences[i].getAnnotation()[a]); // take care of contact matrix too - ContactMatrixI cm=sequences[i].getContactMatrixFor(sequences[i].getAnnotation()[a]); - if (cm!=null) + ContactMatrixI cm = sequences[i] + .getContactMatrixFor(sequences[i].getAnnotation()[a]); + if (cm != null) { - alignment.addContactListFor(sequences[i].getAnnotation()[a], cm); + alignment.addContactListFor(sequences[i].getAnnotation()[a], + cm); } - + alignment.setAnnotationIndex(sequences[i].getAnnotation()[a], a); } @@@ -3155,15 -3138,10 +3155,15 @@@ @Override public void wrapMenuItem_actionPerformed(ActionEvent e) { - scaleAbove.setVisible(wrapMenuItem.isSelected()); - scaleLeft.setVisible(wrapMenuItem.isSelected()); - scaleRight.setVisible(wrapMenuItem.isSelected()); - viewport.setWrapAlignment(wrapMenuItem.isSelected()); + setWrapFormat(wrapMenuItem.isSelected()); + } + + public void setWrapFormat(boolean b) + { + scaleAbove.setVisible(b); + scaleLeft.setVisible(b); + scaleRight.setVisible(b); + viewport.setWrapAlignment(b); alignPanel.updateLayout(); } @@@ -4261,7 -4239,8 +4261,7 @@@ return tp; } - public void showContactMapTree(AlignmentAnnotation aa, - ContactMatrixI cm) + public void showContactMapTree(AlignmentAnnotation aa, ContactMatrixI cm) { int x = 4, y = 5; int w = 400, h = 500; @@@ -4270,10 -4249,10 +4270,10 @@@ { NewickFile fin = new NewickFile( new FileParse(cm.getNewick(), DataSourceType.PASTE)); - String title = cm.getAnnotLabel() + " " + cm.getTreeMethod() + " tree" - + aa.sequenceRef != null + String title = aa.label + " " + + cm.getTreeMethod() + " tree" + (aa.sequenceRef != null ? (" for " + aa.sequenceRef.getDisplayId(false)) - : ""; + : ""); showColumnWiseTree(fin, aa, title, w, h, x, y); } catch (Throwable xx) @@@ -4293,7 -4272,7 +4293,7 @@@ { return null; } - TreePanel tp = new TreePanel(alignPanel, nf, aa, title); + TreePanel tp = new TreePanel(alignPanel, nf, aa, treeTitle); tp.setSize(w, h); @@@ -4302,7 -4281,7 +4302,7 @@@ tp.setLocation(x, y); } - Desktop.addInternalFrame(tp, title, w, h); + Desktop.addInternalFrame(tp, treeTitle, w, h); return tp; } catch (Throwable xx) { diff --combined src/jalview/gui/AnnotationLabels.java index 241e0a3,28065c3..c4a40d8 --- a/src/jalview/gui/AnnotationLabels.java +++ b/src/jalview/gui/AnnotationLabels.java @@@ -20,7 -20,6 +20,7 @@@ */ package jalview.gui; +import java.awt.Canvas; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; @@@ -51,8 -50,6 +51,8 @@@ import javax.swing.ToolTipManager import jalview.analysis.AlignSeq; import jalview.analysis.AlignmentUtils; +import jalview.bin.Cache; +import jalview.bin.Jalview; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.Annotation; @@@ -116,8 -113,6 +116,8 @@@ public class AnnotationLabels extends J private static final String COPYCONS_SEQ = MessageManager .getString("label.copy_consensus_sequence"); + private static final String ADJUST_ANNOTATION_LABELS_WIDTH_PREF = "ADJUST_ANNOTATION_LABELS_WIDTH"; + private final boolean debugRedraw = false; private AlignmentPanel ap; @@@ -136,8 -131,6 +136,8 @@@ private boolean resizePanel = false; + private int annotationIdWidth = -1; + /** * Creates a new AnnotationLabels object * @@@ -145,6 -138,7 +145,6 @@@ */ public AnnotationLabels(AlignmentPanel ap) { - this.ap = ap; av = ap.av; ToolTipManager.sharedInstance().registerComponent(this); @@@ -424,74 -418,65 +424,74 @@@ pop.add(consclipbrd); } - addColourOrFilterByOptions(ap,aa[selectedRow],pop); - + addColourOrFilterByOptions(ap, aa[selectedRow], pop); + if (aa[selectedRow].graph == AlignmentAnnotation.CONTACT_MAP) { - addContactMatrixOptions(ap,aa[selectedRow],pop); - // Set/adjust threshold for grouping ? - // colour alignment by this [type] - // select/hide columns by this row - - } + addContactMatrixOptions(ap, aa[selectedRow], pop); + // Set/adjust threshold for grouping ? + // colour alignment by this [type] + // select/hide columns by this row + } - + } + pop.show(this, evt.getX(), evt.getY()); } static void addColourOrFilterByOptions(final AlignmentPanel ap, - final AlignmentAnnotation alignmentAnnotation, final JPopupMenu pop) + final AlignmentAnnotation alignmentAnnotation, + final JPopupMenu pop) { JMenuItem item; - item = new JMenuItem(MessageManager.getString("label.colour_by_annotation")); + item = new JMenuItem( + MessageManager.getString("label.colour_by_annotation")); item.addActionListener(new ActionListener() { - + @Override public void actionPerformed(ActionEvent e) { - AnnotationColourChooser.displayFor(ap.av, ap,alignmentAnnotation,false); + AnnotationColourChooser.displayFor(ap.av, ap, alignmentAnnotation, + false); }; }); pop.add(item); - if (alignmentAnnotation.sequenceRef!=null) + if (alignmentAnnotation.sequenceRef != null) { - item = new JMenuItem(MessageManager.getString("label.colour_by_annotation")+" ("+MessageManager.getString("label.per_seq")+")"); + item = new JMenuItem( + MessageManager.getString("label.colour_by_annotation") + " (" + + MessageManager.getString("label.per_seq") + ")"); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - AnnotationColourChooser.displayFor(ap.av, ap,alignmentAnnotation,true); + AnnotationColourChooser.displayFor(ap.av, ap, alignmentAnnotation, + true); }; }); pop.add(item); } - item = new JMenuItem(MessageManager.getString("action.select_by_annotation")); + item = new JMenuItem( + MessageManager.getString("action.select_by_annotation")); item.addActionListener(new ActionListener() { - + @Override public void actionPerformed(ActionEvent e) { - AnnotationColumnChooser.displayFor(ap.av,ap,alignmentAnnotation); + AnnotationColumnChooser.displayFor(ap.av, ap, alignmentAnnotation); }; }); pop.add(item); } + static void addContactMatrixOptions(final AlignmentPanel ap, - final AlignmentAnnotation alignmentAnnotation, final JPopupMenu pop) + final AlignmentAnnotation alignmentAnnotation, + final JPopupMenu pop) { - + final ContactMatrixI cm = ap.av.getContactMatrix(alignmentAnnotation); JMenuItem item; if (cm != null) @@@ -500,13 -485,10 +500,13 @@@ if (cm.hasGroups()) { - JCheckBoxMenuItem chitem = new JCheckBoxMenuItem(MessageManager.getString("action.show_groups_on_matrix")); - chitem.setToolTipText(MessageManager.getString("action.show_groups_on_matrix_tooltip")); - boolean showGroups = alignmentAnnotation.isShowGroupsForContactMatrix(); - final AlignmentAnnotation sel_row=alignmentAnnotation; + JCheckBoxMenuItem chitem = new JCheckBoxMenuItem( + MessageManager.getString("action.show_groups_on_matrix")); + chitem.setToolTipText(MessageManager + .getString("action.show_groups_on_matrix_tooltip")); + boolean showGroups = alignmentAnnotation + .isShowGroupsForContactMatrix(); + final AlignmentAnnotation sel_row = alignmentAnnotation; chitem.setState(showGroups); chitem.addActionListener(new ActionListener() { @@@ -515,18 -497,18 +515,20 @@@ public void actionPerformed(ActionEvent e) { sel_row.setShowGroupsForContactMatrix(chitem.getState()); - ap.getAnnotationPanel() - .paint(ap.getAnnotationPanel().getGraphics()); + // so any annotation colour changes are propagated - though they + // probably won't be unless the annotation row colours are removed + // too! + ap.alignmentChanged(); } }); pop.add(chitem); } if (cm.hasTree()) { - item = new JMenuItem(MessageManager.getString("action.show_tree_for_matrix")); - item.setToolTipText(MessageManager.getString("action.show_tree_for_matrix_tooltip")); + item = new JMenuItem( + MessageManager.getString("action.show_tree_for_matrix")); + item.setToolTipText(MessageManager + .getString("action.show_tree_for_matrix_tooltip")); item.addActionListener(new ActionListener() { @@@ -542,10 -524,8 +544,10 @@@ } else { - item = new JMenuItem(MessageManager.getString("action.cluster_matrix")); - item.setToolTipText(MessageManager.getString("action.cluster_matrix_tooltip")); + item = new JMenuItem( + MessageManager.getString("action.cluster_matrix")); + item.setToolTipText( + MessageManager.getString("action.cluster_matrix_tooltip")); item.addActionListener(new ActionListener() { @Override @@@ -557,12 -537,11 +559,15 @@@ public void run() { final long progBar; - ap.alignFrame.setProgressBar(MessageManager.formatMessage("action.clustering_matrix_for",cm.getAnnotDescr(),5f), progBar = System.currentTimeMillis()); + ap.alignFrame.setProgressBar( + MessageManager.formatMessage( + "action.clustering_matrix_for", + cm.getAnnotDescr(), 5f), + progBar = System.currentTimeMillis()); - cm.setGroupSet(GroupSet.makeGroups(cm, 5f, true)); + cm.setGroupSet(GroupSet.makeGroups(cm, true)); + cm.randomlyReColourGroups(); + cm.transferGroupColorsTo(alignmentAnnotation); + ap.alignmentChanged(); ap.alignFrame.showContactMapTree(alignmentAnnotation, cm); ap.alignFrame.setProgressBar(null, progBar); } @@@ -1192,113 -1171,32 +1197,113 @@@ * @param width * Width for scaling labels */ - public void drawComponent(Graphics g, boolean clip, int width) + public void drawComponent(Graphics g, boolean clip, int givenWidth) { - if (av.getFont().getSize() < 10) + int width = givenWidth; + IdwidthAdjuster iwa = null; + if (ap != null) { - g.setFont(font); + iwa = ap.idwidthAdjuster; + if ((Cache.getDefault(ADJUST_ANNOTATION_LABELS_WIDTH_PREF, true) + || Jalview.isHeadlessMode())) + { + Graphics2D g2d = (Graphics2D) g; + Graphics dummy = g2d.create(); + int newAnnotationIdWidth = drawLabels(dummy, clip, width, false, + null); + dummy.dispose(); + Dimension d = ap.calculateDefaultAlignmentIdWidth(); + int alignmentIdWidth = d.width; + if (iwa != null && !iwa.manuallyAdjusted()) + { + // If no manual adjustment to ID column with has been made then adjust + // width match widest of alignment or annotation id widths + width = Math.max(alignmentIdWidth, newAnnotationIdWidth); + } + else if (newAnnotationIdWidth != annotationIdWidth + && newAnnotationIdWidth > givenWidth + && newAnnotationIdWidth > alignmentIdWidth) + { + // otherwise if the annotation id width has become larger than the + // current id width, increase + width = newAnnotationIdWidth; + annotationIdWidth = newAnnotationIdWidth; + } + // set the width if it's changed + if (width != ap.av.getIdWidth()) + { + iwa.setWidth(width); + } + } } else { - g.setFont(av.getFont()); + Graphics2D g2d = (Graphics2D) g; + Graphics dummy = g2d.create(); + int newAnnotationIdWidth = drawLabels(dummy, clip, width, false, + null); + width = Math.max(newAnnotationIdWidth, givenWidth); } + drawLabels(g, clip, width, true, null); + } - FontMetrics fm = g.getFontMetrics(g.getFont()); - g.setColor(Color.white); - g.fillRect(0, 0, getWidth(), getHeight()); + /** + * Render the full set of annotation Labels for the alignment at the given + * cursor. If actuallyDraw is false or g is null then no actual drawing will + * occur, but the widest label width will be returned. If g is null then + * fmetrics must be supplied. + * + * Returns the width of the annotation labels. + * + * @param g + * Graphics2D instance (needed for font scaling) + * @param clip + * - true indicates that only current visible area needs to be + * rendered + * @param width + * Width for scaling labels + * @param fmetrics + * FontMetrics if Graphics object g is null + */ + public int drawLabels(Graphics g, boolean clip, int width, + boolean actuallyDraw, FontMetrics fmetrics) + { + int actualWidth = 0; + if (g != null) + { + if (av.getFont().getSize() < 10) + { + g.setFont(font); + } + else + { + g.setFont(av.getFont()); + } + } + + FontMetrics fm = fmetrics == null ? g.getFontMetrics(g.getFont()) + : fmetrics; + if (actuallyDraw) + { + g.setColor(Color.white); + g.fillRect(0, 0, getWidth(), getHeight()); + } - g.translate(0, getScrollOffset()); - g.setColor(Color.black); + if (actuallyDraw) + { + g.translate(0, getScrollOffset()); + g.setColor(Color.black); + } SequenceI lastSeqRef = null; String lastLabel = null; AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation(); - int fontHeight = g.getFont().getSize(); + int fontHeight = g != null ? g.getFont().getSize() + : fm.getFont().getSize(); int y = 0; int x = 0; int graphExtras = 0; int offset = 0; - Font baseFont = g.getFont(); + Font baseFont = g != null ? g.getFont() : fm.getFont(); FontMetrics baseMetrics = fm; int ofontH = fontHeight; int sOffset = 0; @@@ -1362,10 -1260,8 +1367,10 @@@ continue; } } - g.setColor(Color.black); - + if (actuallyDraw && g != null) + { + g.setColor(Color.black); + } offset = -aa[i].height / 2; if (aa[i].hasText) @@@ -1410,9 -1306,7 +1415,9 @@@ vertBar = true; } } - x = width - fm.stringWidth(label) - 3; + + int labelWidth = fm.stringWidth(label) + 3; + x = width - labelWidth; if (aa[i].graphGroup > -1) { @@@ -1445,15 -1339,10 +1450,15 @@@ s = ((float) fontHeight) / (float) ofontH; Font f = baseFont .deriveFont(AffineTransform.getScaleInstance(s, s)); - g.setFont(f); - fm = g.getFontMetrics(); - graphExtras = (aa[i].height - (groupSize * (fontHeight + 8))) - / 2; + Canvas c = new Canvas(); + fm = c.getFontMetrics(f); + if (actuallyDraw && g != null) + { + g.setFont(f); + // fm = g.getFontMetrics(); + graphExtras = (aa[i].height + - (groupSize * (fontHeight + 8))) / 2; + } } } if (visible) @@@ -1462,81 -1351,58 +1467,81 @@@ { if (aa[gg].graphGroup == aa[i].graphGroup) { - x = width - fm.stringWidth(aa[gg].label) - 3; - g.drawString(aa[gg].label, x, y - graphExtras); - - if (aa[gg]._linecolour != null) + labelWidth = fm.stringWidth(aa[gg].label) + 3; + x = width - labelWidth; + if (actuallyDraw && g != null) { + g.drawString(aa[gg].label, x, y - graphExtras); - g.setColor(aa[gg]._linecolour); - g.drawLine(x, y - graphExtras + 3, - x + fm.stringWidth(aa[gg].label), - y - graphExtras + 3); - } + if (aa[gg]._linecolour != null) + { - g.setColor(Color.black); + g.setColor(aa[gg]._linecolour); + g.drawLine(x, y - graphExtras + 3, + x + fm.stringWidth(aa[gg].label), + y - graphExtras + 3); + } + + g.setColor(Color.black); + } graphExtras += fontHeight + 8; } } } - g.setFont(baseFont); + if (actuallyDraw && g != null) + { + g.setFont(baseFont); + } fm = baseMetrics; fontHeight = ofontH; } else { - if (vertBar) + if (actuallyDraw && g != null) { - g.drawLine(width - 3, y + offset - fontHeight, width - 3, - (int) (y - 1.5 * aa[i].height - offset - fontHeight)); - // g.drawLine(20, y + offset, x - 20, y + offset); + if (vertBar) + { + g.drawLine(width - 3, y + offset - fontHeight, width - 3, + (int) (y - 1.5 * aa[i].height - offset - fontHeight)); + // g.drawLine(20, y + offset, x - 20, y + offset); + } + g.drawString(label, x, y + offset); } - g.drawString(label, x, y + offset); } lastSeqRef = aa[i].sequenceRef; + + if (labelWidth > actualWidth) + { + actualWidth = labelWidth; + } } } if (!resizePanel && dragEvent != null && aa != null) { - g.setColor(Color.lightGray); - g.drawString( - (aa[selectedRow].sequenceRef == null ? "" - : aa[selectedRow].sequenceRef.getName()) - + aa[selectedRow].label, - dragEvent.getX(), dragEvent.getY() - getScrollOffset()); + if (actuallyDraw && g != null) + { + g.setColor(Color.lightGray); + g.drawString( + (aa[selectedRow].sequenceRef == null ? "" + : aa[selectedRow].sequenceRef.getName()) + + aa[selectedRow].label, + dragEvent.getX(), dragEvent.getY() - getScrollOffset()); + } } if (!av.getWrapAlignment() && ((aa == null) || (aa.length < 1))) { - g.drawString(MessageManager.getString("label.right_click"), 2, 8); - g.drawString(MessageManager.getString("label.to_add_annotation"), 2, - 18); + if (actuallyDraw && g != null) + { + g.drawString(MessageManager.getString("label.right_click"), 2, 8); + g.drawString(MessageManager.getString("label.to_add_annotation"), 2, + 18); + } } + + return actualWidth; } public int getScrollOffset()