3 import jalview.datamodel.*;
\r
5 import javax.swing.*;
\r
7 import java.awt.event.*;
\r
9 import java.awt.image.*;
\r
11 public class AnnotationPanel extends JPanel implements MouseListener, MouseMotionListener, ActionListener, AdjustmentListener
\r
17 ArrayList activeRes;
\r
18 static String HELIX ="Helix";
\r
19 static String SHEET ="Sheet";
\r
20 static String LABEL ="Label";
\r
21 static String REMOVE="Remove Annotation";
\r
22 static String COLOUR="Colour";
\r
23 static Color HELIX_COLOUR = Color.red.darker();
\r
24 static Color SHEET_COLOUR = Color.green.darker().darker();
\r
27 BufferedImage image;
\r
32 boolean fastPaint = false;
\r
34 public static int GRAPH_HEIGHT = 40;
\r
38 public AnnotationPanel(AlignmentPanel ap)
\r
42 this.setLayout(null);
\r
43 addMouseListener(this);
\r
44 addMouseMotionListener(this);
\r
45 adjustPanelHeight();
\r
48 ap.annotationScroller.getVerticalScrollBar().addAdjustmentListener( this );
\r
51 public void adjustmentValueChanged(AdjustmentEvent evt)
\r
53 ap.alabels.setScrollOffset( -evt.getValue() );
\r
56 public void adjustPanelHeight()
\r
58 // setHeight of panels
\r
59 AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
\r
62 for (int i = 0; i < aa.length; i++)
\r
70 aa[i].height += av.charHeight;
\r
75 aa[i].height += GRAPH_HEIGHT;
\r
79 height += aa[i].height;
\r
82 this.setPreferredSize(new Dimension(1, height));
\r
86 public void addEditableColumn(int i)
\r
90 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
91 for(int j=0; j<aa.length; j++)
\r
101 activeRes = new ArrayList();
\r
102 activeRes.add(String.valueOf(i));
\r
106 activeRes.add(String.valueOf(i));
\r
111 public void actionPerformed(ActionEvent evt)
\r
114 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
115 Annotation [] anot = aa[activeRow].annotations;
\r
117 if(evt.getActionCommand().equals(REMOVE))
\r
119 for(int i=0; i<activeRes.size(); i++)
\r
121 anot[Integer.parseInt(activeRes.get(i).toString())] = null;
\r
122 anot[Integer.parseInt(activeRes.get(i).toString())] = null;
\r
125 else if(evt.getActionCommand().equals(LABEL))
\r
127 String label = JOptionPane.showInputDialog(this, "Enter Label ", "Enter label", JOptionPane.QUESTION_MESSAGE );
\r
131 if(label.length()>0 && !aa[activeRow].hasText)
\r
132 aa[activeRow].hasText = true;
\r
134 for(int i=0; i<activeRes.size(); i++)
\r
136 int index = Integer.parseInt(activeRes.get(i).toString());
\r
137 if(anot[index]==null)
\r
138 anot[index] = new Annotation(label, "", ' ',0);
\r
139 anot[index].displayCharacter = label;
\r
142 else if(evt.getActionCommand().equals(COLOUR))
\r
144 Color col = JColorChooser.showDialog(this, "Choose foreground colour", Color.black);
\r
145 for (int i = 0; i < activeRes.size(); i++)
\r
147 int index = Integer.parseInt(activeRes.get(i).toString());
\r
148 if (anot[index] == null)
\r
149 anot[index] = new Annotation("", "", ' ', 0);
\r
150 anot[index].colour = col;
\r
153 else // HELIX OR SHEET
\r
156 String symbol = "\u03B1";
\r
157 if(evt.getActionCommand().equals(HELIX))
\r
159 else if(evt.getActionCommand().equals(SHEET))
\r
165 if(!aa[activeRow].hasIcons)
\r
166 aa[activeRow].hasIcons = true;
\r
169 String label = JOptionPane.showInputDialog("Enter a label for the structure?", symbol );
\r
173 if(label.length()>0 && !aa[activeRow].hasText)
\r
174 aa[activeRow].hasText = true;
\r
176 for(int i=0; i<activeRes.size(); i++)
\r
178 int index = Integer.parseInt(activeRes.get(i).toString());
\r
179 if (anot[index] == null)
\r
181 anot[index] = new Annotation(label, "", type, 0);
\r
184 anot[ index ].secondaryStructure = type;
\r
185 anot[ index ].displayCharacter = label;
\r
189 adjustPanelHeight();
\r
197 public void mousePressed(MouseEvent evt)
\r
199 if (SwingUtilities.isRightMouseButton(evt))
\r
201 if(activeRes==null)
\r
204 JPopupMenu pop = new JPopupMenu("Structure type");
\r
205 JMenuItem item = new JMenuItem(HELIX);
\r
206 item.addActionListener(this);
\r
208 item = new JMenuItem(SHEET);
\r
209 item.addActionListener(this);
\r
211 item = new JMenuItem(LABEL);
\r
212 item.addActionListener(this);
\r
214 item = new JMenuItem(COLOUR);
\r
215 item.addActionListener(this);
\r
217 item = new JMenuItem(REMOVE);
\r
218 item.addActionListener(this);
\r
220 pop.show(this, evt.getX(), evt.getY());
\r
225 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
231 for(int i=0; i<aa.length; i++)
\r
233 height+= aa[i].height;
\r
235 if(evt.getY()<height)
\r
237 if(!aa[i].editable)
\r
249 int res = evt.getX() / av.getCharWidth() + av.getStartRes();
\r
251 if(evt.isControlDown() || evt.isAltDown())
\r
252 addEditableColumn(res);
\r
254 else if(evt.isShiftDown())
\r
257 if(activeRes==null)
\r
258 activeRes=new ArrayList();
\r
261 int start = Integer.parseInt( activeRes.get( activeRes.size()-1 ).toString() );
\r
269 for(int n=start; n<=end; n++)
\r
270 addEditableColumn(n);
\r
276 activeRes = new ArrayList();
\r
277 activeRes.add( String.valueOf(res) );
\r
283 public void mouseReleased(MouseEvent evt)
\r
285 public void mouseEntered(MouseEvent evt)
\r
287 public void mouseExited(MouseEvent evt)
\r
289 public void mouseDragged(MouseEvent evt)
\r
291 public void mouseMoved(MouseEvent evt)
\r
293 ToolTipManager.sharedInstance().registerComponent(this);
\r
294 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
300 for(int i=0; i<aa.length; i++)
\r
303 if( aa[i].visible )
\r
304 height += aa[i].height;
\r
306 if(evt.getY()<height)
\r
313 int res = evt.getX() / av.getCharWidth() + av.getStartRes();
\r
314 if(row>-1 && res<aa[row].annotations.length && aa[row].annotations[res]!=null)
\r
316 this.setToolTipText(aa[row].annotations[res].description);
\r
317 StringBuffer text = new StringBuffer("Sequence position " + (res + 1) +
\r
319 aa[row].annotations[res].description);
\r
320 ap.alignFrame.statusBar.setText(text.toString());
\r
325 public void mouseClicked(MouseEvent evt) {}
\r
328 public void paintComponent(Graphics g)
\r
330 g.setColor(Color.white);
\r
331 g.fillRect(0,0,getWidth(), getHeight());
\r
335 g.drawImage(image, 0, 0, this);
\r
340 imgWidth = (av.endRes-av.startRes+1) *av.charWidth;
\r
342 image = new BufferedImage(imgWidth,
\r
343 ap.annotationPanel.getHeight(),
\r
344 BufferedImage.TYPE_INT_RGB);
\r
345 gg = (Graphics2D) image.getGraphics();
\r
346 gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
\r
347 RenderingHints.VALUE_ANTIALIAS_ON);
\r
349 gg.setFont(av.getFont());
\r
350 fm = gg.getFontMetrics();
\r
352 drawComponent( gg, av.startRes, av.endRes+1);
\r
353 g.drawImage( image, 0, 0, this);
\r
357 public void fastPaint(int horizontal)
\r
359 if( horizontal == 0
\r
360 || av.alignment.getAlignmentAnnotation()==null
\r
361 || av.alignment.getAlignmentAnnotation().length<1
\r
368 gg.copyArea( 0,0, imgWidth, getHeight(), -horizontal*av.charWidth, 0 );
\r
369 int sr=av.startRes, er=av.endRes+1, transX=0;
\r
371 if(horizontal>0) // scrollbar pulled right, image to the left
\r
373 transX = (er-sr-horizontal)*av.charWidth;
\r
374 sr = er - horizontal ;
\r
376 else if(horizontal<0)
\r
378 er = sr-horizontal;
\r
382 gg.translate(transX, 0);
\r
384 drawComponent(gg, sr, er);
\r
386 gg.translate( -transX, 0 );
\r
393 public void drawComponent(Graphics2D g, int startRes, int endRes)
\r
395 g.setColor(Color.white);
\r
396 g.fillRect(0,0,(endRes-startRes) *av.charWidth, getHeight());
\r
397 if(av.alignment.getAlignmentAnnotation()==null || av.alignment.getAlignmentAnnotation().length<1)
\r
399 g.setColor(Color.white);
\r
400 g.fillRect(0,0,getWidth(), getHeight());
\r
401 g.setColor(Color.black);
\r
402 g.drawString("Alignment has no annotations",20,15);
\r
406 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
409 char [] lastSS = new char[aa.length];
\r
410 int [] lastSSX= new int[aa.length] ;
\r
411 int iconOffset = av.charHeight/2;
\r
412 boolean validRes = false;
\r
415 for(int i=0; i<aa.length; i++)
\r
417 AlignmentAnnotation row = aa[i];
\r
423 // this is so that we draw the characters below the graph
\r
426 y -= av.charHeight;
\r
429 iconOffset = av.charHeight/2;
\r
433 for(j=startRes; j<endRes; j++)
\r
435 if(row.annotations.length<=j || row.annotations[j]==null)
\r
440 x = (j-startRes)*av.charWidth;
\r
446 g.setColor(Color.red);
\r
448 if(activeRes!=null)
\r
449 for (int n = 0; n < activeRes.size(); n++)
\r
451 int v = Integer.parseInt(activeRes.get(n).toString()) ;
\r
453 g.fillRect( (j-startRes) * av.charWidth, y, av.charWidth, row.height);
\r
459 if(validRes && row.annotations[j].displayCharacter.length()>0)
\r
461 int charOffset = (av.charWidth - fm.charWidth(row.annotations[j].displayCharacter.charAt(0)))/2;
\r
462 g.setColor( row.annotations[j].colour);
\r
465 if (row.annotations[0].secondaryStructure == 'H'
\r
466 || row.annotations[0].secondaryStructure == 'E')
\r
467 g.drawString(row.annotations[j].displayCharacter, x,
\r
468 y + iconOffset + 2);
\r
470 else if( (row.annotations[j].secondaryStructure=='H'
\r
471 || row.annotations[j].secondaryStructure=='E') &&
\r
472 (row.annotations[j-1]==null ||
\r
473 row.annotations[j].secondaryStructure!=row.annotations[j-1].secondaryStructure))
\r
475 g.drawString(row.annotations[j].displayCharacter, x, y + iconOffset + 2);
\r
478 g.drawString(row.annotations[j].displayCharacter, x + charOffset,
\r
479 y + iconOffset + 2);
\r
483 if(!validRes || row.annotations[j].secondaryStructure!=lastSS[i])
\r
488 g.setColor(HELIX_COLOUR);
\r
489 g.fillRoundRect(lastSSX[i], y+4 + iconOffset, x-lastSSX[i], 7, 8, 8);
\r
492 g.setColor(SHEET_COLOUR);
\r
493 g.fillRect(lastSSX[i], y + 4 + iconOffset, x-lastSSX[i]-4, 7);
\r
494 g.fillPolygon(new int[] {x - 4, x- 4, x }
\r
495 , new int[]{y+ iconOffset, y + 14+ iconOffset, y + 8+ iconOffset}, 3);
\r
500 g.setColor(Color.gray);
\r
501 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
506 lastSS[i] = row.annotations[j].secondaryStructure;
\r
512 if (validRes && row.isGraph)
\r
514 g.setColor(new Color(0,0,180));
\r
515 int height = (int)((row.annotations[j].value / row.graphMax)*GRAPH_HEIGHT);
\r
517 if(row.windowLength>1)
\r
520 for(int i2=j- (row.windowLength/2); i2<j+(row.windowLength/2); i2++)
\r
522 if(i2<0 || i2>=av.alignment.getWidth())
\r
525 total += row.annotations[i2].value;
\r
528 total/=row.windowLength;
\r
529 height = (int)( (total / row.graphMax) *GRAPH_HEIGHT);
\r
532 g.setColor(row.annotations[j].colour);
\r
533 g.fillRect(x, y-height, av.charWidth, height );
\r
545 g.setColor(HELIX_COLOUR);
\r
546 g.fillRoundRect(lastSSX[i], y+4+ iconOffset, x - lastSSX[i], 7, 8, 8);
\r
549 g.setColor(SHEET_COLOUR);
\r
550 g.fillRect(lastSSX[i], y + 4+ iconOffset, x - lastSSX[i] - 4, 7);
\r
551 g.fillPolygon(new int[]
\r
554 {y + iconOffset, y + 14+ iconOffset, y + 7+ iconOffset}
\r
560 g.setColor(Color.gray);
\r
561 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
566 if(row.isGraph && row.hasText)
\r
573 // used by overview window
\r
574 public void drawGraph(Graphics g, AlignmentAnnotation aa,int width, int y)
\r
576 g.setColor(Color.white);
\r
577 g.fillRect(0,0,width, y);
\r
578 g.setColor(new Color(0,0,180));
\r
580 for(int j=0; j<aa.annotations.length; j++)
\r
582 g.setColor(new Color(0, 0, 180));
\r
583 int height = (int) ( (aa.annotations[j].value / aa.graphMax) * GRAPH_HEIGHT );
\r
584 g.fillRect(x, y - height, av.charWidth, height);
\r