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
30 public AnnotationPanel(AlignmentPanel ap)
\r
34 this.setLayout(null);
\r
35 addMouseListener(this);
\r
36 addMouseMotionListener(this);
\r
37 adjustPanelHeight();
\r
40 ap.annotationScroller.getVerticalScrollBar().addAdjustmentListener( this );
\r
43 public void adjustmentValueChanged(AdjustmentEvent evt)
\r
45 ap.alabels.setScrollOffset( -evt.getValue() );
\r
48 public void adjustPanelHeight()
\r
50 // setHeight of panels
\r
51 AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
\r
54 for (int i = 0; i < aa.length; i++)
\r
62 aa[i].height += av.charHeight;
\r
71 height += aa[i].height;
\r
74 this.setPreferredSize(new Dimension(1, height));
\r
78 public void addEditableColumn(int i)
\r
82 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
83 for(int j=0; j<aa.length; j++)
\r
93 activeRes = new ArrayList();
\r
94 activeRes.add(String.valueOf(i));
\r
98 activeRes.add(String.valueOf(i));
\r
103 public void actionPerformed(ActionEvent evt)
\r
106 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
107 Annotation [] anot = aa[activeRow].annotations;
\r
109 if(evt.getActionCommand().equals(REMOVE))
\r
111 for(int i=0; i<activeRes.size(); i++)
\r
113 anot[Integer.parseInt(activeRes.get(i).toString())] = null;
\r
114 anot[Integer.parseInt(activeRes.get(i).toString())] = null;
\r
117 else if(evt.getActionCommand().equals(LABEL))
\r
119 String label = JOptionPane.showInputDialog(this, "Enter Label ", "Enter label", JOptionPane.QUESTION_MESSAGE );
\r
123 if(label.length()>0 && !aa[activeRow].hasText)
\r
124 aa[activeRow].hasText = true;
\r
126 for(int i=0; i<activeRes.size(); i++)
\r
128 int index = Integer.parseInt(activeRes.get(i).toString());
\r
129 if(anot[index]==null)
\r
130 anot[index] = new Annotation(label, "", ' ',0);
\r
131 anot[index].displayCharacter = label;
\r
134 else if(evt.getActionCommand().equals(COLOUR))
\r
136 Color col = JColorChooser.showDialog(this, "Choose foreground colour", Color.black);
\r
137 for (int i = 0; i < activeRes.size(); i++)
\r
139 int index = Integer.parseInt(activeRes.get(i).toString());
\r
140 if (anot[index] == null)
\r
141 anot[index] = new Annotation("", "", ' ', 0);
\r
142 anot[index].colour = col;
\r
145 else // HELIX OR SHEET
\r
148 String symbol = "\u03B1";
\r
149 if(evt.getActionCommand().equals(HELIX))
\r
151 else if(evt.getActionCommand().equals(SHEET))
\r
157 if(!aa[activeRow].hasIcons)
\r
158 aa[activeRow].hasIcons = true;
\r
161 String label = JOptionPane.showInputDialog("Enter a label for the structure?", symbol );
\r
165 if(label.length()>0 && !aa[activeRow].hasText)
\r
166 aa[activeRow].hasText = true;
\r
168 for(int i=0; i<activeRes.size(); i++)
\r
170 int index = Integer.parseInt(activeRes.get(i).toString());
\r
171 if (anot[index] == null)
\r
173 anot[index] = new Annotation(label, "", type, 0);
\r
176 anot[ index ].secondaryStructure = type;
\r
177 anot[ index ].displayCharacter = label;
\r
181 adjustPanelHeight();
\r
189 public void mousePressed(MouseEvent evt)
\r
191 if (SwingUtilities.isRightMouseButton(evt))
\r
193 if(activeRes==null)
\r
196 JPopupMenu pop = new JPopupMenu("Structure type");
\r
197 JMenuItem item = new JMenuItem(HELIX);
\r
198 item.addActionListener(this);
\r
200 item = new JMenuItem(SHEET);
\r
201 item.addActionListener(this);
\r
203 item = new JMenuItem(LABEL);
\r
204 item.addActionListener(this);
\r
206 item = new JMenuItem(COLOUR);
\r
207 item.addActionListener(this);
\r
209 item = new JMenuItem(REMOVE);
\r
210 item.addActionListener(this);
\r
212 pop.show(this, evt.getX(), evt.getY());
\r
217 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
223 for(int i=0; i<aa.length; i++)
\r
225 height+= aa[i].height;
\r
227 if(evt.getY()<height)
\r
229 if(!aa[i].editable)
\r
241 int res = evt.getX() / av.getCharWidth() + av.getStartRes();
\r
243 if(evt.isControlDown() || evt.isAltDown())
\r
244 addEditableColumn(res);
\r
246 else if(evt.isShiftDown())
\r
249 if(activeRes==null)
\r
250 activeRes=new ArrayList();
\r
253 int start = Integer.parseInt( activeRes.get( activeRes.size()-1 ).toString() );
\r
261 for(int n=start; n<=end; n++)
\r
262 addEditableColumn(n);
\r
268 activeRes = new ArrayList();
\r
269 activeRes.add( String.valueOf(res) );
\r
275 public void mouseReleased(MouseEvent evt)
\r
277 public void mouseEntered(MouseEvent evt)
\r
279 public void mouseExited(MouseEvent evt)
\r
281 public void mouseDragged(MouseEvent evt)
\r
283 public void mouseMoved(MouseEvent evt)
\r
285 ToolTipManager.sharedInstance().registerComponent(this);
\r
286 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
292 for(int i=0; i<aa.length; i++)
\r
295 if( aa[i].visible )
\r
296 height += aa[i].height;
\r
298 if(evt.getY()<height)
\r
305 int res = evt.getX() / av.getCharWidth() + av.getStartRes();
\r
306 if(row>-1 && aa[row].annotations[res]!=null)
\r
307 this.setToolTipText(aa[row].annotations[res].description);
\r
310 public void mouseClicked(MouseEvent evt) {}
\r
313 public void paintComponent(Graphics g)
\r
316 || bi.getWidth()!=ap.annotationPanel.getWidth()
\r
317 || bi.getHeight()!=ap.annotationPanel.getHeight())
\r
319 bi = new BufferedImage(ap.annotationPanel.getWidth(),
\r
320 ap.annotationPanel.getHeight(),
\r
321 BufferedImage.TYPE_INT_RGB);
\r
324 drawComponent( (Graphics2D)bi.getGraphics() );
\r
325 g.drawImage( bi, 0, 0, this);
\r
328 public void drawComponent(Graphics2D g)
\r
330 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
\r
331 FontMetrics fm = g.getFontMetrics();
\r
332 g.setFont(av.getFont());
\r
333 g.setColor(Color.white);
\r
334 g.fillRect(0,0,getWidth(),getHeight());
\r
336 if(av.alignment.getAlignmentAnnotation()==null || av.alignment.getAlignmentAnnotation().length<1)
\r
338 g.setColor(Color.black);
\r
339 g.drawString("Alignment has no annotations",20,15);
\r
343 AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();
\r
346 char [] lastSS = new char[aa.length];
\r
347 int [] lastSSX= new int[aa.length] ;
\r
348 int iconOffset = av.charHeight/2;
\r
349 boolean validRes = false;
\r
351 for(int i=0; i<aa.length; i++)
\r
353 AlignmentAnnotation row = aa[i];
\r
359 // this is so that we draw the characters below the graph
\r
362 y -= av.charHeight;
\r
365 iconOffset = av.charHeight/2;
\r
369 for(j=av.startRes; j<av.endRes+1; j++)
\r
371 validRes = row.annotations[j]==null?false:true;
\r
373 x = (j-av.getStartRes())*av.charWidth;
\r
379 g.setColor(Color.red);
\r
381 if(activeRes!=null)
\r
382 for (int n = 0; n < activeRes.size(); n++)
\r
384 int v = Integer.parseInt(activeRes.get(n).toString()) ;
\r
386 g.fillRect( (j-av.getStartRes()) * av.charWidth, y, av.charWidth, row.height);
\r
392 if(validRes && row.annotations[j].displayCharacter.length()>0)
\r
394 int charOffset = (av.charWidth -
\r
395 fm.charWidth(row.annotations[j].displayCharacter.
\r
397 g.setColor( row.annotations[j].colour);
\r
400 if (row.annotations[0].secondaryStructure == 'H'
\r
401 || row.annotations[0].secondaryStructure == 'E')
\r
402 g.drawString(row.annotations[j].displayCharacter, x,
\r
403 y + iconOffset + 2);
\r
405 else if( (row.annotations[j].secondaryStructure=='H'
\r
406 || row.annotations[j].secondaryStructure=='E') &&
\r
407 (row.annotations[j-1]==null ||
\r
408 row.annotations[j].secondaryStructure!=row.annotations[j-1].secondaryStructure))
\r
410 g.drawString(row.annotations[j].displayCharacter, x, y + iconOffset + 2);
\r
413 g.drawString(row.annotations[j].displayCharacter, x + charOffset,
\r
414 y + iconOffset + 2);
\r
418 if(!validRes || row.annotations[j].secondaryStructure!=lastSS[i])
\r
423 g.setColor(HELIX_COLOUR);
\r
424 g.fillRoundRect(lastSSX[i], y+4 + iconOffset, x-lastSSX[i], 7, 8, 8);
\r
427 g.setColor(SHEET_COLOUR);
\r
428 g.fillRect(lastSSX[i], y + 4 + iconOffset, x-lastSSX[i]-4, 7);
\r
429 g.fillPolygon(new int[] {x - 4, x- 4, x }
\r
430 , new int[]{y+ iconOffset, y + 14+ iconOffset, y + 8+ iconOffset}, 3);
\r
435 g.setColor(Color.gray);
\r
436 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
441 lastSS[i] = row.annotations[j].secondaryStructure;
\r
447 if (validRes && row.isGraph)
\r
449 g.setColor(new Color(0,0,180));
\r
450 int height = (int)((row.annotations[j].value / row.graphMax)*50);
\r
452 if(row.windowLength>1)
\r
455 for(int i2=j- (row.windowLength/2); i2<j+(row.windowLength/2); i2++)
\r
457 if(i2<0 || i2>=av.alignment.getWidth())
\r
460 total += row.annotations[i2].value;
\r
463 total/=row.windowLength;
\r
464 height = (int)( (total / row.graphMax) *50);
\r
468 g.fillRect(x, y-height, av.charWidth, height );
\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[]
\r
489 {y + iconOffset, y + 14+ iconOffset, y + 7+ iconOffset}
\r
495 g.setColor(Color.gray);
\r
496 g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);
\r
501 if(row.isGraph && row.hasText)
\r
508 // used by overview window
\r
509 public void drawGraph(Graphics g, AlignmentAnnotation aa,int width, int y)
\r
511 g.setColor(Color.white);
\r
512 g.fillRect(0,0,width, y);
\r
513 g.setColor(new Color(0,0,180));
\r
515 for(int j=0; j<aa.annotations.length; j++)
\r
517 g.setColor(new Color(0, 0, 180));
\r
518 int height = (int) ( (aa.annotations[j].value / aa.graphMax) * 50);
\r
519 g.fillRect(x, y - height, av.charWidth, height);
\r