import jalview.api.FeatureColourI;
import jalview.api.FeatureSettingsControllerI;
import jalview.bin.Cache;
-import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
import jalview.gui.Help.HelpId;
import jalview.io.JalviewFileChooser;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
-public class FeatureSettings extends JPanel implements
- FeatureSettingsControllerI
+public class FeatureSettings extends JPanel
+ implements FeatureSettingsControllerI
{
DasSourceBrowser dassourceBrowser;
private static final int MIN_WIDTH = 400;
private static final int MIN_HEIGHT = 400;
+
+ /**
+ * when true, constructor is still executing - so ignore UI events
+ */
+ protected volatile boolean inConstruction = true;
/**
* Constructor
this.af = af;
fr = af.getFeatureRenderer();
// allow transparency to be recovered
- transparency.setMaximum(100 - (int) ((originalTransparency = fr
- .getTransparency()) * 100));
+ transparency.setMaximum(100
+ - (int) ((originalTransparency = fr.getTransparency()) * 100));
try
{
}
frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
- frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
- {
- @Override
- public void internalFrameClosed(
- javax.swing.event.InternalFrameEvent evt)
- {
- fr.removePropertyChangeListener(change);
- dassourceBrowser.fs = null;
- };
- });
+ frame.addInternalFrameListener(
+ new javax.swing.event.InternalFrameAdapter()
+ {
+ @Override
+ public void internalFrameClosed(
+ javax.swing.event.InternalFrameEvent evt)
+ {
+ fr.removePropertyChangeListener(change);
+ dassourceBrowser.fs = null;
+ };
+ });
frame.setLayer(JLayeredPane.PALETTE_LAYER);
+ inConstruction = false;
}
protected void popupSort(final int selectedRow, final String type,
{
final FeatureColourI featureColour = (FeatureColourI) typeCol;
- JPopupMenu men = new JPopupMenu(MessageManager.formatMessage(
- "label.settings_for_param", new String[] { type }));
+ JPopupMenu men = new JPopupMenu(MessageManager
+ .formatMessage("label.settings_for_param", new String[]
+ { type }));
JMenuItem scr = new JMenuItem(
MessageManager.getString("label.sort_by_score"));
men.add(scr);
@Override
public void actionPerformed(ActionEvent e)
{
- me.af.avc.sortAlignmentByFeatureScore(Arrays
- .asList(new String[] { type }));
+ me.af.avc
+ .sortAlignmentByFeatureScore(Arrays.asList(new String[]
+ { type }));
}
});
@Override
public void actionPerformed(ActionEvent e)
{
- me.af.avc.sortAlignmentByFeatureDensity(Arrays
- .asList(new String[] { type }));
+ me.af.avc
+ .sortAlignmentByFeatureDensity(Arrays.asList(new String[]
+ { type }));
}
});
else
{
// probably the color chooser!
- table.setValueAt(
- new FeatureColour(colorChooser.getColor()),
+ table.setValueAt(new FeatureColour(colorChooser.getColor()),
selectedRow, 1);
table.validate();
me.updateFeatureRenderer(
false, type);
}
});
- JMenuItem clearCols = new JMenuItem(
- MessageManager.getString("label.select_columns_not_containing"));
+ JMenuItem clearCols = new JMenuItem(MessageManager
+ .getString("label.select_columns_not_containing"));
clearCols.addActionListener(new ActionListener()
{
@Override
private boolean handlingUpdate = false;
/**
- * contains a float[3] for each feature type string. created by setTableData
+ * holds {featureCount, totalExtent} for each feature type
*/
Map<String, float[]> typeWidth = null;
@Override
synchronized public void discoverAllFeatureData()
{
- Vector<String> allFeatures = new Vector<String>();
- Vector<String> allGroups = new Vector<String>();
- SequenceFeature[] tmpfeatures;
- String group;
- for (int i = 0; i < af.getViewport().getAlignment().getHeight(); i++)
- {
- tmpfeatures = af.getViewport().getAlignment().getSequenceAt(i)
- .getSequenceFeatures();
- if (tmpfeatures == null)
- {
- continue;
- }
+ Set<String> allGroups = new HashSet<>();
+ AlignmentI alignment = af.getViewport().getAlignment();
- int index = 0;
- while (index < tmpfeatures.length)
+ for (int i = 0; i < alignment.getHeight(); i++)
+ {
+ SequenceI seq = alignment.getSequenceAt(i);
+ for (String group : seq.getFeatures().getFeatureGroups(true))
{
- if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)
+ if (group != null && !allGroups.contains(group))
{
- index++;
- continue;
- }
-
- if (tmpfeatures[index].getFeatureGroup() != null)
- {
- group = tmpfeatures[index].featureGroup;
- if (!allGroups.contains(group))
- {
- allGroups.addElement(group);
- checkGroupState(group);
- }
- }
-
- if (!allFeatures.contains(tmpfeatures[index].getType()))
- {
- allFeatures.addElement(tmpfeatures[index].getType());
+ allGroups.add(group);
+ checkGroupState(group);
}
- index++;
}
}
final String grp = group;
final JCheckBox check = new JCheckBox(group, visible);
check.setFont(new Font("Serif", Font.BOLD, 12));
+ check.setToolTipText(group);
check.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent evt)
{
fr.setGroupVisibility(check.getText(), check.isSelected());
- af.alignPanel.getSeqPanel().seqCanvas.repaint();
- if (af.alignPanel.overviewPanel != null)
- {
- af.alignPanel.overviewPanel.updateOverviewImage();
- }
-
resetTable(new String[] { grp });
+ af.alignPanel.paintAlignment(true, true);
}
});
groupPanel.add(check);
synchronized void resetTable(String[] groupChanged)
{
- if (resettingTable == true)
+ if (resettingTable)
{
return;
}
resettingTable = true;
- typeWidth = new Hashtable<String, float[]>();
+ 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<String> visibleChecks = new Vector<String>();
- Set<String> foundGroups = new HashSet<String>();
-
- // Find out which features should be visible depending on which groups
- // are selected / deselected
- // and recompute average width ordering
+
+ Set<String> displayableTypes = new HashSet<>();
+ Set<String> foundGroups = new HashSet<>();
+
+ /*
+ * determine which feature types may be visible depending on
+ * which groups are selected, and recompute average width data
+ */
for (int i = 0; i < af.getViewport().getAlignment().getHeight(); i++)
{
- tmpfeatures = af.getViewport().getAlignment().getSequenceAt(i)
- .getSequenceFeatures();
- if (tmpfeatures == null)
- {
- continue;
- }
+ SequenceI seq = af.getViewport().getAlignment().getSequenceAt(i);
- int index = 0;
- while (index < tmpfeatures.length)
+ /*
+ * get the sequence's groups for positional features
+ * and keep track of which groups are visible
+ */
+ Set<String> groups = seq.getFeatures().getFeatureGroups(true);
+ Set<String> visibleGroups = new HashSet<>();
+ for (String group : groups)
{
- group = tmpfeatures[index].featureGroup;
- foundGroups.add(group);
-
- if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)
- {
- index++;
- continue;
- }
-
if (group == null || checkGroupState(group))
{
- type = tmpfeatures[index].getType();
- if (!visibleChecks.contains(type))
- {
- visibleChecks.addElement(type);
- }
+ visibleGroups.add(group);
}
- if (!typeWidth.containsKey(tmpfeatures[index].getType()))
- {
- typeWidth.put(tmpfeatures[index].getType(),
- avWidth = new float[3]);
- }
- else
- {
- avWidth = typeWidth.get(tmpfeatures[index].getType());
- }
- avWidth[0]++;
- if (tmpfeatures[index].getBegin() > tmpfeatures[index].getEnd())
- {
- avWidth[1] += 1 + tmpfeatures[index].getBegin()
- - tmpfeatures[index].getEnd();
- }
- else
+ }
+ foundGroups.addAll(groups);
+
+ /*
+ * get distinct feature types for visible groups
+ * record distinct visible types, and their count and total length
+ */
+ Set<String> types = seq.getFeatures().getFeatureTypesForGroups(true,
+ visibleGroups.toArray(new String[visibleGroups.size()]));
+ for (String type : types)
+ {
+ displayableTypes.add(type);
+ float[] avWidth = typeWidth.get(type);
+ if (avWidth == null)
{
- avWidth[1] += 1 + tmpfeatures[index].getEnd()
- - tmpfeatures[index].getBegin();
+ avWidth = new float[2];
+ typeWidth.put(type, avWidth);
}
- index++;
+ // todo this could include features with a non-visible group
+ // - do we greatly care?
+ // todo should we include non-displayable features here, and only
+ // update when features are added?
+ avWidth[0] += seq.getFeatures().getFeatureCount(true, type);
+ avWidth[1] += seq.getFeatures().getTotalFeatureLength(type);
}
}
- int fSize = visibleChecks.size();
- Object[][] data = new Object[fSize][3];
+ Object[][] data = new Object[displayableTypes.size()][3];
int dataIndex = 0;
if (fr.hasRenderOrder())
List<String> frl = fr.getRenderOrder();
for (int ro = frl.size() - 1; ro > -1; ro--)
{
- type = frl.get(ro);
+ String type = frl.get(ro);
- if (!visibleChecks.contains(type))
+ if (!displayableTypes.contains(type))
{
continue;
}
data[dataIndex][0] = type;
data[dataIndex][1] = fr.getFeatureStyle(type);
- data[dataIndex][2] = new Boolean(af.getViewport()
- .getFeaturesDisplayed().isVisible(type));
+ data[dataIndex][2] = new Boolean(
+ af.getViewport().getFeaturesDisplayed().isVisible(type));
dataIndex++;
- visibleChecks.removeElement(type);
+ displayableTypes.remove(type);
}
}
- fSize = visibleChecks.size();
- for (int i = 0; i < fSize; i++)
+ /*
+ * process any extra features belonging only to
+ * a group which was just selected
+ */
+ while (!displayableTypes.isEmpty())
{
- // These must be extra features belonging to the group
- // which was just selected
- type = visibleChecks.elementAt(i).toString();
+ String type = displayableTypes.iterator().next();
data[dataIndex][0] = type;
data[dataIndex][1] = fr.getFeatureStyle(type);
data[dataIndex][2] = new Boolean(true);
dataIndex++;
+ displayableTypes.remove(type);
}
if (originalData == null)
table.setModel(new FeatureTableModel(data));
table.getColumnModel().getColumn(0).setPreferredWidth(200);
- groupPanel.setLayout(new GridLayout(fr.getFeatureGroupsSize() / 4 + 1,
- 4));
+ groupPanel.setLayout(
+ new GridLayout(fr.getFeatureGroupsSize() / 4 + 1, 4));
pruneGroups(foundGroups);
groupPanel.validate();
JalviewFileChooser chooser = new JalviewFileChooser("fc",
"Sequence Feature Colours");
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle(MessageManager
- .getString("label.load_feature_colours"));
+ chooser.setDialogTitle(
+ MessageManager.getString("label.load_feature_colours"));
chooser.setToolTipText(MessageManager.getString("action.load"));
int value = chooser.showOpenDialog(this);
try
{
- InputStreamReader in = new InputStreamReader(new FileInputStream(
- file), "UTF-8");
+ InputStreamReader in = new InputStreamReader(
+ new FileInputStream(file), "UTF-8");
JalviewUserColours jucs = JalviewUserColours.unmarshal(in);
JalviewFileChooser chooser = new JalviewFileChooser("fc",
"Sequence Feature Colours");
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle(MessageManager
- .getString("label.save_feature_colours"));
+ chooser.setDialogTitle(
+ MessageManager.getString("label.save_feature_colours"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
col.setRGB(Format.getHexString(fcol.getMaxColour()));
col.setMin(fcol.getMin());
col.setMax(fcol.getMax());
- col.setMinRGB(jalview.util.Format.getHexString(fcol
- .getMinColour()));
+ col.setMinRGB(
+ jalview.util.Format.getHexString(fcol.getMinColour()));
col.setAutoScale(fcol.isAutoScaled());
col.setThreshold(fcol.getThreshold());
col.setColourByLabel(fcol.isColourByLabel());
- col.setThreshType(fcol.isAboveThreshold() ? "ABOVE" : (fcol
- .isBelowThreshold() ? "BELOW" : "NONE"));
+ col.setThreshType(fcol.isAboveThreshold() ? "ABOVE"
+ : (fcol.isBelowThreshold() ? "BELOW" : "NONE"));
}
ucs.addColour(col);
}
public void invertSelection()
{
- for (int i = 0; i < table.getRowCount(); i++)
+ Object[][] data = ((FeatureTableModel) table.getModel()).getData();
+ for (int i = 0; i < data.length; i++)
{
- Boolean value = (Boolean) table.getValueAt(i, 2);
-
- table.setValueAt(new Boolean(!value.booleanValue()), i, 2);
+ data[i][2] = !(Boolean) data[i][2];
}
+ af.alignPanel.paintAlignment(true, true);
}
public void orderByAvWidth()
{
if (fr.setFeaturePriority(data, visibleNew))
{
- af.alignPanel.paintAlignment(true);
+ af.alignPanel.paintAlignment(true, true);
}
}
}
});
sortByDens.setFont(JvSwingUtils.getLabelFont());
- sortByDens.setText(MessageManager
- .getString("label.sequence_sort_by_density"));
+ sortByDens.setText(
+ MessageManager.getString("label.sequence_sort_by_density"));
sortByDens.addActionListener(new ActionListener()
{
@Override
@Override
public void stateChanged(ChangeEvent evt)
{
- fr.setTransparency((100 - transparency.getValue()) / 100f);
- af.alignPanel.paintAlignment(true);
+ if (!inConstruction)
+ {
+ fr.setTransparency((100 - transparency.getValue()) / 100f);
+ af.alignPanel.paintAlignment(true,true);
+ }
}
});
transparency.setMaximum(70);
- transparency.setToolTipText(MessageManager
- .getString("label.transparency_tip"));
+ transparency.setToolTipText(
+ MessageManager.getString("label.transparency_tip"));
fetchDAS.setText(MessageManager.getString("label.fetch_das_features"));
fetchDAS.addActionListener(new ActionListener()
{
public void noDasSourceActive()
{
complete();
- JvOptionPane
- .showInternalConfirmDialog(
- Desktop.desktop,
- MessageManager
- .getString("label.no_das_sources_selected_warn"),
- MessageManager
- .getString("label.no_das_sources_selected_title"),
- JvOptionPane.DEFAULT_OPTION,
- JvOptionPane.INFORMATION_MESSAGE);
+ JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
+ MessageManager.getString("label.no_das_sources_selected_warn"),
+ MessageManager.getString("label.no_das_sources_selected_title"),
+ JvOptionPane.DEFAULT_OPTION, JvOptionPane.INFORMATION_MESSAGE);
}
// ///////////////////////////////////////////////////////////////////////
}
@Override
- public Component getTableCellRendererComponent(JTable tbl,
- Object color, boolean isSelected, boolean hasFocus, int row,
- int column)
+ public Component getTableCellRendererComponent(JTable tbl, Object color,
+ boolean isSelected, boolean hasFocus, int row, int column)
{
FeatureColourI cellColour = (FeatureColourI) color;
// JLabel comp = new JLabel();
}
}
-class ColorEditor extends AbstractCellEditor implements TableCellEditor,
- ActionListener
+class ColorEditor extends AbstractCellEditor
+ implements TableCellEditor, ActionListener
{
FeatureSettings me;