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.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+1);
\r
348 g.drawImage( image, 0, 0, this);
\r
351 public void fastPaint(int horizontal)
\r
353 if(image==null || horizontal ==0)
\r
359 gg.copyArea( 0,0, imgWidth, getHeight(), -horizontal*av.charWidth, 0 );
\r
360 int sr=av.startRes, er=av.endRes+1, transX=0;
\r
362 if(horizontal>0) // scrollbar pulled right, image to the left
\r
364 transX = (er-sr-horizontal)*av.charWidth;
\r
365 sr = er - horizontal ;
\r
367 else if(horizontal<0)
\r
369 er = sr-horizontal;
\r
373 gg.translate(transX, 0);
\r
375 drawComponent(gg, sr, er);
\r
377 gg.translate( -transX, 0 );
\r
384 public void drawComponent(Graphics2D g, int startRes, int endRes)
\r
386 g.setColor(Color.white);
\r
387 g.fillRect(0,0,(endRes-startRes) *av.charWidth, getHeight());
\r
388 if(av.alignment.getAlignmentAnnotation()==null || av.alignment.getAlignmentAnnotation().length<1)
\r
390 g.setColor(Color.black);
\r
391 g.drawString("Alignment has no annotations",20,15);
\r
395 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
398 char [] lastSS = new char[aa.length];
\r
399 int [] lastSSX= new int[aa.length] ;
\r
400 int iconOffset = av.charHeight/2;
\r
401 boolean validRes = false;
\r
403 for(int i=0; i<aa.length; i++)
\r
405 AlignmentAnnotation row = aa[i];
\r
411 // this is so that we draw the characters below the graph
\r
414 y -= av.charHeight;
\r
417 iconOffset = av.charHeight/2;
\r
421 for(j=startRes; j<endRes; j++)
\r
423 validRes = row.annotations[j]==null?false:true;
\r
425 x = (j-startRes)*av.charWidth;
\r
431 g.setColor(Color.red);
\r
433 if(activeRes!=null)
\r
434 for (int n = 0; n < activeRes.size(); n++)
\r
436 int v = Integer.parseInt(activeRes.get(n).toString()) ;
\r
438 g.fillRect( (j-startRes) * av.charWidth, y, av.charWidth, row.height);
\r
444 if(validRes && row.annotations[j].displayCharacter.length()>0)
\r
446 int charOffset = (av.charWidth -
\r
447 fm.charWidth(row.annotations[j].displayCharacter.
\r
449 g.setColor( row.annotations[j].colour);
\r
452 if (row.annotations[0].secondaryStructure == 'H'
\r
453 || row.annotations[0].secondaryStructure == 'E')
\r
454 g.drawString(row.annotations[j].displayCharacter, x,
\r
455 y + iconOffset + 2);
\r
457 else if( (row.annotations[j].secondaryStructure=='H'
\r
458 || row.annotations[j].secondaryStructure=='E') &&
\r
459 (row.annotations[j-1]==null ||
\r
460 row.annotations[j].secondaryStructure!=row.annotations[j-1].secondaryStructure))
\r
462 g.drawString(row.annotations[j].displayCharacter, x, y + iconOffset + 2);
\r
465 g.drawString(row.annotations[j].displayCharacter, x + charOffset,
\r
466 y + iconOffset + 2);
\r
470 if(!validRes || row.annotations[j].secondaryStructure!=lastSS[i])
\r
475 g.setColor(HELIX_COLOUR);
\r
476 g.fillRoundRect(lastSSX[i], y+4 + iconOffset, x-lastSSX[i], 7, 8, 8);
\r
479 g.setColor(SHEET_COLOUR);
\r
480 g.fillRect(lastSSX[i], y + 4 + iconOffset, x-lastSSX[i]-4, 7);
\r
481 g.fillPolygon(new int[] {x - 4, x- 4, x }
\r
482 , new int[]{y+ iconOffset, y + 14+ iconOffset, y + 8+ iconOffset}, 3);
\r
487 g.setColor(Color.gray);
\r
488 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
493 lastSS[i] = row.annotations[j].secondaryStructure;
\r
499 if (validRes && row.isGraph)
\r
501 g.setColor(new Color(0,0,180));
\r
502 int height = (int)((row.annotations[j].value / row.graphMax)*GRAPH_HEIGHT);
\r
504 if(row.windowLength>1)
\r
507 for(int i2=j- (row.windowLength/2); i2<j+(row.windowLength/2); i2++)
\r
509 if(i2<0 || i2>=av.alignment.getWidth())
\r
512 total += row.annotations[i2].value;
\r
515 total/=row.windowLength;
\r
516 height = (int)( (total / row.graphMax) *GRAPH_HEIGHT);
\r
520 g.fillRect(x, y-height, av.charWidth, height );
\r
532 g.setColor(HELIX_COLOUR);
\r
533 g.fillRoundRect(lastSSX[i], y+4+ iconOffset, x - lastSSX[i], 7, 8, 8);
\r
536 g.setColor(SHEET_COLOUR);
\r
537 g.fillRect(lastSSX[i], y + 4+ iconOffset, x - lastSSX[i] - 4, 7);
\r
538 g.fillPolygon(new int[]
\r
541 {y + iconOffset, y + 14+ iconOffset, y + 7+ iconOffset}
\r
547 g.setColor(Color.gray);
\r
548 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
553 if(row.isGraph && row.hasText)
\r
560 // used by overview window
\r
561 public void drawGraph(Graphics g, AlignmentAnnotation aa,int width, int y)
\r
563 g.setColor(Color.white);
\r
564 g.fillRect(0,0,width, y);
\r
565 g.setColor(new Color(0,0,180));
\r
567 for(int j=0; j<aa.annotations.length; j++)
\r
569 g.setColor(new Color(0, 0, 180));
\r
570 int height = (int) ( (aa.annotations[j].value / aa.graphMax) * GRAPH_HEIGHT );
\r
571 g.fillRect(x, y - height, av.charWidth, height);
\r