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
315 this.setToolTipText(aa[row].annotations[res].description);
\r
318 public void mouseClicked(MouseEvent evt) {}
\r
321 public void paintComponent(Graphics g)
\r
323 g.setColor(Color.white);
\r
324 g.fillRect(0,0,getWidth(), getHeight());
\r
328 g.drawImage(image, 0, 0, this);
\r
333 imgWidth = (av.endRes-av.startRes) *av.charWidth;
\r
335 image = new BufferedImage(imgWidth,
\r
336 ap.annotationPanel.getHeight(),
\r
337 BufferedImage.TYPE_INT_RGB);
\r
338 gg = (Graphics2D) image.getGraphics();
\r
339 gg.setColor(Color.white);
\r
340 gg.fillRect(0, 0, imgWidth, getHeight());
\r
341 gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
\r
342 RenderingHints.VALUE_ANTIALIAS_ON);
\r
343 fm = gg.getFontMetrics();
\r
344 gg.setFont(av.getFont());
\r
347 drawComponent( gg, av.startRes, av.endRes);
\r
348 g.drawImage( image, 0, 0, this);
\r
351 public void fastPaint(int horizontal)
\r
354 || av.alignment.getAlignmentAnnotation()==null
\r
355 || av.alignment.getAlignmentAnnotation().length<1
\r
362 gg.copyArea( 0,0, imgWidth, getHeight(), -horizontal*av.charWidth, 0 );
\r
363 int sr=av.startRes, er=av.endRes, transX=0;
\r
365 if(horizontal>0) // scrollbar pulled right, image to the left
\r
367 transX = (er-sr-horizontal)*av.charWidth;
\r
368 sr = er - horizontal ;
\r
370 else if(horizontal<0)
\r
372 er = sr-horizontal;
\r
376 gg.translate(transX, 0);
\r
378 drawComponent(gg, sr, er);
\r
380 gg.translate( -transX, 0 );
\r
387 public void drawComponent(Graphics2D g, int startRes, int endRes)
\r
389 g.setColor(Color.white);
\r
390 g.fillRect(0,0,(endRes-startRes) *av.charWidth, getHeight());
\r
391 if(av.alignment.getAlignmentAnnotation()==null || av.alignment.getAlignmentAnnotation().length<1)
\r
393 g.setColor(Color.white);
\r
394 g.fillRect(0,0,getWidth(), getHeight());
\r
395 g.setColor(Color.black);
\r
396 g.drawString("Alignment has no annotations",20,15);
\r
400 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
403 char [] lastSS = new char[aa.length];
\r
404 int [] lastSSX= new int[aa.length] ;
\r
405 int iconOffset = av.charHeight/2;
\r
406 boolean validRes = false;
\r
408 for(int i=0; i<aa.length; i++)
\r
410 AlignmentAnnotation row = aa[i];
\r
416 // this is so that we draw the characters below the graph
\r
419 y -= av.charHeight;
\r
422 iconOffset = av.charHeight/2;
\r
426 for(j=startRes; j<endRes; j++)
\r
428 validRes = row.annotations[j]==null?false:true;
\r
430 x = (j-startRes)*av.charWidth;
\r
436 g.setColor(Color.red);
\r
438 if(activeRes!=null)
\r
439 for (int n = 0; n < activeRes.size(); n++)
\r
441 int v = Integer.parseInt(activeRes.get(n).toString()) ;
\r
443 g.fillRect( (j-startRes) * av.charWidth, y, av.charWidth, row.height);
\r
449 if(validRes && row.annotations[j].displayCharacter.length()>0)
\r
451 int charOffset = (av.charWidth -
\r
452 fm.charWidth(row.annotations[j].displayCharacter.
\r
454 g.setColor( row.annotations[j].colour);
\r
457 if (row.annotations[0].secondaryStructure == 'H'
\r
458 || row.annotations[0].secondaryStructure == 'E')
\r
459 g.drawString(row.annotations[j].displayCharacter, x,
\r
460 y + iconOffset + 2);
\r
462 else if( (row.annotations[j].secondaryStructure=='H'
\r
463 || row.annotations[j].secondaryStructure=='E') &&
\r
464 (row.annotations[j-1]==null ||
\r
465 row.annotations[j].secondaryStructure!=row.annotations[j-1].secondaryStructure))
\r
467 g.drawString(row.annotations[j].displayCharacter, x, y + iconOffset + 2);
\r
470 g.drawString(row.annotations[j].displayCharacter, x + charOffset,
\r
471 y + iconOffset + 2);
\r
475 if(!validRes || row.annotations[j].secondaryStructure!=lastSS[i])
\r
480 g.setColor(HELIX_COLOUR);
\r
481 g.fillRoundRect(lastSSX[i], y+4 + iconOffset, x-lastSSX[i], 7, 8, 8);
\r
484 g.setColor(SHEET_COLOUR);
\r
485 g.fillRect(lastSSX[i], y + 4 + iconOffset, x-lastSSX[i]-4, 7);
\r
486 g.fillPolygon(new int[] {x - 4, x- 4, x }
\r
487 , new int[]{y+ iconOffset, y + 14+ iconOffset, y + 8+ iconOffset}, 3);
\r
492 g.setColor(Color.gray);
\r
493 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
498 lastSS[i] = row.annotations[j].secondaryStructure;
\r
504 if (validRes && row.isGraph)
\r
506 g.setColor(new Color(0,0,180));
\r
507 int height = (int)((row.annotations[j].value / row.graphMax)*GRAPH_HEIGHT);
\r
509 if(row.windowLength>1)
\r
512 for(int i2=j- (row.windowLength/2); i2<j+(row.windowLength/2); i2++)
\r
514 if(i2<0 || i2>=av.alignment.getWidth())
\r
517 total += row.annotations[i2].value;
\r
520 total/=row.windowLength;
\r
521 height = (int)( (total / row.graphMax) *GRAPH_HEIGHT);
\r
524 g.setColor(row.annotations[j].colour);
\r
525 g.fillRect(x, y-height, av.charWidth, height );
\r
537 g.setColor(HELIX_COLOUR);
\r
538 g.fillRoundRect(lastSSX[i], y+4+ iconOffset, x - lastSSX[i], 7, 8, 8);
\r
541 g.setColor(SHEET_COLOUR);
\r
542 g.fillRect(lastSSX[i], y + 4+ iconOffset, x - lastSSX[i] - 4, 7);
\r
543 g.fillPolygon(new int[]
\r
546 {y + iconOffset, y + 14+ iconOffset, y + 7+ iconOffset}
\r
552 g.setColor(Color.gray);
\r
553 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
558 if(row.isGraph && row.hasText)
\r
565 // used by overview window
\r
566 public void drawGraph(Graphics g, AlignmentAnnotation aa,int width, int y)
\r
568 g.setColor(Color.white);
\r
569 g.fillRect(0,0,width, y);
\r
570 g.setColor(new Color(0,0,180));
\r
572 for(int j=0; j<aa.annotations.length; j++)
\r
574 g.setColor(new Color(0, 0, 180));
\r
575 int height = (int) ( (aa.annotations[j].value / aa.graphMax) * GRAPH_HEIGHT );
\r
576 g.fillRect(x, y - height, av.charWidth, height);
\r