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
36 public AnnotationPanel(AlignmentPanel ap)
\r
40 this.setLayout(null);
\r
41 addMouseListener(this);
\r
42 addMouseMotionListener(this);
\r
43 adjustPanelHeight();
\r
46 ap.annotationScroller.getVerticalScrollBar().addAdjustmentListener( this );
\r
49 public void adjustmentValueChanged(AdjustmentEvent evt)
\r
51 ap.alabels.setScrollOffset( -evt.getValue() );
\r
54 public void adjustPanelHeight()
\r
56 // setHeight of panels
\r
57 AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
\r
60 for (int i = 0; i < aa.length; i++)
\r
68 aa[i].height += av.charHeight;
\r
77 height += aa[i].height;
\r
80 this.setPreferredSize(new Dimension(1, height));
\r
84 public void addEditableColumn(int i)
\r
88 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
89 for(int j=0; j<aa.length; j++)
\r
99 activeRes = new ArrayList();
\r
100 activeRes.add(String.valueOf(i));
\r
104 activeRes.add(String.valueOf(i));
\r
109 public void actionPerformed(ActionEvent evt)
\r
112 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
113 Annotation [] anot = aa[activeRow].annotations;
\r
115 if(evt.getActionCommand().equals(REMOVE))
\r
117 for(int i=0; i<activeRes.size(); i++)
\r
119 anot[Integer.parseInt(activeRes.get(i).toString())] = null;
\r
120 anot[Integer.parseInt(activeRes.get(i).toString())] = null;
\r
123 else if(evt.getActionCommand().equals(LABEL))
\r
125 String label = JOptionPane.showInputDialog(this, "Enter Label ", "Enter label", JOptionPane.QUESTION_MESSAGE );
\r
129 if(label.length()>0 && !aa[activeRow].hasText)
\r
130 aa[activeRow].hasText = true;
\r
132 for(int i=0; i<activeRes.size(); i++)
\r
134 int index = Integer.parseInt(activeRes.get(i).toString());
\r
135 if(anot[index]==null)
\r
136 anot[index] = new Annotation(label, "", ' ',0);
\r
137 anot[index].displayCharacter = label;
\r
140 else if(evt.getActionCommand().equals(COLOUR))
\r
142 Color col = JColorChooser.showDialog(this, "Choose foreground colour", Color.black);
\r
143 for (int i = 0; i < activeRes.size(); i++)
\r
145 int index = Integer.parseInt(activeRes.get(i).toString());
\r
146 if (anot[index] == null)
\r
147 anot[index] = new Annotation("", "", ' ', 0);
\r
148 anot[index].colour = col;
\r
151 else // HELIX OR SHEET
\r
154 String symbol = "\u03B1";
\r
155 if(evt.getActionCommand().equals(HELIX))
\r
157 else if(evt.getActionCommand().equals(SHEET))
\r
163 if(!aa[activeRow].hasIcons)
\r
164 aa[activeRow].hasIcons = true;
\r
167 String label = JOptionPane.showInputDialog("Enter a label for the structure?", symbol );
\r
171 if(label.length()>0 && !aa[activeRow].hasText)
\r
172 aa[activeRow].hasText = true;
\r
174 for(int i=0; i<activeRes.size(); i++)
\r
176 int index = Integer.parseInt(activeRes.get(i).toString());
\r
177 if (anot[index] == null)
\r
179 anot[index] = new Annotation(label, "", type, 0);
\r
182 anot[ index ].secondaryStructure = type;
\r
183 anot[ index ].displayCharacter = label;
\r
187 adjustPanelHeight();
\r
195 public void mousePressed(MouseEvent evt)
\r
197 if (SwingUtilities.isRightMouseButton(evt))
\r
199 if(activeRes==null)
\r
202 JPopupMenu pop = new JPopupMenu("Structure type");
\r
203 JMenuItem item = new JMenuItem(HELIX);
\r
204 item.addActionListener(this);
\r
206 item = new JMenuItem(SHEET);
\r
207 item.addActionListener(this);
\r
209 item = new JMenuItem(LABEL);
\r
210 item.addActionListener(this);
\r
212 item = new JMenuItem(COLOUR);
\r
213 item.addActionListener(this);
\r
215 item = new JMenuItem(REMOVE);
\r
216 item.addActionListener(this);
\r
218 pop.show(this, evt.getX(), evt.getY());
\r
223 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
229 for(int i=0; i<aa.length; i++)
\r
231 height+= aa[i].height;
\r
233 if(evt.getY()<height)
\r
235 if(!aa[i].editable)
\r
247 int res = evt.getX() / av.getCharWidth() + av.getStartRes();
\r
249 if(evt.isControlDown() || evt.isAltDown())
\r
250 addEditableColumn(res);
\r
252 else if(evt.isShiftDown())
\r
255 if(activeRes==null)
\r
256 activeRes=new ArrayList();
\r
259 int start = Integer.parseInt( activeRes.get( activeRes.size()-1 ).toString() );
\r
267 for(int n=start; n<=end; n++)
\r
268 addEditableColumn(n);
\r
274 activeRes = new ArrayList();
\r
275 activeRes.add( String.valueOf(res) );
\r
281 public void mouseReleased(MouseEvent evt)
\r
283 public void mouseEntered(MouseEvent evt)
\r
285 public void mouseExited(MouseEvent evt)
\r
287 public void mouseDragged(MouseEvent evt)
\r
289 public void mouseMoved(MouseEvent evt)
\r
291 ToolTipManager.sharedInstance().registerComponent(this);
\r
292 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
298 for(int i=0; i<aa.length; i++)
\r
301 if( aa[i].visible )
\r
302 height += aa[i].height;
\r
304 if(evt.getY()<height)
\r
311 int res = evt.getX() / av.getCharWidth() + av.getStartRes();
\r
312 if(row>-1 && res<aa[row].annotations.length && aa[row].annotations[res]!=null)
\r
313 this.setToolTipText(aa[row].annotations[res].description);
\r
316 public void mouseClicked(MouseEvent evt) {}
\r
319 public void paintComponent(Graphics g)
\r
321 g.setColor(Color.white);
\r
322 g.fillRect(0,0,getWidth(), getHeight());
\r
326 g.drawImage(image, 0, 0, this);
\r
331 imgWidth = (av.endRes-av.startRes+1) *av.charWidth;
\r
333 image = new BufferedImage(imgWidth,
\r
334 ap.annotationPanel.getHeight(),
\r
335 BufferedImage.TYPE_INT_RGB);
\r
336 gg = (Graphics2D) image.getGraphics();
\r
337 gg.setColor(Color.white);
\r
338 gg.fillRect(0, 0, imgWidth, getHeight());
\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
345 drawComponent( gg, av.startRes, av.endRes+1);
\r
346 g.drawImage( image, 0, 0, this);
\r
349 public void fastPaint(int horizontal)
\r
351 if(image==null || horizontal ==0)
\r
357 gg.copyArea( 0,0, imgWidth, getHeight(), -horizontal*av.charWidth, 0 );
\r
358 int sr=av.startRes, er=av.endRes+1, transX=0;
\r
360 if(horizontal>0) // scrollbar pulled right, image to the left
\r
362 transX = (er-sr-horizontal)*av.charWidth;
\r
363 sr = er - horizontal ;
\r
365 else if(horizontal<0)
\r
367 er = sr-horizontal;
\r
371 gg.translate(transX, 0);
\r
373 drawComponent(gg, sr, er);
\r
375 gg.translate( -transX, 0 );
\r
382 public void drawComponent(Graphics2D g, int startRes, int endRes)
\r
384 g.setColor(Color.white);
\r
385 g.fillRect(0,0,(endRes-startRes) *av.charWidth, getHeight());
\r
386 if(av.alignment.getAlignmentAnnotation()==null || av.alignment.getAlignmentAnnotation().length<1)
\r
388 g.setColor(Color.black);
\r
389 g.drawString("Alignment has no annotations",20,15);
\r
393 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
396 char [] lastSS = new char[aa.length];
\r
397 int [] lastSSX= new int[aa.length] ;
\r
398 int iconOffset = av.charHeight/2;
\r
399 boolean validRes = false;
\r
401 for(int i=0; i<aa.length; i++)
\r
403 AlignmentAnnotation row = aa[i];
\r
409 // this is so that we draw the characters below the graph
\r
412 y -= av.charHeight;
\r
415 iconOffset = av.charHeight/2;
\r
419 for(j=startRes; j<endRes; j++)
\r
421 validRes = row.annotations[j]==null?false:true;
\r
423 x = (j-startRes)*av.charWidth;
\r
429 g.setColor(Color.red);
\r
431 if(activeRes!=null)
\r
432 for (int n = 0; n < activeRes.size(); n++)
\r
434 int v = Integer.parseInt(activeRes.get(n).toString()) ;
\r
436 g.fillRect( (j-startRes) * av.charWidth, y, av.charWidth, row.height);
\r
442 if(validRes && row.annotations[j].displayCharacter.length()>0)
\r
444 int charOffset = (av.charWidth -
\r
445 fm.charWidth(row.annotations[j].displayCharacter.
\r
447 g.setColor( row.annotations[j].colour);
\r
450 if (row.annotations[0].secondaryStructure == 'H'
\r
451 || row.annotations[0].secondaryStructure == 'E')
\r
452 g.drawString(row.annotations[j].displayCharacter, x,
\r
453 y + iconOffset + 2);
\r
455 else if( (row.annotations[j].secondaryStructure=='H'
\r
456 || row.annotations[j].secondaryStructure=='E') &&
\r
457 (row.annotations[j-1]==null ||
\r
458 row.annotations[j].secondaryStructure!=row.annotations[j-1].secondaryStructure))
\r
460 g.drawString(row.annotations[j].displayCharacter, x, y + iconOffset + 2);
\r
463 g.drawString(row.annotations[j].displayCharacter, x + charOffset,
\r
464 y + iconOffset + 2);
\r
468 if(!validRes || row.annotations[j].secondaryStructure!=lastSS[i])
\r
473 g.setColor(HELIX_COLOUR);
\r
474 g.fillRoundRect(lastSSX[i], y+4 + iconOffset, x-lastSSX[i], 7, 8, 8);
\r
477 g.setColor(SHEET_COLOUR);
\r
478 g.fillRect(lastSSX[i], y + 4 + iconOffset, x-lastSSX[i]-4, 7);
\r
479 g.fillPolygon(new int[] {x - 4, x- 4, x }
\r
480 , new int[]{y+ iconOffset, y + 14+ iconOffset, y + 8+ iconOffset}, 3);
\r
485 g.setColor(Color.gray);
\r
486 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
491 lastSS[i] = row.annotations[j].secondaryStructure;
\r
497 if (validRes && row.isGraph)
\r
499 g.setColor(new Color(0,0,180));
\r
500 int height = (int)((row.annotations[j].value / row.graphMax)*50);
\r
502 if(row.windowLength>1)
\r
505 for(int i2=j- (row.windowLength/2); i2<j+(row.windowLength/2); i2++)
\r
507 if(i2<0 || i2>=av.alignment.getWidth())
\r
510 total += row.annotations[i2].value;
\r
513 total/=row.windowLength;
\r
514 height = (int)( (total / row.graphMax) *50);
\r
518 g.fillRect(x, y-height, av.charWidth, height );
\r
530 g.setColor(HELIX_COLOUR);
\r
531 g.fillRoundRect(lastSSX[i], y+4+ iconOffset, x - lastSSX[i], 7, 8, 8);
\r
534 g.setColor(SHEET_COLOUR);
\r
535 g.fillRect(lastSSX[i], y + 4+ iconOffset, x - lastSSX[i] - 4, 7);
\r
536 g.fillPolygon(new int[]
\r
539 {y + iconOffset, y + 14+ iconOffset, y + 7+ iconOffset}
\r
545 g.setColor(Color.gray);
\r
546 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
551 if(row.isGraph && row.hasText)
\r
558 // used by overview window
\r
559 public void drawGraph(Graphics g, AlignmentAnnotation aa,int width, int y)
\r
561 g.setColor(Color.white);
\r
562 g.fillRect(0,0,width, y);
\r
563 g.setColor(new Color(0,0,180));
\r
565 for(int j=0; j<aa.annotations.length; j++)
\r
567 g.setColor(new Color(0, 0, 180));
\r
568 int height = (int) ( (aa.annotations[j].value / aa.graphMax) * 50);
\r
569 g.fillRect(x, y - height, av.charWidth, height);
\r