From 2c38e67b296c7133dae36d5dbd0064c602b85d4f Mon Sep 17 00:00:00 2001 From: Tobias Holenstein Date: Thu, 30 Mar 2023 08:12:10 +0000 Subject: [PATCH] 8302644: IGV: Apply filters per graph tab and not globally Reviewed-by: rcastanedalo, chagedorn, thartmann --- .../sun/hotspot/igv/filter/CustomFilter.java | 20 +- .../sun/hotspot/igv/filter/FilterChain.java | 74 +-- .../igv/filter/FilterChainProvider.java | 16 +- .../sun/hotspot/igv/filter/FilterSetting.java | 82 --- .../FilterChainProviderImplementation.java | 30 +- .../hotspot/igv/filterwindow/FilterNode.java | 20 +- .../igv/filterwindow/FilterTopComponent.java | 541 ++++++++---------- .../actions/MoveFilterDownAction.java | 4 +- .../actions/MoveFilterUpAction.java | 4 +- .../actions/RemoveFilterAction.java | 5 +- .../sun/hotspot/igv/servercompiler/layer.xml | 36 +- .../hotspot/igv/util/RangeSliderModel.java | 11 + .../sun/hotspot/igv/view/DiagramScene.java | 2 - .../hotspot/igv/view/DiagramViewModel.java | 182 ++++-- .../hotspot/igv/view/EditorTopComponent.java | 63 +- .../igv/view/GraphViewerImplementation.java | 8 +- .../view/actions/GlobalSelectionAction.java | 2 +- 17 files changed, 542 insertions(+), 558 deletions(-) delete mode 100644 src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterSetting.java diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/CustomFilter.java b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/CustomFilter.java index ce47bcdac69..99bf8af0414 100644 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/CustomFilter.java +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/CustomFilter.java @@ -40,7 +40,7 @@ public class CustomFilter extends AbstractFilter { private String code; private String name; - private ScriptEngine engine; + private final ScriptEngine engine; public CustomFilter(String name, String code, ScriptEngine engine) { this.name = name; @@ -60,31 +60,25 @@ public class CustomFilter extends AbstractFilter { public void setName(String s) { name = s; - fireChangedEvent(); } public void setCode(String s) { code = s; - fireChangedEvent(); } @Override public OpenCookie getEditor() { - return new OpenCookie() { - - @Override - public void open() { - openInEditor(); - } - }; + return this::openInEditor; } public boolean openInEditor() { EditFilterDialog dialog = new EditFilterDialog(CustomFilter.this); dialog.setVisible(true); - boolean result = dialog.wasAccepted(); - this.getChangedEvent().fire(); - return result; + boolean accepted = dialog.wasAccepted(); + if (accepted) { + getChangedEvent().fire(); + } + return accepted; } @Override diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterChain.java b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterChain.java index dcfff410779..937db46a252 100644 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterChain.java +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterChain.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import com.sun.hotspot.igv.data.ChangedListener; import com.sun.hotspot.igv.graph.Diagram; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; /** @@ -37,24 +38,29 @@ import java.util.List; */ public class FilterChain implements ChangedEventProvider { - private List filters; - private transient ChangedEvent changedEvent; + private final List filters; + private final transient ChangedEvent changedEvent; + private final String name; - private ChangedListener changedListener = new ChangedListener() { + private final ChangedListener changedListener = new ChangedListener() { @Override public void changed(Filter source) { changedEvent.fire(); } }; - public FilterChain() { + public FilterChain(String name) { + this.name = name; filters = new ArrayList<>(); changedEvent = new ChangedEvent<>(this); } - public FilterChain(FilterChain f) { - this.filters = new ArrayList<>(f.filters); - changedEvent = new ChangedEvent<>(this); + public FilterChain() { + this(""); + } + + public void sortBy(List order) { + filters.sort(Comparator.comparingInt(f -> order.indexOf(f.getName()))); } @Override @@ -62,35 +68,14 @@ public class FilterChain implements ChangedEventProvider { return changedEvent; } - public Filter getFilterAt(int index) { - assert index >= 0 && index < filters.size(); - return filters.get(index); - } - - public void apply(Diagram d) { - for (Filter f : filters) { - f.apply(d); - } - } - - public void apply(Diagram d, FilterChain sequence) { - List applied = new ArrayList<>(); - for (Filter f : sequence.getFilters()) { - if (filters.contains(f)) { - f.apply(d); - applied.add(f); - } - } - - - for (Filter f : filters) { - if (!applied.contains(f)) { - f.apply(d); + public void applyInOrder(Diagram diagram, FilterChain filterOrder) { + for (Filter filter : filterOrder.getFilters()) { + if (filters.contains(filter)) { + filter.apply(diagram); } } } - public void addFilter(Filter filter) { assert filter != null; filters.add(filter); @@ -102,6 +87,14 @@ public class FilterChain implements ChangedEventProvider { return filters.contains(filter); } + public void clearFilters() { + for (Filter filter : filters) { + filter.getChangedEvent().removeListener(changedListener); + } + filters.clear(); + changedEvent.fire(); + } + public void removeFilter(Filter filter) { assert filters.contains(filter); filters.remove(filter); @@ -129,7 +122,22 @@ public class FilterChain implements ChangedEventProvider { changedEvent.fire(); } + public void addFilters(List filtersToAdd) { + for (Filter filter : filtersToAdd) { + addFilter(filter); + } + } + public List getFilters() { return Collections.unmodifiableList(filters); } + + public String getName() { + return name; + } + + @Override + public String toString() { + return getName(); + } } diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterChainProvider.java b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterChainProvider.java index 29ae9abc40e..4574cf3c971 100644 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterChainProvider.java +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterChainProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,23 @@ */ package com.sun.hotspot.igv.filter; +import com.sun.hotspot.igv.data.ChangedListener; +import javax.swing.JComboBox; + /** * * @author Thomas Wuerthinger */ public interface FilterChainProvider { - public FilterChain getFilterChain(); + FilterChain getFilterChain(); + FilterChain getAllFiltersOrdered(); - public FilterChain getSequence(); + FilterChain createNewCustomFilterChain(); + + void setCustomFilterChain(FilterChain filterChain); + + void selectFilterChain(FilterChain filterChain); + + void setFilterChainSelectionChangedListener(ChangedListener> listener); } diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterSetting.java b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterSetting.java deleted file mode 100644 index b0fa5ab2ff7..00000000000 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/FilterSetting.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ -package com.sun.hotspot.igv.filter; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -/** - * - * @author Thomas Wuerthinger - */ -public class FilterSetting { - - private Set filters; - private String name; - - public FilterSetting() { - this(null); - } - - public FilterSetting(String name) { - this.name = name; - filters = new HashSet<>(); - } - - public Set getFilters() { - return Collections.unmodifiableSet(filters); - } - - public void addFilter(Filter f) { - assert !filters.contains(f); - filters.add(f); - } - - public void removeFilter(Filter f) { - assert filters.contains(f); - filters.remove(f); - } - - public boolean containsFilter(Filter f) { - return filters.contains(f); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getFilterCount() { - return filters.size(); - } - - @Override - public String toString() { - return getName(); - } -} diff --git a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterChainProviderImplementation.java b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterChainProviderImplementation.java index c0e8dd58e29..99161634d07 100644 --- a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterChainProviderImplementation.java +++ b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterChainProviderImplementation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,10 @@ */ package com.sun.hotspot.igv.filterwindow; +import com.sun.hotspot.igv.data.ChangedListener; import com.sun.hotspot.igv.filter.FilterChain; import com.sun.hotspot.igv.filter.FilterChainProvider; +import javax.swing.JComboBox; import org.openide.util.lookup.ServiceProvider; /** @@ -36,11 +38,31 @@ public class FilterChainProviderImplementation implements FilterChainProvider { @Override public FilterChain getFilterChain() { - return FilterTopComponent.findInstance().getFilterChain(); + return FilterTopComponent.findInstance().getCurrentChain(); } @Override - public FilterChain getSequence() { - return FilterTopComponent.findInstance().getSequence(); + public FilterChain getAllFiltersOrdered() { + return FilterTopComponent.findInstance().getAllFiltersOrdered(); + } + + @Override + public FilterChain createNewCustomFilterChain() { + return FilterTopComponent.findInstance().createNewCustomFilterChain(); + } + + @Override + public void selectFilterChain(FilterChain filterChain) { + FilterTopComponent.findInstance().selectFilterChain(filterChain); + } + + @Override + public void setCustomFilterChain(FilterChain filterChain) { + FilterTopComponent.findInstance().setCustomFilterChain(filterChain); + } + + @Override + public void setFilterChainSelectionChangedListener(ChangedListener> listener) { + FilterTopComponent.findInstance().setFilterChainSelectionChangedListener(listener); } } diff --git a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterNode.java b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterNode.java index b4cccb824ed..91a6307b895 100644 --- a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterNode.java +++ b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,10 +45,9 @@ import org.openide.util.lookup.InstanceContent; * * @author Thomas Wuerthinger */ -public class FilterNode extends CheckNode implements LookupListener, ChangedListener { +public class FilterNode extends CheckNode implements ChangedListener { - private Filter filter; - private Lookup.Result result; + private final Filter filter; public FilterNode(Filter filter) { this(filter, new InstanceContent()); @@ -64,12 +63,8 @@ public class FilterNode extends CheckNode implements LookupListener, ChangedList update(); - Lookup.Template tpl = new Lookup.Template<>(FilterChain.class); - result = Utilities.actionsGlobalContext().lookup(tpl); - result.addLookupListener(this); - FilterTopComponent.findInstance().getFilterSettingsChangedEvent().addListener(this); - resultChanged(null); + changed(FilterTopComponent.findInstance()); setShortDescription("Double-click to open filter"); } @@ -99,13 +94,8 @@ public class FilterNode extends CheckNode implements LookupListener, ChangedList return OpenAction.get(OpenAction.class).createContextAwareInstance(Utilities.actionsGlobalContext()); } - @Override - public void resultChanged(LookupEvent lookupEvent) { - changed(FilterTopComponent.findInstance()); - } - @Override public void changed(FilterTopComponent source) { - setSelected(source.getFilterChain().containsFilter(filter)); + setSelected(source.getCurrentChain().containsFilter(filter)); } } diff --git a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java index b2437f9b5b6..3c80aa25bde 100644 --- a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java +++ b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,11 +28,11 @@ import com.sun.hotspot.igv.data.ChangedListener; import com.sun.hotspot.igv.filter.CustomFilter; import com.sun.hotspot.igv.filter.Filter; import com.sun.hotspot.igv.filter.FilterChain; -import com.sun.hotspot.igv.filter.FilterSetting; import com.sun.hotspot.igv.filterwindow.actions.*; import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; import java.awt.Dimension; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.*; import java.util.*; @@ -42,8 +42,7 @@ import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; -import javax.swing.JComboBox; -import javax.swing.UIManager; +import javax.swing.*; import javax.swing.border.Border; import org.openide.DialogDisplayer; import org.openide.ErrorManager; @@ -67,7 +66,7 @@ import org.openide.windows.WindowManager; * * @author Thomas Wuerthinger */ -public final class FilterTopComponent extends TopComponent implements LookupListener, ExplorerManager.Provider { +public final class FilterTopComponent extends TopComponent implements ExplorerManager.Provider { private static FilterTopComponent instance; public static final String FOLDER_ID = "Filters"; @@ -75,101 +74,158 @@ public final class FilterTopComponent extends TopComponent implements LookupList public static final String ENABLED_ID = "enabled"; public static final String PREFERRED_ID = "FilterTopComponent"; public static final String JAVASCRIPT_HELPER_ID = "JavaScriptHelper"; - private CheckListView view; - private ExplorerManager manager; - private FilterChain filterChain; - private FilterChain sequence; - private ScriptEngine engine; - private Lookup.Result result; - private JComboBox comboBox; - private List filterSettings; - private FilterSetting customFilterSetting = new FilterSetting("-- Custom --"); - private ChangedEvent filterSettingsChangedEvent; - private ActionListener comboBoxActionListener = new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - comboBoxSelectionChanged(); - } + private final CheckListView view; + private final ExplorerManager manager; + private final ScriptEngine engine; + private final JComboBox comboBox; + private final FilterChain allFiltersOrdered = new FilterChain(); + private static final FilterChain defaultFilterChain = new FilterChain("DEFAULT"); + private FilterChain customFilterChain; + private final ChangedEvent filterSettingsChangedEvent = new ChangedEvent<>(this); + private ChangedEvent> filterChainSelectionChangedEvent; + private final ActionListener comboBoxSelectionChangedListener = l -> { + comboBoxSelectionChanged(); + // notify model that user selected a different filter profile + filterChainSelectionChangedEvent.fire(); }; + private static final String CUSTOM_LABEL = "--Local--"; + private static final String GLOBAL_LABEL = "--Global--"; + + + public FilterChain createNewCustomFilterChain() { + FilterChain newCustomFilterChain = new FilterChain(CUSTOM_LABEL); + newCustomFilterChain.addFilters(customFilterChain.getFilters()); + return newCustomFilterChain; + } + + static class CustomCellRenderer extends DefaultListCellRenderer { + + public CustomCellRenderer() { + setOpaque(true); + } + + public Component getListCellRendererComponent(JList jc, Object val, int idx, + boolean isSelected, boolean cellHasFocus) { + setText(" " + val.toString()); + if (idx == 0) { + setForeground(Color.GRAY); + } else { + setForeground(Color.BLACK); + } + if (isSelected) { + setBackground(Color.LIGHT_GRAY); + } else { + setBackground(Color.WHITE); + } + return this; + } + } + + private FilterTopComponent() { + initComponents(); + setName(NbBundle.getMessage(FilterTopComponent.class, "CTL_FilterTopComponent")); + setToolTipText(NbBundle.getMessage(FilterTopComponent.class, "HINT_FilterTopComponent")); + + ScriptEngineManager sem = new ScriptEngineManager(); + engine = sem.getEngineByName("ECMAScript"); + try { + engine.eval(getJsHelperText()); + } catch (ScriptException ex) { + Exceptions.printStackTrace(ex); + } + engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE).put("IO", System.out); + + initFilters(); + comboBox = new JComboBox<>(); + comboBox.setRenderer(new CustomCellRenderer()); + customFilterChain = new FilterChain(CUSTOM_LABEL); + customFilterChain.addFilters(defaultFilterChain.getFilters()); + comboBox.addItem(customFilterChain); + FilterChain globalFilterChain = new FilterChain(GLOBAL_LABEL); + globalFilterChain.addFilters(defaultFilterChain.getFilters()); + comboBox.addItem(globalFilterChain); + comboBox.setSelectedItem(globalFilterChain); + filterChainSelectionChangedEvent = new ChangedEvent<>(comboBox); + + manager = new ExplorerManager(); + manager.setRootContext(new AbstractNode(new FilterChildren())); + associateLookup(ExplorerUtils.createLookup(manager, getActionMap())); + view = new CheckListView(); + + ToolbarPool.getDefault().setPreferredIconSize(16); + Toolbar toolBar = new Toolbar(); + toolBar.setBorder((Border) UIManager.get("Nb.Editor.Toolbar.border")); //NOI18N + toolBar.setMinimumSize(new Dimension(0,0)); // MacOS BUG with ToolbarWithOverflow + + toolBar.add(comboBox); + this.add(toolBar, BorderLayout.NORTH); + toolBar.add(SaveFilterSettingsAction.get(SaveFilterSettingsAction.class)); + toolBar.add(RemoveFilterSettingsAction.get(RemoveFilterSettingsAction.class)); + toolBar.addSeparator(); + toolBar.add(NewFilterAction.get(NewFilterAction.class)); + toolBar.add(RemoveFilterAction.get(RemoveFilterAction.class).createContextAwareInstance(this.getLookup())); + toolBar.add(MoveFilterUpAction.get(MoveFilterUpAction.class).createContextAwareInstance(this.getLookup())); + toolBar.add(MoveFilterDownAction.get(MoveFilterDownAction.class).createContextAwareInstance(this.getLookup())); + this.add(view, BorderLayout.CENTER); + + comboBox.addActionListener(comboBoxSelectionChangedListener); + comboBoxSelectionChanged(); + } public ChangedEvent getFilterSettingsChangedEvent() { return filterSettingsChangedEvent; } - public FilterChain getSequence() { - return sequence; + public void setFilterChainSelectionChangedListener(ChangedListener> listener) { + filterChainSelectionChangedEvent = new ChangedEvent<>(comboBox); + filterChainSelectionChangedEvent.addListener(listener); } - public void updateSelection() { - Node[] nodes = this.getExplorerManager().getSelectedNodes(); - int[] arr = new int[nodes.length]; - for (int i = 0; i < nodes.length; i++) { - int index = sequence.getFilters().indexOf(((FilterNode) nodes[i]).getFilter()); - arr[i] = index; + public FilterChain getAllFiltersOrdered() { + return allFiltersOrdered; + } + + public FilterChain getCurrentChain() { + return (FilterChain) comboBox.getSelectedItem(); + } + + public void selectFilterChain(FilterChain filterChain) { + comboBox.removeActionListener(comboBoxSelectionChangedListener); + comboBox.setSelectedItem(filterChain); + if (comboBox.getSelectedIndex() < 0) { + comboBox.setSelectedIndex(0); } - view.showSelection(arr); + comboBox.addActionListener(comboBoxSelectionChangedListener); + comboBoxSelectionChanged(); + } + + public void setCustomFilterChain(FilterChain filterChain) { + comboBox.removeActionListener(comboBoxSelectionChangedListener); + comboBox.removeItem(customFilterChain); + customFilterChain = filterChain; + comboBox.insertItemAt(customFilterChain, 0); + comboBox.addActionListener(comboBoxSelectionChangedListener); } private void comboBoxSelectionChanged() { - - Object o = comboBox.getSelectedItem(); - if (o == null) { - return; + FilterChain currentChain = getCurrentChain(); + if (currentChain != null) { + filterSettingsChangedEvent.fire(); // notify all FilterNodes to update checkbox selection + SystemAction.get(RemoveFilterSettingsAction.class).setEnabled(currentChain != customFilterChain); + SystemAction.get(SaveFilterSettingsAction.class).setEnabled(true); } - assert o instanceof FilterSetting; - FilterSetting s = (FilterSetting) o; - - if (s != customFilterSetting) { - FilterChain chain = getFilterChain(); - chain.getChangedEvent().beginAtomic(); - List toRemove = new ArrayList<>(); - for (Filter f : chain.getFilters()) { - if (!s.containsFilter(f)) { - toRemove.add(f); - } - } - for (Filter f : toRemove) { - chain.removeFilter(f); - } - - for (Filter f : s.getFilters()) { - if (!chain.containsFilter(f)) { - chain.addFilter(f); - } - } - - chain.getChangedEvent().endAtomic(); - filterSettingsChangedEvent.fire(); - } else { - this.updateComboBoxSelection(); - } - - SystemAction.get(RemoveFilterSettingsAction.class).setEnabled(comboBox.getSelectedItem() != this.customFilterSetting); - SystemAction.get(SaveFilterSettingsAction.class).setEnabled(comboBox.getSelectedItem() == this.customFilterSetting); - } - - private void updateComboBox() { - comboBox.removeAllItems(); - comboBox.addItem(customFilterSetting); - for (FilterSetting s : filterSettings) { - comboBox.addItem(s); - } - - this.updateComboBoxSelection(); } public void addFilterSetting() { NotifyDescriptor.InputLine l = new NotifyDescriptor.InputLine("Name of the new profile:", "Filter Profile"); if (DialogDisplayer.getDefault().notify(l) == NotifyDescriptor.OK_OPTION) { String name = l.getInputText(); - - FilterSetting toRemove = null; - for (FilterSetting s : filterSettings) { + for (int i=0; i filters = this.getFilterChain().getFilters(); - boolean found = false; - for (FilterSetting s : filterSettings) { - if (s.getFilterCount() == filters.size()) { - boolean ok = true; - for (Filter f : filters) { - if (!s.containsFilter(f)) { - ok = false; - } - } - - if (ok) { - if (comboBox.getSelectedItem() != s) { - comboBox.setSelectedItem(s); - } - found = true; - break; - } - } - } - - if (!found && comboBox.getSelectedItem() != customFilterSetting) { - comboBox.setSelectedItem(customFilterSetting); - } - } - private class FilterChildren extends Children.Keys implements ChangedListener { - private HashMap nodeHash = new HashMap<>(); + private final HashMap nodeHash = new HashMap<>(); @Override protected Node[] createNodes(Filter filter) { @@ -262,22 +271,31 @@ public final class FilterTopComponent extends TopComponent implements LookupList } public FilterChildren() { - sequence.getChangedEvent().addListener(source -> addNotify()); - + allFiltersOrdered.getChangedEvent().addListener(source -> addNotify()); setBefore(false); } @Override protected void addNotify() { - setKeys(sequence.getFilters()); + setKeys(allFiltersOrdered.getFilters()); updateSelection(); } + private void updateSelection() { + Node[] nodes = getExplorerManager().getSelectedNodes(); + int[] arr = new int[nodes.length]; + for (int i = 0; i < nodes.length; i++) { + int index = allFiltersOrdered.getFilters().indexOf(((FilterNode) nodes[i]).getFilter()); + arr[i] = index; + } + view.showSelection(arr); + } + @Override public void changed(CheckNode source) { FilterNode node = (FilterNode) source; Filter f = node.getFilter(); - FilterChain chain = getFilterChain(); + FilterChain chain = getCurrentChain(); if (node.isSelected()) { if (!chain.containsFilter(f)) { chain.addFilter(f); @@ -289,14 +307,9 @@ public final class FilterTopComponent extends TopComponent implements LookupList } view.revalidate(); view.repaint(); - updateComboBoxSelection(); } } - public FilterChain getFilterChain() { - return filterChain; - } - private static String getJsHelperText() { InputStream is = null; StringBuilder sb = new StringBuilder("if (typeof importPackage === 'undefined') { try { load('nashorn:mozilla_compat.js'); } catch (e) {} }" @@ -327,80 +340,46 @@ public final class FilterTopComponent extends TopComponent implements LookupList return sb.toString(); } - private FilterTopComponent() { - filterSettingsChangedEvent = new ChangedEvent<>(this); - initComponents(); - setName(NbBundle.getMessage(FilterTopComponent.class, "CTL_FilterTopComponent")); - setToolTipText(NbBundle.getMessage(FilterTopComponent.class, "HINT_FilterTopComponent")); - // setIcon(Utilities.loadImage(ICON_PATH, true)); - - sequence = new FilterChain(); - filterChain = new FilterChain(); - ScriptEngineManager sem = new ScriptEngineManager(); - engine = sem.getEngineByName("ECMAScript"); - try { - engine.eval(getJsHelperText()); - } catch (ScriptException ex) { - Exceptions.printStackTrace(ex); - } - engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE).put("IO", System.out); - initFilters(); - manager = new ExplorerManager(); - manager.setRootContext(new AbstractNode(new FilterChildren())); - associateLookup(ExplorerUtils.createLookup(manager, getActionMap())); - view = new CheckListView(); - - ToolbarPool.getDefault().setPreferredIconSize(16); - Toolbar toolBar = new Toolbar(); - toolBar.setBorder((Border) UIManager.get("Nb.Editor.Toolbar.border")); //NOI18N - toolBar.setMinimumSize(new Dimension(0,0)); // MacOS BUG with ToolbarWithOverflow - - comboBox = new JComboBox(); - toolBar.add(comboBox); - this.add(toolBar, BorderLayout.NORTH); - toolBar.add(SaveFilterSettingsAction.get(SaveFilterSettingsAction.class)); - toolBar.add(RemoveFilterSettingsAction.get(RemoveFilterSettingsAction.class)); - toolBar.addSeparator(); - toolBar.add(NewFilterAction.get(NewFilterAction.class)); - toolBar.add(RemoveFilterAction.get(RemoveFilterAction.class).createContextAwareInstance(this.getLookup())); - toolBar.add(MoveFilterUpAction.get(MoveFilterUpAction.class).createContextAwareInstance(this.getLookup())); - toolBar.add(MoveFilterDownAction.get(MoveFilterDownAction.class).createContextAwareInstance(this.getLookup())); - this.add(view, BorderLayout.CENTER); - - filterSettings = new ArrayList<>(); - updateComboBox(); - - comboBox.addActionListener(comboBoxActionListener); - setChain(filterChain); - } - public void newFilter() { - CustomFilter cf = new CustomFilter("My custom filter", "", engine); - if (cf.openInEditor()) { - sequence.addFilter(cf); - FileObject fo = getFileObject(cf); - FilterChangedListener listener = new FilterChangedListener(fo, cf); - listener.changed(cf); - cf.getChangedEvent().addListener(listener); + CustomFilter customFilter = new CustomFilter("My custom filter", "", engine); + if (customFilter.openInEditor()) { + addFilter(customFilter); } } - public void removeFilter(Filter f) { - com.sun.hotspot.igv.filter.CustomFilter cf = (com.sun.hotspot.igv.filter.CustomFilter) f; + public void addFilter(CustomFilter customFilter) { + allFiltersOrdered.addFilter(customFilter); + FileObject fileObject = getFileObject(customFilter); + FilterChangedListener listener = new FilterChangedListener(fileObject, customFilter); + listener.changed(customFilter); + customFilter.getChangedEvent().addListener(listener); + } - sequence.removeFilter(cf); + public void removeFilter(CustomFilter customFilter) { + allFiltersOrdered.removeFilter(customFilter); try { - getFileObject(cf).delete(); + getFileObject(customFilter).delete(); } catch (IOException ex) { Exceptions.printStackTrace(ex); } + } + private FileObject getFileObject(CustomFilter customFilter) { + FileObject fileObject = FileUtil.getConfigRoot().getFileObject(FOLDER_ID + "/" + customFilter.getName() + ".js"); + if (fileObject == null) { + try { + fileObject = FileUtil.getConfigRoot().getFileObject(FOLDER_ID).createData(customFilter.getName() + ".js"); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + return fileObject; } private static class FilterChangedListener implements ChangedListener { private FileObject fileObject; - private CustomFilter filter; + private final CustomFilter filter; public FilterChangedListener(FileObject fo, CustomFilter cf) { fileObject = fo; @@ -412,10 +391,9 @@ public final class FilterTopComponent extends TopComponent implements LookupList try { if (!fileObject.getName().equals(filter.getName())) { FileLock lock = fileObject.lock(); - fileObject.move(lock, fileObject.getParent(), filter.getName(), ""); + fileObject.move(lock, fileObject.getParent(), filter.getName(), "js"); lock.releaseLock(); - FileObject newFileObject = fileObject.getParent().getFileObject(filter.getName()); - fileObject = newFileObject; + fileObject = fileObject.getParent().getFileObject(filter.getName() + ".js"); } FileLock lock = fileObject.lock(); @@ -457,12 +435,11 @@ public final class FilterTopComponent extends TopComponent implements LookupList sb.append("\n"); } code = sb.toString(); - } catch (FileNotFoundException ex) { - Exceptions.printStackTrace(ex); } catch (IOException ex) { Exceptions.printStackTrace(ex); } finally { try { + assert is != null; is.close(); } catch (IOException ex) { Exceptions.printStackTrace(ex); @@ -472,7 +449,6 @@ public final class FilterTopComponent extends TopComponent implements LookupList String displayName = fo.getName(); - final CustomFilter cf = new CustomFilter(displayName, code, engine); map.put(displayName, cf); @@ -480,12 +456,10 @@ public final class FilterTopComponent extends TopComponent implements LookupList afterMap.put(cf, after); Boolean enabled = (Boolean) fo.getAttribute(ENABLED_ID); - if (enabled != null && (boolean) enabled) { + if (enabled != null && enabled) { enabledSet.add(cf); } - cf.getChangedEvent().addListener(new FilterChangedListener(fo, cf)); - customFilters.add(cf); } @@ -511,9 +485,9 @@ public final class FilterTopComponent extends TopComponent implements LookupList } for (CustomFilter cf : customFilters) { - sequence.addFilter(cf); + addFilter(cf); if (enabledSet.contains(cf)) { - filterChain.addFilter(cf); + defaultFilterChain.addFilter(cf); } } } @@ -574,40 +548,6 @@ public final class FilterTopComponent extends TopComponent implements LookupList return manager; } - @Override - public void componentOpened() { - Lookup.Template tpl = new Lookup.Template<>(FilterChain.class); - result = Utilities.actionsGlobalContext().lookup(tpl); - result.addLookupListener(this); - } - - @Override - public void componentClosed() { - result.removeLookupListener(this); - result = null; - } - - @Override - public void resultChanged(LookupEvent lookupEvent) { - setChain(Utilities.actionsGlobalContext().lookup(FilterChain.class)); - } - - public void setChain(FilterChain chain) { - updateComboBoxSelection(); - } - - private FileObject getFileObject(CustomFilter cf) { - FileObject fo = FileUtil.getConfigRoot().getFileObject(FOLDER_ID + "/" + cf.getName()); - if (fo == null) { - try { - fo = FileUtil.getConfigRoot().getFileObject(FOLDER_ID).createData(cf.getName()); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } - } - return fo; - } - @Override public boolean requestFocus(boolean temporary) { view.requestFocus(); @@ -626,44 +566,73 @@ public final class FilterTopComponent extends TopComponent implements LookupList view.requestFocus(); } + @Override public void writeExternal(ObjectOutput out) throws IOException { super.writeExternal(out); - out.writeInt(filterSettings.size()); - for (FilterSetting f : filterSettings) { - out.writeUTF(f.getName()); - - out.writeInt(f.getFilterCount()); - for (Filter filter : f.getFilters()) { + out.writeUTF(getCurrentChain().getName()); + out.writeInt(comboBox.getItemCount()); + for (int i=0; i order = new ArrayList<>(); + int filterOrderCount = in.readInt(); + for (int i = 0; i < filterOrderCount; i++) { + String name = in.readUTF(); + order.add(name); + } + allFiltersOrdered.sortBy(order); + } + + public CustomFilter findFilter(String name) { + for (Filter f : allFiltersOrdered.getFilters()) { CustomFilter cf = (CustomFilter) f; if (cf.getName().equals(name)) { return cf; @@ -672,26 +641,4 @@ public final class FilterTopComponent extends TopComponent implements LookupList return null; } - - @Override - public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - super.readExternal(in); - - int filterSettingsCount = in.readInt(); - for (int i = 0; i < filterSettingsCount; i++) { - String name = in.readUTF(); - FilterSetting s = new FilterSetting(name); - int filterCount = in.readInt(); - for (int j = 0; j < filterCount; j++) { - String filterName = in.readUTF(); - CustomFilter filter = findFilter(filterName); - if (filter != null) { - s.addFilter(filter); - } - } - - filterSettings.add(s); - } - updateComboBox(); - } } diff --git a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/MoveFilterDownAction.java b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/MoveFilterDownAction.java index df994346e27..639aec0905d 100644 --- a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/MoveFilterDownAction.java +++ b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/MoveFilterDownAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ public final class MoveFilterDownAction extends CookieAction { protected void performAction(Node[] activatedNodes) { for (Node n : activatedNodes) { Filter c = n.getLookup().lookup(Filter.class); - FilterTopComponent.findInstance().getSequence().moveFilterDown(c); + FilterTopComponent.findInstance().getAllFiltersOrdered().moveFilterDown(c); } } diff --git a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/MoveFilterUpAction.java b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/MoveFilterUpAction.java index ce5c5e71181..d7452336ed7 100644 --- a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/MoveFilterUpAction.java +++ b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/MoveFilterUpAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ public final class MoveFilterUpAction extends CookieAction { protected void performAction(Node[] activatedNodes) { for (Node n : activatedNodes) { Filter c = n.getLookup().lookup(Filter.class); - FilterTopComponent.findInstance().getSequence().moveFilterUp(c); + FilterTopComponent.findInstance().getAllFiltersOrdered().moveFilterUp(c); } } diff --git a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterAction.java b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterAction.java index 42d569b5342..2f6750558a9 100644 --- a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterAction.java +++ b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterAction.java @@ -23,6 +23,7 @@ */ package com.sun.hotspot.igv.filterwindow.actions; +import com.sun.hotspot.igv.filter.CustomFilter; import com.sun.hotspot.igv.filter.Filter; import com.sun.hotspot.igv.filterwindow.FilterTopComponent; import javax.swing.Action; @@ -54,8 +55,8 @@ public final class RemoveFilterAction extends CookieAction { options[2]); if (n == JOptionPane.YES_OPTION) { - for (int i = 0; i < activatedNodes.length; i++) { - FilterTopComponent.findInstance().removeFilter(activatedNodes[i].getLookup().lookup(Filter.class)); + for (Node activatedNode : activatedNodes) { + FilterTopComponent.findInstance().removeFilter(activatedNode.getLookup().lookup(CustomFilter.class)); } } } diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml index e51e45e0073..209aaab3926 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml @@ -2,74 +2,74 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/src/utils/IdealGraphVisualizer/Util/src/main/java/com/sun/hotspot/igv/util/RangeSliderModel.java b/src/utils/IdealGraphVisualizer/Util/src/main/java/com/sun/hotspot/igv/util/RangeSliderModel.java index f217a1a616e..f64156e78fb 100644 --- a/src/utils/IdealGraphVisualizer/Util/src/main/java/com/sun/hotspot/igv/util/RangeSliderModel.java +++ b/src/utils/IdealGraphVisualizer/Util/src/main/java/com/sun/hotspot/igv/util/RangeSliderModel.java @@ -45,7 +45,18 @@ public class RangeSliderModel implements ChangedEventProvider private int secondPosition; private List colors; + public RangeSliderModel(RangeSliderModel model) { + firstPosition = model.getFirstPosition(); + secondPosition = model.getSecondPosition(); + changedEvent = new ChangedEvent<>(this); + colorChangedEvent = new ChangedEvent<>(this); + positions = new ArrayList<>(model.getPositions()); + colors = new ArrayList<>(model.getColors()); + } + public RangeSliderModel() { + firstPosition = -1; + secondPosition = -1; changedEvent = new ChangedEvent<>(this); colorChangedEvent = new ChangedEvent<>(this); positions = new ArrayList<>(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 5beaa26ed05..e4ee0be8311 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -487,7 +487,6 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl } } }); - update(); } @Override @@ -638,7 +637,6 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl } private void graphChanged() { - update(); centerRootNode(); addUndo(); } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index 7ef7bae0742..48ee2d9d0f6 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -52,13 +52,15 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene private ArrayList graphs; private Set hiddenNodes; private Set selectedNodes; - private final FilterChain filterChain; + private FilterChain filterChain; + private final FilterChain customFilterChain; + private final FilterChain filtersOrder; private Diagram diagram; private InputGraph cachedInputGraph; - private final ChangedEvent diagramChangedEvent; - private final ChangedEvent graphChangedEvent; - private final ChangedEvent selectedNodesChangedEvent; - private final ChangedEvent hiddenNodesChangedEvent; + private final ChangedEvent diagramChangedEvent = new ChangedEvent<>(this); + private final ChangedEvent graphChangedEvent = new ChangedEvent<>(this); + private final ChangedEvent selectedNodesChangedEvent = new ChangedEvent<>(this); + private final ChangedEvent hiddenNodesChangedEvent = new ChangedEvent<>(this); private ChangedListener titleChangedListener = g -> {}; private boolean showSea; private boolean showBlocks; @@ -68,7 +70,10 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene private boolean hideDuplicates; private static boolean globalSelection = false; - private final ChangedListener filterChainChangedListener = source -> filterChanged(); + private final ChangedListener filterChainChangedListener = changedFilterChain -> { + assert filterChain == changedFilterChain; + rebuildDiagram(); + }; public Group getGroup() { return group; @@ -78,36 +83,44 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene return globalSelection; } - public void setGlobalSelection(boolean enable) { + public void setGlobalSelection(boolean enable, boolean fire) { globalSelection = enable; - diagramChangedEvent.fire(); + if (fire && enable) { + diagramChangedEvent.fire(); + } } public boolean getShowSea() { return showSea; } - public void setShowSea(boolean b) { - showSea = b; - diagramChangedEvent.fire(); + public void setShowSea(boolean enable) { + showSea = enable; + if (enable) { + diagramChangedEvent.fire(); + } } public boolean getShowBlocks() { return showBlocks; } - public void setShowBlocks(boolean b) { - showBlocks = b; - diagramChangedEvent.fire(); + public void setShowBlocks(boolean enable) { + showBlocks = enable; + if (enable) { + diagramChangedEvent.fire(); + } } public boolean getShowCFG() { return showCFG; } - public void setShowCFG(boolean b) { - showCFG = b; - diagramChangedEvent.fire(); + public void setShowCFG(boolean enable) { + showCFG = enable; + if (enable) { + diagramChangedEvent.fire(); + } } public boolean getShowNodeHull() { @@ -147,33 +160,8 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene return hideDuplicates; } - public DiagramViewModel(InputGraph graph) { - FilterChainProvider provider = Lookup.getDefault().lookup(FilterChainProvider.class); - if (provider == null) { - filterChain = new FilterChain(); - } else { - filterChain = provider.getFilterChain(); - } - globalSelection = GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected(); - showSea = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.SEA_OF_NODES; - showBlocks = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CLUSTERED_SEA_OF_NODES; - showCFG = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CONTROL_FLOW_GRAPH; - showNodeHull = true; - showEmptyBlocks = true; - group = graph.getGroup(); - hiddenNodes = new HashSet<>(); - selectedNodes = new HashSet<>(); - - diagramChangedEvent = new ChangedEvent<>(this); - graphChangedEvent = new ChangedEvent<>(this); - selectedNodesChangedEvent = new ChangedEvent<>(this); - hiddenNodesChangedEvent = new ChangedEvent<>(this); - - super.getChangedEvent().addListener(this); - - // If the group has been emptied, all corresponding graph views - // will be closed, so do nothing. - ChangedListener groupContentChangedListener = g -> { + private void initGroup() { + group.getChangedEvent().addListener(g -> { assert g == group; if (group.getGraphs().isEmpty()) { // If the group has been emptied, all corresponding graph views @@ -182,12 +170,60 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene } filterGraphs(); setSelectedNodes(selectedNodes); - }; - - group.getChangedEvent().addListener(groupContentChangedListener); - filterChain.getChangedEvent().addListener(filterChainChangedListener); - + }); filterGraphs(); + super.getChangedEvent().addListener(this); + } + + public DiagramViewModel(DiagramViewModel model) { + super(model); + globalSelection = false; + group = model.getGroup(); + initGroup(); + graphs = new ArrayList<>(model.graphs); + + // initialize the filters from a model + FilterChainProvider provider = Lookup.getDefault().lookup(FilterChainProvider.class); + assert provider != null; + customFilterChain = provider.createNewCustomFilterChain(); + customFilterChain.clearFilters(); + customFilterChain.addFilters(model.getCustomFilterChain().getFilters()); + setFilterChain(model.getFilterChain()); + filtersOrder = provider.getAllFiltersOrdered(); + + globalSelection = GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected(); + showCFG = model.getShowCFG(); + showSea = model.getShowSea(); + showBlocks = model.getShowBlocks(); + showNodeHull = model.getShowNodeHull(); + showEmptyBlocks = model.getShowEmptyBlocks(); + hideDuplicates = model.getHideDuplicates(); + + hiddenNodes = new HashSet<>(model.getHiddenNodes()); + selectedNodes = new HashSet<>(); + changed(this); + } + + public DiagramViewModel(InputGraph graph) { + group = graph.getGroup(); + initGroup(); + + FilterChainProvider provider = Lookup.getDefault().lookup(FilterChainProvider.class); + assert provider != null; + customFilterChain = provider.createNewCustomFilterChain(); + setFilterChain(provider.getFilterChain()); + filtersOrder = provider.getAllFiltersOrdered(); + + globalSelection = GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected(); + showSea = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.SEA_OF_NODES; + showBlocks = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CLUSTERED_SEA_OF_NODES; + showCFG = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CONTROL_FLOW_GRAPH; + showNodeHull = true; + showEmptyBlocks = true; + hideDuplicates = false; + + hiddenNodes = new HashSet<>(); + selectedNodes = new HashSet<>(); selectGraph(graph); } @@ -290,13 +326,37 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene hiddenNodesChangedEvent.fire(); } - public FilterChain getSequenceFilterChain() { - return filterChain; + private void setFilterChain(FilterChain newFC) { + assert newFC != null && customFilterChain != null; + if (filterChain != null) { + filterChain.getChangedEvent().removeListener(filterChainChangedListener); + } + if (newFC.getName().equals(customFilterChain.getName())) { + filterChain = customFilterChain; + } else { + filterChain = newFC; + } + filterChain.getChangedEvent().addListener(filterChainChangedListener); } - private void filterChanged() { - rebuildDiagram(); - diagramChangedEvent.fire(); + void activateModel() { + FilterChainProvider provider = Lookup.getDefault().lookup(FilterChainProvider.class); + if (provider != null) { + provider.setCustomFilterChain(customFilterChain); + provider.selectFilterChain(filterChain); + + // link the Filters window with this model + provider.setFilterChainSelectionChangedListener(l -> { + // this function is called when user selects a different filter profile for this model + setFilterChain(provider.getFilterChain()); + rebuildDiagram(); + }); + } + } + + void close() { + filterChain.getChangedEvent().removeListener(filterChainChangedListener); + getChangedEvent().fire(); } private void rebuildDiagram() { @@ -312,7 +372,8 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT), Settings.get().get(Settings.NODE_SHORT_TEXT, Settings.NODE_SHORT_TEXT_DEFAULT), Settings.get().get(Settings.NODE_TINY_TEXT, Settings.NODE_TINY_TEXT_DEFAULT)); - getFilterChain().apply(diagram, getSequenceFilterChain()); + diagram.setCFG(getShowCFG()); + filterChain.applyInOrder(diagram, filtersOrder); if (graph.isDiffGraph()) { ColorFilter f = new ColorFilter(""); f.addRule(stateColorRule("same", Color.white)); @@ -321,12 +382,17 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene f.addRule(stateColorRule("deleted", Color.red)); f.apply(diagram); } + diagramChangedEvent.fire(); } public FilterChain getFilterChain() { return filterChain; } + public FilterChain getCustomFilterChain() { + return customFilterChain; + } + /* * Select the set of graphs to be presented. */ @@ -403,7 +469,6 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene } public Diagram getDiagram() { - diagram.setCFG(getShowCFG()); return diagram; } @@ -431,11 +496,6 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene titleChangedListener = titleCallback::accept; } - void close() { - filterChain.getChangedEvent().removeListener(filterChainChangedListener); - getChangedEvent().fire(); - } - Iterable getGraphsForward() { return () -> new Iterator() { int index = getFirstPosition(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java index 9347593ab18..1f1d6fe83d1 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -28,11 +28,10 @@ import com.sun.hotspot.igv.data.Group; import com.sun.hotspot.igv.data.InputGraph; import com.sun.hotspot.igv.data.InputNode; import com.sun.hotspot.igv.data.services.InputGraphProvider; -import com.sun.hotspot.igv.filter.FilterChain; -import com.sun.hotspot.igv.filter.FilterChainProvider; -import com.sun.hotspot.igv.settings.Settings; +import com.sun.hotspot.igv.graph.Figure; import com.sun.hotspot.igv.util.LookupHistory; import com.sun.hotspot.igv.util.RangeSlider; +import com.sun.hotspot.igv.util.StringUtils; import com.sun.hotspot.igv.view.actions.*; import java.awt.*; import java.awt.event.MouseEvent; @@ -46,7 +45,6 @@ import org.openide.actions.UndoAction; import org.openide.awt.Toolbar; import org.openide.awt.ToolbarPool; import org.openide.awt.UndoRedo; -import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.Utilities; import org.openide.util.actions.Presenter; @@ -70,15 +68,12 @@ public final class EditorTopComponent extends TopComponent implements TopCompone private final JPanel centerPanel; private final CardLayout cardLayout; private final Toolbar quickSearchToolbar; + private boolean useBoldDisplayName = false; private static final JPanel quickSearchPresenter = (JPanel) ((Presenter.Toolbar) Utilities.actionsForPath("Actions/Search").get(0)).getToolbarPresenter(); private static final String PREFERRED_ID = "EditorTopComponent"; private static final String SATELLITE_STRING = "satellite"; private static final String SCENE_STRING = "scene"; - public EditorTopComponent(InputGraph graph) { - this(new DiagramViewModel(graph)); - } - public EditorTopComponent(DiagramViewModel diagramViewModel) { initComponents(); @@ -372,9 +367,35 @@ public final class EditorTopComponent extends TopComponent implements TopCompone scene.getComponent().requestFocus(); } + @Override + public void setDisplayName(String displayName) { + super.setDisplayName(displayName); + if (useBoldDisplayName) { + setHtmlDisplayName("" + StringUtils.escapeHTML(getDisplayName()) + ""); + } else { + setHtmlDisplayName(getDisplayName()); + } + } + + private void setBoldDisplayName(boolean bold) { + useBoldDisplayName = bold; + setDisplayName(getDisplayName()); + } + @Override protected void componentActivated() { super.componentActivated(); + getModel().activateModel(); + WindowManager manager = WindowManager.getDefault(); + for (Mode m : manager.getModes()) { + for (TopComponent topComponent : manager.getOpenedTopComponents(m)) { + if (topComponent instanceof EditorTopComponent) { + EditorTopComponent editor = (EditorTopComponent) topComponent; + editor.setBoldDisplayName(false); + } + } + } + setBoldDisplayName(true); quickSearchToolbar.add(quickSearchPresenter); quickSearchPresenter.revalidate(); } @@ -390,19 +411,23 @@ public final class EditorTopComponent extends TopComponent implements TopCompone @Override public TopComponent cloneComponent() { - DiagramViewModel model = new DiagramViewModel(getModel().getFirstGraph()); - if (getModel().getGraph().isDiffGraph()) { - model.setPositions(getModel().getFirstPosition(), getModel().getSecondPosition()); - } - model.setHiddenNodes(new HashSet<>(getModel().getHiddenNodes())); - model.setShowCFG(getModel().getShowCFG()); - model.setShowSea(getModel().getShowSea()); - model.setShowBlocks(getModel().getShowBlocks()); - model.setShowNodeHull(getModel().getShowNodeHull()); - model.setShowEmptyBlocks(getModel().getShowEmptyBlocks()); - model.setHideDuplicates(getModel().getHideDuplicates()); + DiagramViewModel model = new DiagramViewModel(getModel()); + model.setGlobalSelection(false, false); EditorTopComponent etc = new EditorTopComponent(model); + + Set selectedNodes = new HashSet<>(); + for (Figure figure : getModel().getSelectedFigures()) { + selectedNodes.add(figure.getInputNode()); + } + etc.addSelectedNodes(selectedNodes, false); + model.setGlobalSelection(GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected(), false); etc.resetUndoRedo(); + + int currentZoomLevel = scene.getZoomPercentage(); + SwingUtilities.invokeLater(() -> { + etc.setZoomLevel(currentZoomLevel); + etc.centerSelectedNodes(); + }); return etc; } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/GraphViewerImplementation.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/GraphViewerImplementation.java index 5f118efb30e..d4b88135408 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/GraphViewerImplementation.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/GraphViewerImplementation.java @@ -62,9 +62,9 @@ public class GraphViewerImplementation implements GraphViewer { return; } } - - EditorTopComponent tc = new EditorTopComponent(graph); - tc.open(); - tc.requestActive(); + DiagramViewModel model = new DiagramViewModel(graph); + EditorTopComponent etc = new EditorTopComponent(model); + etc.open(); + etc.requestActive(); } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/GlobalSelectionAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/GlobalSelectionAction.java index 279483c7798..7c5ef0ea781 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/GlobalSelectionAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/GlobalSelectionAction.java @@ -74,7 +74,7 @@ public final class GlobalSelectionAction extends CallableSystemAction { putValue(SELECTED_KEY, isSelected); EditorTopComponent editor = EditorTopComponent.getActive(); if (editor != null) { - SwingUtilities.invokeLater(() -> editor.getModel().setGlobalSelection(isSelected)); + SwingUtilities.invokeLater(() -> editor.getModel().setGlobalSelection(isSelected, true)); } }