Skip to content

Commit 9e0f602

Browse files
committed
GeneListTunable for use with GeneMANIA task
1 parent a9d47cb commit 9e0f602

File tree

8 files changed

+486
-5
lines changed

8 files changed

+486
-5
lines changed

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/CyActivator.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.baderlab.csplugins.enrichmentmap.style.ChartFactoryManager;
2828
import org.baderlab.csplugins.enrichmentmap.style.EMStyleBuilder;
2929
import org.baderlab.csplugins.enrichmentmap.style.charts.radialheatmap.RadialHeatMapChartFactory;
30+
import org.baderlab.csplugins.enrichmentmap.task.tunables.GeneListGUITunableHandler;
31+
import org.baderlab.csplugins.enrichmentmap.task.tunables.GeneListTunable;
3032
import org.baderlab.csplugins.enrichmentmap.view.EMColumnPresentation;
3133
import org.baderlab.csplugins.enrichmentmap.view.control.ControlPanelMediator;
3234
import org.baderlab.csplugins.enrichmentmap.view.creation.CreationDialogShowAction;
@@ -40,6 +42,8 @@
4042
import org.cytoscape.view.presentation.customgraphics.CyCustomGraphics2Factory;
4143
import org.cytoscape.work.ServiceProperties;
4244
import org.cytoscape.work.TaskFactory;
45+
import org.cytoscape.work.swing.GUITunableHandlerFactory;
46+
import org.cytoscape.work.swing.SimpleGUITunableHandlerFactory;
4347
import org.ops4j.peaberry.osgi.OSGiModule;
4448
import org.osgi.framework.BundleContext;
4549

@@ -117,6 +121,11 @@ public void start(BundleContext bc) {
117121
Properties colProps = new Properties();
118122
colProps.put(CyColumnPresentation.NAMESPACE, EMStyleBuilder.Columns.NAMESPACE);
119123
registerService(bc, new EMColumnPresentation(), CyColumnPresentation.class, colProps);
124+
125+
// gene list GUI tunable handler
126+
SimpleGUITunableHandlerFactory<GeneListGUITunableHandler> geneListGuiHandler
127+
= new SimpleGUITunableHandlerFactory<>(GeneListGUITunableHandler.class, GeneListTunable.class);
128+
registerService(bc, geneListGuiHandler, GUITunableHandlerFactory.class);
120129
}
121130

122131
// If the App is updated or restarted then we want to reload the model and view from the tables

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/task/genemania/QueryGeneManiaTask.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.List;
66
import java.util.Map;
77

