Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/ui/HighPrecisionJScrollBar.java @ 3945:8ed53447f690
Merge
author | iveresov |
---|---|
date | Thu, 15 Sep 2011 12:44:09 -0700 |
parents | c18cbe5936b8 |
children |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
196
diff
changeset
|
2 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. |
0 | 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. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
196
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
196
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
196
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.ui; | |
26 | |
27 import java.awt.event.*; | |
28 import javax.swing.*; | |
29 import javax.swing.event.*; | |
30 import java.math.*; | |
31 import java.util.*; | |
32 | |
33 /** A JScrollBar which uses BigIntegers as the representation for the | |
34 minimum, maximum, unit increment, etc. Interaction with the | |
35 buttons and track is accurate to unit and block increments; | |
36 however, if the scale of the scrollbar (defined by | |
37 getMaximumHP().subtract(getMinimumHP())) is very large, each | |
38 interaction with the thumb will necessarily cause extremely large | |
39 motion of the value. */ | |
40 | |
41 public class HighPrecisionJScrollBar extends JScrollBar { | |
42 private BigInteger valueHP; | |
43 private BigInteger visibleHP; | |
44 private BigInteger minimumHP; | |
45 private BigInteger maximumHP; | |
46 private BigInteger unitIncrementHP; | |
47 private BigInteger blockIncrementHP; | |
48 private BigDecimal scaleFactor; | |
49 private BigInteger rangeHP; | |
50 // The underlying scrollbar runs a range from 0..BIG_RANGE-1 | |
51 private static final int BIG_RANGE = 10000; | |
52 // Do we need to scale HP values up/down to fit in 0..BIG_RANGE-1? | |
53 private boolean down; | |
54 private java.util.List changeListeners = new ArrayList(); | |
55 // Number of digits after decimal point to use when scaling between | |
56 // high and low precision | |
57 private static final int SCALE = 20; | |
58 | |
59 | |
60 // This is a hack to allow us to differentiate between clicks on the | |
61 // arrow and track since we can't get useful information from | |
62 // JScrollBars' AdjustmentListener (bug in design of BasicUI | |
63 // classes; FIXME: file RFE.) | |
64 private static final int UNIT_INCREMENT = 1; | |
65 private static final int BLOCK_INCREMENT = 2; | |
66 private static final int MINIMUM = 0; | |
67 private static final int MAXIMUM = 65536; | |
68 private boolean updating = false; | |
69 private int lastValueSeen = -1; | |
70 | |
71 public HighPrecisionJScrollBar() { | |
72 super(); | |
73 initialize(); | |
74 installListener(); | |
75 } | |
76 | |
77 public HighPrecisionJScrollBar(int orientation) { | |
78 super(orientation); | |
79 initialize(); | |
80 installListener(); | |
81 } | |
82 | |
83 /** value, minimum and maximum should be positive */ | |
84 public HighPrecisionJScrollBar(int orientation, BigInteger value, BigInteger minimum, BigInteger maximum) { | |
85 super(orientation); | |
86 initialize(value, minimum, maximum); | |
87 installListener(); | |
88 } | |
89 | |
90 public BigInteger getValueHP() { | |
91 return valueHP; | |
92 } | |
93 | |
94 | |
95 /** NOTE: the real value will always be set to be (value mod | |
96 unitIncrement) == 0, subtracting off the mod of the passed value | |
97 if necessary. */ | |
98 | |
99 public void setValueHP(BigInteger value) { | |
100 if (value.compareTo(getMaximumHP()) > 0) { | |
101 value = getMaximumHP(); | |
102 } else if (value.compareTo(getMinimumHP()) < 0) { | |
103 value = getMinimumHP(); | |
104 } | |
105 valueHP = value.subtract(value.mod(unitIncrementHP)); | |
106 int lpValue = toUnderlyingRange(this.valueHP); | |
107 if (getValueHP().add(getVisibleAmountHP()).compareTo(getMaximumHP()) >= 0 ) { | |
108 lpValue = BIG_RANGE - getVisibleAmount(); | |
109 } | |
110 lastValueSeen = lpValue; | |
111 setValue(lpValue); | |
112 fireStateChanged(); | |
113 } | |
114 public BigInteger getMinimumHP() { | |
115 return minimumHP; | |
116 } | |
117 | |
118 public void setMinimumHP(BigInteger minimum) { | |
119 setRange(minimum, maximumHP); | |
120 updateScrollBarValues(); | |
121 } | |
122 | |
123 public BigInteger getMaximumHP() { | |
124 return maximumHP; | |
125 } | |
126 | |
127 public void setMaximumHP(BigInteger maximum) { | |
128 setRange(minimumHP, maximum); | |
129 updateScrollBarValues(); | |
130 } | |
131 | |
132 public BigInteger getVisibleAmountHP() { | |
133 return visibleHP; | |
134 } | |
135 | |
136 public void setVisibleAmountHP(BigInteger visibleAmount) { | |
137 this.visibleHP = visibleAmount; | |
138 // int lpVisAmt = toUnderlyingRange(visibleAmount); | |
139 // Make certain that visibleAmount value that are full range come out looking like full range | |
140 int lpVisAmt; | |
141 if (visibleAmount.compareTo(rangeHP) < 0) { | |
142 lpVisAmt = scaleToUnderlying(visibleAmount); | |
143 if (lpVisAmt == 0) { | |
144 lpVisAmt = 1; | |
145 } | |
146 setVisible(true); | |
147 } else { | |
148 lpVisAmt = BIG_RANGE; | |
149 setVisible(false); | |
150 } | |
151 setVisibleAmount(lpVisAmt); | |
152 } | |
153 | |
154 public BigInteger getBlockIncrementHP() { | |
155 return blockIncrementHP; | |
156 } | |
157 | |
158 public void setBlockIncrementHP(BigInteger blockIncrement) { | |
159 this.blockIncrementHP = blockIncrement; | |
160 // NOTE we do not forward this to the underlying scrollBar because of | |
161 // the earlier mentioned hack. | |
162 } | |
163 | |
164 public BigInteger getUnitIncrementHP() { | |
165 return unitIncrementHP; | |
166 } | |
167 | |
168 public void setUnitIncrementHP(BigInteger unitIncrement) { | |
169 this.unitIncrementHP = unitIncrement; | |
170 // NOTE we do not forward this to the underlying scrollBar because of | |
171 // the earlier mentioned hack. | |
172 } | |
173 | |
174 | |
175 public void addChangeListener(ChangeListener l) { | |
176 changeListeners.add(l); | |
177 } | |
178 | |
179 public void removeChangeListener(ChangeListener l) { | |
180 changeListeners.remove(l); | |
181 } | |
182 | |
183 //---------------------------------------------------------------------- | |
184 // Programmatic access to scrollbar functionality | |
185 // (Causes change events to be sent) | |
186 | |
187 public void scrollUpOrLeft() { | |
188 if (updating) return; | |
189 beginUpdate(); | |
190 setValueHP(getValueHP().subtract(getUnitIncrementHP())); | |
191 endUpdate(); | |
192 } | |
193 | |
194 public void scrollDownOrRight() { | |
195 if (updating) return; | |
196 beginUpdate(); | |
197 setValueHP(getValueHP().add(getUnitIncrementHP())); | |
198 endUpdate(); | |
199 } | |
200 | |
201 public void pageUpOrLeft() { | |
202 if (updating) return; | |
203 beginUpdate(); | |
204 setValueHP(getValueHP().subtract(getBlockIncrementHP())); | |
205 endUpdate(); | |
206 } | |
207 | |
208 public void pageDownOrRight() { | |
209 if (updating) return; | |
210 beginUpdate(); | |
211 setValueHP(getValueHP().add(getBlockIncrementHP())); | |
212 endUpdate(); | |
213 } | |
214 | |
215 //---------------------------------------------------------------------- | |
216 // Internals only below this point | |
217 // | |
218 | |
219 private void beginUpdate() { | |
220 updating = true; | |
221 } | |
222 | |
223 private void endUpdate() { | |
224 updating = false; | |
225 } | |
226 | |
227 private void initialize(BigInteger value, BigInteger minimum, BigInteger maximum) { | |
228 // Initialize the underlying scrollbar to the standard range values | |
229 // The increments are important and are how we differentiate arrow from track events | |
230 setMinimum(0); | |
231 setMaximum(BIG_RANGE - 1); | |
232 setValue(0); | |
233 setVisibleAmount(1); | |
234 setUnitIncrement(UNIT_INCREMENT); | |
235 setBlockIncrement(BLOCK_INCREMENT); | |
236 | |
237 setUnitIncrementHP(new BigInteger(Integer.toString(getUnitIncrement()))); | |
238 setBlockIncrementHP(new BigInteger(Integer.toString(getBlockIncrement()))); | |
239 | |
240 // Must set range and value first (it sets min/max) | |
241 setRange(minimum, maximum); | |
242 | |
243 setVisibleAmountHP(new BigInteger(Integer.toString(getVisibleAmount()))); | |
244 setValueHP(value); | |
245 } | |
246 | |
247 private void initialize() { | |
248 BigInteger min = new BigInteger(Integer.toString(getMinimum())); | |
249 BigInteger max = new BigInteger(Integer.toString(getMaximum())); | |
250 initialize(min, min, max); | |
251 } | |
252 | |
253 private void setRange(BigInteger minimum, BigInteger maximum) { | |
254 if (minimum.compareTo(maximum) > 0 ) { | |
255 throw new RuntimeException("Bad scrollbar range " + minimum + " > " + maximum); | |
256 } | |
257 minimumHP = minimum; | |
258 maximumHP = maximum; | |
259 rangeHP = maximum.subtract(minimum).add(BigInteger.ONE); | |
260 BigInteger range2 = new BigInteger(Integer.toString(BIG_RANGE)); | |
261 if (rangeHP.compareTo(range2) >= 0 ) { | |
262 down = true; | |
263 scaleFactor = new BigDecimal(rangeHP, SCALE).divide(new BigDecimal(range2, SCALE), BigDecimal.ROUND_DOWN).max(new BigDecimal(BigInteger.ONE)); | |
264 } else { | |
265 down = false; | |
266 scaleFactor = new BigDecimal(range2, SCALE).divide(new BigDecimal(rangeHP, SCALE), BigDecimal.ROUND_DOWN).max(new BigDecimal(BigInteger.ONE)); | |
267 } | |
268 // FIXME: should put in original scaling algorithm (shifting by | |
269 // number of bits) as alternative when scale between low and high | |
270 // precision is very large | |
271 } | |
272 | |
273 // A range update is complete. Rescale our computed values and | |
274 // inform the underlying scrollBar as needed. | |
275 private void updateScrollBarValues() { | |
276 setValueHP(getValueHP()); | |
277 setVisibleAmountHP(getVisibleAmountHP()); | |
278 setBlockIncrementHP(getBlockIncrementHP()); | |
279 setUnitIncrementHP(getUnitIncrementHP()); | |
280 } | |
281 | |
282 private BigDecimal getScaleFactor() { | |
283 return scaleFactor; | |
284 } | |
285 | |
286 | |
287 // Value scaling routines | |
288 private BigInteger scaleToHP(int i) { | |
289 BigDecimal ib = new BigDecimal(Integer.toString(i)); | |
290 if (down) return ib.multiply(getScaleFactor()).toBigInteger(); | |
291 else return ib.divide(getScaleFactor(), BigDecimal.ROUND_DOWN).toBigInteger(); | |
292 } | |
293 | |
294 private int scaleToUnderlying(BigInteger i) { | |
295 BigDecimal d = new BigDecimal(i); | |
296 if (down) return d.divide(getScaleFactor(), BigDecimal.ROUND_DOWN).intValue(); | |
297 else return d.multiply(getScaleFactor()).intValue(); | |
298 } | |
299 | |
300 // Range scaling routines | |
301 private BigInteger toHPRange(int i) { | |
302 return scaleToHP(i).add(minimumHP); | |
303 // return ib.shiftLeft(Math.max(2, maximumHP.bitLength() - 33)); | |
304 } | |
305 | |
306 private int toUnderlyingRange(BigInteger i) { | |
307 return scaleToUnderlying(i.subtract(minimumHP)); | |
308 // return i.shiftRight(Math.max(2, maximumHP.bitLength() - 33)).intValue(); | |
309 } | |
310 | |
311 private void installListener() { | |
312 super.addAdjustmentListener(new AdjustmentListener() { | |
313 public void adjustmentValueChanged(AdjustmentEvent e) { | |
314 if (updating) { | |
315 return; | |
316 } | |
317 beginUpdate(); | |
318 switch (e.getAdjustmentType()) { | |
319 case AdjustmentEvent.TRACK: | |
320 int val = e.getValue(); | |
321 int diff = val - lastValueSeen; | |
322 int absDiff = Math.abs(diff); | |
323 // System.err.println("diff: " + diff + " absDiff: " + absDiff); | |
324 if (absDiff == UNIT_INCREMENT) { | |
325 if (diff > 0) { | |
326 // System.err.println("case 1"); | |
327 setValueHP(getValueHP().add(getUnitIncrementHP())); | |
328 } else { | |
329 // System.err.println("case 2"); | |
330 setValueHP(getValueHP().subtract(getUnitIncrementHP())); | |
331 } | |
332 } else if (absDiff == BLOCK_INCREMENT) { | |
333 if (diff > 0) { | |
334 // System.err.println("case 3"); | |
335 setValueHP(getValueHP().add(getBlockIncrementHP())); | |
336 } else { | |
337 // System.err.println("case 4"); | |
338 setValueHP(getValueHP().subtract(getBlockIncrementHP())); | |
339 } | |
340 } else { | |
341 // System.err.println("case 5"); | |
342 // FIXME: seem to be getting spurious update events, | |
343 // with diff = 0, upon mouse down/up on the track | |
344 if (absDiff != 0) { | |
345 // Convert low-precision value to high precision | |
346 // (note we lose the low bits) | |
347 BigInteger i = null; | |
348 if (e.getValue() == getMinimum()) { | |
349 i = getMinimumHP(); | |
350 } else if (e.getValue() >= getMaximum() - 1) { | |
351 i = getMaximumHP(); | |
352 } else { | |
353 i = toHPRange(e.getValue()); | |
354 } | |
355 setValueHP(i); | |
356 } | |
357 } | |
358 break; | |
359 default: | |
360 // Should not reach here, but leaving it a no-op in case | |
361 // we later get the other events (should revisit code in | |
362 // that case) | |
363 break; | |
364 } | |
365 endUpdate(); | |
366 } | |
367 }); | |
368 } | |
369 | |
370 private void fireStateChanged() { | |
371 ChangeEvent e = null; | |
372 for (Iterator iter = changeListeners.iterator(); iter.hasNext(); ) { | |
373 ChangeListener l = (ChangeListener) iter.next(); | |
374 if (e == null) { | |
375 e = new ChangeEvent(this); | |
376 } | |
377 l.stateChanged(e); | |
378 } | |
379 } | |
380 | |
381 public static void main(String[] args) { | |
382 JFrame frame = new JFrame(); | |
383 frame.setSize(300, 300); | |
384 // 32-bit version | |
385 /* | |
386 HighPrecisionJScrollBar hpsb = | |
387 new HighPrecisionJScrollBar( | |
388 JScrollBar.VERTICAL, | |
389 new BigInteger(1, new byte[] { | |
390 (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00}), | |
391 new BigInteger(1, new byte[] { | |
392 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}), | |
393 new BigInteger(1, new byte[] { | |
394 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF})); | |
395 hpsb.setUnitIncrementHP(new BigInteger(1, new byte[] { | |
396 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01})); | |
397 hpsb.setBlockIncrementHP(new BigInteger(1, new byte[] { | |
398 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10})); | |
399 */ | |
400 | |
401 // 64-bit version | |
402 HighPrecisionJScrollBar hpsb = | |
403 new HighPrecisionJScrollBar( | |
404 JScrollBar.VERTICAL, | |
405 new BigInteger(1, new byte[] { | |
406 (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, | |
407 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}), | |
408 new BigInteger(1, new byte[] { | |
409 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, | |
410 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}), | |
411 new BigInteger(1, new byte[] { | |
412 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, | |
413 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF})); | |
414 hpsb.setUnitIncrementHP(new BigInteger(1, new byte[] { | |
415 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, | |
416 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01})); | |
417 hpsb.setBlockIncrementHP(new BigInteger(1, new byte[] { | |
418 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, | |
419 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10})); | |
420 hpsb.addChangeListener(new ChangeListener() { | |
421 public void stateChanged(ChangeEvent e) { | |
422 HighPrecisionJScrollBar h = (HighPrecisionJScrollBar) e.getSource(); | |
423 System.out.println("New value = 0x" + h.getValueHP().toString(16)); | |
424 } | |
425 }); | |
426 frame.getContentPane().add(hpsb); | |
152
c70a245cad3a
6670684: 4/5 SA command universe did not print out CMS space information
dcubed
parents:
0
diff
changeset
|
427 frame.setVisible(true); |
0 | 428 } |
429 | |
430 } |