package jalview.gui; import jalview.datamodel.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*; import java.awt.image.*; public class AnnotationPanel extends JPanel implements MouseListener, MouseMotionListener, ActionListener, AdjustmentListener { AlignViewport av; AlignmentPanel ap; int activeRow =-1; ArrayList activeRes; static String HELIX ="Helix"; static String SHEET ="Sheet"; static String LABEL ="Label"; static String REMOVE="Remove Annotation"; static String COLOUR="Colour"; static Color HELIX_COLOUR = Color.red.darker(); static Color SHEET_COLOUR = Color.green.darker().darker(); BufferedImage image; Graphics2D gg; FontMetrics fm; int imgWidth=0; boolean fastPaint = false; public static int GRAPH_HEIGHT = 40; public AnnotationPanel(AlignmentPanel ap) { this.ap = ap; av = ap.av; this.setLayout(null); addMouseListener(this); addMouseMotionListener(this); adjustPanelHeight(); ap.annotationScroller.getVerticalScrollBar().addAdjustmentListener( this ); } public void adjustmentValueChanged(AdjustmentEvent evt) { ap.alabels.setScrollOffset( -evt.getValue() ); } public void adjustPanelHeight() { // setHeight of panels AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation(); int height = 0; if(aa!=null) for (int i = 0; i < aa.length; i++) { if(!aa[i].visible) continue; aa[i].height = 0; if(aa[i].hasText) aa[i].height += av.charHeight; if (aa[i].hasIcons) aa[i].height += 16; if (aa[i].isGraph) aa[i].height += GRAPH_HEIGHT; if(aa[i].height==0) aa[i].height = 20; height += aa[i].height; } else height=20; this.setPreferredSize(new Dimension(1, height)); } public void addEditableColumn(int i) { if(activeRow==-1) { AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation(); for(int j=0; j0 && !aa[activeRow].hasText) aa[activeRow].hasText = true; for(int i=0; i0 && !aa[activeRow].hasText) aa[activeRow].hasText = true; for(int i=0; i-1 && res0) // scrollbar pulled right, image to the left { transX = (er-sr-horizontal)*av.charWidth; sr = er - horizontal ; } else if(horizontal<0) { er = sr-horizontal; } gg.translate(transX, 0); drawComponent(gg, sr, er); gg.translate( -transX, 0 ); fastPaint = true; repaint(); } public void drawComponent(Graphics2D g, int startRes, int endRes) { g.setColor(Color.white); g.fillRect(0,0,(endRes-startRes) *av.charWidth, getHeight()); if(av.alignment.getAlignmentAnnotation()==null || av.alignment.getAlignmentAnnotation().length<1) { g.setColor(Color.white); g.fillRect(0,0,getWidth(), getHeight()); g.setColor(Color.black); g.drawString("Alignment has no annotations",20,15); return; } AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation(); int j, x=0, y=0; char [] lastSS = new char[aa.length]; int [] lastSSX= new int[aa.length] ; int iconOffset = av.charHeight/2; boolean validRes = false; //\u03B2 \u03B1 for(int i=0; i0) { int charOffset = (av.charWidth - fm.charWidth(row.annotations[j].displayCharacter.charAt(0)))/2; g.setColor( row.annotations[j].colour); if(j==0) { if (row.annotations[0].secondaryStructure == 'H' || row.annotations[0].secondaryStructure == 'E') g.drawString(row.annotations[j].displayCharacter, x, y + iconOffset + 2); } else if( (row.annotations[j].secondaryStructure=='H' || row.annotations[j].secondaryStructure=='E') && (row.annotations[j-1]==null || row.annotations[j].secondaryStructure!=row.annotations[j-1].secondaryStructure)) g.drawString(row.annotations[j].displayCharacter, x, y + iconOffset + 2); if(!row.hasIcons) g.drawString(row.annotations[j].displayCharacter, x + charOffset, y + iconOffset + 2); } if(row.hasIcons) if(!validRes || row.annotations[j].secondaryStructure!=lastSS[i]) { switch (lastSS[i]) { case 'H': g.setColor(HELIX_COLOUR); g.fillRoundRect(lastSSX[i], y+4 + iconOffset, x-lastSSX[i], 7, 8, 8); break; case 'E': g.setColor(SHEET_COLOUR); g.fillRect(lastSSX[i], y + 4 + iconOffset, x-lastSSX[i]-4, 7); g.fillPolygon(new int[] {x - 4, x- 4, x } , new int[]{y+ iconOffset, y + 14+ iconOffset, y + 8+ iconOffset}, 3); break; case 'C': break; default : g.setColor(Color.gray); g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2); break; } if(validRes) lastSS[i] = row.annotations[j].secondaryStructure; else lastSS[i] = ' '; lastSSX[i] = x; } if (validRes && row.isGraph) { g.setColor(new Color(0,0,180)); int height = (int)((row.annotations[j].value / row.graphMax)*GRAPH_HEIGHT); if(row.windowLength>1) { int total =0; for(int i2=j- (row.windowLength/2); i2=av.alignment.getWidth()) continue; total += row.annotations[i2].value; } total/=row.windowLength; height = (int)( (total / row.graphMax) *GRAPH_HEIGHT); } g.setColor(row.annotations[j].colour); g.fillRect(x, y-height, av.charWidth, height ); } } x+=av.charWidth; if(row.hasIcons) switch (lastSS[i]) { case 'H': g.setColor(HELIX_COLOUR); g.fillRoundRect(lastSSX[i], y+4+ iconOffset, x - lastSSX[i], 7, 8, 8); break; case 'E': g.setColor(SHEET_COLOUR); g.fillRect(lastSSX[i], y + 4+ iconOffset, x - lastSSX[i] - 4, 7); g.fillPolygon(new int[] {x - 4, x - 4, x} , new int[] {y + iconOffset, y + 14+ iconOffset, y + 7+ iconOffset} , 3); break; case 'C': break; default: g.setColor(Color.gray); g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2); break; } if(row.isGraph && row.hasText) y+=av.charHeight; if(!row.isGraph) y+=aa[i].height; } } // used by overview window public void drawGraph(Graphics g, AlignmentAnnotation aa,int width, int y) { g.setColor(Color.white); g.fillRect(0,0,width, y); g.setColor(new Color(0,0,180)); int x = 0; for(int j=0; j