X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FFeatureSettings.java;h=22800ea30f07175787f964904cb3d3e1ac6ef560;hb=2de8acfae59aced665e4c37ad0f7dcc2ed68818e;hp=6c5990a80aff82a1adec14bc38264c7c8fbfd115;hpb=2bc54fc3fc79e09819a6e650ecd38446322a5f3c;p=jalview.git diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index 6c5990a..22800ea 100755 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -1,17 +1,17 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer - * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle - * + * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1) + * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA @@ -30,24 +30,36 @@ import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; +import jalview.analysis.AlignmentSorter; +import jalview.commands.OrderCommand; import jalview.datamodel.*; import jalview.io.*; +import jalview.schemes.GraduatedColor; -public class FeatureSettings - extends JPanel +public class FeatureSettings extends JPanel { DasSourceBrowser dassourceBrowser; - jalview.io.DasSequenceFeatureFetcher dasFeatureFetcher; + + jalview.ws.DasSequenceFeatureFetcher dasFeatureFetcher; + JPanel settingsPane = new JPanel(); + JPanel dasSettingsPane = new JPanel(); final FeatureRenderer fr; + public final AlignFrame af; + Object[][] originalData; + final JInternalFrame frame; + JScrollPane scrollPane = new JScrollPane(); + JTable table; + JPanel groupPanel; + JSlider transparency = new JSlider(); JPanel transPanel = new JPanel(new FlowLayout()); @@ -62,8 +74,7 @@ public class FeatureSettings try { jbInit(); - } - catch (Exception ex) + } catch (Exception ex) { ex.printStackTrace(); } @@ -71,11 +82,9 @@ public class FeatureSettings table = new JTable(); table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12)); table.setFont(new Font("Verdana", Font.PLAIN, 12)); - table.setDefaultRenderer(Color.class, - new ColorRenderer()); + table.setDefaultRenderer(Color.class, new ColorRenderer()); - table.setDefaultEditor(Color.class, - new ColorEditor()); + table.setDefaultEditor(Color.class, new ColorEditor()); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); @@ -84,6 +93,11 @@ public class FeatureSettings public void mousePressed(MouseEvent evt) { selectedRow = table.rowAtPoint(evt.getPoint()); + if (javax.swing.SwingUtilities.isRightMouseButton(evt)) + { + popupSort((String) table.getValueAt(selectedRow, 0), fr.minmax, + evt.getX(), evt.getY()); + } } }); @@ -92,9 +106,7 @@ public class FeatureSettings public void mouseDragged(MouseEvent evt) { int newRow = table.rowAtPoint(evt.getPoint()); - if (newRow != selectedRow - && selectedRow != -1 - && newRow != -1) + if (newRow != selectedRow && selectedRow != -1 && newRow != -1) { Object[] temp = new Object[3]; temp[0] = table.getValueAt(selectedRow, 0); @@ -119,49 +131,127 @@ public class FeatureSettings dassourceBrowser = new DasSourceBrowser(); dasSettingsPane.add(dassourceBrowser, BorderLayout.CENTER); - if (af.getViewport().featuresDisplayed == null || fr.renderOrder == null) + if (af.getViewport().featuresDisplayed == null + || fr.renderOrder == null) { fr.findAllFeatures(true); // display everything! } setTableData(); final PropertyChangeListener change; - final FeatureSettings fs=this; - fr.addPropertyChangeListener(change=new PropertyChangeListener() { + final FeatureSettings fs = this; + fr.addPropertyChangeListener(change = new PropertyChangeListener() + { public void propertyChange(PropertyChangeEvent evt) { - if (!fs.resettingTable && !fs.handlingUpdate) { - fs.handlingUpdate=true; - fs.resetTable(new String[] {}); // groups may be added - fs.handlingUpdate=false; + if (!fs.resettingTable && !fs.handlingUpdate) + { + fs.handlingUpdate = true; + fs.resetTable(null); // new groups may be added with new seuqence + // feature types only + fs.handlingUpdate = false; } } - + }); - + frame = new JInternalFrame(); frame.setContentPane(this); Desktop.addInternalFrame(frame, "Sequence Feature Settings", 400, 450); - frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter() + frame + .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter() + { + public void internalFrameClosed( + javax.swing.event.InternalFrameEvent evt) + { + fr.removePropertyChangeListener(change); + }; + }); + frame.setLayer(JLayeredPane.PALETTE_LAYER); + } + + protected void popupSort(final String type, final Hashtable minmax, + int x, int y) + { + JPopupMenu men = new JPopupMenu("Settings for " + type); + JMenuItem scr = new JMenuItem("Sort by Score"); + men.add(scr); + final FeatureSettings me = this; + scr.addActionListener(new ActionListener() { - public void internalFrameClosed( - javax.swing.event.InternalFrameEvent evt) + + public void actionPerformed(ActionEvent e) { - fr.removePropertyChangeListener(change); + me.sortByScore(new String[] + { type }); } - ; + }); - frame.setLayer(JLayeredPane.PALETTE_LAYER); + JMenuItem dens = new JMenuItem("Sort by Density"); + dens.addActionListener(new ActionListener() + { + + public void actionPerformed(ActionEvent e) + { + me.sortByDens(new String[] + { type }); + } + + }); + men.add(dens); + if (minmax != null) + { + final Object typeMinMax = minmax.get(type); + final JCheckBoxMenuItem chb = new JCheckBoxMenuItem("Vary Height"); + // this is broken at the moment + chb.setSelected(minmax.get(type) != null); + chb.addActionListener(new ActionListener() + { + + public void actionPerformed(ActionEvent e) + { + chb.setState(chb.getState()); + if (chb.getState()) + { + minmax.put(type, null); + } + else + { + minmax.put(type, typeMinMax); + } + } + + }); + men.add(chb); + if (typeMinMax != null && ((float[][]) typeMinMax)[0] != null) + { + // graduated colourschemes for those where minmax exists for the positional features + JMenuItem mxcol = new JMenuItem("Min Max Colour"); + men.add(mxcol); + mxcol.addActionListener(new ActionListener() + { + + public void actionPerformed(ActionEvent e) + { + new FeatureColourChooser(me, type); + } + + }); + } + } + men.show(table, x, y); } + /** * true when Feature Settings are updating from feature renderer */ - private boolean handlingUpdate=false; - + private boolean handlingUpdate = false; + /** * contains a float[3] for each feature type string. created by setTableData */ - Hashtable typeWidth=null; + Hashtable typeWidth = null; + synchronized public void setTableData() { if (fr.featureGroups == null) @@ -174,14 +264,14 @@ public class FeatureSettings String group; for (int i = 0; i < af.getViewport().alignment.getHeight(); i++) { - if (af.getViewport().alignment.getSequenceAt(i).getDatasetSequence(). - getSequenceFeatures() == null) + if (af.getViewport().alignment.getSequenceAt(i).getDatasetSequence() + .getSequenceFeatures() == null) { continue; } - tmpfeatures = af.getViewport().alignment.getSequenceAt(i). - getDatasetSequence().getSequenceFeatures(); + tmpfeatures = af.getViewport().alignment.getSequenceAt(i) + .getDatasetSequence().getSequenceFeatures(); int index = 0; while (index < tmpfeatures.length) @@ -198,57 +288,10 @@ public class FeatureSettings if (!allGroups.contains(group)) { allGroups.addElement(group); - - boolean visible; - if (fr.featureGroups.containsKey(group)) + if (group != null) { - visible = ( (Boolean) fr.featureGroups.get(group)).booleanValue(); - } else { - visible=true; //initGroups || fr.av.featuresDisplayed.containsKey(tmpfeatures[index].getType()); + checkGroupState(group); } - - if (groupPanel == null) - { - groupPanel = new JPanel(); - } - - boolean alreadyAdded = false; - for (int g = 0; g < groupPanel.getComponentCount(); g++) - { - if ( ( (JCheckBox) groupPanel.getComponent(g)) - .getText().equals(group)) - { - alreadyAdded = true; - break; - } - } - - if (alreadyAdded) - { - - continue; - } - - fr.featureGroups.put(group, new Boolean(visible)); - final String grp = group; - final JCheckBox check = new JCheckBox(group, visible); - check.setFont(new Font("Serif", Font.BOLD, 12)); - check.addItemListener(new ItemListener() - { - public void itemStateChanged(ItemEvent evt) - { - fr.featureGroups.put(check.getText(), - new Boolean(check.isSelected())); - af.alignPanel.seqPanel.seqCanvas.repaint(); - if (af.alignPanel.overviewPanel != null) - { - af.alignPanel.overviewPanel.updateOverviewImage(); - } - - resetTable(new String[] { grp } ); - } - }); - groupPanel.add(check); } } @@ -259,31 +302,100 @@ public class FeatureSettings index++; } } - + resetTable(null); validate(); } - boolean resettingTable=false; - void resetTable(String[] groupChanged) + + /** + * + * @param group + * @return true if group has been seen before and is already added to set. + */ + private boolean checkGroupState(String group) + { + boolean visible; + if (fr.featureGroups.containsKey(group)) + { + visible = ((Boolean) fr.featureGroups.get(group)).booleanValue(); + } + else + { + visible = true; // new group is always made visible + } + + if (groupPanel == null) + { + groupPanel = new JPanel(); + } + + boolean alreadyAdded = false; + for (int g = 0; g < groupPanel.getComponentCount(); g++) + { + if (((JCheckBox) groupPanel.getComponent(g)).getText().equals(group)) + { + alreadyAdded = true; + ((JCheckBox) groupPanel.getComponent(g)).setSelected(visible); + break; + } + } + + if (alreadyAdded) + { + + return true; + } + + fr.featureGroups.put(group, new Boolean(visible)); + final String grp = group; + final JCheckBox check = new JCheckBox(group, visible); + check.setFont(new Font("Serif", Font.BOLD, 12)); + check.addItemListener(new ItemListener() + { + public void itemStateChanged(ItemEvent evt) + { + fr.featureGroups.put(check.getText(), new Boolean(check + .isSelected())); + af.alignPanel.seqPanel.seqCanvas.repaint(); + if (af.alignPanel.overviewPanel != null) + { + af.alignPanel.overviewPanel.updateOverviewImage(); + } + + resetTable(new String[] + { grp }); + } + }); + groupPanel.add(check); + return false; + } + + boolean resettingTable = false; + + synchronized void resetTable(String[] groupChanged) { - resettingTable=true; - typeWidth=new Hashtable(); - Vector groupchanged = new Vector(); - // TODO: change avWidth calculation to 'per-sequence' average and use long rather than float - float[] avWidth=null; + if (resettingTable == true) + { + return; + } + resettingTable = true; + typeWidth = new Hashtable(); + // TODO: change avWidth calculation to 'per-sequence' average and use long + // rather than float + float[] avWidth = null; SequenceFeature[] tmpfeatures; String group = null, type; Vector visibleChecks = new Vector(); - //Find out which features should be visible depending on which groups - //are selected / deselected - //and recompute average width ordering + // Find out which features should be visible depending on which groups + // are selected / deselected + // and recompute average width ordering for (int i = 0; i < af.getViewport().alignment.getHeight(); i++) { - tmpfeatures = af.getViewport().alignment.getSequenceAt(i). - getDatasetSequence().getSequenceFeatures(); + tmpfeatures = af.getViewport().alignment.getSequenceAt(i) + .getDatasetSequence().getSequenceFeatures(); if (tmpfeatures == null) { continue; @@ -300,26 +412,36 @@ public class FeatureSettings continue; } - if (group == null || fr.featureGroups.get(group) == null || - ( (Boolean) fr.featureGroups.get(group)).booleanValue()) + if (group == null || fr.featureGroups.get(group) == null + || ((Boolean) fr.featureGroups.get(group)).booleanValue()) { + if (group != null) + checkGroupState(group); type = tmpfeatures[index].getType(); if (!visibleChecks.contains(type)) { visibleChecks.addElement(type); } } - if (!typeWidth.containsKey(tmpfeatures[index].getType())) { - typeWidth.put(tmpfeatures[index].getType(), avWidth=new float[3]); - } else { + if (!typeWidth.containsKey(tmpfeatures[index].getType())) + { + typeWidth.put(tmpfeatures[index].getType(), + avWidth = new float[3]); + } + else + { avWidth = (float[]) typeWidth.get(tmpfeatures[index].getType()); } avWidth[0]++; - if (tmpfeatures[index].getBegin()>tmpfeatures[index].getEnd()) + if (tmpfeatures[index].getBegin() > tmpfeatures[index].getEnd()) + { + avWidth[1] += 1 + tmpfeatures[index].getBegin() + - tmpfeatures[index].getEnd(); + } + else { - avWidth[1]+=1+tmpfeatures[index].getBegin()-tmpfeatures[index].getEnd(); - } else { - avWidth[1]+=1+tmpfeatures[index].getEnd()-tmpfeatures[index].getBegin(); + avWidth[1] += 1 + tmpfeatures[index].getEnd() + - tmpfeatures[index].getBegin(); } index++; } @@ -332,9 +454,11 @@ public class FeatureSettings if (fr.renderOrder != null) { if (!handlingUpdate) - fr.findAllFeatures(groupChanged!=null); // prod to update colourschemes. but don't affect display - //First add the checks in the previous render order, - //in case the window has been closed and reopened + fr.findAllFeatures(groupChanged != null); // prod to update + // colourschemes. but don't + // affect display + // First add the checks in the previous render order, + // in case the window has been closed and reopened for (int ro = fr.renderOrder.length - 1; ro > -1; ro--) { type = fr.renderOrder[ro]; @@ -346,7 +470,8 @@ public class FeatureSettings data[dataIndex][0] = type; data[dataIndex][1] = fr.getColour(type); - data[dataIndex][2] = new Boolean(af.getViewport().featuresDisplayed.containsKey(type)); + data[dataIndex][2] = new Boolean(af.getViewport().featuresDisplayed + .containsKey(type)); dataIndex++; visibleChecks.removeElement(type); } @@ -355,15 +480,15 @@ public class FeatureSettings fSize = visibleChecks.size(); for (int i = 0; i < fSize; i++) { - //These must be extra features belonging to the group - //which was just selected + // These must be extra features belonging to the group + // which was just selected type = visibleChecks.elementAt(i).toString(); data[dataIndex][0] = type; data[dataIndex][1] = fr.getColour(type); if (data[dataIndex][1] == null) { - //"Colour has been updated in another view!!" + // "Colour has been updated in another view!!" fr.renderOrder = null; return; } @@ -383,31 +508,33 @@ public class FeatureSettings if (groupPanel != null) { - groupPanel.setLayout( - new GridLayout(fr.featureGroups.size() / 4 + 1, 4)); + groupPanel.setLayout(new GridLayout(fr.featureGroups.size() / 4 + 1, + 4)); groupPanel.validate(); bigPanel.add(groupPanel, BorderLayout.NORTH); } - updateFeatureRenderer(data, groupChanged!=null); - resettingTable=false; + updateFeatureRenderer(data, groupChanged != null); + resettingTable = false; } + /** * reorder data based on the featureRenderers global priority list. + * * @param data */ private void ensureOrder(Object[][] data) { - boolean sort=false; + boolean sort = false; float[] order = new float[data.length]; - for (int i=0;i1) - sort = sort || order[i-1]>order[i]; + if (order[i] < 0) + order[i] = fr.setOrder(data[i][0].toString(), i / order.length); + if (i > 1) + sort = sort || order[i - 1] > order[i]; } if (sort) jalview.util.QuickSort.sort(order, data); @@ -415,12 +542,10 @@ public class FeatureSettings void load() { - JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache. - getProperty( - "LAST_DIRECTORY"), new String[] - {"fc"}, - new String[] - {"Sequence Feature Colours"}, "Sequence Feature Colours"); + JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache + .getProperty("LAST_DIRECTORY"), new String[] + { "fc" }, new String[] + { "Sequence Feature Colours" }, "Sequence Feature Colours"); chooser.setFileView(new jalview.io.JalviewFileView()); chooser.setDialogTitle("Load Feature Colours"); chooser.setToolTipText("Load"); @@ -434,29 +559,28 @@ public class FeatureSettings try { InputStreamReader in = new InputStreamReader(new FileInputStream( - file), "UTF-8"); + file), "UTF-8"); - jalview.binding.JalviewUserColours jucs = new jalview.binding. - JalviewUserColours(); + jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours(); jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in); - for (int i = jucs.getColourCount()-1; i >=0; i--) + for (int i = jucs.getColourCount() - 1; i >= 0; i--) { String name; - fr.setColour(name=jucs.getColour(i).getName(), - new Color(Integer.parseInt(jucs.getColour(i).getRGB(), - 16))); - fr.setOrder(name,(i==0) ? 0 : i/jucs.getColourCount()); + fr.setColour(name = jucs.getColour(i).getName(), new Color( + Integer.parseInt(jucs.getColour(i).getRGB(), 16))); + fr.setOrder(name, (i == 0) ? 0 : i / jucs.getColourCount()); } - if (table!=null) { + if (table != null) + { resetTable(null); - Object[][] data=((FeatureTableModel) table.getModel()).getData(); + Object[][] data = ((FeatureTableModel) table.getModel()) + .getData(); ensureOrder(data); - updateFeatureRenderer(data,false); + updateFeatureRenderer(data, false); table.repaint(); } - } - catch (Exception ex) + } catch (Exception ex) { System.out.println("Error loading User Colour File\n" + ex); } @@ -465,12 +589,10 @@ public class FeatureSettings void save() { - JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache. - getProperty( - "LAST_DIRECTORY"), new String[] - {"fc"}, - new String[] - {"Sequence Feature Colours"}, "Sequence Feature Colours"); + JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache + .getProperty("LAST_DIRECTORY"), new String[] + { "fc" }, new String[] + { "Sequence Feature Colours" }, "Sequence Feature Colours"); chooser.setFileView(new jalview.io.JalviewFileView()); chooser.setDialogTitle("Save Feature Colour Scheme"); chooser.setToolTipText("Save"); @@ -480,37 +602,36 @@ public class FeatureSettings if (value == JalviewFileChooser.APPROVE_OPTION) { String choice = chooser.getSelectedFile().getPath(); - jalview.binding.JalviewUserColours ucs = new jalview.binding. - JalviewUserColours(); + jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours(); ucs.setSchemeName("Sequence Features"); try { PrintWriter out = new PrintWriter(new OutputStreamWriter( - new FileOutputStream(choice), "UTF-8")); + new FileOutputStream(choice), "UTF-8")); Enumeration e = fr.featureColours.keys(); float[] sortOrder = new float[fr.featureColours.size()]; String[] sortTypes = new String[fr.featureColours.size()]; - int i=0; + int i = 0; while (e.hasMoreElements()) { sortTypes[i] = e.nextElement().toString(); - sortOrder[i] = fr.getOrder(sortTypes[i]); + sortOrder[i] = fr.getOrder(sortTypes[i]); i++; } jalview.util.QuickSort.sort(sortOrder, sortTypes); - sortOrder=null; - for (i=0; i0) { - width[i] = awidth[1]/awidth[0];// *awidth[0]*awidth[2]; - better weight - but have to make per sequence, too (awidth[2]) - //if (width[i]==1) // hack to distinguish single width sequences. - num++; - } else { - width[i]=0; - } - if (max 0) + { + width[i] = awidth[1] / awidth[0];// *awidth[0]*awidth[2]; - better + // weight - but have to make per + // sequence, too (awidth[2]) + // if (width[i]==1) // hack to distinguish single width sequences. + num++; + } + else + { + width[i] = 0; + } + if (max < width[i]) + max = width[i]; + } + boolean sort = false; + for (int i = 0; i < width.length; i++) + { + // awidth = (float[]) typeWidth.get(data[i][0]); + if (width[i] == 0) { width[i] = fr.getOrder(data[i][0].toString()); - if (width[i]<0) + if (width[i] < 0) { - width[i] = fr.setOrder(data[i][0].toString(), i/data.length); + width[i] = fr.setOrder(data[i][0].toString(), i / data.length); } - } else { - width[i] /=max; // normalize - fr.setOrder(data[i][0].toString(), width[i]); // store for later } - if (i>0) - sort = sort || width[i-1]>width[i]; + else + { + width[i] /= max; // normalize + fr.setOrder(data[i][0].toString(), width[i]); // store for later + } + if (i > 0) + sort = sort || width[i - 1] > width[i]; } if (sort) jalview.util.QuickSort.sort(width, data); // update global priority order - - updateFeatureRenderer(data,false); + + updateFeatureRenderer(data, false); table.repaint(); } + public void close() { try { frame.setClosed(true); + } catch (Exception exe) + { } - catch (Exception exe) - {} } @@ -587,38 +718,56 @@ public class FeatureSettings { updateFeatureRenderer(data, true); } + private void updateFeatureRenderer(Object[][] data, boolean visibleNew) { fr.setFeaturePriority(data, visibleNew); af.alignPanel.paintAlignment(true); - - if (af.alignPanel.overviewPanel != null) - { - af.alignPanel.overviewPanel.updateOverviewImage(); - } } int selectedRow = -1; + JTabbedPane tabbedPane = new JTabbedPane(); + BorderLayout borderLayout1 = new BorderLayout(); + BorderLayout borderLayout2 = new BorderLayout(); + BorderLayout borderLayout3 = new BorderLayout(); + JPanel bigPanel = new JPanel(); + BorderLayout borderLayout4 = new BorderLayout(); + JButton invert = new JButton(); + JPanel buttonPanel = new JPanel(); + JButton cancel = new JButton(); + JButton ok = new JButton(); + JButton loadColours = new JButton(); + JButton saveColours = new JButton(); + JPanel dasButtonPanel = new JPanel(); + JButton fetchDAS = new JButton(); + JButton saveDAS = new JButton(); + JButton cancelDAS = new JButton(); + JButton optimizeOrder = new JButton(); + + JButton sortByScore = new JButton(); + + JButton sortByDens = new JButton(); + JPanel transbuttons = new JPanel(new BorderLayout()); - private void jbInit() - throws Exception + + private void jbInit() throws Exception { this.setLayout(borderLayout1); settingsPane.setLayout(borderLayout2); @@ -635,11 +784,31 @@ public class FeatureSettings }); optimizeOrder.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); optimizeOrder.setText("Optimise Order"); - optimizeOrder.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { + optimizeOrder.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { orderByAvWidth(); } }); + sortByScore.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); + sortByScore.setText("Seq sort by Score"); + sortByScore.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + sortByScore(null); + } + }); + sortByDens.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); + sortByDens.setText("Seq Sort by density"); + sortByDens.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + sortByDens(null); + } + }); cancel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); cancel.setText("Cancel"); cancel.addActionListener(new ActionListener() @@ -681,7 +850,7 @@ public class FeatureSettings { public void stateChanged(ChangeEvent evt) { - fr.setTransparency( (float) (100 - transparency.getValue()) / 100f); + fr.setTransparency((float) (100 - transparency.getValue()) / 100f); af.alignPanel.paintAlignment(true); } }); @@ -720,12 +889,14 @@ public class FeatureSettings bigPanel.add(transPanel, java.awt.BorderLayout.SOUTH); transPanel.add(transparency); transbuttons.add(invert, java.awt.BorderLayout.NORTH); - transbuttons.add(optimizeOrder,java.awt.BorderLayout.SOUTH); + transbuttons.add(optimizeOrder, java.awt.BorderLayout.SOUTH); transPanel.add(transbuttons); buttonPanel.add(ok); buttonPanel.add(cancel); buttonPanel.add(loadColours); buttonPanel.add(saveColours); + buttonPanel.add(sortByScore); + buttonPanel.add(sortByDens); bigPanel.add(scrollPane, java.awt.BorderLayout.CENTER); dasSettingsPane.add(dasButtonPanel, java.awt.BorderLayout.SOUTH); dasButtonPanel.add(fetchDAS); @@ -735,28 +906,150 @@ public class FeatureSettings settingsPane.add(buttonPanel, java.awt.BorderLayout.SOUTH); } + protected void sortByDens(String[] typ) + { + sortBy(typ, "Sort by Density", AlignmentSorter.FEATURE_DENSITY); + } + + protected void sortBy(String[] typ, String methodText, final String method) + { + if (typ == null) + { + typ = getDisplayedFeatureTypes(); + } + String gps[] = null; + gps = getDisplayedFeatureGroups(); + if (typ != null) + { + for (int i = 0; i < typ.length; i++) + { + System.err.println("Sorting on Types:" + typ[i]); + } + } + if (gps != null) + { + + for (int i = 0; i < gps.length; i++) + { + System.err.println("Sorting on groups:" + gps[i]); + } + } + AlignmentPanel alignPanel = af.alignPanel; + AlignmentI al = alignPanel.av.getAlignment(); + + int start, stop; + SequenceGroup sg = alignPanel.av.getSelectionGroup(); + if (sg != null) + { + start = sg.getStartRes(); + stop = sg.getEndRes(); + } + else + { + start = 0; + stop = al.getWidth(); + } + SequenceI[] oldOrder = al.getSequencesArray(); + AlignmentSorter.sortByFeature(typ, gps, start, stop, al, method); + af.addHistoryItem(new OrderCommand(methodText, oldOrder, alignPanel.av + .getAlignment())); + alignPanel.paintAlignment(true); + + } + + protected void sortByScore(String[] typ) + { + sortBy(typ, "Sort by Feature Score", AlignmentSorter.FEATURE_SCORE); + } + + private String[] getDisplayedFeatureTypes() + { + String[] typ = null; + if (fr != null) + { + synchronized (fr.renderOrder) + { + typ = new String[fr.renderOrder.length]; + System.arraycopy(fr.renderOrder, 0, typ, 0, typ.length); + for (int i = 0; i < typ.length; i++) + { + if (af.viewport.featuresDisplayed.get(typ[i]) == null) + { + typ[i] = null; + } + } + } + } + return typ; + } + + private String[] getDisplayedFeatureGroups() + { + String[] gps = null; + if (fr != null) + { + + if (fr.featureGroups != null) + { + Enumeration en = fr.featureGroups.keys(); + gps = new String[fr.featureColours.size()]; + int g = 0; + boolean valid = false; + while (en.hasMoreElements()) + { + String gp = (String) en.nextElement(); + Boolean on = (Boolean) fr.featureGroups.get(gp); + if (on != null && on.booleanValue()) + { + valid = true; + gps[g++] = gp; + } + } + while (g < gps.length) + { + gps[g++] = null; + } + if (!valid) + { + return null; + } + } + } + return gps; + } + public void fetchDAS_actionPerformed(ActionEvent e) { fetchDAS.setEnabled(false); cancelDAS.setEnabled(true); Vector selectedSources = dassourceBrowser.getSelectedSources(); + doDasFeatureFetch(selectedSources, true, true); + } + /** + * get the features from selectedSources for all or the current selection + * + * @param selectedSources + * @param checkDbRefs + * @param promptFetchDbRefs + */ + private void doDasFeatureFetch(Vector selectedSources, + boolean checkDbRefs, boolean promptFetchDbRefs) + { SequenceI[] dataset, seqs; int iSize; - - if (af.getViewport().getSelectionGroup() != null - && af.getViewport().getSelectionGroup().getSize() > 0) + AlignViewport vp = af.getViewport(); + if (vp.getSelectionGroup() != null + && vp.getSelectionGroup().getSize() > 0) { - iSize = af.getViewport().getSelectionGroup().getSize(); + iSize = vp.getSelectionGroup().getSize(); dataset = new SequenceI[iSize]; - seqs = af.getViewport().getSelectionGroup(). - getSequencesInOrder( - af.getViewport().getAlignment()); + seqs = vp.getSelectionGroup().getSequencesInOrder(vp.getAlignment()); } else { - iSize = af.getViewport().getAlignment().getHeight(); - seqs = af.getViewport().getAlignment().getSequencesArray(); + iSize = vp.getAlignment().getHeight(); + seqs = vp.getAlignment().getSequencesArray(); } dataset = new SequenceI[iSize]; @@ -765,19 +1058,80 @@ public class FeatureSettings dataset[i] = seqs[i].getDatasetSequence(); } - dasFeatureFetcher = - new jalview.io.DasSequenceFeatureFetcher( - dataset, - this, - selectedSources); cancelDAS.setEnabled(true); + dasFeatureFetcher = new jalview.ws.DasSequenceFeatureFetcher(dataset, + this, selectedSources, checkDbRefs, promptFetchDbRefs); af.getViewport().setShowSequenceFeatures(true); af.showSeqFeatures.setSelected(true); } + /** + * blocking call to initialise the das source browser + */ + public void initDasSources() + { + dassourceBrowser.initDasSources(); + } + + /** + * examine the current list of das sources and return any matching the given + * nicknames in sources + * + * @param sources + * Vector of Strings to resolve to DAS source nicknames. + * @return sources that are present in source list. + */ + public Vector resolveSourceNicknames(Vector sources) + { + return dassourceBrowser.resolveSourceNicknames(sources); + } + + /** + * get currently selected das sources. ensure you have called initDasSources + * before calling this. + * + * @return vector of selected das source nicknames + */ + public Vector getSelectedSources() + { + return dassourceBrowser.getSelectedSources(); + } + + /** + * properly initialise DAS fetcher and then initiate a new thread to fetch + * features from the named sources (rather than any turned on by default) + * + * @param sources + */ + public void fetchDasFeatures(Vector sources) + { + initDasSources(); + Vector resolved = resolveSourceNicknames(sources); + if (resolved.size() == 0) + { + resolved = dassourceBrowser.getSelectedSources(); + } + if (resolved.size() > 0) + { + final Vector dassources = resolved; + SwingUtilities.invokeLater(new Runnable() + { + + public void run() + { + fetchDAS.setEnabled(false); + cancelDAS.setEnabled(true); + doDasFeatureFetch(dassources, true, false); + + } + }); + } + } + public void saveDAS_actionPerformed(ActionEvent e) { - dassourceBrowser.saveProperties(jalview.bin.Cache.applicationProperties); + dassourceBrowser + .saveProperties(jalview.bin.Cache.applicationProperties); } public void complete() @@ -788,16 +1142,28 @@ public class FeatureSettings public void cancelDAS_actionPerformed(ActionEvent e) { - dasFeatureFetcher.cancel(); + if (dasFeatureFetcher != null) + { + dasFeatureFetcher.cancel(); + } fetchDAS.setEnabled(true); cancelDAS.setEnabled(false); } - ///////////////////////////////////////////////////////////////////////// + public void noDasSourceActive() + { + complete(); + JOptionPane.showInternalConfirmDialog(Desktop.desktop, + "No das sources were selected.\n" + + "Please select some sources and\n" + " try again.", + "No Sources Selected", JOptionPane.DEFAULT_OPTION, + JOptionPane.INFORMATION_MESSAGE); + } + + // /////////////////////////////////////////////////////////////////////// // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html - ///////////////////////////////////////////////////////////////////////// - class FeatureTableModel - extends AbstractTableModel + // /////////////////////////////////////////////////////////////////////// + class FeatureTableModel extends AbstractTableModel { FeatureTableModel(Object[][] data) { @@ -805,8 +1171,8 @@ public class FeatureSettings } private String[] columnNames = - { - "Feature Type", "Colour", "Display"}; + { "Feature Type", "Colour", "Display" }; + private Object[][] data; public Object[][] getData() @@ -863,30 +1229,47 @@ public class FeatureSettings } - class ColorRenderer - extends JLabel implements TableCellRenderer + class ColorRenderer extends JLabel implements TableCellRenderer { javax.swing.border.Border unselectedBorder = null; + javax.swing.border.Border selectedBorder = null; public ColorRenderer() { - setOpaque(true); //MUST do this for background to show up. + setOpaque(true); // MUST do this for background to show up. } - public Component getTableCellRendererComponent( - JTable table, Object color, - boolean isSelected, boolean hasFocus, - int row, int column) + public Component getTableCellRendererComponent(JTable table, + Object color, boolean isSelected, boolean hasFocus, int row, + int column) { - Color newColor = (Color) color; - setBackground(newColor); + Color newColor; + color = fr.featureColours.get((String) table.getModel().getValueAt( + row, 0)); + if (color instanceof GraduatedColor) + { + newColor = ((GraduatedColor) color).getMaxColor(); + Color minCol = ((GraduatedColor) color).getMinColor();; + setBackground(newColor); + setToolTipText("RGB value: Max (" + newColor.getRed() + ", " + + newColor.getGreen() + ", " + newColor.getBlue() + + ")\nMin (" + minCol.getRed() + ", " + minCol.getGreen() + + ", " + minCol.getBlue() + ")"); + } + else + { + newColor = (Color) color; + setBackground(newColor); + setToolTipText("RGB value: " + newColor.getRed() + ", " + + newColor.getGreen() + ", " + newColor.getBlue()); + } if (isSelected) { if (selectedBorder == null) { selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, - table.getSelectionBackground()); + table.getSelectionBackground()); } setBorder(selectedBorder); } @@ -895,86 +1278,79 @@ public class FeatureSettings if (unselectedBorder == null) { unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, - table.getBackground()); + table.getBackground()); } setBorder(unselectedBorder); } - setToolTipText("RGB value: " + newColor.getRed() + ", " - + newColor.getGreen() + ", " - + newColor.getBlue()); return this; } } } -class ColorEditor - extends AbstractCellEditor implements TableCellEditor, - ActionListener +class ColorEditor extends AbstractCellEditor implements TableCellEditor, + ActionListener { Color currentColor; + JButton button; + JColorChooser colorChooser; + JDialog dialog; + protected static final String EDIT = "edit"; public ColorEditor() { - //Set up the editor (from the table's point of view), - //which is a button. - //This button brings up the color chooser dialog, - //which is the editor from the user's point of view. + // Set up the editor (from the table's point of view), + // which is a button. + // This button brings up the color chooser dialog, + // which is the editor from the user's point of view. button = new JButton(); button.setActionCommand(EDIT); button.addActionListener(this); button.setBorderPainted(false); - //Set up the dialog that the button brings up. + // Set up the dialog that the button brings up. colorChooser = new JColorChooser(); - dialog = JColorChooser.createDialog(button, - "Select new Colour", - true, //modal - colorChooser, - this, //OK button handler - null); //no CANCEL button handler + dialog = JColorChooser.createDialog(button, "Select new Colour", true, // modal + colorChooser, this, // OK button handler + null); // no CANCEL button handler } /** - * Handles events from the editor button and from - * the dialog's OK button. + * Handles events from the editor button and from the dialog's OK button. */ public void actionPerformed(ActionEvent e) { if (EDIT.equals(e.getActionCommand())) { - //The user has clicked the cell, so - //bring up the dialog. + // The user has clicked the cell, so + // bring up the dialog. button.setBackground(currentColor); colorChooser.setColor(currentColor); dialog.setVisible(true); - //Make the renderer reappear. + // Make the renderer reappear. fireEditingStopped(); } else - { //User pressed dialog's "OK" button. + { // User pressed dialog's "OK" button. currentColor = colorChooser.getColor(); } } - //Implement the one CellEditor method that AbstractCellEditor doesn't. + // Implement the one CellEditor method that AbstractCellEditor doesn't. public Object getCellEditorValue() { return currentColor; } - //Implement the one method defined by TableCellEditor. - public Component getTableCellEditorComponent(JTable table, - Object value, - boolean isSelected, - int row, - int column) + // Implement the one method defined by TableCellEditor. + public Component getTableCellEditorComponent(JTable table, Object value, + boolean isSelected, int row, int column) { currentColor = (Color) value; return button;