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+1) *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.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
\r
340 RenderingHints.VALUE_ANTIALIAS_ON);
\r
341 fm = gg.getFontMetrics();
\r
342 gg.setFont(av.getFont());
\r
344 drawComponent( gg, av.startRes, av.endRes+1);
\r
345 g.drawImage( image, 0, 0, this);
\r
349 public void fastPaint(int horizontal)
\r
351 if( horizontal == 0
\r
352 || av.alignment.getAlignmentAnnotation()==null
\r
353 || av.alignment.getAlignmentAnnotation().length<1
\r
360 gg.copyArea( 0,0, imgWidth, getHeight(), -horizontal*av.charWidth, 0 );
\r
361 int sr=av.startRes, er=av.endRes+1, transX=0;
\r
363 if(horizontal>0) // scrollbar pulled right, image to the left
\r
365 transX = (er-sr-horizontal)*av.charWidth;
\r
366 sr = er - horizontal ;
\r
368 else if(horizontal<0)
\r
370 er = sr-horizontal;
\r
374 gg.translate(transX, 0);
\r
376 drawComponent(gg, sr, er);
\r
378 gg.translate( -transX, 0 );
\r
385 public void drawComponent(Graphics2D g, int startRes, int endRes)
\r
387 g.setColor(Color.white);
\r
388 g.fillRect(0,0,(endRes-startRes) *av.charWidth, getHeight());
\r
389 if(av.alignment.getAlignmentAnnotation()==null || av.alignment.getAlignmentAnnotation().length<1)
\r
391 g.setColor(Color.white);
\r
392 g.fillRect(0,0,getWidth(), getHeight());
\r
393 g.setColor(Color.black);
\r
394 g.drawString("Alignment has no annotations",20,15);
\r
398 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
401 char [] lastSS = new char[aa.length];
\r
402 int [] lastSSX= new int[aa.length] ;
\r
403 int iconOffset = av.charHeight/2;
\r
404 boolean validRes = false;
\r
407 for(int i=0; i<aa.length; i++)
\r
409 AlignmentAnnotation row = aa[i];
\r
415 // this is so that we draw the characters below the graph
\r
418 y -= av.charHeight;
\r
421 iconOffset = av.charHeight/2;
\r
425 for(j=startRes; j<endRes; j++)
\r
427 validRes = row.annotations[j]==null?false:true;
\r
429 x = (j-startRes)*av.charWidth;
\r
435 g.setColor(Color.red);
\r
437 if(activeRes!=null)
\r
438 for (int n = 0; n < activeRes.size(); n++)
\r
440 int v = Integer.parseInt(activeRes.get(n).toString()) ;
\r
442 g.fillRect( (j-startRes) * av.charWidth, y, av.charWidth, row.height);
\r
448 if(validRes && row.annotations[j].displayCharacter.length()>0)
\r
450 int charOffset = (av.charWidth -
\r
451 fm.charWidth(row.annotations[j].displayCharacter.
\r
453 g.setColor( row.annotations[j].colour);
\r
456 if (row.annotations[0].secondaryStructure == 'H'
\r
457 || row.annotations[0].secondaryStructure == 'E')
\r
458 g.drawString(row.annotations[j].displayCharacter, x,
\r
459 y + iconOffset + 2);
\r
461 else if( (row.annotations[j].secondaryStructure=='H'
\r
462 || row.annotations[j].secondaryStructure=='E') &&
\r
463 (row.annotations[j-1]==null ||
\r
464 row.annotations[j].secondaryStructure!=row.annotations[j-1].secondaryStructure))
\r
466 g.drawString(row.annotations[j].displayCharacter, x, y + iconOffset + 2);
\r
469 g.drawString(row.annotations[j].displayCharacter, x + charOffset,
\r
470 y + iconOffset + 2);
\r
474 if(!validRes || row.annotations[j].secondaryStructure!=lastSS[i])
\r
479 g.setColor(HELIX_COLOUR);
\r
480 g.fillRoundRect(lastSSX[i], y+4 + iconOffset, x-lastSSX[i], 7, 8, 8);
\r
483 g.setColor(SHEET_COLOUR);
\r
484 g.fillRect(lastSSX[i], y + 4 + iconOffset, x-lastSSX[i]-4, 7);
\r
485 g.fillPolygon(new int[] {x - 4, x- 4, x }
\r
486 , new int[]{y+ iconOffset, y + 14+ iconOffset, y + 8+ iconOffset}, 3);
\r
491 g.setColor(Color.gray);
\r
492 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
497 lastSS[i] = row.annotations[j].secondaryStructure;
\r
503 if (validRes && row.isGraph)
\r
505 g.setColor(new Color(0,0,180));
\r
506 int height = (int)((row.annotations[j].value / row.graphMax)*GRAPH_HEIGHT);
\r
508 if(row.windowLength>1)
\r
511 for(int i2=j- (row.windowLength/2); i2<j+(row.windowLength/2); i2++)
\r
513 if(i2<0 || i2>=av.alignment.getWidth())
\r
516 total += row.annotations[i2].value;
\r
519 total/=row.windowLength;
\r
520 height = (int)( (total / row.graphMax) *GRAPH_HEIGHT);
\r
523 g.setColor(row.annotations[j].colour);
\r
524 g.fillRect(x, y-height, av.charWidth, height );
\r
536 g.setColor(HELIX_COLOUR);
\r
537 g.fillRoundRect(lastSSX[i], y+4+ iconOffset, x - lastSSX[i], 7, 8, 8);
\r
540 g.setColor(SHEET_COLOUR);
\r
541 g.fillRect(lastSSX[i], y + 4+ iconOffset, x - lastSSX[i] - 4, 7);
\r
542 g.fillPolygon(new int[]
\r
545 {y + iconOffset, y + 14+ iconOffset, y + 7+ iconOffset}
\r
551 g.setColor(Color.gray);
\r
552 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
557 if(row.isGraph && row.hasText)
\r
564 // used by overview window
\r
565 public void drawGraph(Graphics g, AlignmentAnnotation aa,int width, int y)
\r
567 g.setColor(Color.white);
\r
568 g.fillRect(0,0,width, y);
\r
569 g.setColor(new Color(0,0,180));
\r
571 for(int j=0; j<aa.annotations.length; j++)
\r
573 g.setColor(new Color(0, 0, 180));
\r
574 int height = (int) ( (aa.annotations[j].value / aa.graphMax) * GRAPH_HEIGHT );
\r
575 g.fillRect(x, y - height, av.charWidth, height);
\r