Lines 31-40
Link Here
|
31 |
import java.awt.event.ItemEvent; |
31 |
import java.awt.event.ItemEvent; |
32 |
import java.awt.event.ItemListener; |
32 |
import java.awt.event.ItemListener; |
33 |
import java.io.IOException; |
33 |
import java.io.IOException; |
|
|
34 |
import java.util.ArrayList; |
35 |
import java.util.Arrays; |
34 |
import java.util.Collections; |
36 |
import java.util.Collections; |
|
|
37 |
import java.util.Enumeration; |
35 |
import java.util.HashMap; |
38 |
import java.util.HashMap; |
|
|
39 |
import java.util.HashSet; |
36 |
import java.util.List; |
40 |
import java.util.List; |
37 |
import java.util.Map; |
41 |
import java.util.Map; |
|
|
42 |
import java.util.Set; |
43 |
import java.util.stream.Collectors; |
38 |
|
44 |
|
39 |
import javax.swing.BorderFactory; |
45 |
import javax.swing.BorderFactory; |
40 |
import javax.swing.ComboBoxModel; |
46 |
import javax.swing.ComboBoxModel; |
Lines 53-62
Link Here
|
53 |
import javax.swing.tree.DefaultMutableTreeNode; |
59 |
import javax.swing.tree.DefaultMutableTreeNode; |
54 |
import javax.swing.tree.DefaultTreeCellRenderer; |
60 |
import javax.swing.tree.DefaultTreeCellRenderer; |
55 |
import javax.swing.tree.DefaultTreeModel; |
61 |
import javax.swing.tree.DefaultTreeModel; |
|
|
62 |
import javax.swing.tree.TreeNode; |
56 |
import javax.swing.tree.TreePath; |
63 |
import javax.swing.tree.TreePath; |
57 |
import javax.swing.tree.TreeSelectionModel; |
64 |
import javax.swing.tree.TreeSelectionModel; |
58 |
|
65 |
|
59 |
import org.apache.commons.collections.Buffer; |
66 |
import org.apache.commons.collections.Buffer; |
|
|
67 |
import org.apache.commons.collections.EnumerationUtils; |
60 |
import org.apache.commons.collections.buffer.CircularFifoBuffer; |
68 |
import org.apache.commons.collections.buffer.CircularFifoBuffer; |
61 |
import org.apache.commons.collections.buffer.UnboundedFifoBuffer; |
69 |
import org.apache.commons.collections.buffer.UnboundedFifoBuffer; |
62 |
import org.apache.commons.lang3.StringUtils; |
70 |
import org.apache.commons.lang3.StringUtils; |
Lines 169-178
Link Here
|
169 |
* Update the visualizer with new data. |
177 |
* Update the visualizer with new data. |
170 |
*/ |
178 |
*/ |
171 |
private void updateGui() { |
179 |
private void updateGui() { |
|
|
180 |
TreePath selectedPath = null; |
181 |
Object oldSelectedElement; |
182 |
Set<Object> oldExpandedElements; |
183 |
Set<TreePath> newExpandedPaths = new HashSet<>(); |
172 |
synchronized (buffer) { |
184 |
synchronized (buffer) { |
173 |
if (!dataChanged) { |
185 |
if (!dataChanged) { |
174 |
return; |
186 |
return; |
175 |
} |
187 |
} |
|
|
188 |
|
189 |
final Enumeration<TreePath> expandedElements = jTree.getExpandedDescendants(new TreePath(root)); |
190 |
oldExpandedElements = extractExpandedObjects(expandedElements); |
191 |
oldSelectedElement = getSelectedObject(); |
176 |
root.removeAllChildren(); |
192 |
root.removeAllChildren(); |
177 |
for (Object sampler: buffer) { |
193 |
for (Object sampler: buffer) { |
178 |
SampleResult res = (SampleResult) sampler; |
194 |
SampleResult res = (SampleResult) sampler; |
Lines 179-185
Link Here
|
179 |
// Add sample |
195 |
// Add sample |
180 |
DefaultMutableTreeNode currNode = new SearchableTreeNode(res, treeModel); |
196 |
DefaultMutableTreeNode currNode = new SearchableTreeNode(res, treeModel); |
181 |
treeModel.insertNodeInto(currNode, root, root.getChildCount()); |
197 |
treeModel.insertNodeInto(currNode, root, root.getChildCount()); |
182 |
addSubResults(currNode, res); |
198 |
List<TreeNode> path = new ArrayList<>(Arrays.asList(root, currNode)); |
|
|
199 |
selectedPath = checkExpandedOrSelected(path, |
200 |
res, oldSelectedElement, |
201 |
oldExpandedElements, newExpandedPaths, selectedPath); |
202 |
TreePath potentialSelection = addSubResults(currNode, res, path, oldSelectedElement, oldExpandedElements, newExpandedPaths); |
203 |
if (potentialSelection != null) { |
204 |
selectedPath = potentialSelection; |
205 |
} |
183 |
// Add any assertion that failed as children of the sample node |
206 |
// Add any assertion that failed as children of the sample node |
184 |
AssertionResult[] assertionResults = res.getAssertionResults(); |
207 |
AssertionResult[] assertionResults = res.getAssertionResults(); |
185 |
int assertionIndex = currNode.getChildCount(); |
208 |
int assertionIndex = currNode.getChildCount(); |
Lines 187-192
Link Here
|
187 |
if (assertionResult.isFailure() || assertionResult.isError()) { |
210 |
if (assertionResult.isFailure() || assertionResult.isError()) { |
188 |
DefaultMutableTreeNode assertionNode = new SearchableTreeNode(assertionResult, treeModel); |
211 |
DefaultMutableTreeNode assertionNode = new SearchableTreeNode(assertionResult, treeModel); |
189 |
treeModel.insertNodeInto(assertionNode, currNode, assertionIndex++); |
212 |
treeModel.insertNodeInto(assertionNode, currNode, assertionIndex++); |
|
|
213 |
selectedPath = checkExpandedOrSelected(path, |
214 |
assertionResult, oldSelectedElement, |
215 |
oldExpandedElements, newExpandedPaths, selectedPath, |
216 |
assertionNode); |
190 |
} |
217 |
} |
191 |
} |
218 |
} |
192 |
} |
219 |
} |
Lines 197-202
Link Here
|
197 |
if (root.getChildCount() == 1) { |
224 |
if (root.getChildCount() == 1) { |
198 |
jTree.expandPath(new TreePath(root)); |
225 |
jTree.expandPath(new TreePath(root)); |
199 |
} |
226 |
} |
|
|
227 |
newExpandedPaths.stream().forEach(jTree::expandPath); |
228 |
if (selectedPath != null) { |
229 |
jTree.setSelectionPath(selectedPath); |
230 |
} |
200 |
if (autoScrollCB.isSelected() && root.getChildCount() > 1) { |
231 |
if (autoScrollCB.isSelected() && root.getChildCount() > 1) { |
201 |
jTree.scrollPathToVisible(new TreePath(new Object[] { root, |
232 |
jTree.scrollPathToVisible(new TreePath(new Object[] { root, |
202 |
treeModel.getChild(root, root.getChildCount() - 1) })); |
233 |
treeModel.getChild(root, root.getChildCount() - 1) })); |
Lines 203-212
Link Here
|
203 |
} |
234 |
} |
204 |
} |
235 |
} |
205 |
|
236 |
|
206 |
private void addSubResults(DefaultMutableTreeNode currNode, SampleResult res) { |
237 |
private Object getSelectedObject() { |
|
|
238 |
Object oldSelectedElement; |
239 |
DefaultMutableTreeNode oldSelectedNode = (DefaultMutableTreeNode) jTree.getLastSelectedPathComponent(); |
240 |
oldSelectedElement = oldSelectedNode == null ? null : oldSelectedNode.getUserObject(); |
241 |
return oldSelectedElement; |
242 |
} |
243 |
|
244 |
private TreePath checkExpandedOrSelected(List<TreeNode> path, |
245 |
Object item, Object oldSelectedObject, |
246 |
Set<Object> oldExpandedObjects, Set<TreePath> newExpandedPaths, |
247 |
TreePath defaultPath) { |
248 |
TreePath result = defaultPath; |
249 |
if (oldSelectedObject == item) { |
250 |
result = toTreePath(path); |
251 |
} |
252 |
if (oldExpandedObjects.contains(item)) { |
253 |
newExpandedPaths.add(toTreePath(path)); |
254 |
} |
255 |
return result; |
256 |
} |
257 |
|
258 |
private TreePath checkExpandedOrSelected(List<TreeNode> path, |
259 |
Object item, Object oldSelectedObject, |
260 |
Set<Object> oldExpandedObjects, Set<TreePath> newExpandedPaths, |
261 |
TreePath defaultPath, DefaultMutableTreeNode extensionNode) { |
262 |
TreePath result = defaultPath; |
263 |
if (oldSelectedObject == item) { |
264 |
result = toTreePath(path, extensionNode); |
265 |
} |
266 |
if (oldExpandedObjects.contains(item)) { |
267 |
newExpandedPaths.add(toTreePath(path, extensionNode)); |
268 |
} |
269 |
return result; |
270 |
} |
271 |
|
272 |
private Set<Object> extractExpandedObjects(final Enumeration<TreePath> expandedElements) { |
273 |
if (expandedElements != null) { |
274 |
@SuppressWarnings("unchecked") |
275 |
final List<TreePath> list = EnumerationUtils.toList(expandedElements); |
276 |
log.debug("Expanded: {}", list); |
277 |
Set<Object> result = list.stream() |
278 |
.map(TreePath::getLastPathComponent) |
279 |
.map(c -> (DefaultMutableTreeNode) c) |
280 |
.map(DefaultMutableTreeNode::getUserObject) |
281 |
.collect(Collectors.toSet()); |
282 |
log.debug("Elements: {}", result); |
283 |
return result; |
284 |
} |
285 |
return Collections.emptySet(); |
286 |
} |
287 |
|
288 |
private TreePath addSubResults(DefaultMutableTreeNode currNode, |
289 |
SampleResult res, List<TreeNode> path, Object selectedObject, |
290 |
Set<Object> oldExpandedObjects, Set<TreePath> newExpandedPaths) { |
207 |
SampleResult[] subResults = res.getSubResults(); |
291 |
SampleResult[] subResults = res.getSubResults(); |
208 |
|
292 |
|
209 |
int leafIndex = 0; |
293 |
int leafIndex = 0; |
|
|
294 |
TreePath result = null; |
210 |
|
295 |
|
211 |
for (SampleResult child : subResults) { |
296 |
for (SampleResult child : subResults) { |
212 |
log.debug("updateGui1 : child sample result - {}", child); |
297 |
log.debug("updateGui1 : child sample result - {}", child); |
Lines 213-219
Link Here
|
213 |
DefaultMutableTreeNode leafNode = new SearchableTreeNode(child, treeModel); |
298 |
DefaultMutableTreeNode leafNode = new SearchableTreeNode(child, treeModel); |
214 |
|
299 |
|
215 |
treeModel.insertNodeInto(leafNode, currNode, leafIndex++); |
300 |
treeModel.insertNodeInto(leafNode, currNode, leafIndex++); |
216 |
addSubResults(leafNode, child); |
301 |
List<TreeNode> newPath = new ArrayList<>(path); |
|
|
302 |
newPath.add(leafNode); |
303 |
result = checkExpandedOrSelected(newPath, child, selectedObject, oldExpandedObjects, newExpandedPaths, result); |
304 |
addSubResults(leafNode, child, newPath, selectedObject, oldExpandedObjects, newExpandedPaths); |
217 |
// Add any assertion that failed as children of the sample node |
305 |
// Add any assertion that failed as children of the sample node |
218 |
AssertionResult[] assertionResults = child.getAssertionResults(); |
306 |
AssertionResult[] assertionResults = child.getAssertionResults(); |
219 |
int assertionIndex = leafNode.getChildCount(); |
307 |
int assertionIndex = leafNode.getChildCount(); |
Lines 221-231
Link Here
|
221 |
if (item.isFailure() || item.isError()) { |
309 |
if (item.isFailure() || item.isError()) { |
222 |
DefaultMutableTreeNode assertionNode = new SearchableTreeNode(item, treeModel); |
310 |
DefaultMutableTreeNode assertionNode = new SearchableTreeNode(item, treeModel); |
223 |
treeModel.insertNodeInto(assertionNode, leafNode, assertionIndex++); |
311 |
treeModel.insertNodeInto(assertionNode, leafNode, assertionIndex++); |
|
|
312 |
result = checkExpandedOrSelected(path, item, |
313 |
selectedObject, oldExpandedObjects, newExpandedPaths, result, |
314 |
assertionNode); |
224 |
} |
315 |
} |
225 |
} |
316 |
} |
226 |
} |
317 |
} |
|
|
318 |
return result; |
227 |
} |
319 |
} |
228 |
|
320 |
|
|
|
321 |
private TreePath toTreePath(List<TreeNode> newPath) { |
322 |
return new TreePath(newPath.toArray(new TreeNode[newPath.size()])); |
323 |
} |
324 |
|
325 |
private TreePath toTreePath(List<TreeNode> path, |
326 |
DefaultMutableTreeNode extensionNode) { |
327 |
TreeNode[] result = path.toArray(new TreeNode[path.size() + 1]); |
328 |
result[result.length - 1] = extensionNode; |
329 |
return new TreePath(result); |
330 |
} |
331 |
|
229 |
/** {@inheritDoc} */ |
332 |
/** {@inheritDoc} */ |
230 |
@Override |
333 |
@Override |
231 |
public void clearData() { |
334 |
public void clearData() { |