2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4.0.b2)
3 * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 package jalview.appletgui;
24 import java.awt.event.*;
26 import jalview.datamodel.*;
28 public class FeatureSettings extends Panel implements ItemListener,
29 MouseListener, MouseMotionListener, ActionListener,
42 Panel featurePanel = new Panel();
44 ScrollPane scrollPane;
46 boolean alignmentHasFeatures = false;
50 Scrollbar transparency;
52 public FeatureSettings(final AlignmentPanel ap)
56 ap.av.featureSettings = this;
57 fr = ap.seqPanel.seqCanvas.getFeatureRenderer();
59 transparency = new Scrollbar(Scrollbar.HORIZONTAL,
60 100 - (int) (fr.transparency * 100), 1, 1, 100);
62 if (fr.transparencySetter != null)
64 transparency.addAdjustmentListener(this);
68 transparency.setEnabled(false);
71 java.net.URL url = getClass().getResource("/images/link.gif");
74 linkImage = java.awt.Toolkit.getDefaultToolkit().getImage(url);
77 if (av.featuresDisplayed == null)
84 this.setLayout(new BorderLayout());
85 scrollPane = new ScrollPane();
86 scrollPane.add(featurePanel);
87 if (alignmentHasFeatures)
89 add(scrollPane, BorderLayout.CENTER);
92 Button invert = new Button("Invert Selection");
93 invert.addActionListener(this);
95 Panel lowerPanel = new Panel(new GridLayout(2, 1, 5, 10));
96 lowerPanel.add(invert);
98 Panel tPanel = new Panel(new BorderLayout());
100 if (fr.transparencySetter != null)
102 tPanel.add(transparency, BorderLayout.CENTER);
103 tPanel.add(new Label("Transparency"), BorderLayout.EAST);
108 new Label("Transparency not available in this web browser"),
109 BorderLayout.CENTER);
112 lowerPanel.add(tPanel, BorderLayout.SOUTH);
114 add(lowerPanel, BorderLayout.SOUTH);
116 if (groupPanel != null)
118 groupPanel.setLayout(new GridLayout(fr.featureGroups.size() / 4 + 1,
120 groupPanel.validate();
122 add(groupPanel, BorderLayout.NORTH);
126 final FeatureSettings me = this;
127 frame.addWindowListener(new WindowAdapter()
129 public void windowClosing(WindowEvent e)
131 if (me.av.featureSettings == me)
133 me.av.featureSettings = null;
139 int height = featurePanel.getComponentCount() * 50 + 60;
141 height = Math.max(200, height);
142 height = Math.min(400, height);
144 jalview.bin.JalviewLite.addFrame(frame, "Feature Settings", width,
148 public void paint(Graphics g)
150 g.setColor(Color.black);
151 g.drawString("No Features added to this alignment!!", 10, 20);
152 g.drawString("(Features can be added from searches or", 10, 40);
153 g.drawString("from Jalview / GFF features files)", 10, 60);
156 public void setTableData()
158 alignmentHasFeatures = fr.buildGroupHash();
159 if (alignmentHasFeatures)
168 * rebuilds the group panel
170 public void rebuildGroups()
172 boolean rdrw = false;
173 if (groupPanel == null)
175 groupPanel = new Panel();
180 groupPanel.removeAll();
183 Enumeration gps = fr.featureGroups.keys();
184 while (gps.hasMoreElements())
186 String group = (String) gps.nextElement();
187 Boolean vis = (Boolean) fr.featureGroups.get(group);
188 Checkbox check = new MyCheckbox(group, vis.booleanValue(),
189 (fr.featureLinks != null && fr.featureLinks
190 .containsKey(group)));
191 check.addMouseListener(this);
192 check.setFont(new Font("Serif", Font.BOLD, 12));
193 check.addItemListener(this);
194 groupPanel.add(check);
198 groupPanel.validate();
202 // This routine adds and removes checkboxes depending on
203 // Group selection states
204 void resetTable(boolean groupsChanged)
206 SequenceFeature[] tmpfeatures;
207 String group = null, type;
208 Vector visibleChecks = new Vector();
210 for (int i = 0; i < av.alignment.getHeight(); i++)
212 if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)
217 tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();
219 while (index < tmpfeatures.length)
221 group = tmpfeatures[index].featureGroup;
223 if (group == null || fr.featureGroups.get(group) == null
224 || ((Boolean) fr.featureGroups.get(group)).booleanValue())
226 type = tmpfeatures[index].getType();
227 if (!visibleChecks.contains(type))
229 visibleChecks.addElement(type);
237 int cSize = featurePanel.getComponentCount();
239 // This will remove any checkboxes which shouldn't be
241 for (int i = 0; i < cSize; i++)
243 comps = featurePanel.getComponents();
244 check = (Checkbox) comps[i];
245 if (!visibleChecks.contains(check.getLabel()))
247 featurePanel.remove(i);
253 if (fr.renderOrder != null)
255 // First add the checks in the previous render order,
256 // in case the window has been closed and reopened
257 for (int ro = fr.renderOrder.length - 1; ro > -1; ro--)
259 String item = fr.renderOrder[ro];
261 if (!visibleChecks.contains(item))
266 visibleChecks.removeElement(item);
268 addCheck(false, item);
272 // now add checkboxes which should be visible,
273 // if they have not already been added
274 Enumeration en = visibleChecks.elements();
276 while (en.hasMoreElements())
278 addCheck(groupsChanged, en.nextElement().toString());
281 featurePanel.setLayout(new GridLayout(featurePanel.getComponentCount(),
283 featurePanel.validate();
285 if (scrollPane != null)
287 scrollPane.validate();
290 itemStateChanged(null);
294 * update the checklist of feature types with the given type
296 * @param groupsChanged
297 * true means if the type is not in the display list then it
298 * will be added and displayed
300 * feature type to be checked for in the list.
302 void addCheck(boolean groupsChanged, String type)
305 Component[] comps = featurePanel.getComponents();
308 for (int i = 0; i < featurePanel.getComponentCount(); i++)
310 check = (Checkbox) comps[i];
311 if (check.getLabel().equals(type))
320 boolean selected = false;
321 if (groupsChanged || av.featuresDisplayed.containsKey(type))
326 check = new MyCheckbox(
329 (fr.featureLinks != null && fr.featureLinks.containsKey(type)));
331 check.addMouseListener(this);
332 check.addMouseMotionListener(this);
333 check.setBackground(fr.getColour(type));
334 check.addItemListener(this);
337 // add at beginning of stack.
338 featurePanel.add(check, 0);
342 // add at end of stack.
343 featurePanel.add(check);
348 public void actionPerformed(ActionEvent evt)
350 for (int i = 0; i < featurePanel.getComponentCount(); i++)
352 Checkbox check = (Checkbox) featurePanel.getComponent(i);
353 check.setState(!check.getState());
358 public void itemStateChanged(ItemEvent evt)
362 // Is the source a top level featureGroup?
363 Checkbox source = (Checkbox) evt.getSource();
364 if (fr.featureGroups.containsKey(source.getLabel()))
366 fr.featureGroups.put(source.getLabel(), new Boolean(source
368 ap.seqPanel.seqCanvas.repaint();
369 if (ap.overviewPanel != null)
371 ap.overviewPanel.updateOverviewImage();
381 void selectionChanged()
383 Component[] comps = featurePanel.getComponents();
384 int cSize = comps.length;
386 Object[][] tmp = new Object[cSize][3];
388 for (int i = 0; i < cSize; i++)
390 Checkbox check = (Checkbox) comps[i];
391 tmp[tmpSize][0] = check.getLabel();
392 tmp[tmpSize][1] = fr.getColour(check.getLabel());
393 tmp[tmpSize][2] = new Boolean(check.getState());
397 Object[][] data = new Object[tmpSize][3];
398 System.arraycopy(tmp, 0, data, 0, tmpSize);
400 fr.setFeaturePriority(data);
402 ap.paintAlignment(true);
405 MyCheckbox selectedCheck;
407 boolean dragging = false;
409 public void mousePressed(MouseEvent evt)
412 selectedCheck = (MyCheckbox) evt.getSource();
414 if (fr.featureLinks != null
415 && fr.featureLinks.containsKey(selectedCheck.getLabel()))
417 if (evt.getX() > selectedCheck.stringWidth + 20)
425 public void mouseDragged(MouseEvent evt)
427 if (((Component) evt.getSource()).getParent() != featurePanel)
434 public void mouseReleased(MouseEvent evt)
436 if (((Component) evt.getSource()).getParent() != featurePanel)
441 Component comp = null;
442 Checkbox target = null;
444 int height = evt.getY() + evt.getComponent().getLocation().y;
446 if (height > featurePanel.getSize().height)
450 .getComponent(featurePanel.getComponentCount() - 1);
454 comp = featurePanel.getComponent(0);
458 comp = featurePanel.getComponentAt(evt.getX(), evt.getY()
459 + evt.getComponent().getLocation().y);
462 if (comp != null && comp instanceof Checkbox)
464 target = (Checkbox) comp;
467 if (selectedCheck != null && target != null && selectedCheck != target)
469 int targetIndex = -1;
470 for (int i = 0; i < featurePanel.getComponentCount(); i++)
472 if (target == featurePanel.getComponent(i))
479 featurePanel.remove(selectedCheck);
480 featurePanel.add(selectedCheck, targetIndex);
481 featurePanel.validate();
482 itemStateChanged(null);
486 public void setUserColour(String feature, Color col)
488 fr.setColour(feature, col);
489 featurePanel.removeAll();
491 ap.paintAlignment(true);
494 public void mouseEntered(MouseEvent evt)
498 public void mouseExited(MouseEvent evt)
502 public void mouseClicked(MouseEvent evt)
504 MyCheckbox check = (MyCheckbox) evt.getSource();
506 if (fr.featureLinks != null
507 && fr.featureLinks.containsKey(check.getLabel()))
509 if (evt.getX() > check.stringWidth + 20)
512 String link = fr.featureLinks.get(check.getLabel()).toString();
513 ap.alignFrame.showURL(link.substring(link.indexOf("|") + 1), link
514 .substring(0, link.indexOf("|")));
518 if (check.getParent() != featurePanel)
523 if (evt.getClickCount() > 1)
525 new UserDefinedColours(this, check.getLabel(), fr.getColour(check
530 public void mouseMoved(MouseEvent evt)
534 public void adjustmentValueChanged(AdjustmentEvent evt)
536 fr.transparency = ((float) (100 - transparency.getValue()) / 100f);
537 ap.seqPanel.seqCanvas.repaint();
541 class MyCheckbox extends Checkbox
543 public int stringWidth;
547 public MyCheckbox(String label, boolean checked, boolean haslink)
549 super(label, checked);
551 FontMetrics fm = av.nullFrame.getFontMetrics(av.nullFrame.getFont());
552 stringWidth = fm.stringWidth(label);
553 this.hasLink = haslink;
556 public void paint(Graphics g)
560 g.drawImage(linkImage, stringWidth + 25,
561 (getSize().height - linkImage.getHeight(this)) / 2, this);