DiagramViewModel.java revision 470:ad8c8ca4ab0f
1/*
2 * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package com.sun.hotspot.igv.view;
26
27import com.sun.hotspot.igv.data.Group;
28import com.sun.hotspot.igv.data.InputGraph;
29import com.sun.hotspot.igv.data.InputNode;
30import com.sun.hotspot.igv.difference.Difference;
31import com.sun.hotspot.igv.filter.FilterChain;
32import com.sun.hotspot.igv.graph.Diagram;
33import com.sun.hotspot.igv.data.ChangedEvent;
34import com.sun.hotspot.igv.util.RangeSliderModel;
35import java.util.ArrayList;
36import java.util.Collections;
37import java.util.HashSet;
38import java.util.List;
39import java.util.Set;
40import com.sun.hotspot.igv.data.ChangedListener;
41import com.sun.hotspot.igv.settings.Settings;
42import java.awt.Color;
43
44/**
45 *
46 * @author Thomas Wuerthinger
47 */
48public class DiagramViewModel extends RangeSliderModel implements ChangedListener<RangeSliderModel> {
49
50    // Warning: Update setData method if fields are added
51    private Group group;
52    private Set<Integer> hiddenNodes;
53    private Set<Integer> onScreenNodes;
54    private Set<Integer> selectedNodes;
55    private FilterChain filterChain;
56    private FilterChain sequenceFilterChain;
57    private Diagram diagram;
58    private ChangedEvent<DiagramViewModel> groupChangedEvent;
59    private ChangedEvent<DiagramViewModel> diagramChangedEvent;
60    private ChangedEvent<DiagramViewModel> viewChangedEvent;
61    private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
62    private boolean showBlocks;
63    private boolean showNodeHull;
64    private ChangedListener<FilterChain> filterChainChangedListener = new ChangedListener<FilterChain>() {
65
66        public void changed(FilterChain source) {
67            diagramChanged();
68        }
69    };
70
71    @Override
72    public DiagramViewModel copy() {
73        DiagramViewModel result = new DiagramViewModel(group, filterChain, sequenceFilterChain);
74        result.setData(this);
75        return result;
76    }
77
78    public void setData(DiagramViewModel newModel) {
79        super.setData(newModel);
80        boolean diagramChanged = false;
81        boolean viewChanged = false;
82        boolean viewPropertiesChanged = false;
83
84        boolean groupChanged = (group == newModel.group);
85        this.group = newModel.group;
86        diagramChanged |= (filterChain != newModel.filterChain);
87        this.filterChain = newModel.filterChain;
88        diagramChanged |= (sequenceFilterChain != newModel.sequenceFilterChain);
89        this.sequenceFilterChain = newModel.sequenceFilterChain;
90        diagramChanged |= (diagram != newModel.diagram);
91        this.diagram = newModel.diagram;
92        viewChanged |= (hiddenNodes != newModel.hiddenNodes);
93        this.hiddenNodes = newModel.hiddenNodes;
94        viewChanged |= (onScreenNodes != newModel.onScreenNodes);
95        this.onScreenNodes = newModel.onScreenNodes;
96        viewChanged |= (selectedNodes != newModel.selectedNodes);
97        this.selectedNodes = newModel.selectedNodes;
98        viewPropertiesChanged |= (showBlocks != newModel.showBlocks);
99        this.showBlocks = newModel.showBlocks;
100        viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
101        this.showNodeHull = newModel.showNodeHull;
102
103        if(groupChanged) {
104            groupChangedEvent.fire();
105        }
106
107        if (diagramChanged) {
108            diagramChangedEvent.fire();
109        }
110        if (viewPropertiesChanged) {
111            viewPropertiesChangedEvent.fire();
112        }
113        if (viewChanged) {
114            viewChangedEvent.fire();
115        }
116    }
117
118    public boolean getShowBlocks() {
119        return showBlocks;
120    }
121
122    public void setShowBlocks(boolean b) {
123        showBlocks = b;
124        viewPropertiesChangedEvent.fire();
125    }
126
127    public boolean getShowNodeHull() {
128        return showNodeHull;
129    }
130
131    public void setShowNodeHull(boolean b) {
132        showNodeHull = b;
133        viewPropertiesChangedEvent.fire();
134    }
135
136    public DiagramViewModel(Group g, FilterChain filterChain, FilterChain sequenceFilterChain) {
137        super(calculateStringList(g));
138
139        this.showNodeHull = true;
140        this.showBlocks = true;
141        this.group = g;
142        assert filterChain != null;
143        this.filterChain = filterChain;
144        assert sequenceFilterChain != null;
145        this.sequenceFilterChain = sequenceFilterChain;
146        hiddenNodes = new HashSet<Integer>();
147        onScreenNodes = new HashSet<Integer>();
148        selectedNodes = new HashSet<Integer>();
149        super.getChangedEvent().addListener(this);
150        diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this);
151        viewChangedEvent = new ChangedEvent<DiagramViewModel>(this);
152        viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
153        groupChangedEvent = new ChangedEvent<DiagramViewModel>(this);
154        groupChangedEvent.addListener(groupChangedListener);
155        groupChangedEvent.fire();
156
157        filterChain.getChangedEvent().addListener(filterChainChangedListener);
158        sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
159    }
160
161    private final ChangedListener<DiagramViewModel> groupChangedListener = new ChangedListener<DiagramViewModel>() {
162
163        private Group oldGroup;
164
165        public void changed(DiagramViewModel source) {
166            if(oldGroup != null) {
167                oldGroup.getChangedEvent().removeListener(groupContentChangedListener);
168            }
169            group.getChangedEvent().addListener(groupContentChangedListener);
170            oldGroup = group;
171        }
172    };
173
174
175    private final ChangedListener<Group> groupContentChangedListener = new ChangedListener<Group>() {
176
177        public void changed(Group source) {
178            assert source == group;
179            setPositions(calculateStringList(source));
180            setSelectedNodes(selectedNodes);
181        }
182
183    };
184
185    public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
186        return diagramChangedEvent;
187    }
188
189    public ChangedEvent<DiagramViewModel> getViewChangedEvent() {
190        return viewChangedEvent;
191    }
192
193    public ChangedEvent<DiagramViewModel> getViewPropertiesChangedEvent() {
194        return viewPropertiesChangedEvent;
195    }
196
197    public Set<Integer> getSelectedNodes() {
198        return Collections.unmodifiableSet(selectedNodes);
199    }
200
201    public Set<Integer> getHiddenNodes() {
202        return Collections.unmodifiableSet(hiddenNodes);
203    }
204
205    public Set<Integer> getOnScreenNodes() {
206        return Collections.unmodifiableSet(onScreenNodes);
207    }
208
209    public void setSelectedNodes(Set<Integer> nodes) {
210        this.selectedNodes = nodes;
211        List<Color> colors = new ArrayList<Color>();
212        for (String s : getPositions()) {
213            colors.add(Color.black);
214        }
215        if (nodes.size() >= 1) {
216            for (Integer id : nodes) {
217                if (id < 0) {
218                    id = -id;
219                }
220                InputNode last = null;
221                int index = 0;
222                for (InputGraph g : group.getGraphs()) {
223                    Color curColor = colors.get(index);
224                    InputNode cur = g.getNode(id);
225                    if (cur != null) {
226                        if (last == null) {
227                            curColor = Color.green;
228                        } else {
229                            if (last.equals(cur)) {
230                                if (curColor == Color.black) {
231                                    curColor = Color.white;
232                                }
233                            } else {
234                                if (curColor != Color.green) {
235                                    curColor = Color.orange;
236                                }
237                            }
238                        }
239                    }
240                    last = cur;
241                    colors.set(index, curColor);
242                    index++;
243                }
244            }
245            this.setColors(colors);
246        }
247        setColors(colors);
248        viewChangedEvent.fire();
249    }
250
251    public void setHiddenNodes(Set<Integer> nodes) {
252        this.hiddenNodes = nodes;
253        viewChangedEvent.fire();
254    }
255
256    public void setOnScreenNodes(Set<Integer> onScreenNodes) {
257        this.onScreenNodes = onScreenNodes;
258        viewChangedEvent.fire();
259    }
260
261    public FilterChain getSequenceFilterChain() {
262        return filterChain;
263    }
264
265    public void setSequenceFilterChain(FilterChain chain) {
266        assert chain != null : "sequenceFilterChain must never be null";
267        sequenceFilterChain.getChangedEvent().removeListener(filterChainChangedListener);
268        sequenceFilterChain = chain;
269        sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
270        diagramChanged();
271    }
272
273    private void diagramChanged() {
274        // clear diagram
275        diagram = null;
276        getDiagramChangedEvent().fire();
277
278    }
279
280    public FilterChain getFilterChain() {
281        return filterChain;
282    }
283
284    public void setFilterChain(FilterChain chain) {
285        assert chain != null : "filterChain must never be null";
286        filterChain.getChangedEvent().removeListener(filterChainChangedListener);
287        filterChain = chain;
288        filterChain.getChangedEvent().addListener(filterChainChangedListener);
289        diagramChanged();
290    }
291
292    private static List<String> calculateStringList(Group g) {
293        List<String> result = new ArrayList<String>();
294        for (InputGraph graph : g.getGraphs()) {
295            result.add(graph.getName());
296        }
297        return result;
298    }
299
300    public InputGraph getFirstGraph() {
301        return group.getGraphs().get(getFirstPosition());
302    }
303
304    public InputGraph getSecondGraph() {
305        List<InputGraph> graphs = group.getGraphs();
306        if (graphs.size() >= getSecondPosition())
307            return group.getGraphs().get(getSecondPosition());
308        return getFirstGraph();
309    }
310
311    public void selectGraph(InputGraph g) {
312        int index = group.getGraphs().indexOf(g);
313        assert index != -1;
314        setPositions(index, index);
315    }
316
317    public Diagram getDiagramToView() {
318
319        if (diagram == null) {
320            diagram = Diagram.createDiagram(getGraphToView(), Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT));
321            getFilterChain().apply(diagram, getSequenceFilterChain());
322        }
323
324        return diagram;
325    }
326
327    public InputGraph getGraphToView() {
328        if (getFirstGraph() != getSecondGraph()) {
329            InputGraph inputGraph = Difference.createDiffGraph(getSecondGraph(), getFirstGraph());
330            return inputGraph;
331        } else {
332            InputGraph inputGraph = getFirstGraph();
333            return inputGraph;
334        }
335    }
336
337    public void changed(RangeSliderModel source) {
338        diagramChanged();
339    }
340}
341