Skip to content

Commit 0e70f89

Browse files
authored
Adds checkboxes to observation list (#196)
+ Adds ability do disable and enable observations to observe during SMC execution
2 parents 56022b9 + dd17175 commit 0e70f89

File tree

4 files changed

+119
-20
lines changed

4 files changed

+119
-20
lines changed

src/main/java/dk/aau/cs/TCTL/visitors/SMCQueryVisitor.java

+16-14
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package dk.aau.cs.TCTL.visitors;
22

3+
import java.util.ArrayList;
34
import java.util.List;
45

56
import dk.aau.cs.TCTL.*;
67
import dk.aau.cs.verification.SMCSettings;
78
import dk.aau.cs.verification.observations.Observation;
89

910
public class SMCQueryVisitor extends LTLQueryVisitor {
10-
1111
private static final String XML_SMC = "smc";
1212
private static final String XML_TIME_BOUND_TAG = "time-bound";
1313
private static final String XML_STEP_BOUND_TAG = "step-bound";
@@ -18,20 +18,22 @@ public class SMCQueryVisitor extends LTLQueryVisitor {
1818
private static final String XML_INTERVAL_WIDTH_TAG = "interval-width";
1919
private static final String XML_COMPARE_TO_FLOAT_TAG = "compare-to";
2020
private static final String XML_OBSERVATIONS = "observations";
21-
private static final String XML_WATCH = "watch";
22-
private static final String XML_WATCH_ID = "id";
23-
private static final String XML_WATCH_NAME = "name";
2421

2522
public String getXMLQueryFor(TCTLAbstractProperty property, String queryName, SMCSettings settings) {
26-
buildXMLQuery(property, queryName, settings);
23+
buildXMLQuery(property, queryName, settings, true);
2724
return getFormatted();
2825
}
2926

3027
public void buildXMLQuery(TCTLAbstractProperty property, String queryName, SMCSettings settings) {
28+
buildXMLQuery(property, queryName, settings, false);
29+
}
30+
31+
public void buildXMLQuery(TCTLAbstractProperty property, String queryName, SMCSettings settings, boolean discardDisabled) {
3132
xmlQuery.append(startTag(XML_PROP) + queryInfo(queryName) + smcTag(settings));
3233

33-
if (!settings.getObservations().isEmpty()) {
34-
xmlQuery.append(observationTag(settings.getObservations()));
34+
List<Observation> observations = settings.getObservations();
35+
if (!observations.isEmpty()) {
36+
xmlQuery.append(observationTag(observations, discardDisabled));
3537
}
3638

3739
xmlQuery.append(startTag(XML_FORMULA));
@@ -57,10 +59,14 @@ private String smcTag(SMCSettings settings) {
5759
return emptyElement(tagContent);
5860
}
5961

60-
private String observationTag(List<Observation> observations) {
62+
private String observationTag(List<Observation> observations, boolean discardDisabled) {
6163
String observationXml = startTag(XML_OBSERVATIONS);
62-
63-
for (Observation observation : observations) {
64+
List<Observation> observationsCopy = new ArrayList<>(observations);
65+
if (discardDisabled) {
66+
observationsCopy.removeIf(observation -> !observation.isEnabled());
67+
}
68+
69+
for (Observation observation : observationsCopy) {
6470
observationXml += observation.toXml();
6571
}
6672

@@ -69,10 +75,6 @@ private String observationTag(List<Observation> observations) {
6975
return observationXml;
7076
}
7177

72-
private String tagAttribute(String name, String value) {
73-
return " " + name + "=\"" + value + "\"";
74-
}
75-
7678
private String tagAttribute(String name, float value) {
7779
return " " + name + "=\"" + String.valueOf(value) + "\"";
7880
}

src/main/java/dk/aau/cs/io/queries/TAPNQueryLoader.java

+5
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ private TAPNQuery parseTAPNQuery(Element queryElement, TimedArcPetriNetNetwork n
135135

136136
Element root = getFirstElementChild(watch);
137137
Observation observation = new Observation(name, parseObsExpression(root));
138+
139+
if (watch.hasAttribute("isEnabled")) {
140+
observation.setEnabled(watch.getAttribute("isEnabled").equals("true"));
141+
}
142+
138143
observations.add(observation);
139144
}
140145

src/main/java/dk/aau/cs/verification/observations/Observation.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
public class Observation {
77
private String name;
8+
private boolean isEnabled = true;
89

910
private ObsExpression expression = new ObsPlaceHolder();
1011

@@ -25,6 +26,10 @@ public ObsExpression getExpression() {
2526
return expression;
2627
}
2728

29+
public boolean isEnabled() {
30+
return isEnabled;
31+
}
32+
2833
public void setName(String name) {
2934
this.name = name;
3035
}
@@ -33,12 +38,16 @@ public void setExpression(ObsExpression expression) {
3338
this.expression = expression;
3439
}
3540

41+
public void setEnabled(boolean isEnabled) {
42+
this.isEnabled = isEnabled;
43+
}
44+
3645
@Override
3746
public String toString() {
3847
return name + ": " + expression.toString();
3948
}
4049

4150
public String toXml() {
42-
return "<watch name=\"" + name + "\">" + expression.toXml() + "</watch>";
51+
return "<watch name=\"" + name + "\" isEnabled=\"" + isEnabled + "\">" + expression.toXml() + "</watch>";
4352
}
4453
}

src/main/java/net/tapaal/gui/petrinet/dialog/ObservationListDialog.java

+88-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
import javax.swing.DefaultListCellRenderer;
44
import javax.swing.DefaultListModel;
55
import javax.swing.JButton;
6+
import javax.swing.JCheckBox;
7+
import javax.swing.JLabel;
68
import javax.swing.JList;
79
import javax.swing.JPanel;
810
import javax.swing.JScrollPane;
911
import javax.swing.JViewport;
10-
import javax.swing.SwingUtilities;
12+
import javax.swing.ListCellRenderer;
1113
import javax.swing.event.ListDataListener;
1214
import javax.swing.event.ListDataEvent;
1315

@@ -16,15 +18,19 @@
1618
import pipe.gui.TAPAALGUI;
1719
import pipe.gui.swingcomponents.EscapableDialog;
1820

21+
import java.awt.BorderLayout;
1922
import java.awt.Component;
2023
import java.awt.Dimension;
2124
import java.awt.FontMetrics;
2225
import java.awt.GridBagLayout;
2326
import java.awt.Insets;
27+
import java.awt.Rectangle;
2428
import java.awt.event.MouseAdapter;
2529
import java.awt.event.MouseEvent;
2630
import java.awt.GridBagConstraints;
31+
import java.util.HashMap;
2732
import java.util.List;
33+
import java.util.Map;
2834

2935
public class ObservationListDialog extends EscapableDialog {
3036
private final TimedArcPetriNetNetwork tapnNetwork;
@@ -73,6 +79,74 @@ public Component getListCellRendererComponent(JList<?> list, Object value, int i
7379
}
7480
}
7581

82+
private static class CheckboxListRenderer extends JPanel implements ListCellRenderer<Observation> {
83+
private final JCheckBox checkBox;
84+
private final JLabel label;
85+
private final EllipsisListCellRenderer ellipsisRenderer;
86+
87+
public CheckboxListRenderer() {
88+
setLayout(new BorderLayout());
89+
checkBox = new JCheckBox();
90+
label = new JLabel();
91+
ellipsisRenderer = new EllipsisListCellRenderer();
92+
add(checkBox, BorderLayout.WEST);
93+
add(label, BorderLayout.CENTER);
94+
}
95+
96+
@Override
97+
public Component getListCellRendererComponent(JList<? extends Observation> list, Observation value, int index, boolean isSelected, boolean cellHasFocus) {
98+
ellipsisRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
99+
100+
boolean checked = ((CheckboxListModel)list.getModel()).isChecked(value);
101+
checkBox.setSelected(checked);
102+
103+
setToolTipText("Select the observation to be monitored during SMC execution");
104+
105+
label.setText(value.toString());
106+
label.setToolTipText(ellipsisRenderer.getToolTipText());
107+
label.setEnabled(checked);
108+
109+
setBackground(isSelected ? list.getSelectionBackground() : list.getBackground());
110+
setForeground(isSelected ? list.getSelectionForeground() : list.getForeground());
111+
checkBox.setBackground(getBackground());
112+
label.setBackground(getBackground());
113+
114+
return this;
115+
}
116+
}
117+
118+
private static class CheckboxListModel extends DefaultListModel<Observation> {
119+
private final Map<Observation, Boolean> checkMap = new HashMap<>();
120+
121+
public boolean isChecked(Observation observation) {
122+
return checkMap.getOrDefault(observation, observation.isEnabled());
123+
}
124+
125+
public void toggleChecked(Observation observation) {
126+
boolean currentState = isChecked(observation);
127+
boolean newState = !currentState;
128+
checkMap.put(observation, newState);
129+
observation.setEnabled(newState);
130+
int index = indexOf(observation);
131+
if (index >= 0) {
132+
fireContentsChanged(this, index, index);
133+
}
134+
}
135+
136+
@Override
137+
public void addElement(Observation observation) {
138+
super.addElement(observation);
139+
checkMap.put(observation, observation.isEnabled());
140+
}
141+
142+
@Override
143+
public boolean removeElement(Object observation) {
144+
boolean removed = super.removeElement(observation);
145+
checkMap.remove(observation);
146+
return removed;
147+
}
148+
}
149+
76150
private void init() {
77151
setSize(500, 350);
78152
setResizable(false);
@@ -81,7 +155,8 @@ private void init() {
81155

82156
JPanel observationPanel = new JPanel();
83157
observationPanel.setLayout(new GridBagLayout());
84-
DefaultListModel<Observation> listModel = new DefaultListModel<>();
158+
159+
CheckboxListModel listModel = new CheckboxListModel();
85160
for (Observation observation : observations) {
86161
listModel.addElement(observation);
87162
}
@@ -110,7 +185,7 @@ public void contentsChanged(ListDataEvent e) {
110185
});
111186

112187
JList<Observation> observationList = new JList<>(listModel);
113-
observationList.setCellRenderer(new EllipsisListCellRenderer());
188+
observationList.setCellRenderer(new CheckboxListRenderer());
114189

115190
JScrollPane observationScrollPane = new JScrollPane(observationList);
116191
observationScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
@@ -125,8 +200,16 @@ public void contentsChanged(ListDataEvent e) {
125200
observationList.addMouseListener(new MouseAdapter() {
126201
@Override
127202
public void mouseClicked(MouseEvent e) {
128-
if (e.getClickCount() == 2) {
129-
showEditObservationDialog(observationList.getSelectedIndex(), listModel);
203+
int index = observationList.locationToIndex(e.getPoint());
204+
if (index >= 0) {
205+
Rectangle bounds = observationList.getCellBounds(index, index);
206+
if (bounds != null && e.getX() < bounds.x + 20) {
207+
Observation observation = listModel.getElementAt(index);
208+
listModel.toggleChecked(observation);
209+
observationList.repaint();
210+
} else if (e.getClickCount() == 2) {
211+
showEditObservationDialog(observationList.getSelectedIndex(), listModel);
212+
}
130213
}
131214
}
132215
});

0 commit comments

Comments
 (0)