2 * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
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
25 import java.awt.event.*;
26 import java.beans.PropertyChangeEvent;
27 import java.beans.PropertyChangeListener;
30 import javax.swing.event.*;
31 import javax.swing.table.*;
33 import jalview.analysis.AlignmentSorter;
34 import jalview.commands.OrderCommand;
35 import jalview.datamodel.*;
37 import jalview.schemes.GraduatedColor;
39 public class FeatureSettings extends JPanel
41 DasSourceBrowser dassourceBrowser;
43 jalview.ws.DasSequenceFeatureFetcher dasFeatureFetcher;
45 JPanel settingsPane = new JPanel();
47 JPanel dasSettingsPane = new JPanel();
49 final FeatureRenderer fr;
51 public final AlignFrame af;
53 Object[][] originalData;
55 final JInternalFrame frame;
57 JScrollPane scrollPane = new JScrollPane();
63 JSlider transparency = new JSlider();
65 JPanel transPanel = new JPanel(new FlowLayout());
67 public FeatureSettings(AlignFrame af)
70 fr = af.getFeatureRenderer();
72 transparency.setMaximum(100 - (int) (fr.transparency * 100));
77 } catch (Exception ex)
83 table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12));
84 table.setFont(new Font("Verdana", Font.PLAIN, 12));
85 table.setDefaultRenderer(Color.class, new ColorRenderer());
87 table.setDefaultEditor(Color.class, new ColorEditor());
89 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
91 table.addMouseListener(new MouseAdapter()
93 public void mousePressed(MouseEvent evt)
95 selectedRow = table.rowAtPoint(evt.getPoint());
96 if (javax.swing.SwingUtilities.isRightMouseButton(evt))
98 popupSort((String) table.getValueAt(selectedRow, 0), fr.minmax,
99 evt.getX(), evt.getY());
104 table.addMouseMotionListener(new MouseMotionAdapter()
106 public void mouseDragged(MouseEvent evt)
108 int newRow = table.rowAtPoint(evt.getPoint());
109 if (newRow != selectedRow && selectedRow != -1 && newRow != -1)
111 Object[] temp = new Object[3];
112 temp[0] = table.getValueAt(selectedRow, 0);
113 temp[1] = table.getValueAt(selectedRow, 1);
114 temp[2] = table.getValueAt(selectedRow, 2);
116 table.setValueAt(table.getValueAt(newRow, 0), selectedRow, 0);
117 table.setValueAt(table.getValueAt(newRow, 1), selectedRow, 1);
118 table.setValueAt(table.getValueAt(newRow, 2), selectedRow, 2);
120 table.setValueAt(temp[0], newRow, 0);
121 table.setValueAt(temp[1], newRow, 1);
122 table.setValueAt(temp[2], newRow, 2);
124 selectedRow = newRow;
129 scrollPane.setViewportView(table);
131 dassourceBrowser = new DasSourceBrowser();
132 dasSettingsPane.add(dassourceBrowser, BorderLayout.CENTER);
134 if (af.getViewport().featuresDisplayed == null
135 || fr.renderOrder == null)
137 fr.findAllFeatures(true); // display everything!
141 final PropertyChangeListener change;
142 final FeatureSettings fs = this;
143 fr.addPropertyChangeListener(change = new PropertyChangeListener()
145 public void propertyChange(PropertyChangeEvent evt)
147 if (!fs.resettingTable && !fs.handlingUpdate)
149 fs.handlingUpdate = true;
150 fs.resetTable(null); // new groups may be added with new seuqence
151 // feature types only
152 fs.handlingUpdate = false;
158 frame = new JInternalFrame();
159 frame.setContentPane(this);
160 Desktop.addInternalFrame(frame, "Sequence Feature Settings", 400, 450);
162 .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
164 public void internalFrameClosed(
165 javax.swing.event.InternalFrameEvent evt)
167 fr.removePropertyChangeListener(change);
170 frame.setLayer(JLayeredPane.PALETTE_LAYER);
173 protected void popupSort(final String type, final Hashtable minmax,
176 JPopupMenu men = new JPopupMenu("Settings for " + type);
177 JMenuItem scr = new JMenuItem("Sort by Score");
179 final FeatureSettings me = this;
180 scr.addActionListener(new ActionListener()
183 public void actionPerformed(ActionEvent e)
185 me.sortByScore(new String[]
190 JMenuItem dens = new JMenuItem("Sort by Density");
191 dens.addActionListener(new ActionListener()
194 public void actionPerformed(ActionEvent e)
196 me.sortByDens(new String[]
204 final Object typeMinMax = minmax.get(type);
205 final JCheckBoxMenuItem chb = new JCheckBoxMenuItem("Vary Height");
206 // this is broken at the moment
207 chb.setSelected(minmax.get(type) != null);
208 chb.addActionListener(new ActionListener()
211 public void actionPerformed(ActionEvent e)
213 chb.setState(chb.getState());
216 minmax.put(type, null);
220 minmax.put(type, typeMinMax);
226 if (typeMinMax != null && ((float[][]) typeMinMax)[0] != null)
228 // graduated colourschemes for those where minmax exists for the positional features
229 JMenuItem mxcol = new JMenuItem("Min Max Colour");
231 mxcol.addActionListener(new ActionListener()
234 public void actionPerformed(ActionEvent e)
236 new FeatureColourChooser(me, type);
242 men.show(table, x, y);
246 * true when Feature Settings are updating from feature renderer
248 private boolean handlingUpdate = false;
251 * contains a float[3] for each feature type string. created by setTableData
253 Hashtable typeWidth = null;
255 synchronized public void setTableData()
257 if (fr.featureGroups == null)
259 fr.featureGroups = new Hashtable();
261 Vector allFeatures = new Vector();
262 Vector allGroups = new Vector();
263 SequenceFeature[] tmpfeatures;
265 for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
267 if (af.getViewport().alignment.getSequenceAt(i).getDatasetSequence()
268 .getSequenceFeatures() == null)
273 tmpfeatures = af.getViewport().alignment.getSequenceAt(i)
274 .getDatasetSequence().getSequenceFeatures();
277 while (index < tmpfeatures.length)
279 if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)
285 if (tmpfeatures[index].getFeatureGroup() != null)
287 group = tmpfeatures[index].featureGroup;
288 if (!allGroups.contains(group))
290 allGroups.addElement(group);
293 checkGroupState(group);
298 if (!allFeatures.contains(tmpfeatures[index].getType()))
300 allFeatures.addElement(tmpfeatures[index].getType());
314 * @return true if group has been seen before and is already added to set.
316 private boolean checkGroupState(String group)
319 if (fr.featureGroups.containsKey(group))
321 visible = ((Boolean) fr.featureGroups.get(group)).booleanValue();
325 visible = true; // new group is always made visible
328 if (groupPanel == null)
330 groupPanel = new JPanel();
333 boolean alreadyAdded = false;
334 for (int g = 0; g < groupPanel.getComponentCount(); g++)
336 if (((JCheckBox) groupPanel.getComponent(g)).getText().equals(group))
339 ((JCheckBox) groupPanel.getComponent(g)).setSelected(visible);
350 fr.featureGroups.put(group, new Boolean(visible));
351 final String grp = group;
352 final JCheckBox check = new JCheckBox(group, visible);
353 check.setFont(new Font("Serif", Font.BOLD, 12));
354 check.addItemListener(new ItemListener()
356 public void itemStateChanged(ItemEvent evt)
358 fr.featureGroups.put(check.getText(), new Boolean(check
360 af.alignPanel.seqPanel.seqCanvas.repaint();
361 if (af.alignPanel.overviewPanel != null)
363 af.alignPanel.overviewPanel.updateOverviewImage();
366 resetTable(new String[]
370 groupPanel.add(check);
374 boolean resettingTable = false;
376 synchronized void resetTable(String[] groupChanged)
378 if (resettingTable == true)
382 resettingTable = true;
383 typeWidth = new Hashtable();
384 // TODO: change avWidth calculation to 'per-sequence' average and use long
386 float[] avWidth = null;
387 SequenceFeature[] tmpfeatures;
388 String group = null, type;
389 Vector visibleChecks = new Vector();
391 // Find out which features should be visible depending on which groups
392 // are selected / deselected
393 // and recompute average width ordering
394 for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)
397 tmpfeatures = af.getViewport().alignment.getSequenceAt(i)
398 .getDatasetSequence().getSequenceFeatures();
399 if (tmpfeatures == null)
405 while (index < tmpfeatures.length)
407 group = tmpfeatures[index].featureGroup;
409 if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)
415 if (group == null || fr.featureGroups.get(group) == null
416 || ((Boolean) fr.featureGroups.get(group)).booleanValue())
419 checkGroupState(group);
420 type = tmpfeatures[index].getType();
421 if (!visibleChecks.contains(type))
423 visibleChecks.addElement(type);
426 if (!typeWidth.containsKey(tmpfeatures[index].getType()))
428 typeWidth.put(tmpfeatures[index].getType(),
429 avWidth = new float[3]);
433 avWidth = (float[]) typeWidth.get(tmpfeatures[index].getType());
436 if (tmpfeatures[index].getBegin() > tmpfeatures[index].getEnd())
438 avWidth[1] += 1 + tmpfeatures[index].getBegin()
439 - tmpfeatures[index].getEnd();
443 avWidth[1] += 1 + tmpfeatures[index].getEnd()
444 - tmpfeatures[index].getBegin();
450 int fSize = visibleChecks.size();
451 Object[][] data = new Object[fSize][3];
454 if (fr.renderOrder != null)
457 fr.findAllFeatures(groupChanged != null); // prod to update
458 // colourschemes. but don't
460 // First add the checks in the previous render order,
461 // in case the window has been closed and reopened
462 for (int ro = fr.renderOrder.length - 1; ro > -1; ro--)
464 type = fr.renderOrder[ro];
466 if (!visibleChecks.contains(type))
471 data[dataIndex][0] = type;
472 data[dataIndex][1] = fr.getColour(type);
473 data[dataIndex][2] = new Boolean(af.getViewport().featuresDisplayed
476 visibleChecks.removeElement(type);
480 fSize = visibleChecks.size();
481 for (int i = 0; i < fSize; i++)
483 // These must be extra features belonging to the group
484 // which was just selected
485 type = visibleChecks.elementAt(i).toString();
486 data[dataIndex][0] = type;
488 data[dataIndex][1] = fr.getColour(type);
489 if (data[dataIndex][1] == null)
491 // "Colour has been updated in another view!!"
492 fr.renderOrder = null;
496 data[dataIndex][2] = new Boolean(true);
500 if (originalData == null)
502 originalData = new Object[data.length][3];
503 System.arraycopy(data, 0, originalData, 0, data.length);
506 table.setModel(new FeatureTableModel(data));
507 table.getColumnModel().getColumn(0).setPreferredWidth(200);
509 if (groupPanel != null)
511 groupPanel.setLayout(new GridLayout(fr.featureGroups.size() / 4 + 1,
514 groupPanel.validate();
515 bigPanel.add(groupPanel, BorderLayout.NORTH);
518 updateFeatureRenderer(data, groupChanged != null);
519 resettingTable = false;
523 * reorder data based on the featureRenderers global priority list.
527 private void ensureOrder(Object[][] data)
529 boolean sort = false;
530 float[] order = new float[data.length];
531 for (int i = 0; i < order.length; i++)
533 order[i] = fr.getOrder(data[i][0].toString());
535 order[i] = fr.setOrder(data[i][0].toString(), i / order.length);
537 sort = sort || order[i - 1] > order[i];
540 jalview.util.QuickSort.sort(order, data);
545 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
546 .getProperty("LAST_DIRECTORY"), new String[]
547 { "fc" }, new String[]
548 { "Sequence Feature Colours" }, "Sequence Feature Colours");
549 chooser.setFileView(new jalview.io.JalviewFileView());
550 chooser.setDialogTitle("Load Feature Colours");
551 chooser.setToolTipText("Load");
553 int value = chooser.showOpenDialog(this);
555 if (value == JalviewFileChooser.APPROVE_OPTION)
557 File file = chooser.getSelectedFile();
561 InputStreamReader in = new InputStreamReader(new FileInputStream(
564 jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();
565 jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);
567 for (int i = jucs.getColourCount() - 1; i >= 0; i--)
570 fr.setColour(name = jucs.getColour(i).getName(), new Color(
571 Integer.parseInt(jucs.getColour(i).getRGB(), 16)));
572 fr.setOrder(name, (i == 0) ? 0 : i / jucs.getColourCount());
577 Object[][] data = ((FeatureTableModel) table.getModel())
580 updateFeatureRenderer(data, false);
583 } catch (Exception ex)
585 System.out.println("Error loading User Colour File\n" + ex);
592 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
593 .getProperty("LAST_DIRECTORY"), new String[]
594 { "fc" }, new String[]
595 { "Sequence Feature Colours" }, "Sequence Feature Colours");
596 chooser.setFileView(new jalview.io.JalviewFileView());
597 chooser.setDialogTitle("Save Feature Colour Scheme");
598 chooser.setToolTipText("Save");
600 int value = chooser.showSaveDialog(this);
602 if (value == JalviewFileChooser.APPROVE_OPTION)
604 String choice = chooser.getSelectedFile().getPath();
605 jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();
606 ucs.setSchemeName("Sequence Features");
609 PrintWriter out = new PrintWriter(new OutputStreamWriter(
610 new FileOutputStream(choice), "UTF-8"));
612 Enumeration e = fr.featureColours.keys();
613 float[] sortOrder = new float[fr.featureColours.size()];
614 String[] sortTypes = new String[fr.featureColours.size()];
616 while (e.hasMoreElements())
618 sortTypes[i] = e.nextElement().toString();
619 sortOrder[i] = fr.getOrder(sortTypes[i]);
622 jalview.util.QuickSort.sort(sortOrder, sortTypes);
624 for (i = 0; i < sortTypes.length; i++)
626 jalview.binding.Colour col = new jalview.binding.Colour();
627 col.setName(sortTypes[i]);
628 col.setRGB(jalview.util.Format.getHexString(fr.getColour(col
634 } catch (Exception ex)
636 ex.printStackTrace();
641 public void invertSelection()
643 for (int i = 0; i < table.getRowCount(); i++)
645 Boolean value = (Boolean) table.getValueAt(i, 2);
647 table.setValueAt(new Boolean(!value.booleanValue()), i, 2);
651 public void orderByAvWidth()
653 if (table == null || table.getModel() == null)
655 Object[][] data = ((FeatureTableModel) table.getModel()).getData();
656 float[] width = new float[data.length];
660 for (int i = 0; i < data.length; i++)
662 awidth = (float[]) typeWidth.get(data[i][0]);
665 width[i] = awidth[1] / awidth[0];// *awidth[0]*awidth[2]; - better
666 // weight - but have to make per
667 // sequence, too (awidth[2])
668 // if (width[i]==1) // hack to distinguish single width sequences.
678 boolean sort = false;
679 for (int i = 0; i < width.length; i++)
681 // awidth = (float[]) typeWidth.get(data[i][0]);
684 width[i] = fr.getOrder(data[i][0].toString());
687 width[i] = fr.setOrder(data[i][0].toString(), i / data.length);
692 width[i] /= max; // normalize
693 fr.setOrder(data[i][0].toString(), width[i]); // store for later
696 sort = sort || width[i - 1] > width[i];
699 jalview.util.QuickSort.sort(width, data);
700 // update global priority order
702 updateFeatureRenderer(data, false);
710 frame.setClosed(true);
711 } catch (Exception exe)
717 public void updateFeatureRenderer(Object[][] data)
719 updateFeatureRenderer(data, true);
722 private void updateFeatureRenderer(Object[][] data, boolean visibleNew)
724 fr.setFeaturePriority(data, visibleNew);
725 af.alignPanel.paintAlignment(true);
728 int selectedRow = -1;
730 JTabbedPane tabbedPane = new JTabbedPane();
732 BorderLayout borderLayout1 = new BorderLayout();
734 BorderLayout borderLayout2 = new BorderLayout();
736 BorderLayout borderLayout3 = new BorderLayout();
738 JPanel bigPanel = new JPanel();
740 BorderLayout borderLayout4 = new BorderLayout();
742 JButton invert = new JButton();
744 JPanel buttonPanel = new JPanel();
746 JButton cancel = new JButton();
748 JButton ok = new JButton();
750 JButton loadColours = new JButton();
752 JButton saveColours = new JButton();
754 JPanel dasButtonPanel = new JPanel();
756 JButton fetchDAS = new JButton();
758 JButton saveDAS = new JButton();
760 JButton cancelDAS = new JButton();
762 JButton optimizeOrder = new JButton();
764 JButton sortByScore = new JButton();
766 JButton sortByDens = new JButton();
768 JPanel transbuttons = new JPanel(new BorderLayout());
770 private void jbInit() throws Exception
772 this.setLayout(borderLayout1);
773 settingsPane.setLayout(borderLayout2);
774 dasSettingsPane.setLayout(borderLayout3);
775 bigPanel.setLayout(borderLayout4);
776 invert.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
777 invert.setText("Invert Selection");
778 invert.addActionListener(new ActionListener()
780 public void actionPerformed(ActionEvent e)
785 optimizeOrder.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
786 optimizeOrder.setText("Optimise Order");
787 optimizeOrder.addActionListener(new ActionListener()
789 public void actionPerformed(ActionEvent e)
794 sortByScore.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
795 sortByScore.setText("Seq sort by Score");
796 sortByScore.addActionListener(new ActionListener()
798 public void actionPerformed(ActionEvent e)
803 sortByDens.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
804 sortByDens.setText("Seq Sort by density");
805 sortByDens.addActionListener(new ActionListener()
807 public void actionPerformed(ActionEvent e)
812 cancel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
813 cancel.setText("Cancel");
814 cancel.addActionListener(new ActionListener()
816 public void actionPerformed(ActionEvent e)
818 updateFeatureRenderer(originalData);
822 ok.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
824 ok.addActionListener(new ActionListener()
826 public void actionPerformed(ActionEvent e)
831 loadColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
832 loadColours.setText("Load Colours");
833 loadColours.addActionListener(new ActionListener()
835 public void actionPerformed(ActionEvent e)
840 saveColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
841 saveColours.setText("Save Colours");
842 saveColours.addActionListener(new ActionListener()
844 public void actionPerformed(ActionEvent e)
849 transparency.addChangeListener(new ChangeListener()
851 public void stateChanged(ChangeEvent evt)
853 fr.setTransparency((float) (100 - transparency.getValue()) / 100f);
854 af.alignPanel.paintAlignment(true);
858 transparency.setMaximum(70);
859 fetchDAS.setText("Fetch DAS Features");
860 fetchDAS.addActionListener(new ActionListener()
862 public void actionPerformed(ActionEvent e)
864 fetchDAS_actionPerformed(e);
867 saveDAS.setText("Save as default");
868 saveDAS.addActionListener(new ActionListener()
870 public void actionPerformed(ActionEvent e)
872 saveDAS_actionPerformed(e);
875 dasButtonPanel.setBorder(BorderFactory.createEtchedBorder());
876 dasSettingsPane.setBorder(null);
877 cancelDAS.setEnabled(false);
878 cancelDAS.setText("Cancel Fetch");
879 cancelDAS.addActionListener(new ActionListener()
881 public void actionPerformed(ActionEvent e)
883 cancelDAS_actionPerformed(e);
886 this.add(tabbedPane, java.awt.BorderLayout.CENTER);
887 tabbedPane.addTab("Feature Settings", settingsPane);
888 tabbedPane.addTab("DAS Settings", dasSettingsPane);
889 bigPanel.add(transPanel, java.awt.BorderLayout.SOUTH);
890 transPanel.add(transparency);
891 transbuttons.add(invert, java.awt.BorderLayout.NORTH);
892 transbuttons.add(optimizeOrder, java.awt.BorderLayout.SOUTH);
893 transPanel.add(transbuttons);
895 buttonPanel.add(cancel);
896 buttonPanel.add(loadColours);
897 buttonPanel.add(saveColours);
898 buttonPanel.add(sortByScore);
899 buttonPanel.add(sortByDens);
900 bigPanel.add(scrollPane, java.awt.BorderLayout.CENTER);
901 dasSettingsPane.add(dasButtonPanel, java.awt.BorderLayout.SOUTH);
902 dasButtonPanel.add(fetchDAS);
903 dasButtonPanel.add(cancelDAS);
904 dasButtonPanel.add(saveDAS);
905 settingsPane.add(bigPanel, java.awt.BorderLayout.CENTER);
906 settingsPane.add(buttonPanel, java.awt.BorderLayout.SOUTH);
909 protected void sortByDens(String[] typ)
911 sortBy(typ, "Sort by Density", AlignmentSorter.FEATURE_DENSITY);
914 protected void sortBy(String[] typ, String methodText, final String method)
918 typ = getDisplayedFeatureTypes();
921 gps = getDisplayedFeatureGroups();
924 for (int i = 0; i < typ.length; i++)
926 System.err.println("Sorting on Types:" + typ[i]);
932 for (int i = 0; i < gps.length; i++)
934 System.err.println("Sorting on groups:" + gps[i]);
937 AlignmentPanel alignPanel = af.alignPanel;
938 AlignmentI al = alignPanel.av.getAlignment();
941 SequenceGroup sg = alignPanel.av.getSelectionGroup();
944 start = sg.getStartRes();
945 stop = sg.getEndRes();
950 stop = al.getWidth();
952 SequenceI[] oldOrder = al.getSequencesArray();
953 AlignmentSorter.sortByFeature(typ, gps, start, stop, al, method);
954 af.addHistoryItem(new OrderCommand(methodText, oldOrder, alignPanel.av
956 alignPanel.paintAlignment(true);
960 protected void sortByScore(String[] typ)
962 sortBy(typ, "Sort by Feature Score", AlignmentSorter.FEATURE_SCORE);
965 private String[] getDisplayedFeatureTypes()
970 synchronized (fr.renderOrder)
972 typ = new String[fr.renderOrder.length];
973 System.arraycopy(fr.renderOrder, 0, typ, 0, typ.length);
974 for (int i = 0; i < typ.length; i++)
976 if (af.viewport.featuresDisplayed.get(typ[i]) == null)
986 private String[] getDisplayedFeatureGroups()
992 if (fr.featureGroups != null)
994 Enumeration en = fr.featureGroups.keys();
995 gps = new String[fr.featureColours.size()];
997 boolean valid = false;
998 while (en.hasMoreElements())
1000 String gp = (String) en.nextElement();
1001 Boolean on = (Boolean) fr.featureGroups.get(gp);
1002 if (on != null && on.booleanValue())
1008 while (g < gps.length)
1021 public void fetchDAS_actionPerformed(ActionEvent e)
1023 fetchDAS.setEnabled(false);
1024 cancelDAS.setEnabled(true);
1025 Vector selectedSources = dassourceBrowser.getSelectedSources();
1026 doDasFeatureFetch(selectedSources, true, true);
1030 * get the features from selectedSources for all or the current selection
1032 * @param selectedSources
1033 * @param checkDbRefs
1034 * @param promptFetchDbRefs
1036 private void doDasFeatureFetch(Vector selectedSources,
1037 boolean checkDbRefs, boolean promptFetchDbRefs)
1039 SequenceI[] dataset, seqs;
1041 AlignViewport vp = af.getViewport();
1042 if (vp.getSelectionGroup() != null
1043 && vp.getSelectionGroup().getSize() > 0)
1045 iSize = vp.getSelectionGroup().getSize();
1046 dataset = new SequenceI[iSize];
1047 seqs = vp.getSelectionGroup().getSequencesInOrder(vp.getAlignment());
1051 iSize = vp.getAlignment().getHeight();
1052 seqs = vp.getAlignment().getSequencesArray();
1055 dataset = new SequenceI[iSize];
1056 for (int i = 0; i < iSize; i++)
1058 dataset[i] = seqs[i].getDatasetSequence();
1061 cancelDAS.setEnabled(true);
1062 dasFeatureFetcher = new jalview.ws.DasSequenceFeatureFetcher(dataset,
1063 this, selectedSources, checkDbRefs, promptFetchDbRefs);
1064 af.getViewport().setShowSequenceFeatures(true);
1065 af.showSeqFeatures.setSelected(true);
1069 * blocking call to initialise the das source browser
1071 public void initDasSources()
1073 dassourceBrowser.initDasSources();
1077 * examine the current list of das sources and return any matching the given
1078 * nicknames in sources
1081 * Vector of Strings to resolve to DAS source nicknames.
1082 * @return sources that are present in source list.
1084 public Vector resolveSourceNicknames(Vector sources)
1086 return dassourceBrowser.resolveSourceNicknames(sources);
1090 * get currently selected das sources. ensure you have called initDasSources
1091 * before calling this.
1093 * @return vector of selected das source nicknames
1095 public Vector getSelectedSources()
1097 return dassourceBrowser.getSelectedSources();
1101 * properly initialise DAS fetcher and then initiate a new thread to fetch
1102 * features from the named sources (rather than any turned on by default)
1106 public void fetchDasFeatures(Vector sources)
1109 Vector resolved = resolveSourceNicknames(sources);
1110 if (resolved.size() == 0)
1112 resolved = dassourceBrowser.getSelectedSources();
1114 if (resolved.size() > 0)
1116 final Vector dassources = resolved;
1117 SwingUtilities.invokeLater(new Runnable()
1122 fetchDAS.setEnabled(false);
1123 cancelDAS.setEnabled(true);
1124 doDasFeatureFetch(dassources, true, false);
1131 public void saveDAS_actionPerformed(ActionEvent e)
1134 .saveProperties(jalview.bin.Cache.applicationProperties);
1137 public void complete()
1139 fetchDAS.setEnabled(true);
1140 cancelDAS.setEnabled(false);
1143 public void cancelDAS_actionPerformed(ActionEvent e)
1145 if (dasFeatureFetcher != null)
1147 dasFeatureFetcher.cancel();
1149 fetchDAS.setEnabled(true);
1150 cancelDAS.setEnabled(false);
1153 public void noDasSourceActive()
1156 JOptionPane.showInternalConfirmDialog(Desktop.desktop,
1157 "No das sources were selected.\n"
1158 + "Please select some sources and\n" + " try again.",
1159 "No Sources Selected", JOptionPane.DEFAULT_OPTION,
1160 JOptionPane.INFORMATION_MESSAGE);
1163 // ///////////////////////////////////////////////////////////////////////
1164 // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
1165 // ///////////////////////////////////////////////////////////////////////
1166 class FeatureTableModel extends AbstractTableModel
1168 FeatureTableModel(Object[][] data)
1173 private String[] columnNames =
1174 { "Feature Type", "Colour", "Display" };
1176 private Object[][] data;
1178 public Object[][] getData()
1183 public void setData(Object[][] data)
1188 public int getColumnCount()
1190 return columnNames.length;
1193 public Object[] getRow(int row)
1198 public int getRowCount()
1203 public String getColumnName(int col)
1205 return columnNames[col];
1208 public Object getValueAt(int row, int col)
1210 return data[row][col];
1213 public Class getColumnClass(int c)
1215 return getValueAt(0, c).getClass();
1218 public boolean isCellEditable(int row, int col)
1220 return col == 0 ? false : true;
1223 public void setValueAt(Object value, int row, int col)
1225 data[row][col] = value;
1226 fireTableCellUpdated(row, col);
1227 updateFeatureRenderer(data);
1232 class ColorRenderer extends JLabel implements TableCellRenderer
1234 javax.swing.border.Border unselectedBorder = null;
1236 javax.swing.border.Border selectedBorder = null;
1238 public ColorRenderer()
1240 setOpaque(true); // MUST do this for background to show up.
1243 public Component getTableCellRendererComponent(JTable table,
1244 Object color, boolean isSelected, boolean hasFocus, int row,
1248 color = fr.featureColours.get((String) table.getModel().getValueAt(
1250 if (color instanceof GraduatedColor)
1252 newColor = ((GraduatedColor) color).getMaxColor();
1253 Color minCol = ((GraduatedColor) color).getMinColor();;
1254 setBackground(newColor);
1255 setToolTipText("RGB value: Max (" + newColor.getRed() + ", "
1256 + newColor.getGreen() + ", " + newColor.getBlue()
1257 + ")\nMin (" + minCol.getRed() + ", " + minCol.getGreen()
1258 + ", " + minCol.getBlue() + ")");
1262 newColor = (Color) color;
1263 setBackground(newColor);
1264 setToolTipText("RGB value: " + newColor.getRed() + ", "
1265 + newColor.getGreen() + ", " + newColor.getBlue());
1269 if (selectedBorder == null)
1271 selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
1272 table.getSelectionBackground());
1274 setBorder(selectedBorder);
1278 if (unselectedBorder == null)
1280 unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
1281 table.getBackground());
1283 setBorder(unselectedBorder);
1291 class ColorEditor extends AbstractCellEditor implements TableCellEditor,
1298 JColorChooser colorChooser;
1302 protected static final String EDIT = "edit";
1304 public ColorEditor()
1306 // Set up the editor (from the table's point of view),
1307 // which is a button.
1308 // This button brings up the color chooser dialog,
1309 // which is the editor from the user's point of view.
1310 button = new JButton();
1311 button.setActionCommand(EDIT);
1312 button.addActionListener(this);
1313 button.setBorderPainted(false);
1314 // Set up the dialog that the button brings up.
1315 colorChooser = new JColorChooser();
1316 dialog = JColorChooser.createDialog(button, "Select new Colour", true, // modal
1317 colorChooser, this, // OK button handler
1318 null); // no CANCEL button handler
1322 * Handles events from the editor button and from the dialog's OK button.
1324 public void actionPerformed(ActionEvent e)
1327 if (EDIT.equals(e.getActionCommand()))
1329 // The user has clicked the cell, so
1330 // bring up the dialog.
1331 button.setBackground(currentColor);
1332 colorChooser.setColor(currentColor);
1333 dialog.setVisible(true);
1335 // Make the renderer reappear.
1336 fireEditingStopped();
1340 { // User pressed dialog's "OK" button.
1341 currentColor = colorChooser.getColor();
1345 // Implement the one CellEditor method that AbstractCellEditor doesn't.
1346 public Object getCellEditorValue()
1348 return currentColor;
1351 // Implement the one method defined by TableCellEditor.
1352 public Component getTableCellEditorComponent(JTable table, Object value,
1353 boolean isSelected, int row, int column)
1355 currentColor = (Color) value;