X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fgui%2FFeatureSettings.java;h=de61be3a87b23d907cef9e0d19d361a2939c9c37;hb=32c4c7d4e5db964461c541ee2252510aa3e9e563;hp=5e4f5407f8f734848f0333fbcda12eaf9af84314;hpb=8c0f35fa0bee850e670c157157cc335d8a1a49ae;p=jalview.git diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index 5e4f540..de61be3 100755 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -23,6 +23,9 @@ import java.util.*; import java.awt.*; import java.awt.event.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; @@ -34,7 +37,7 @@ public class FeatureSettings extends JPanel { DasSourceBrowser dassourceBrowser; - jalview.io.DasSequenceFeatureFetcher dasFeatureFetcher; + jalview.ws.DasSequenceFeatureFetcher dasFeatureFetcher; JPanel settingsPane = new JPanel(); JPanel dasSettingsPane = new JPanel(); @@ -118,29 +121,57 @@ public class FeatureSettings if (af.getViewport().featuresDisplayed == null || fr.renderOrder == null) { - fr.findAllFeatures(); + fr.findAllFeatures(true); // display everything! } setTableData(); + final PropertyChangeListener change; + final FeatureSettings fs=this; + fr.addPropertyChangeListener(change=new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) + { + 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() + { + public void internalFrameClosed( + javax.swing.event.InternalFrameEvent evt) + { + fr.removePropertyChangeListener(change); + } + ; + }); frame.setLayer(JLayeredPane.PALETTE_LAYER); } + /** + * true when Feature Settings are updating from feature renderer + */ + private boolean handlingUpdate=false; + /** + * contains a float[3] for each feature type string. created by setTableData + */ + Hashtable typeWidth=null; synchronized public void setTableData() { if (fr.featureGroups == null) { fr.featureGroups = new Hashtable(); } - Vector allFeatures = new Vector(); Vector allGroups = new Vector(); SequenceFeature[] tmpfeatures; String group; - for (int i = 0; i < af.getViewport().alignment.getHeight(); i++) { if (af.getViewport().alignment.getSequenceAt(i).getDatasetSequence(). @@ -167,54 +198,10 @@ public class FeatureSettings if (!allGroups.contains(group)) { allGroups.addElement(group); - - boolean visible = true; - if (fr.featureGroups.containsKey(group)) - { - visible = ( (Boolean) fr.featureGroups.get(group)).booleanValue(); - } - - 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) + if (group!=null) { - continue; + checkGroupState(group); } - - fr.featureGroups.put(group, new Boolean(visible)); - - 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(true); - } - }); - groupPanel.add(check); } } @@ -226,19 +213,87 @@ public class FeatureSettings } } - resetTable(false); + resetTable(null); validate(); } + /** + * + * @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; + } + } - void resetTable(boolean groupsChanged) + 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) { + 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 for (int i = 0; i < af.getViewport().alignment.getHeight(); i++) { @@ -263,12 +318,26 @@ public class FeatureSettings 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 { + avWidth = (float[]) typeWidth.get(tmpfeatures[index].getType()); + } + avWidth[0]++; + if (tmpfeatures[index].getBegin()>tmpfeatures[index].getEnd()) + { + avWidth[1]+=1+tmpfeatures[index].getBegin()-tmpfeatures[index].getEnd(); + } else { + avWidth[1]+=1+tmpfeatures[index].getEnd()-tmpfeatures[index].getBegin(); + } index++; } } @@ -279,6 +348,8 @@ 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 for (int ro = fr.renderOrder.length - 1; ro > -1; ro--) @@ -292,8 +363,7 @@ 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); } @@ -337,8 +407,27 @@ public class FeatureSettings bigPanel.add(groupPanel, BorderLayout.NORTH); } - updateFeatureRenderer(data); - + 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; + float[] order = new float[data.length]; + for (int i=0;i1) + sort = sort || order[i-1]>order[i]; + } + if (sort) + jalview.util.QuickSort.sort(order, data); } void load() @@ -368,15 +457,21 @@ public class FeatureSettings JalviewUserColours(); jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in); - for (int i = 0; i < jucs.getColourCount(); i++) + for (int i = jucs.getColourCount()-1; i >=0; i--) { - fr.setColour(jucs.getColour(i).getName(), + 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()); + } + if (table!=null) { + resetTable(null); + Object[][] data=((FeatureTableModel) table.getModel()).getData(); + ensureOrder(data); + updateFeatureRenderer(data,false); + table.repaint(); } - - setTableData(); - af.alignPanel.paintAlignment(true); } catch (Exception ex) { @@ -411,15 +506,24 @@ public class FeatureSettings 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; while (e.hasMoreElements()) { + sortTypes[i] = e.nextElement().toString(); + 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 (max0) + sort = sort || width[i-1]>width[i]; + } + if (sort) + jalview.util.QuickSort.sort(width, data); + // update global priority order + updateFeatureRenderer(data,false); + table.repaint(); + } public void close() { try @@ -455,13 +602,12 @@ public class FeatureSettings public void updateFeatureRenderer(Object[][] data) { - fr.setFeaturePriority(data); + 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; @@ -481,6 +627,8 @@ public class FeatureSettings JButton fetchDAS = new JButton(); JButton saveDAS = new JButton(); JButton cancelDAS = new JButton(); + JButton optimizeOrder = new JButton(); + JPanel transbuttons = new JPanel(new BorderLayout()); private void jbInit() throws Exception { @@ -497,6 +645,13 @@ public class FeatureSettings invertSelection(); } }); + optimizeOrder.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); + optimizeOrder.setText("Optimise Order"); + optimizeOrder.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + orderByAvWidth(); + } + }); cancel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); cancel.setText("Cancel"); cancel.addActionListener(new ActionListener() @@ -576,7 +731,9 @@ public class FeatureSettings tabbedPane.addTab("DAS Settings", dasSettingsPane); bigPanel.add(transPanel, java.awt.BorderLayout.SOUTH); transPanel.add(transparency); - transPanel.add(invert); + transbuttons.add(invert, java.awt.BorderLayout.NORTH); + transbuttons.add(optimizeOrder,java.awt.BorderLayout.SOUTH); + transPanel.add(transbuttons); buttonPanel.add(ok); buttonPanel.add(cancel); buttonPanel.add(loadColours); @@ -621,7 +778,7 @@ public class FeatureSettings } dasFeatureFetcher = - new jalview.io.DasSequenceFeatureFetcher( + new jalview.ws.DasSequenceFeatureFetcher( dataset, this, selectedSources); @@ -647,6 +804,17 @@ public class FeatureSettings fetchDAS.setEnabled(true); cancelDAS.setEnabled(false); } + public void noDasSourceActive() + { + 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); + complete(); + } ///////////////////////////////////////////////////////////////////////// // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html @@ -761,6 +929,7 @@ public class FeatureSettings return this; } } + } class ColorEditor