View | Details | Raw Unified | Return to bug 60961
Collapse All | Expand All

(-)src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java (-3 / +106 lines)
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() {

Return to bug 60961