8+
import org.baderlab.csplugins.enrichmentmap.task.tunables.GeneListTunable;
89
import org.cytoscape.command.CommandExecutorTaskFactory;
910
import org.cytoscape.work.AbstractTask;
1011
import org.cytoscape.work.FinishStatus;
@@ -29,6 +30,9 @@ public class QueryGeneManiaTask extends AbstractTask {
2930
public static final String GENEMANIA_ORGANISMS_COMMAND = "organisms";
3031
public static final String GENEMANIA_SEARCH_COMMAND = "search";
3132

33+
@Tunable(description = "Genes:")
34+
public GeneListTunable geneList;
35+
3236
@Tunable(description = "Organism:")
3337
public ListSingleSelection<GMOrganism> organisms;
3438

@@ -38,7 +42,6 @@ public class QueryGeneManiaTask extends AbstractTask {
3842
@Tunable(description = "Network Weighting:")
3943
public ListSingleSelection<GMWeightingMethod> weightingMethods;
4044

41-
private final String query;
4245
private GMSearchResult result;
4346

4447
private static long lastTaxonomyId = 9606; // H.sapiens
@@ -51,10 +54,10 @@ public static interface Factory {
5154

5255
@Inject
5356
public QueryGeneManiaTask(@Assisted List<String> geneList) {
54-
query = String.join("|", geneList);
55-
organisms = new ListSingleSelection<>();
56-
weightingMethods = new ListSingleSelection<>(GMWeightingMethod.values());
57-
weightingMethods.setSelectedValue(weightingMethods.getPossibleValues().get(0));
57+
this.geneList = new GeneListTunable(geneList);
58+
this.organisms = new ListSingleSelection<>();
59+
this.weightingMethods = new ListSingleSelection<>(GMWeightingMethod.values());
60+
this.weightingMethods.setSelectedValue(weightingMethods.getPossibleValues().get(0));
5861
}
5962

6063
@ProvidesTitle
@@ -83,6 +86,9 @@ public void run(TaskMonitor tm) throws Exception {
8386
tm.setTitle("EnrichmentMap");
8487
tm.setStatusMessage("Querying GeneMANIA...");
8588

89+
String query = String.join("|", geneList.getSelectedGenes());
90+
System.out.println(query);
91+
8692
Map<String, Object> args = new HashMap<>();
8793
args.put("organism", "" + organisms.getSelectedValue().getTaxonomyId());
8894
args.put("genes", query);
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package org.baderlab.csplugins.enrichmentmap.task.tunables;
2+
3+
import java.lang.reflect.Field;
4+
import java.lang.reflect.Method;
5+
import java.util.List;
6+
7+
import javax.swing.GroupLayout;
8+
import javax.swing.JLabel;
9+
import javax.swing.JPanel;
10+
11+
import org.baderlab.csplugins.enrichmentmap.view.util.CheckboxData;
12+
import org.baderlab.csplugins.enrichmentmap.view.util.CheckboxList;
13+
import org.cytoscape.util.swing.LookAndFeelUtil;
14+
import org.cytoscape.work.Tunable;
15+
import org.cytoscape.work.swing.AbstractGUITunableHandler;
16+
17+
public class GeneListGUITunableHandler extends AbstractGUITunableHandler {
18+
19+
private JPanel panel;
20+
private CheckboxList<String> checkBoxList;
21+
22+
public GeneListGUITunableHandler(Field field, Object instance, Tunable tunable) {
23+
super(field, instance, tunable);
24+
init();
25+
}
26+
27+
public GeneListGUITunableHandler(Method getter, Method setter, Object instance, Tunable tunable) {
28+
super(getter, setter, instance, tunable);
29+
init();
30+
}
31+
32+
private GeneListTunable getGeneListTunable() {
33+
try {
34+
return (GeneListTunable) getValue();
35+
} catch(final Exception e) {
36+
throw new IllegalStateException("bad object", e);
37+
}
38+
}
39+
40+
private void init() {
41+
panel = createGeneListPanel();
42+
}
43+
44+
private JPanel createGeneListPanel() {
45+
JLabel title = new JLabel(getDescription());
46+
47+
GeneListPanel<String> checkboxPanel = new GeneListPanel<>();
48+
for(String gene : getGeneListTunable().getGenes()) {
49+
checkboxPanel.getModel().addElement(new CheckboxData<>(gene));
50+
}
51+
52+
JPanel panel = new JPanel();
53+
54+
final GroupLayout layout = new GroupLayout(panel);
55+
panel.setLayout(layout);
56+
layout.setAutoCreateContainerGaps(true);
57+
layout.setAutoCreateGaps(true);
58+
59+
layout.setHorizontalGroup(layout.createParallelGroup()
60+
.addComponent(title)
61+
.addGroup(layout.createSequentialGroup()
62+
.addComponent(checkboxPanel)
63+
)
64+
);
65+
66+
layout.setVerticalGroup(layout.createSequentialGroup()
67+
.addComponent(title)
68+
.addGroup(layout.createParallelGroup()
69+
.addComponent(checkboxPanel)
70+
)
71+
);
72+
73+
if(LookAndFeelUtil.isAquaLAF())
74+
panel.setOpaque(false);
75+
return panel;
76+
}
77+
78+
@Override
79+
public JPanel getJPanel() {
80+
return panel;
81+
}
82+
83+
@Override
84+
public void handle() {
85+
List<String> selectedGenes = checkBoxList.getSelectedData();
86+
getGeneListTunable().setSelectedGenes(selectedGenes);
87+
}
88+
89+
@Override
90+
public void update() {
91+
}
92+
93+
}
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
package org.baderlab.csplugins.enrichmentmap.task.tunables;
2+
3+
import static javax.swing.GroupLayout.DEFAULT_SIZE;
4+
import static javax.swing.GroupLayout.PREFERRED_SIZE;
5+
import static javax.swing.GroupLayout.Alignment.CENTER;
6+
import static org.cytoscape.util.swing.LookAndFeelUtil.isAquaLAF;
7+
8+
import java.util.ArrayList;
9+
import java.util.Collections;
10+
import java.util.List;
11+
import java.util.stream.Collectors;
12+
13+
import javax.swing.GroupLayout;
14+
import javax.swing.JButton;
15+
import javax.swing.JPanel;
16+
import javax.swing.JScrollPane;
17+
import javax.swing.event.ListDataEvent;
18+
import javax.swing.event.ListDataListener;
19+
20+
import org.baderlab.csplugins.enrichmentmap.view.util.CheckboxData;
21+
import org.baderlab.csplugins.enrichmentmap.view.util.CheckboxList;
22+
import org.baderlab.csplugins.enrichmentmap.view.util.CheckboxListModel;
23+
import org.cytoscape.util.swing.LookAndFeelUtil;
24+
25+
@SuppressWarnings("serial")
26+
public class GeneListPanel<T> extends JPanel {
27+
28+
private CheckboxList<T> checkboxList;
29+
private CheckboxListModel<T> checkboxListModel;
30+
private JButton selectAllButton;
31+
private JButton selectNoneButton;
32+
33+
34+
public GeneListPanel() {
35+
checkboxListModel = new CheckboxListModel<>();
36+
checkboxList = new CheckboxList<>(checkboxListModel);
37+
38+
JScrollPane scrollPane = new JScrollPane();
39+
scrollPane.setViewportView(checkboxList);
40+
41+
selectAllButton = new JButton("Select All");
42+
selectNoneButton = new JButton("Select None");
43+
44+
selectAllButton.addActionListener(e -> {
45+
List<CheckboxData<T>> oldValue = getSelectedData();
46+
checkboxListModel.forEach(cb -> cb.setSelected(true));
47+
checkboxList.invalidate();
48+
checkboxList.repaint();
49+
updateSelectionButtons();
50+
firePropertyChange("selectedData", oldValue, getSelectedData());
51+
});
52+
selectNoneButton.addActionListener(e -> {
53+
List<CheckboxData<T>> oldValue = getSelectedData();
54+
checkboxListModel.forEach(cb -> cb.setSelected(false));
55+
checkboxList.invalidate();
56+
checkboxList.repaint();
57+
updateSelectionButtons();
58+
firePropertyChange("selectedData", oldValue, Collections.emptyList());
59+
});
60+
61+
62+
selectAllButton.setEnabled(false);
63+
selectNoneButton.setEnabled(false);
64+
65+
checkboxListModel.addListDataListener(new ListDataListener() {
66+
@Override
67+
public void intervalRemoved(ListDataEvent e) {
68+
updateSelectionButtons();
69+
}
70+
@Override
71+
public void intervalAdded(ListDataEvent e) {
72+
updateSelectionButtons();
73+
}
74+
@Override
75+
public void contentsChanged(ListDataEvent e) {
76+
updateSelectionButtons();
77+
}
78+
});
79+
80+
checkboxList.addListSelectionListener(evt -> {
81+
if (!evt.getValueIsAdjusting()) {
82+
updateSelectionButtons();
83+
firePropertyChange("selectedData", null, getSelectedData());
84+
}
85+
});
86+
87+
if (isAquaLAF()) {
88+
selectAllButton.putClientProperty("JButton.buttonType", "gradient");
89+
selectAllButton.putClientProperty("JComponent.sizeVariant", "small");
90+
selectNoneButton.putClientProperty("JButton.buttonType", "gradient");
91+
selectNoneButton.putClientProperty("JComponent.sizeVariant", "small");
92+
}
93+
94+
LookAndFeelUtil.equalizeSize(selectAllButton, selectNoneButton);
95+
96+
final GroupLayout layout = new GroupLayout(this);
97+
setLayout(layout);
98+
layout.setAutoCreateContainerGaps(false);
99+
layout.setAutoCreateGaps(!LookAndFeelUtil.isAquaLAF());
100+
101+
layout.setHorizontalGroup(layout.createSequentialGroup()
102+
.addComponent(scrollPane, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
103+
.addGroup(layout.createParallelGroup(CENTER, true)
104+
.addComponent(selectAllButton, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE)
105+
.addComponent(selectNoneButton, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE)
106+
)
107+
);
108+
layout.setVerticalGroup(layout.createParallelGroup()
109+
.addComponent(scrollPane, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
110+
.addGroup(layout.createSequentialGroup()
111+
.addComponent(selectAllButton)
112+
.addComponent(selectNoneButton)
113+
)
114+
);
115+
116+
if (LookAndFeelUtil.isAquaLAF())
117+
setOpaque(false);
118+
}
119+
120+
121+
private void updateSelectionButtons() {
122+
boolean enabled = isEnabled() && !checkboxListModel.isEmpty();
123+
List<CheckboxData<T>> selectedData = getSelectedData();
124+
125+
selectAllButton.setEnabled(enabled && selectedData.size() < checkboxListModel.size());
126+
selectNoneButton.setEnabled(enabled && selectedData.size() > 0);
127+
}
128+
129+
public CheckboxList<T> getCheckboxList() {
130+
return checkboxList;
131+
}
132+
133+
public CheckboxListModel<T> getModel() {
134+
return checkboxListModel;
135+
}
136+
137+
public List<T> getSelectedDataItems() {
138+
return checkboxListModel.stream()
139+
.filter(CheckboxData::isSelected)
140+
.map(CheckboxData::getData)
141+
.collect(Collectors.toList());
142+
}
143+
144+
@Override
145+
public void setEnabled(boolean enabled) {
146+
super.setEnabled(enabled);
147+
checkboxList.setEnabled(enabled);
148+
updateSelectionButtons();
149+
}
150+
151+
public List<CheckboxData<T>> getSelectedData() {
152+
List<CheckboxData<T>> list = new ArrayList<>();
153+
int size = getModel().getSize();
154+
155+
for (int i = 0; i < size; i++) {
156+
CheckboxData<T> data = (CheckboxData<T>) getModel().getElementAt(i);
157+
158+
if (data.isSelected())
159+
list.add(data);
160+
}
161+
162+
return list;
163+
}
164+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package org.baderlab.csplugins.enrichmentmap.task.tunables;
2+
3+
import java.util.Collections;
4+
import java.util.List;
5+
6+
public class GeneListTunable {
7+
8+
private List<String> genes;
9+
private List<String> selectedGenes;
10+
private List<String> leadingEdgeGenes;
11+
12+
13+
public GeneListTunable(List<String> genes) {
14+
this.genes = genes;
15+
this.selectedGenes = genes;
16+
this.leadingEdgeGenes = Collections.emptyList();
17+
}
18+
19+
public void setLeadingEdgeGenes(List<String> genes) {
20+
this.leadingEdgeGenes = genes;
21+
}
22+
23+
public List<String> getLeadingEdgeGenes() {
24+
return leadingEdgeGenes;
25+
}
26+
27+
public void setSelectedGenes(List<String> selectedGenes) {
28+
this.selectedGenes = selectedGenes;
29+
}
30+
31+
public List<String> getSelectedGenes() {
32+
return selectedGenes;
33+
}
34+
35+
public List<String> getGenes() {
36+
return genes;
37+
}
38+
39+
}

0 commit comments

Comments
 (0)