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
35 public AnnotationPanel(AlignmentPanel ap)
\r
39 this.setLayout(null);
\r
40 addMouseListener(this);
\r
41 addMouseMotionListener(this);
\r
42 adjustPanelHeight();
\r
45 ap.annotationScroller.getVerticalScrollBar().addAdjustmentListener( this );
\r
48 public void adjustmentValueChanged(AdjustmentEvent evt)
\r
50 ap.alabels.setScrollOffset( -evt.getValue() );
\r
53 public void adjustPanelHeight()
\r
55 // setHeight of panels
\r
56 AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
\r
59 for (int i = 0; i < aa.length; i++)
\r
67 aa[i].height += av.charHeight;
\r
76 height += aa[i].height;
\r
79 this.setPreferredSize(new Dimension(1, height));
\r
83 public void addEditableColumn(int i)
\r
87 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
88 for(int j=0; j<aa.length; j++)
\r
98 activeRes = new ArrayList();
\r
99 activeRes.add(String.valueOf(i));
\r
103 activeRes.add(String.valueOf(i));
\r
108 public void actionPerformed(ActionEvent evt)
\r
111 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
112 Annotation [] anot = aa[activeRow].annotations;
\r
114 if(evt.getActionCommand().equals(REMOVE))
\r
116 for(int i=0; i<activeRes.size(); i++)
\r
118 anot[Integer.parseInt(activeRes.get(i).toString())] = null;
\r
119 anot[Integer.parseInt(activeRes.get(i).toString())] = null;
\r
122 else if(evt.getActionCommand().equals(LABEL))
\r
124 String label = JOptionPane.showInputDialog(this, "Enter Label ", "Enter label", JOptionPane.QUESTION_MESSAGE );
\r
128 if(label.length()>0 && !aa[activeRow].hasText)
\r
129 aa[activeRow].hasText = true;
\r
131 for(int i=0; i<activeRes.size(); i++)
\r
133 int index = Integer.parseInt(activeRes.get(i).toString());
\r
134 if(anot[index]==null)
\r
135 anot[index] = new Annotation(label, "", ' ',0);
\r
136 anot[index].displayCharacter = label;
\r
139 else if(evt.getActionCommand().equals(COLOUR))
\r
141 Color col = JColorChooser.showDialog(this, "Choose foreground colour", Color.black);
\r
142 for (int i = 0; i < activeRes.size(); i++)
\r
144 int index = Integer.parseInt(activeRes.get(i).toString());
\r
145 if (anot[index] == null)
\r
146 anot[index] = new Annotation("", "", ' ', 0);
\r
147 anot[index].colour = col;
\r
150 else // HELIX OR SHEET
\r
153 String symbol = "\u03B1";
\r
154 if(evt.getActionCommand().equals(HELIX))
\r
156 else if(evt.getActionCommand().equals(SHEET))
\r
162 if(!aa[activeRow].hasIcons)
\r
163 aa[activeRow].hasIcons = true;
\r
166 String label = JOptionPane.showInputDialog("Enter a label for the structure?", symbol );
\r
170 if(label.length()>0 && !aa[activeRow].hasText)
\r
171 aa[activeRow].hasText = true;
\r
173 for(int i=0; i<activeRes.size(); i++)
\r
175 int index = Integer.parseInt(activeRes.get(i).toString());
\r
176 if (anot[index] == null)
\r
178 anot[index] = new Annotation(label, "", type, 0);
\r
181 anot[ index ].secondaryStructure = type;
\r
182 anot[ index ].displayCharacter = label;
\r
186 adjustPanelHeight();
\r
194 public void mousePressed(MouseEvent evt)
\r
196 if (SwingUtilities.isRightMouseButton(evt))
\r
198 if(activeRes==null)
\r
201 JPopupMenu pop = new JPopupMenu("Structure type");
\r
202 JMenuItem item = new JMenuItem(HELIX);
\r
203 item.addActionListener(this);
\r
205 item = new JMenuItem(SHEET);
\r
206 item.addActionListener(this);
\r
208 item = new JMenuItem(LABEL);
\r
209 item.addActionListener(this);
\r
211 item = new JMenuItem(COLOUR);
\r
212 item.addActionListener(this);
\r
214 item = new JMenuItem(REMOVE);
\r
215 item.addActionListener(this);
\r
217 pop.show(this, evt.getX(), evt.getY());
\r
222 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
228 for(int i=0; i<aa.length; i++)
\r
230 height+= aa[i].height;
\r
232 if(evt.getY()<height)
\r
234 if(!aa[i].editable)
\r
246 int res = evt.getX() / av.getCharWidth() + av.getStartRes();
\r
248 if(evt.isControlDown() || evt.isAltDown())
\r
249 addEditableColumn(res);
\r
251 else if(evt.isShiftDown())
\r
254 if(activeRes==null)
\r
255 activeRes=new ArrayList();
\r
258 int start = Integer.parseInt( activeRes.get( activeRes.size()-1 ).toString() );
\r
266 for(int n=start; n<=end; n++)
\r
267 addEditableColumn(n);
\r
273 activeRes = new ArrayList();
\r
274 activeRes.add( String.valueOf(res) );
\r
280 public void mouseReleased(MouseEvent evt)
\r
282 public void mouseEntered(MouseEvent evt)
\r
284 public void mouseExited(MouseEvent evt)
\r
286 public void mouseDragged(MouseEvent evt)
\r
288 public void mouseMoved(MouseEvent evt)
\r
290 ToolTipManager.sharedInstance().registerComponent(this);
\r
291 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
297 for(int i=0; i<aa.length; i++)
\r
300 if( aa[i].visible )
\r
301 height += aa[i].height;
\r
303 if(evt.getY()<height)
\r
310 int res = evt.getX() / av.getCharWidth() + av.getStartRes();
\r
311 if(row>-1 && res<aa[row].annotations.length && aa[row].annotations[res]!=null)
\r
312 this.setToolTipText(aa[row].annotations[res].description);
\r
315 public void mouseClicked(MouseEvent evt) {}
\r
318 public void paintComponent(Graphics g)
\r
320 g.setColor(Color.white);
\r
321 g.fillRect(0,0,getWidth(), getHeight());
\r
323 imgWidth = (av.endRes-av.startRes+1) *av.charWidth;
\r
325 image = new BufferedImage(imgWidth,
\r
326 ap.annotationPanel.getHeight(),
\r
327 BufferedImage.TYPE_INT_RGB);
\r
328 gg = (Graphics2D) image.getGraphics();
\r
329 gg.setColor(Color.white);
\r
330 gg.fillRect(0, 0, imgWidth, getHeight());
\r
331 gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
\r
332 RenderingHints.VALUE_ANTIALIAS_ON);
\r
333 fm = gg.getFontMetrics();
\r
334 gg.setFont(av.getFont());
\r
337 drawComponent( gg, av.startRes, av.endRes+1);
\r
338 g.drawImage( image, 0, 0, this);
\r
341 public void fastPaint(int horizontal)
\r
343 if(image==null || horizontal ==0)
\r
349 gg.copyArea( 0,0, imgWidth, getHeight(), -horizontal*av.charWidth, 0 );
\r
350 int sr=av.startRes, er=av.endRes+1, transX=0;
\r
352 if(horizontal>0) // scrollbar pulled right, image to the left
\r
354 transX = (er-sr-horizontal)*av.charWidth;
\r
355 sr = er - horizontal ;
\r
357 else if(horizontal<0)
\r
359 er = sr-horizontal;
\r
363 gg.translate(transX, 0);
\r
365 drawComponent(gg, sr, er);
\r
367 gg.translate( -transX, 0 );
\r
369 getGraphics().drawImage(image, 0, 0, this);
\r
373 public void drawComponent(Graphics2D g, int startRes, int endRes)
\r
375 g.setColor(Color.white);
\r
376 g.fillRect(0,0,(endRes-startRes) *av.charWidth, getHeight());
\r
377 if(av.alignment.getAlignmentAnnotation()==null || av.alignment.getAlignmentAnnotation().length<1)
\r
379 g.setColor(Color.black);
\r
380 g.drawString("Alignment has no annotations",20,15);
\r
384 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
387 char [] lastSS = new char[aa.length];
\r
388 int [] lastSSX= new int[aa.length] ;
\r
389 int iconOffset = av.charHeight/2;
\r
390 boolean validRes = false;
\r
392 for(int i=0; i<aa.length; i++)
\r
394 AlignmentAnnotation row = aa[i];
\r
400 // this is so that we draw the characters below the graph
\r
403 y -= av.charHeight;
\r
406 iconOffset = av.charHeight/2;
\r
410 for(j=startRes; j<endRes; j++)
\r
412 validRes = row.annotations[j]==null?false:true;
\r
414 x = (j-startRes)*av.charWidth;
\r
420 g.setColor(Color.red);
\r
422 if(activeRes!=null)
\r
423 for (int n = 0; n < activeRes.size(); n++)
\r
425 int v = Integer.parseInt(activeRes.get(n).toString()) ;
\r
427 g.fillRect( (j-startRes) * av.charWidth, y, av.charWidth, row.height);
\r
433 if(validRes && row.annotations[j].displayCharacter.length()>0)
\r
435 int charOffset = (av.charWidth -
\r
436 fm.charWidth(row.annotations[j].displayCharacter.
\r
438 g.setColor( row.annotations[j].colour);
\r
441 if (row.annotations[0].secondaryStructure == 'H'
\r
442 || row.annotations[0].secondaryStructure == 'E')
\r
443 g.drawString(row.annotations[j].displayCharacter, x,
\r
444 y + iconOffset + 2);
\r
446 else if( (row.annotations[j].secondaryStructure=='H'
\r
447 || row.annotations[j].secondaryStructure=='E') &&
\r
448 (row.annotations[j-1]==null ||
\r
449 row.annotations[j].secondaryStructure!=row.annotations[j-1].secondaryStructure))
\r
451 g.drawString(row.annotations[j].displayCharacter, x, y + iconOffset + 2);
\r
454 g.drawString(row.annotations[j].displayCharacter, x + charOffset,
\r
455 y + iconOffset + 2);
\r
459 if(!validRes || row.annotations[j].secondaryStructure!=lastSS[i])
\r
464 g.setColor(HELIX_COLOUR);
\r
465 g.fillRoundRect(lastSSX[i], y+4 + iconOffset, x-lastSSX[i], 7, 8, 8);
\r
468 g.setColor(SHEET_COLOUR);
\r
469 g.fillRect(lastSSX[i], y + 4 + iconOffset, x-lastSSX[i]-4, 7);
\r
470 g.fillPolygon(new int[] {x - 4, x- 4, x }
\r
471 , new int[]{y+ iconOffset, y + 14+ iconOffset, y + 8+ iconOffset}, 3);
\r
476 g.setColor(Color.gray);
\r
477 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
482 lastSS[i] = row.annotations[j].secondaryStructure;
\r
488 if (validRes && row.isGraph)
\r
490 g.setColor(new Color(0,0,180));
\r
491 int height = (int)((row.annotations[j].value / row.graphMax)*50);
\r
493 if(row.windowLength>1)
\r
496 for(int i2=j- (row.windowLength/2); i2<j+(row.windowLength/2); i2++)
\r
498 if(i2<0 || i2>=av.alignment.getWidth())
\r
501 total += row.annotations[i2].value;
\r
504 total/=row.windowLength;
\r
505 height = (int)( (total / row.graphMax) *50);
\r
509 g.fillRect(x, y-height, av.charWidth, height );
\r
521 g.setColor(HELIX_COLOUR);
\r
522 g.fillRoundRect(lastSSX[i], y+4+ iconOffset, x - lastSSX[i], 7, 8, 8);
\r
525 g.setColor(SHEET_COLOUR);
\r
526 g.fillRect(lastSSX[i], y + 4+ iconOffset, x - lastSSX[i] - 4, 7);
\r
527 g.fillPolygon(new int[]
\r
530 {y + iconOffset, y + 14+ iconOffset, y + 7+ iconOffset}
\r
536 g.setColor(Color.gray);
\r
537 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
542 if(row.isGraph && row.hasText)
\r
549 // used by overview window
\r
550 public void drawGraph(Graphics g, AlignmentAnnotation aa,int width, int y)
\r
552 g.setColor(Color.white);
\r
553 g.fillRect(0,0,width, y);
\r
554 g.setColor(new Color(0,0,180));
\r
556 for(int j=0; j<aa.annotations.length; j++)
\r
558 g.setColor(new Color(0, 0, 180));
\r
559 int height = (int) ( (aa.annotations[j].value / aa.graphMax) * 50);
\r
560 g.fillRect(x, y - height, av.charWidth, height);
\r