1
+ /*******************************************************************************
2
+ * Copyright (c) 2006, 2016 Tom Schindl and others.
3
+ *
4
+ * This program and the accompanying materials
5
+ * are made available under the terms of the Eclipse Public License 2.0
6
+ * which accompanies this distribution, and is available at
7
+ * https://www.eclipse.org/legal/epl-2.0/
8
+ *
9
+ * SPDX-License-Identifier: EPL-2.0
10
+ *
11
+ * Contributors:
12
+ * Tom Schindl - initial API and implementation
13
+ * Lars Vogel <[email protected] > - Bug 486603
14
+ * Wim Jongman <[email protected] > - Overhaul without preloading model
15
+ *******************************************************************************/
16
+
17
+ package org .eclipse .jface .snippets .viewers ;
18
+
19
+ import java .util .Random ;
20
+ import java .util .concurrent .TimeUnit ;
21
+ import java .util .concurrent .atomic .AtomicLong ;
22
+
23
+ import org .eclipse .jface .layout .GridDataFactory ;
24
+ import org .eclipse .jface .viewers .ILazyTreeContentProvider ;
25
+ import org .eclipse .jface .viewers .LabelProvider ;
26
+ import org .eclipse .jface .viewers .TreeViewer ;
27
+ import org .eclipse .swt .SWT ;
28
+ import org .eclipse .swt .layout .GridData ;
29
+ import org .eclipse .swt .layout .GridLayout ;
30
+ import org .eclipse .swt .widgets .Display ;
31
+ import org .eclipse .swt .widgets .Shell ;
32
+ import org .eclipse .swt .widgets .Text ;
33
+
34
+ /**
35
+ * A simple TreeViewer example to demonstrate the usage of an
36
+ * ILazyContentProvider.
37
+ *
38
+ */
39
+ public class Snippet047VirtualBigTreeViewer {
40
+
41
+ private static final int MODEL_DEEP = 1 ;
42
+ private static final int MODEL_MAX_CHILD_COUNT = 20_000 ;
43
+ private static final int MODEL_MIN_CHILDS = 10 ;
44
+ private static final Random RANDOM = new Random ();
45
+ private static AtomicLong rendered = new AtomicLong ();
46
+ private static AtomicLong updated = new AtomicLong ();
47
+ private static AtomicLong childcount = new AtomicLong ();
48
+ private final TreeViewer fViewer ;
49
+ private final Text fText ;
50
+
51
+ private class MyContentProvider implements ILazyTreeContentProvider {
52
+
53
+ @ Override
54
+ public Object getParent (Object element ) {
55
+
56
+ return ((Node ) element ).getParent ();
57
+ }
58
+
59
+ @ Override
60
+ public void updateChildCount (Object element , int currentChildCount ) {
61
+
62
+ childcount .incrementAndGet ();
63
+ int cc = ((Node ) element ).getChildCount ();
64
+ if (cc != currentChildCount ) {
65
+ fViewer .setChildCount (element , cc );
66
+ }
67
+ }
68
+
69
+ @ Override
70
+ public void updateElement (Object parent , int index ) {
71
+
72
+ updated .incrementAndGet ();
73
+ Node element = ((Node ) parent ).getChild (index );
74
+ fViewer .replace (parent , index , element );
75
+ fViewer .setChildCount (element , element .getChildCount ());
76
+ }
77
+ }
78
+
79
+ public class Node {
80
+
81
+ private Node [] fChildren ;
82
+ private final int fCounter ;
83
+ private final Node fParent ;
84
+
85
+ public Node (int counter , Node parent ) {
86
+
87
+ fCounter = counter ;
88
+ fParent = parent ;
89
+ }
90
+
91
+ public Node getParent () {
92
+
93
+ return fParent ;
94
+ }
95
+
96
+ public Node [] getChildren () {
97
+
98
+ return fChildren ;
99
+ }
100
+
101
+ public Node getChild (int index ) {
102
+
103
+ if (fChildren == null ) {
104
+ return null ;
105
+ }
106
+ return fChildren [index ];
107
+ }
108
+
109
+ public int getChildCount () {
110
+
111
+ if (fChildren == null ) {
112
+ return 0 ;
113
+ }
114
+ return fChildren .length ;
115
+ }
116
+
117
+ @ Override
118
+ public String toString () {
119
+
120
+ Node parent = getParent ();
121
+ String type = parent == null ? "Root" : parent .getParent () == null ? "Node" : "Leaf" ;
122
+ return type + " " + this .fCounter + " of " + (parent == null ? "" : String .valueOf (parent .getChildCount ()))
123
+ + " with " + getChildCount () + " childs" ;
124
+ }
125
+ }
126
+
127
+ public Snippet047VirtualBigTreeViewer (Shell shell ) {
128
+
129
+ System .out .println ("Create large model..." );
130
+ Node root = createModel ();
131
+ System .out .println ("Show UI" );
132
+ fText = new Text (shell , SWT .SINGLE | SWT .LEAD | SWT .BORDER );
133
+ fText .setLayoutData (new GridData (SWT .FILL , SWT .CENTER , true , false ));
134
+ fText .setEnabled (false );
135
+ fViewer = new TreeViewer (shell , SWT .VIRTUAL | SWT .BORDER );
136
+ fViewer .setLabelProvider (new LabelProvider () {
137
+
138
+ @ Override
139
+ public String getText (Object element ) {
140
+
141
+ rendered .incrementAndGet ();
142
+ return super .getText (element );
143
+ }
144
+ });
145
+ fViewer .setContentProvider (new MyContentProvider ());
146
+ fViewer .setUseHashlookup (true );
147
+ fViewer .setInput (root );
148
+ fViewer .getTree ().setLayoutData (GridDataFactory .fillDefaults ().create ());
149
+ fViewer .setChildCount (root , root .getChildCount ());
150
+ fViewer .getTree ().setLayoutData (new GridData (SWT .FILL , SWT .FILL , true , true ));
151
+ // at this point the model only contains what is visible on the screen.
152
+ }
153
+
154
+ private Node createModel () {
155
+
156
+ Node root = new Node (-1 , null );
157
+ createChilds (root , 0 );
158
+ return root ;
159
+ }
160
+
161
+ private void createChilds (Node parent , int i ) {
162
+
163
+ if (i > MODEL_DEEP ) {
164
+ return ;
165
+ }
166
+ int childs = RANDOM .nextInt (MODEL_MIN_CHILDS , MODEL_MAX_CHILD_COUNT );
167
+ parent .fChildren = new Node [childs ];
168
+ for (int j = 0 ; j < childs ; j ++) {
169
+ parent .fChildren [j ] = new Node (j , parent );
170
+ createChilds (parent .fChildren [j ], i + 1 );
171
+ }
172
+ }
173
+
174
+ /**
175
+ * @param args
176
+ */
177
+ public static void main (String [] args ) {
178
+
179
+ Thread thread = new Thread (new Runnable () {
180
+
181
+ @ Override
182
+ public void run () {
183
+
184
+ try {
185
+ long last = 0 ;
186
+ while (true ) {
187
+ TimeUnit .SECONDS .sleep (1 );
188
+ long current = rendered .get ();
189
+ if (current != last ) {
190
+ last = current ;
191
+ System .out .println ("Total render requests: " + current + ", " + updated .get ()
192
+ + " update elements, " + childcount .get () + " update childcounts" );
193
+ }
194
+ }
195
+ } catch (InterruptedException e ) {
196
+ return ;
197
+ }
198
+ }
199
+ });
200
+ thread .setDaemon (true );
201
+ thread .start ();
202
+ Display display = new Display ();
203
+ Shell shell = new Shell (display );
204
+ shell .setLayout (new GridLayout ());
205
+ new Snippet047VirtualBigTreeViewer (shell );
206
+ shell .setSize (800 , 600 );
207
+ shell .open ();
208
+ while (!shell .isDisposed ()) {
209
+ if (!display .readAndDispatch ()) {
210
+ display .sleep ();
211
+ }
212
+ }
213
+ display .dispose ();
214
+ }
215
+ }
0 commit comments