Mercurial > projects > dwt-addons
comparison dwtx/draw2d/ScrollBar.d @ 98:95307ad235d9
Added Draw2d code, still work in progress
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 03 Aug 2008 00:52:14 +0200 |
parents | |
children | 2d6540440fe6 |
comparison
equal
deleted
inserted
replaced
96:b492ba44e44d | 98:95307ad235d9 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2005 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwtx.draw2d.ScrollBar; | |
14 | |
15 import dwt.dwthelper.utils; | |
16 | |
17 import dwtx.dwtxhelper.Bean; | |
18 | |
19 import dwt.graphics.Color; | |
20 import dwtx.draw2d.geometry.Dimension; | |
21 import dwtx.draw2d.geometry.Point; | |
22 import dwtx.draw2d.geometry.Rectangle; | |
23 import dwtx.draw2d.geometry.Transposer; | |
24 | |
25 import dwtx.draw2d.Orientable; | |
26 import dwtx.draw2d.Figure; | |
27 import dwtx.draw2d.IFigure; | |
28 import dwtx.draw2d.RangeModel; | |
29 import dwtx.draw2d.Clickable; | |
30 import dwtx.draw2d.MouseMotionListener; | |
31 import dwtx.draw2d.MouseListener; | |
32 import dwtx.draw2d.MouseEvent; | |
33 import dwtx.draw2d.FigureUtilities; | |
34 import dwtx.draw2d.ColorConstants; | |
35 import dwtx.draw2d.Button; | |
36 import dwtx.draw2d.RangeModel; | |
37 import dwtx.draw2d.DefaultRangeModel; | |
38 import dwtx.draw2d.ArrowButton; | |
39 import dwtx.draw2d.ButtonBorder; | |
40 import dwtx.draw2d.ChangeListener; | |
41 import dwtx.draw2d.ChangeEvent; | |
42 import dwtx.draw2d.Panel; | |
43 import dwtx.draw2d.ScrollBarLayout; | |
44 import dwtx.draw2d.SchemeBorder; | |
45 import dwtx.draw2d.ActionListener; | |
46 import dwtx.draw2d.ActionEvent; | |
47 | |
48 /** | |
49 * Provides for the scrollbars used by the {@link ScrollPane}. A ScrollBar is made up of | |
50 * five essential Figures: An 'Up' arrow button, a 'Down' arrow button, a draggable | |
51 * 'Thumb', a 'Pageup' button, and a 'Pagedown' button. | |
52 */ | |
53 public class ScrollBar | |
54 : Figure | |
55 , Orientable, PropertyChangeListener | |
56 { | |
57 | |
58 private static const int ORIENTATION_FLAG = Figure.MAX_FLAG << 1; | |
59 /** @see Figure#MAX_FLAG */ | |
60 protected static const int MAX_FLAG = ORIENTATION_FLAG; | |
61 | |
62 private static const Color COLOR_TRACK; | |
63 static this(){ | |
64 COLOR_TRACK = FigureUtilities.mixColors( | |
65 ColorConstants.white, | |
66 ColorConstants.button); | |
67 } | |
68 | |
69 private RangeModel rangeModel = null; | |
70 private IFigure thumb; | |
71 private Clickable pageUp_, pageDown_; | |
72 private Clickable buttonUp, buttonDown; | |
73 /** | |
74 * Listens to mouse events on the scrollbar to take care of scrolling. | |
75 */ | |
76 protected ThumbDragger thumbDragger; | |
77 | |
78 private bool isHorizontal_ = false; | |
79 | |
80 private int pageIncrement = 50; | |
81 private int stepIncrement = 10; | |
82 | |
83 /** | |
84 * Transposes from vertical to horizontal if needed. | |
85 */ | |
86 protected /+final+/ Transposer transposer; | |
87 | |
88 private void instanceInit(){ | |
89 thumbDragger = new ThumbDragger(); | |
90 transposer = new Transposer(); | |
91 setRangeModel(new DefaultRangeModel()); | |
92 } | |
93 | |
94 /** | |
95 * Constructs a ScrollBar. ScrollBar orientation is vertical by default. Call | |
96 * {@link #setHorizontal(bool)} with <code>true</code> to set horizontal orientation. | |
97 * | |
98 * @since 2.0 | |
99 */ | |
100 public this() { | |
101 instanceInit(); | |
102 initialize(); | |
103 } | |
104 | |
105 /** | |
106 * Creates the default 'Up' ArrowButton for the ScrollBar. | |
107 * | |
108 * @return the up button | |
109 * @since 2.0 | |
110 */ | |
111 protected Clickable createDefaultUpButton() { | |
112 Button buttonUp = new ArrowButton(); | |
113 buttonUp.setBorder(new ButtonBorder(ButtonBorder.SCHEMES.BUTTON_SCROLLBAR)); | |
114 return buttonUp; | |
115 } | |
116 | |
117 /** | |
118 * Creates the default 'Down' ArrowButton for the ScrollBar. | |
119 * | |
120 * @return the down button | |
121 * @since 2.0 | |
122 */ | |
123 protected Clickable createDefaultDownButton() { | |
124 Button buttonDown = new ArrowButton(); | |
125 buttonDown.setBorder(new ButtonBorder(ButtonBorder.SCHEMES.BUTTON_SCROLLBAR)); | |
126 return buttonDown; | |
127 } | |
128 | |
129 /** | |
130 * Creates the pagedown Figure for the Scrollbar. | |
131 * | |
132 * @return the page down figure | |
133 * @since 2.0 | |
134 */ | |
135 protected Clickable createPageDown() { | |
136 return createPageUp(); | |
137 } | |
138 | |
139 /** | |
140 * Creates the pageup Figure for the Scrollbar. | |
141 * | |
142 * @return the page up figure | |
143 * @since 2.0 | |
144 */ | |
145 protected Clickable createPageUp() { | |
146 Clickable clickable = new Clickable(); | |
147 clickable.setOpaque(true); | |
148 clickable.setBackgroundColor(COLOR_TRACK); | |
149 clickable.setRequestFocusEnabled(false); | |
150 clickable.setFocusTraversable(false); | |
151 clickable.addChangeListener( dgChangeListener( (ChangeEvent evt, Clickable clickable_){ | |
152 if (clickable_.getModel().isArmed()) | |
153 clickable_.setBackgroundColor(ColorConstants.black); | |
154 else | |
155 clickable_.setBackgroundColor(COLOR_TRACK); | |
156 }, clickable)); | |
157 return clickable; | |
158 } | |
159 | |
160 /** | |
161 * Creates the Scrollbar's "thumb", the draggable Figure that indicates the Scrollbar's | |
162 * position. | |
163 * | |
164 * @return the thumb figure | |
165 * @since 2.0 | |
166 */ | |
167 protected IFigure createDefaultThumb() { | |
168 Panel thumb = new Panel(); | |
169 thumb.setMinimumSize(new Dimension(6, 6)); | |
170 thumb.setBackgroundColor(ColorConstants.button); | |
171 | |
172 thumb.setBorder(new SchemeBorder(SchemeBorder.SCHEMES.BUTTON_CONTRAST)); | |
173 return thumb; | |
174 } | |
175 | |
176 /** | |
177 * Returns the figure used as the up button. | |
178 * @return the up button | |
179 */ | |
180 protected IFigure getButtonUp() { | |
181 // TODO: The set method takes a Clickable while the get method returns an IFigure. | |
182 // Change the get method to return Clickable (since that's what it's typed as). | |
183 return buttonUp; | |
184 } | |
185 | |
186 /** | |
187 * Returns the figure used as the down button. | |
188 * @return the down button | |
189 */ | |
190 protected IFigure getButtonDown() { | |
191 // TODO: The set method takes a Clickable while the get method returns an IFigure. | |
192 // Change the get method to return Clickable (since that's what it's typed as). | |
193 return buttonDown; | |
194 } | |
195 | |
196 /** | |
197 * Returns the extent. | |
198 * @return the extent | |
199 * @see RangeModel#getExtent() | |
200 */ | |
201 public int getExtent() { | |
202 return getRangeModel().getExtent(); | |
203 } | |
204 | |
205 /** | |
206 * Returns the minumum value. | |
207 * @return the minimum | |
208 * @see RangeModel#getMinimum() | |
209 */ | |
210 public int getMinimum() { | |
211 return getRangeModel().getMinimum(); | |
212 } | |
213 | |
214 /** | |
215 * Returns the maximum value. | |
216 * @return the maximum | |
217 * @see RangeModel#getMaximum() | |
218 */ | |
219 public int getMaximum() { | |
220 return getRangeModel().getMaximum(); | |
221 } | |
222 | |
223 /** | |
224 * Returns the figure used for page down. | |
225 * @return the page down figure | |
226 */ | |
227 protected IFigure getPageDown() { | |
228 // TODO: The set method takes a Clickable while the get method returns an IFigure. | |
229 // Change the get method to return Clickable (since that's what it's typed as). | |
230 return pageDown_; | |
231 } | |
232 | |
233 /** | |
234 * Returns the the amound the scrollbar will move when the page up or page down areas are | |
235 * pressed. | |
236 * @return the page increment | |
237 */ | |
238 public int getPageIncrement() { | |
239 return pageIncrement; | |
240 } | |
241 | |
242 /** | |
243 * Returns the figure used for page up. | |
244 * @return the page up figure | |
245 */ | |
246 protected IFigure getPageUp() { | |
247 // TODO: The set method takes a Clickable while the get method returns an IFigure. | |
248 // Change the get method to return Clickable (since that's what it's typed as). | |
249 return pageUp_; | |
250 } | |
251 | |
252 /** | |
253 * Returns the range model for this scrollbar. | |
254 * @return the range model | |
255 */ | |
256 public RangeModel getRangeModel() { | |
257 return rangeModel; | |
258 } | |
259 | |
260 /** | |
261 * Returns the amount the scrollbar will move when the up or down arrow buttons are | |
262 * pressed. | |
263 * @return the step increment | |
264 */ | |
265 public int getStepIncrement() { | |
266 return stepIncrement; | |
267 } | |
268 | |
269 /** | |
270 * Returns the figure used as the scrollbar's thumb. | |
271 * @return the thumb figure | |
272 */ | |
273 protected IFigure getThumb() { | |
274 return thumb; | |
275 } | |
276 | |
277 /** | |
278 * Returns the current scroll position of the scrollbar. | |
279 * @return the current value | |
280 * @see RangeModel#getValue() | |
281 */ | |
282 public int getValue() { | |
283 return getRangeModel().getValue(); | |
284 } | |
285 | |
286 /** | |
287 * Returns the size of the range of allowable values. | |
288 * @return the value range | |
289 */ | |
290 protected int getValueRange() { | |
291 return getMaximum() - getExtent() - getMinimum(); | |
292 } | |
293 | |
294 /** | |
295 * Initilization of the ScrollBar. Sets the Scrollbar to have a ScrollBarLayout with | |
296 * vertical orientation. Creates the Figures that make up the components of the ScrollBar. | |
297 * | |
298 * @since 2.0 | |
299 */ | |
300 protected void initialize() { | |
301 setLayoutManager(new ScrollBarLayout(transposer)); | |
302 setUpClickable(createDefaultUpButton()); | |
303 setDownClickable(createDefaultDownButton()); | |
304 setPageUp(createPageUp()); | |
305 setPageDown(createPageDown()); | |
306 setThumb(createDefaultThumb()); | |
307 } | |
308 | |
309 /** | |
310 * Returns <code>true</code> if this scrollbar is orientated horizontally, | |
311 * <code>false</code> otherwise. | |
312 * @return whether this scrollbar is horizontal | |
313 */ | |
314 public bool isHorizontal() { | |
315 return isHorizontal_; | |
316 } | |
317 | |
318 private void pageDown() { | |
319 setValue(getValue() + getPageIncrement()); | |
320 } | |
321 | |
322 private void pageUp() { | |
323 setValue(getValue() - getPageIncrement()); | |
324 } | |
325 | |
326 /** | |
327 * @see PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) | |
328 */ | |
329 public void propertyChange(PropertyChangeEvent event) { | |
330 if (null !is cast(RangeModel)event.getSource() ) { | |
331 setEnabled(getRangeModel().isEnabled()); | |
332 if (RangeModel.PROPERTY_VALUE.equals(event.getPropertyName())) { | |
333 firePropertyChange("value", event.getOldValue(), //$NON-NLS-1$ | |
334 event.getNewValue()); | |
335 revalidate(); | |
336 } | |
337 if (RangeModel.PROPERTY_MINIMUM.equals(event.getPropertyName())) { | |
338 firePropertyChange("value", event.getOldValue(), //$NON-NLS-1$ | |
339 event.getNewValue()); | |
340 revalidate(); | |
341 } | |
342 if (RangeModel.PROPERTY_MAXIMUM.equals(event.getPropertyName())) { | |
343 firePropertyChange("value", event.getOldValue(), //$NON-NLS-1$ | |
344 event.getNewValue()); | |
345 revalidate(); | |
346 } | |
347 if (RangeModel.PROPERTY_EXTENT.equals(event.getPropertyName())) { | |
348 firePropertyChange("value", event.getOldValue(), //$NON-NLS-1$ | |
349 event.getNewValue()); | |
350 revalidate(); | |
351 } | |
352 } | |
353 } | |
354 | |
355 /** | |
356 * @see IFigure#revalidate() | |
357 */ | |
358 public void revalidate() { | |
359 // Override default revalidate to prevent going up the parent chain. Reason for this | |
360 // is that preferred size never changes unless orientation changes. | |
361 invalidate(); | |
362 getUpdateManager().addInvalidFigure(this); | |
363 } | |
364 | |
365 /** | |
366 * Does nothing because this doesn't make sense for a scrollbar. | |
367 * @see Orientable#setDirection(int) | |
368 */ | |
369 public void setDirection(int direction) { | |
370 //Doesn't make sense for Scrollbar. | |
371 } | |
372 | |
373 /** | |
374 * Sets the Clickable that represents the down arrow of the Scrollbar to <i>down</i>. | |
375 * | |
376 * @param down the down button | |
377 * @since 2.0 | |
378 */ | |
379 public void setDownClickable(Clickable down) { | |
380 if (buttonDown !is null) { | |
381 remove(buttonDown); | |
382 } | |
383 buttonDown = down; | |
384 if (buttonDown !is null) { | |
385 if (auto b = cast(Orientable)buttonDown ) | |
386 b.setDirection(isHorizontal() | |
387 ? Orientable.EAST | |
388 : Orientable.SOUTH); | |
389 buttonDown.setFiringMethod(Clickable.REPEAT_FIRING); | |
390 buttonDown.addActionListener(dgActionListener( (ActionEvent evt){ | |
391 stepDown(); | |
392 })); | |
393 add(buttonDown, stringcast(ScrollBarLayout.DOWN_ARROW)); | |
394 } | |
395 } | |
396 | |
397 /** | |
398 * Sets the Clickable that represents the up arrow of the Scrollbar to <i>up</i>. | |
399 * | |
400 * @param up the up button | |
401 * @since 2.0 | |
402 */ | |
403 public void setUpClickable(Clickable up) { | |
404 if (buttonUp !is null) { | |
405 remove(buttonUp); | |
406 } | |
407 buttonUp = up; | |
408 if (up !is null) { | |
409 if (auto o = cast(Orientable)up ) | |
410 o.setDirection(isHorizontal() | |
411 ? Orientable.WEST | |
412 : Orientable.NORTH); | |
413 buttonUp.setFiringMethod(Clickable.REPEAT_FIRING); | |
414 buttonUp.addActionListener(dgActionListener( (ActionEvent evt){ | |
415 stepUp(); | |
416 })); | |
417 add(buttonUp, stringcast(ScrollBarLayout.UP_ARROW)); | |
418 } | |
419 } | |
420 | |
421 /** | |
422 * @see IFigure#setEnabled(bool) | |
423 */ | |
424 public void setEnabled(bool value) { | |
425 if (isEnabled() is value) | |
426 return; | |
427 super.setEnabled(value); | |
428 setChildrenEnabled(value); | |
429 if (getThumb() !is null) { | |
430 getThumb().setVisible(value); | |
431 revalidate(); | |
432 } | |
433 } | |
434 | |
435 /** | |
436 * Sets the extent of the Scrollbar to <i>ext</i> | |
437 * | |
438 * @param ext the extent | |
439 * @since 2.0 | |
440 */ | |
441 public void setExtent(int ext) { | |
442 if (getExtent() is ext) | |
443 return; | |
444 getRangeModel().setExtent(ext); | |
445 } | |
446 | |
447 /** | |
448 * Sets the orientation of the ScrollBar. If <code>true</code>, the Scrollbar will have | |
449 * a horizontal orientation. If <code>false</code>, the scrollBar will have a vertical | |
450 * orientation. | |
451 * | |
452 * @param value <code>true</code> if the scrollbar should be horizontal | |
453 * @since 2.0 | |
454 */ | |
455 public final void setHorizontal(bool value) { | |
456 setOrientation(value ? HORIZONTAL : VERTICAL); | |
457 } | |
458 | |
459 /** | |
460 * Sets the maximum position to <i>max</i>. | |
461 * | |
462 * @param max the maximum position | |
463 * @since 2.0 | |
464 */ | |
465 public void setMaximum(int max) { | |
466 if (getMaximum() is max) | |
467 return; | |
468 getRangeModel().setMaximum(max); | |
469 } | |
470 | |
471 /** | |
472 * Sets the minimum position to <i>min</i>. | |
473 * | |
474 * @param min the minumum position | |
475 * @since 2.0 | |
476 */ | |
477 public void setMinimum(int min) { | |
478 if (getMinimum() is min) | |
479 return; | |
480 getRangeModel().setMinimum(min); | |
481 } | |
482 | |
483 /** | |
484 * @see Orientable#setOrientation(int) | |
485 */ | |
486 public void setOrientation(int value) { | |
487 if ((value is HORIZONTAL) is isHorizontal()) | |
488 return; | |
489 isHorizontal_ = value is HORIZONTAL; | |
490 transposer.setEnabled(isHorizontal_); | |
491 | |
492 setChildrenOrientation(value); | |
493 super.revalidate(); | |
494 } | |
495 | |
496 /** | |
497 * Sets the ScrollBar to scroll <i>increment</i> pixels when its pageup or pagedown | |
498 * buttons are pressed. (Note that the pageup and pagedown buttons are <b>NOT</b> the | |
499 * arrow buttons, they are the figures between the arrow buttons and the ScrollBar's | |
500 * thumb figure). | |
501 * | |
502 * @param increment the new page increment | |
503 * @since 2.0 | |
504 */ | |
505 public void setPageIncrement(int increment) { | |
506 pageIncrement = increment; | |
507 } | |
508 | |
509 /** | |
510 * Sets the pagedown button to the passed Clickable. The pagedown button is the figure | |
511 * between the down arrow button and the ScrollBar's thumb figure. | |
512 * | |
513 * @param down the page down figure | |
514 * @since 2.0 | |
515 */ | |
516 public void setPageDown(Clickable down) { | |
517 if (pageDown_ !is null) | |
518 remove(pageDown_); | |
519 pageDown_ = down; | |
520 if (pageDown_ !is null) { | |
521 pageDown_.setFiringMethod(Clickable.REPEAT_FIRING); | |
522 pageDown_.addActionListener(dgActionListener( (ActionEvent evt){ | |
523 pageDown(); | |
524 })); | |
525 add(down,stringcast( ScrollBarLayout.PAGE_DOWN)); | |
526 } | |
527 } | |
528 | |
529 /** | |
530 * Sets the pageup button to the passed Clickable. The pageup button is the rectangular | |
531 * figure between the down arrow button and the ScrollBar's thumb figure. | |
532 * | |
533 * @param up the page up figure | |
534 * @since 2.0 | |
535 */ | |
536 public void setPageUp(Clickable up) { | |
537 if (pageUp_ !is null) | |
538 remove(pageUp_); | |
539 pageUp_ = up; | |
540 if (pageUp_ !is null) { | |
541 pageUp_.setFiringMethod(Clickable.REPEAT_FIRING); | |
542 pageUp_.addActionListener(dgActionListener((ActionEvent evt){ | |
543 pageUp(); | |
544 })); | |
545 add(pageUp_, stringcast(ScrollBarLayout.PAGE_UP)); | |
546 } | |
547 } | |
548 | |
549 /** | |
550 * Sets the ScrollBar's RangeModel to the passed value. | |
551 * | |
552 * @param rangeModel the new range model | |
553 * @since 2.0 | |
554 */ | |
555 public void setRangeModel(RangeModel rangeModel) { | |
556 if (this.rangeModel !is null) | |
557 this.rangeModel.removePropertyChangeListener(this); | |
558 this.rangeModel = rangeModel; | |
559 rangeModel.addPropertyChangeListener(this); | |
560 } | |
561 | |
562 /** | |
563 * Sets the ScrollBar's step increment to the passed value. The step increment indicates | |
564 * how many pixels the ScrollBar will scroll when its up or down arrow button is pressed. | |
565 * | |
566 * @param increment the new step increment | |
567 * @since 2.0 | |
568 */ | |
569 public void setStepIncrement(int increment) { | |
570 stepIncrement = increment; | |
571 } | |
572 | |
573 /** | |
574 * Sets the ScrollBar's thumb to the passed Figure. The thumb is the draggable component | |
575 * of the ScrollBar that indicates the ScrollBar's position. | |
576 * | |
577 * @param figure the thumb figure | |
578 * @since 2.0 | |
579 */ | |
580 public void setThumb(IFigure figure) { | |
581 if (thumb !is null) { | |
582 thumb.removeMouseListener(thumbDragger); | |
583 thumb.removeMouseMotionListener(thumbDragger); | |
584 remove(thumb); | |
585 } | |
586 thumb = figure; | |
587 if (thumb !is null) { | |
588 thumb.addMouseListener(thumbDragger); | |
589 thumb.addMouseMotionListener(thumbDragger); | |
590 add(thumb, stringcast(ScrollBarLayout.THUMB)); | |
591 } | |
592 } | |
593 | |
594 /** | |
595 * Sets the value of the Scrollbar to <i>v</i> | |
596 * | |
597 * @param v the new value | |
598 * @since 2.0 | |
599 */ | |
600 public void setValue(int v) { | |
601 getRangeModel().setValue(v); | |
602 } | |
603 | |
604 /** | |
605 * Causes the ScrollBar to scroll down (or right) by the value of its step increment. | |
606 * | |
607 * @since 2.0 | |
608 */ | |
609 protected void stepDown() { | |
610 setValue(getValue() + getStepIncrement()); | |
611 } | |
612 | |
613 /** | |
614 * Causes the ScrollBar to scroll up (or left) by the value of its step increment. | |
615 * | |
616 * @since 2.0 | |
617 */ | |
618 protected void stepUp() { | |
619 setValue(getValue() - getStepIncrement()); | |
620 } | |
621 | |
622 class ThumbDragger | |
623 : MouseMotionListener.Stub | |
624 , MouseListener | |
625 { | |
626 protected Point start; | |
627 protected int dragRange; | |
628 protected int revertValue; | |
629 protected bool armed; | |
630 public this() { } | |
631 | |
632 public void mousePressed(MouseEvent me) { | |
633 armed = true; | |
634 start = me.getLocation(); | |
635 Rectangle area = new Rectangle(transposer.t(getClientArea())); | |
636 Dimension thumbSize = transposer.t(getThumb().getSize()); | |
637 if (getButtonUp() !is null) | |
638 area.height -= transposer.t(getButtonUp().getSize()).height; | |
639 if (getButtonDown() !is null) | |
640 area.height -= transposer.t(getButtonDown().getSize()).height; | |
641 Dimension sizeDifference = new Dimension(area.width, | |
642 area.height - thumbSize.height); | |
643 dragRange = sizeDifference.height; | |
644 revertValue = getValue(); | |
645 me.consume(); | |
646 } | |
647 | |
648 public void mouseDragged(MouseEvent me) { | |
649 if (!armed) | |
650 return; | |
651 Dimension difference = transposer.t(me.getLocation().getDifference(start)); | |
652 int change = getValueRange() * difference.height / dragRange; | |
653 setValue(revertValue + change); | |
654 me.consume(); | |
655 } | |
656 | |
657 public void mouseReleased(MouseEvent me) { | |
658 if (!armed) | |
659 return; | |
660 armed = false; | |
661 me.consume(); | |
662 } | |
663 | |
664 public void mouseDoubleClicked(MouseEvent me) { } | |
665 } | |
666 | |
667 } |