File: GraphSelectionDemo.java

package info (click to toggle)
libjgraph-java 5.12.4.2%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: buster, stretch
  • size: 7,884 kB
  • ctags: 7,321
  • sloc: java: 20,619; xml: 135; sh: 51; makefile: 10
file content (260 lines) | stat: -rw-r--r-- 7,584 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/*
 * @(#)GraphSelectionDemo.java 3.3 23-APR-04
 *
 * Copyright (c) 2001-2004, Gaudenz Alder All rights reserved.
 *
 * See LICENSE file in distribution for licensing details of this source file
 */
package com.jgraph.example;

import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import org.jgraph.JGraph;
import org.jgraph.event.GraphModelEvent;
import org.jgraph.event.GraphModelListener;
import org.jgraph.event.GraphSelectionEvent;
import org.jgraph.event.GraphSelectionListener;
import org.jgraph.graph.GraphModel;

/**
 * With this example you'll learn how to listen to graph selection event,
 * program graph selections and navigate accross the graph groups.
 * 
 * This demo is is a bit like the GraphTreeModel demo. But this time, we
 * synchronize the graph and the tree selection with two listeners.
 * 
 * There are two issues actually. The first is that we should disable one
 * listener when we programatically change its selection after the other
 * listener receives a selection event (else we would fail in infinite loops).
 * The other issue is navigating the graph and especially its group in order to
 * get the equivalent tree selection. Also notice that ports should be handled
 * like a special kind of group children.
 * 
 * @author rvalyi
 */
public class GraphSelectionDemo extends DefaultTreeModel implements
		GraphModelListener {

	private static JTree tree;

	private static JGraph graph;

	private static GraphSelectionDemo gtModel;

	private static GraphModelTreeNode gtModelTreeNode;
	
	private static SyncGraphSelectionListener mySyncTreeSelectionListener = new SyncGraphSelectionListener();

	public static void main(String[] args) {
		// Switch off D3D because of Sun XOR painting bug
		// See http://www.jgraph.com/forum/viewtopic.php?t=4066
		System.setProperty("sun.java2d.d3d", "false");
		JFrame frame = new JFrame("GraphSelectionDemo");
		graph = new JGraph();
		gtModel = new GraphSelectionDemo(graph.getModel());
		gtModelTreeNode = new GraphModelTreeNode(graph.getModel());
		graph.getModel().addGraphModelListener(gtModel);
		tree = new JTree(gtModel);
		tree.setRootVisible(false);
		JScrollPane sGraph = new JScrollPane(graph);
		JScrollPane sTree = new JScrollPane(tree);
		tree.addTreeSelectionListener(new SyncTreeSelectionListener());
		graph.addGraphSelectionListener(mySyncTreeSelectionListener);
		graph.addMouseListener(new MyMouseListener());
		JSplitPane pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sTree,
				sGraph);
		frame.getContentPane().add(pane);
		frame.pack();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}

	public GraphSelectionDemo(GraphModel model) {
		super(new GraphModelTreeNode(model));
	}

	public void graphChanged(GraphModelEvent e) {
		reload();
	}

	public static class SyncTreeSelectionListener implements
			TreeSelectionListener {

		public void valueChanged(TreeSelectionEvent e) {
			if (tree.isSelectionEmpty())//a selection in the graph can trigger that event while no tree selection exists yet
				return;
			TreePath[] treeSelection = tree.getSelectionModel()
					.getSelectionPaths();
			Object[] graphSelection = new Object[treeSelection.length];

			for (int i = 0; i < treeSelection.length; i++) {
				graphSelection[i] = treeSelection[i].getLastPathComponent();
			}

			// now we set the corresponding graph selection
			graph.setSelectionCells(graphSelection);

			/*
			 * System.out .print(tree.getSelectionModel().getSelectionPath() +
			 * "\n");
			 */
		}
	}
	
	/**
	 * Prevent from loosing the synchronisation after a graph element is dragged
	 */
	public static class MyMouseListener extends MouseInputAdapter {
        public void mouseReleased(MouseEvent e) {
            if (e.getSource() instanceof JGraph) {
                mySyncTreeSelectionListener.valueChanged(null);
            }
        }
    }

	public static class SyncGraphSelectionListener implements
			GraphSelectionListener {
		public void valueChanged(GraphSelectionEvent e) {
			Object selectedPort = null;
			Object[] selection = graph.getSelectionModel().getSelectionCells();
			if (selection == null)
				return;
			TreePath[] paths = new TreePath[selection.length];
			for (int i = 0; i < selection.length; i++) {

				ArrayList list = new ArrayList();
				Object selected = selection[i];
				if (selected == null)
					return;
				list.add(tree.getModel().getRoot());
				if (graph.getModel().isPort(selected)) {// shift if a port
					// is
					// selected
					selectedPort = selected;
					selected = graph.getModel().getParent(selected);
				}

				list = computeTreePathSelection(list, graph.getModel()
						.getParent(selected), selected);
				if (selectedPort != null)
					list.add(selectedPort);
				TreePath treePath = new TreePath(list.toArray());

				if (treePath != null) {
					paths[i] = treePath;
					// System.out.print( treePath.toString() + "\n");
				}

			}

			// to emphasis the change, we collapse the whole tree before
			// assigning a new selection
			int treeSize = tree.getRowCount();
			int row = 0;
			while (row < treeSize) {
				tree.collapseRow(row);
				row++;
			}

			// now we set the corresponding tree selection
			tree.setSelectionPaths(paths);
		}

		/**
		 * Recursively adds the selected graph cells to the array list, starting
		 * from the current child and going until the graph root.
		 * 
		 * @param currentList
		 * @param parent
		 * @param child
		 * @return collection of selected graph cells
		 */
		public ArrayList computeTreePathSelection(ArrayList currentList,
				Object parent, Object child) {
			if (parent == null) {
				currentList.add(child);
				return currentList;
			}

			int parentIndex = graph.getModel().getIndexOfRoot(parent);

			if (parentIndex < 0) {// then parent is in a group or is a port
				computeTreePathSelection(currentList, graph.getModel()
						.getParent(parent), parent);
			}

			// parentIndex refer to a valid selected node in the tree
			currentList.add(gtModelTreeNode.getChildAt(parentIndex));

			// index of the child in the graph
			int childIndex = graph.getModel().getIndexOfChild(parent, child);
			// corresponding node in the tree
			Object node = tree.getModel().getChild(parent, childIndex);

			currentList.add(node);
			return currentList;
		}
	}

	/**
	 * See the GraphModelTree demo
	 */
	public static class GraphModelTreeNode implements TreeNode {

		protected GraphModel model;

		public GraphModelTreeNode(GraphModel model) {
			this.model = model;
		}

		public Enumeration children() {
			Vector v = new Vector();
			for (int i = 0; i < model.getRootCount(); i++)
				v.add(model.getRootAt(i));
			return v.elements();
		}

		public boolean getAllowsChildren() {
			return true;
		}

		public TreeNode getChildAt(int childIndex) {
				return (TreeNode) model.getRootAt(childIndex);
		}

		public int getChildCount() {
			return model.getRootCount();
		}

		public int getIndex(TreeNode node) {
			return model.getIndexOfRoot(node);
		}

		public TreeNode getParent() {
			return null;
		}

		public boolean isLeaf() {
			return false;
		}

		public String toString() {
			return model.toString();
		}
	}

}