rev 8703 : RT-40186: Update copyright header for files modified in 2015
1 /*
2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 /*
27 * StubToolkit.java
28 */
29
30 package com.sun.javafx.pgstub;
31
32 import com.sun.glass.ui.CommonDialogs.FileChooserResult;
33 import com.sun.javafx.application.PlatformImpl;
34 import com.sun.javafx.embed.HostInterface;
35 import com.sun.javafx.geom.Path2D;
36 import com.sun.javafx.geom.Shape;
37 import com.sun.javafx.geom.transform.BaseTransform;
38 import com.sun.javafx.menu.MenuBase;
39 import com.sun.javafx.perf.PerformanceTracker;
40 import com.sun.javafx.runtime.async.AsyncOperation;
41 import com.sun.javafx.runtime.async.AsyncOperationListener;
42 import com.sun.javafx.scene.text.HitInfo;
43 import com.sun.javafx.scene.text.TextLayoutFactory;
44 import com.sun.javafx.tk.*;
45 import com.sun.prism.BasicStroke;
46 import com.sun.scenario.DelayedRunnable;
47 import com.sun.scenario.animation.AbstractMasterTimer;
48 import com.sun.scenario.effect.FilterContext;
49 import com.sun.scenario.effect.Filterable;
50 import javafx.application.ConditionalFeature;
51 import javafx.geometry.Dimension2D;
52 import javafx.scene.image.Image;
53 import javafx.scene.input.*;
54 import javafx.scene.paint.Color;
55 import javafx.scene.paint.ImagePattern;
56 import javafx.scene.paint.LinearGradient;
57 import javafx.scene.paint.RadialGradient;
58 import javafx.scene.shape.*;
59 import javafx.stage.FileChooser.ExtensionFilter;
60 import javafx.stage.Modality;
61 import javafx.stage.StageStyle;
62 import javafx.stage.Window;
63 import javafx.util.Pair;
64
65 import java.io.File;
66 import java.io.InputStream;
67 import java.security.AccessControlContext;
68 import java.util.*;
69 import java.util.concurrent.Future;
70
71 /**
72 * A Toolkit implementation for use with Testing.
73 *
74 * @author Richard
75 */
76 public class StubToolkit extends Toolkit {
77
78 private Map<Object, Object> contextMap = new HashMap<Object, Object>();
79
80 private StubMasterTimer masterTimer = new StubMasterTimer();
81
82 private PerformanceTracker performanceTracker = new StubPerformanceTracker();
83
84 private final StubImageLoaderFactory imageLoaderFactory =
85 new StubImageLoaderFactory();
86
87 private CursorSizeConverter cursorSizeConverter =
88 CursorSizeConverter.NO_CURSOR_SUPPORT;
89
90 private int maximumCursorColors = 2;
91
92 private TKScreenConfigurationListener screenConfigurationListener;
93
94 private static final ScreenConfiguration[] DEFAULT_SCREEN_CONFIG = {
95 new ScreenConfiguration(0, 0, 1920, 1200, 0, 0, 1920, 1172, 96)
96 };
97
98 private ScreenConfiguration[] screenConfigurations = DEFAULT_SCREEN_CONFIG;
99
100 static {
101 try {
102 // ugly hack to initialize "runLater" method in Platform.java
103 PlatformImpl.startup(() -> {});
104 } catch (Exception ex) {}
105
106 // allow tests to access PG scenegraph
107 // so that they can run with assertion enabled
108 javafx.scene.Scene.impl_setAllowPGAccess(true);
109 }
110 private boolean pulseRequested;
111
112 /*
113 * overrides of Toolkit's abstract functions
114 */
115
116 @Override
117 public boolean init() {
118 return true;
119 }
120
121 @Override
122 public TKStage createTKStage(Window peerWindow, boolean securityDialog, StageStyle stageStyle, boolean primary, Modality modality, TKStage owner, boolean rtl, AccessControlContext acc) {
123
124 return new StubStage();
125 }
126
127 @Override
128 public TKStage createTKPopupStage(Window peerWindow, StageStyle popupStyle, TKStage owner, AccessControlContext acc) {
129 return new StubPopupStage();
130 }
131
132 @Override
133 public TKStage createTKEmbeddedStage(HostInterface host, AccessControlContext acc) {
134 return new StubStage();
135 }
136
137 @Override
138 public AppletWindow createAppletWindow(long parent, String serverName) {
139 // unsupported
140 return null;
141 }
142
143 @Override
144 public void closeAppletWindow() {
145 // unsupported
146 }
147
148 private final TKSystemMenu systemMenu = new StubSystemMenu();
149 @Override
150 public TKSystemMenu getSystemMenu() {
151 return systemMenu;
152 }
153
154 @Override
155 public void startup(Runnable runnable) {
156 runnable.run();
157 }
158
159 @Override
160 public void checkFxUserThread() {
161 // Do nothing
162 }
163
164 @Override
165 public boolean isFxUserThread() {
166 // Always on the FX app thread
167 return true;
168 }
169
170 @Override
171 public void defer(Runnable runnable) {
172 runnable.run();
173 }
174
175 @Override
176 public void exit() {
177 System.exit(0);
178 }
179
180 @Override
181 public Future addRenderJob(RenderJob rj) {
182 return rj;
183 }
184
185 @Override
186 public Map<Object, Object> getContextMap() {
187 return contextMap;
188 }
189
190 @Override public int getRefreshRate() {
191 return -1;
192 }
193
194 private DelayedRunnable animationRunnable;
195
196 @Override
197 public void setAnimationRunnable(DelayedRunnable animationRunnable) {
198 this.animationRunnable = animationRunnable;
199 }
200
201 @Override
202 public PerformanceTracker getPerformanceTracker() {
203 return performanceTracker;
204 }
205
206 @Override public PerformanceTracker createPerformanceTracker() {
207 return new StubPerformanceTracker();
208 }
209
210 @Override
211 protected Object createColorPaint(Color paint) {
212 return new com.sun.prism.paint.Color((float) paint.getRed(),
213 (float) paint.getGreen(),
214 (float) paint.getBlue(),
215 (float) paint.getOpacity());
216 }
217
218 @Override
219 protected Object createLinearGradientPaint(LinearGradient paint) {
220 // Non functioning but compiles
221 return new com.sun.prism.paint.Color(1, 1, 1, 1);
222 }
223
224 @Override
225 protected Object createRadialGradientPaint(RadialGradient paint) {
226 // Non functioning but compiles
227 return new com.sun.prism.paint.Color(1, 1, 1, 1);
228 }
229
230 @Override
231 protected Object createImagePatternPaint(ImagePattern paint) {
232 // Non functioning but compiles
233 return new com.sun.prism.paint.Color(1, 1, 1, 1);
234 }
235
236 static BasicStroke tmpStroke = new BasicStroke();
237 void initStroke(StrokeType pgtype, double strokewidth,
238 StrokeLineCap pgcap,
239 StrokeLineJoin pgjoin, float miterLimit)
240 {
241 int type;
242 if (pgtype == StrokeType.CENTERED) {
243 type = BasicStroke.TYPE_CENTERED;
244 } else if (pgtype == StrokeType.INSIDE) {
245 type = BasicStroke.TYPE_INNER;
246 } else {
247 type = BasicStroke.TYPE_OUTER;
248 }
249
250 int cap;
251 if (pgcap == StrokeLineCap.BUTT) {
252 cap = BasicStroke.CAP_BUTT;
253 } else if (pgcap == StrokeLineCap.SQUARE) {
254 cap = BasicStroke.CAP_SQUARE;
255 } else {
256 cap = BasicStroke.CAP_ROUND;
257 }
258
259 int join;
260 if (pgjoin == StrokeLineJoin.BEVEL) {
261 join = BasicStroke.JOIN_BEVEL;
262 } else if (pgjoin == StrokeLineJoin.MITER) {
263 join = BasicStroke.JOIN_MITER;
264 } else {
265 join = BasicStroke.JOIN_ROUND;
266 }
267
268 tmpStroke.set(type, (float) strokewidth, cap, join, miterLimit);
269 }
270
271 @Override
272 public void accumulateStrokeBounds(Shape shape, float bbox[],
273 StrokeType pgtype,
274 double strokewidth,
275 StrokeLineCap pgcap,
276 StrokeLineJoin pgjoin,
277 float miterLimit,
278 BaseTransform tx)
279 {
280
281 initStroke(pgtype, strokewidth, pgcap, pgjoin, miterLimit);
282 // TODO: The accumulation could be done directly without creating a Shape
283 Shape.accumulate(bbox, tmpStroke.createStrokedShape(shape), tx);
284 }
285
286 @Override
287 public boolean strokeContains(Shape shape, double x, double y,
288 StrokeType pgtype,
289 double strokewidth,
290 StrokeLineCap pgcap,
291 StrokeLineJoin pgjoin,
292 float miterLimit)
293 {
294 initStroke(pgtype, strokewidth, pgcap, pgjoin, miterLimit);
295 // TODO: The contains testing could be done directly without creating a Shape
296 return tmpStroke.createStrokedShape(shape).contains((float) x, (float) y);
297 }
298
299 @Override
300 public Shape createStrokedShape(Shape shape,
301 StrokeType pgtype,
302 double strokewidth,
303 StrokeLineCap pgcap,
304 StrokeLineJoin pgjoin,
305 float miterLimit,
306 float[] dashArray,
307 float dashOffset) {
308 initStroke(pgtype, strokewidth, pgcap, pgjoin, miterLimit);
309 return tmpStroke.createStrokedShape(shape);
310 }
311
312 public CursorSizeConverter getCursorSizeConverter() {
313 return cursorSizeConverter;
314 }
315
316 public void setCursorSizeConverter(
317 CursorSizeConverter cursorSizeConverter) {
318 this.cursorSizeConverter = cursorSizeConverter;
319 }
320
321 @Override
322 public Dimension2D getBestCursorSize(int preferredWidth, int preferredHeight) {
323 return cursorSizeConverter.getBestCursorSize(preferredWidth,
324 preferredHeight);
325 }
326
327 @Override
328 public int getMaximumCursorColors() {
329 return maximumCursorColors;
330 }
331
332 public void setMaximumCursorColors(int maximumCursorColors) {
333 this.maximumCursorColors = maximumCursorColors;
334 }
335
336 @Override
337 public AbstractMasterTimer getMasterTimer() {
338 return masterTimer;
339 }
340
341 @Override
342 public FontLoader getFontLoader() {
343 return new StubFontLoader();
344 }
345
346 @Override
347 public TextLayoutFactory getTextLayoutFactory() {
348 return new StubTextLayoutFactory();
349 }
350
351 @Override public boolean isSupported(ConditionalFeature feature) {
352 if (feature == ConditionalFeature.SCENE3D) {
353 return true;
354 } else if (feature == ConditionalFeature.TRANSPARENT_WINDOW) {
355 return true;
356 }
357 return false;
358 }
359
360 /*
361 * additional testing functions
362 */
363 public void fireTestPulse() {
364 firePulse();
365 }
366
367 public boolean isPulseRequested() {
368 return pulseRequested;
369 }
370
371 public void clearPulseRequested() {
372 pulseRequested = false;
373 }
374
375 // do nothing -- bringing in FrameJob and MasterTimer also bring in
376 // Settings and crap which isn't setup for the testing stuff because
377 // we don't run through a RuntimeProvider or do normal startup
378 // public @Override public void triggerNextPulse():Void { }
379 @Override public void requestNextPulse() {
380 pulseRequested = true;
381 }
382
383 private TKClipboard clipboard = new TKClipboard() {
384 private Map<DataFormat, Object> map = new HashMap<DataFormat, Object>();
385 private Image image;
386 private double offsetX;
387 private double offsetY;
388
389 @Override
390 public void setSecurityContext(AccessControlContext ctx) {
391 }
392
393 @Override public Set<DataFormat> getContentTypes() {
394 return map.keySet();
395 }
396
397 @Override public boolean putContent(Pair<DataFormat, Object>... content) {
398 boolean good;
399 for (Pair<DataFormat,Object> pair : content) {
400 good = map.put(pair.getKey(), pair.getValue()) == pair.getValue();
401 if (!good) return false;
402 }
403 return true;
404 }
405
406 @Override public Object getContent(DataFormat dataFormat) {
407 return map.get(dataFormat);
408 }
409
410 @Override public boolean hasContent(DataFormat dataFormat) {
411 return map.containsKey(dataFormat);
412 }
413
414 @Override public Set<TransferMode> getTransferModes() {
415 Set<TransferMode> modes = new HashSet<TransferMode>();
416 modes.add(TransferMode.COPY);
417 return modes;
418 }
419
420 @Override
421 public void setDragView(Image image) {
422 this.image = image;
423 }
424
425 @Override
426 public void setDragViewOffsetX(double offsetX) {
427 this.offsetX = offsetX;
428 }
429
430 @Override
431 public void setDragViewOffsetY(double offsetY) {
432 this.offsetY = offsetY;
433 }
434
435 @Override
436 public Image getDragView() {
437 return image;
438 }
439
440 @Override
441 public double getDragViewOffsetX() {
442 return offsetX;
443 }
444
445 @Override
446 public double getDragViewOffsetY() {
447 return offsetY;
448 }
449 };
450
451
452 @Override
453 public TKClipboard getSystemClipboard() {
454 return clipboard;
455 }
456
457 @Override public TKClipboard getNamedClipboard(String name) {
458 return null;
459 }
460
461 public static TKClipboard createDragboard() {
462 StubToolkit tk = (StubToolkit)Toolkit.getToolkit();
463 if (tk.dndDelegate != null) {
464 return tk.dndDelegate.createDragboard();
465 }
466 return null;
467 }
468
469 @Override
470 public void enableDrop(TKScene s, TKDropTargetListener l) {
471 if (dndDelegate != null) {
472 dndDelegate.enableDrop(l);
473 }
474 }
475
476 private ScreenConfigurationAccessor accessor = new ScreenConfigurationAccessor() {
477 @Override
478 public int getMinX(Object obj) {
479 return ((ScreenConfiguration) obj).getMinX();
480 }
481
482 @Override
483 public int getMinY(Object obj) {
484 return ((ScreenConfiguration) obj).getMinY();
485 }
486
487 @Override
488 public int getWidth(Object obj) {
489 return ((ScreenConfiguration) obj).getWidth();
490 }
491
492 @Override
493 public int getHeight(Object obj) {
494 return ((ScreenConfiguration) obj).getHeight();
495 }
496
497 @Override
498 public int getVisualMinX(Object obj) {
499 return ((ScreenConfiguration) obj).getVisualMinX();
500 }
501
502 @Override
503 public int getVisualMinY(Object obj) {
504 return ((ScreenConfiguration) obj).getVisualMinY();
505 }
506
507 @Override
508 public int getVisualWidth(Object obj) {
509 return ((ScreenConfiguration) obj).getVisualWidth();
510 }
511
512 @Override
513 public int getVisualHeight(Object obj) {
514 return ((ScreenConfiguration) obj).getVisualHeight();
515 }
516
517 @Override
518 public float getDPI(Object obj) {
519 return ((ScreenConfiguration) obj).getDPI();
520 }
521
522 @Override
523 public float getScale(Object obj) {
524 return ((ScreenConfiguration) obj).getScale();
525 }
526 };
527
528 @Override
529 public ScreenConfigurationAccessor setScreenConfigurationListener(
530 TKScreenConfigurationListener listener) {
531 screenConfigurationListener = listener;
532 return accessor;
533 }
534
535 @Override
536 public ScreenConfiguration getPrimaryScreen() {
537 return screenConfigurations[0];
538 }
539
540 public void setScreens(ScreenConfiguration... screenConfigurations) {
541 this.screenConfigurations = screenConfigurations.clone();
542 if (screenConfigurationListener != null) {
543 screenConfigurationListener.screenConfigurationChanged();
544 }
545 }
546
547 public void resetScreens() {
548 setScreens(DEFAULT_SCREEN_CONFIG);
549 }
550
551 @Override
552 public List<ScreenConfiguration> getScreens() {
553 return Arrays.asList(screenConfigurations);
554 }
555
556 @Override
557 public ScreenConfigurationAccessor getScreenConfigurationAccessor() {
558 return accessor;
559 }
560
561 @Override public void registerDragGestureListener(TKScene s, Set<TransferMode> tm, TKDragGestureListener l) {
562 if (dndDelegate != null) {
563 dndDelegate.registerListener(l);
564 }
565 }
566
567 @Override public void startDrag(TKScene scene, Set<TransferMode> tm, TKDragSourceListener l, Dragboard dragboard) {
568 if (dndDelegate != null) {
569 dndDelegate.startDrag(scene, tm, l, dragboard);
570 }
571 }
572
573 @Override
574 public ImageLoader loadImage(String url, int width, int height,
575 boolean preserveRatio, boolean smooth) {
576 return imageLoaderFactory.createImageLoader(url, width, height,
577 preserveRatio, smooth);
578 }
579
580 @Override
581 public ImageLoader loadImage(InputStream stream, int width, int height,
582 boolean preserveRatio, boolean smooth) {
583 return imageLoaderFactory.createImageLoader(stream, width, height,
584 preserveRatio, smooth);
585 }
586
587 @Override
588 public AsyncOperation loadImageAsync(
589 AsyncOperationListener listener, String url, int width, int height,
590 boolean preserveRatio, boolean smooth) {
591 return imageLoaderFactory.createAsyncImageLoader(
592 listener, url, width, height, preserveRatio, smooth);
593 }
594
595 @Override
596 public ImageLoader loadPlatformImage(Object platformImage) {
597 return imageLoaderFactory.createImageLoader(platformImage,
598 0, 0, false, false);
599 }
600
601 @Override
602 public PlatformImage createPlatformImage(int w, int h) {
603 PlatformImage image = new StubWritablePlatformImage(w, h);
604 imageLoaderFactory.registerImage(image, new StubPlatformImageInfo(w, h));
605 return image;
606 }
607
608 @Override
609 public void waitFor(Task t) {
610 throw new UnsupportedOperationException();
611 }
612
613 @Override
614 public int getKeyCodeForChar(String character) {
615 if (charToKeyCodeMap != null) {
616 final KeyCode keyCode = charToKeyCodeMap.get(character);
617 if (keyCode != null) {
618 return keyCode.impl_getCode();
619 }
620 }
621
622 return 0;
623 }
624
625 @Override
626 public PathElement[] convertShapeToFXPath(Object shape) {
627 // Had to be mocked up for TextField tests (for the caret!)
628 // Since the "shape" could be anything, I'm just returning
629 // something here, doesn't matter what.
630 return new PathElement[0];
631 }
632
633 @Override
634 public HitInfo convertHitInfoToFX(Object hit) {
635 return (HitInfo) hit;
636 }
637
638 @Override
639 public Filterable toFilterable(Image img) {
640 return StubFilterable.create((StubPlatformImage)img.impl_getPlatformImage());
641 }
642
643 @Override
644 public FilterContext getFilterContext(Object config) {
645 throw new UnsupportedOperationException();
646 }
647
648 @Override
649 public boolean isForwardTraversalKey(KeyEvent e) {
650 throw new UnsupportedOperationException();
651 }
652
653 @Override
654 public boolean isBackwardTraversalKey(KeyEvent e) {
655 throw new UnsupportedOperationException();
656 }
657
658 @Override
659 public Object createSVGPathObject(SVGPath svgpath) {
660 int windingRule = (svgpath.getFillRule() == FillRule.NON_ZERO) ?
661 Path2D.WIND_NON_ZERO : Path2D.WIND_EVEN_ODD;
662
663 return new SVGPathImpl(svgpath.getContent(), windingRule);
664 }
665
666 @Override
667 public Path2D createSVGPath2D(SVGPath svgpath) {
668 int windingRule = (svgpath.getFillRule() == FillRule.NON_ZERO) ?
669 Path2D.WIND_NON_ZERO : Path2D.WIND_EVEN_ODD;
670
671 return new SVGPathImpl(svgpath.getContent(), windingRule);
672 }
673
674 @Override
675 public boolean imageContains(Object image, float x, float y) {
676 return ((StubPlatformImage) image).getImageInfo()
677 .contains((int) x, (int) y);
678 }
679
680 public void setCurrentTime(long millis) {
681 masterTimer.setCurrentTime(millis);
682 }
683
684 public void handleAnimation() {
685 if (animationRunnable != null) {
686 try {
687 animationRunnable.run();
688 } catch (Throwable t) {
689 t.printStackTrace();
690 }
691 }
692 }
693
694 public StubImageLoaderFactory getImageLoaderFactory() {
695 return imageLoaderFactory;
696 }
697
698 public void setAnimationTime(final long millis) {
699 setCurrentTime(millis);
700 handleAnimation();
701 fireTestPulse();
702 }
703
704 @Override
705 public void installInputMethodRequests(TKScene scene, InputMethodRequests requests) {
706 // just do nothing here.
707 }
708
709 private Map<String, KeyCode> charToKeyCodeMap;
710
711 public void setCharToKeyCodeMap(Map<String, KeyCode> charToKeyCodeMap) {
712 this.charToKeyCodeMap = charToKeyCodeMap;
713 }
714
715 @Override
716 public Object renderToImage(ImageRenderingContext context) {
717 throw new UnsupportedOperationException();
718 }
719
720 @Override public Object enterNestedEventLoop(Object key) {
721 throw new UnsupportedOperationException("Not supported yet.");
722 }
723
724 @Override public void exitNestedEventLoop(Object key, Object rval) {
725 throw new UnsupportedOperationException("Not supported yet.");
726 }
727
728 @Override
729 public boolean isNestedLoopRunning() {
730 return false;
731 }
732
733 private KeyCode platformShortcutKey = KeyCode.SHORTCUT;
734
735 public void setPlatformShortcutKey(final KeyCode platformShortcutKey) {
736 this.platformShortcutKey = platformShortcutKey;
737 }
738
739 public KeyCode getPlatformShortcutKey() {
740 return platformShortcutKey;
741 }
742
743 private DndDelegate dndDelegate;
744 public void setDndDelegate(DndDelegate dndDelegate) {
745 this.dndDelegate = dndDelegate;
746 }
747
748
749 public interface DndDelegate {
750 void startDrag(TKScene scene, Set<TransferMode> tm,
751 TKDragSourceListener l, Dragboard dragboard);
752
753 TKClipboard createDragboard();
754
755 DragEvent convertDragEventToFx(Object event, Dragboard dragboard);
756
757 void registerListener(TKDragGestureListener l);
758
759 void enableDrop(TKDropTargetListener l);
760 }
761
762 public interface CommonDialogsSupport {
763 FileChooserResult showFileChooser(TKStage ownerWindow,
764 String title,
765 File initialDirectory,
766 String initialFileName,
767 FileChooserType fileChooserType,
768 List<ExtensionFilter> extensionFilters,
769 ExtensionFilter selectedFilter);
770
771 File showDirectoryChooser(TKStage ownerWindow,
772 String title,
773 File initialDirectory);
774 }
775
776 private CommonDialogsSupport commonDialogsSupport;
777 public void setCommonDialogsSupport(
778 final CommonDialogsSupport commonDialogsSupport) {
779 this.commonDialogsSupport = commonDialogsSupport;
780 }
781
782 @Override
783 public FileChooserResult showFileChooser(TKStage ownerWindow,
784 String title,
785 File initialDirectory,
786 String initialFileName,
787 FileChooserType fileChooserType,
788 List<ExtensionFilter> extensionFilters,
789 ExtensionFilter selectedFilter) {
790 return commonDialogsSupport.showFileChooser(
791 ownerWindow,
792 title,
793 initialDirectory,
794 initialFileName,
795 fileChooserType,
796 extensionFilters,
797 selectedFilter);
798 }
799
800
801 @Override
802 public File showDirectoryChooser(TKStage ownerWindow,
803 String title,
804 File initialDirectory) {
805 return commonDialogsSupport.showDirectoryChooser(
806 ownerWindow,
807 title,
808 initialDirectory);
809 }
810
811 @Override
812 public long getMultiClickTime() {
813 return 500L;
814 }
815
816 @Override
817 public int getMultiClickMaxX() {
818 return 5;
819 }
820
821 @Override
822 public int getMultiClickMaxY() {
823 return 5;
824 }
825
826 public static final class ScreenConfiguration {
827 private final int minX;
828 private final int minY;
829 private final int width;
830 private final int height;
831 private final int visualMinX;
832 private final int visualMinY;
833 private final int visualWidth;
834 private final int visualHeight;
835 private final float dpi;
836 private final float scale;
837
838 public ScreenConfiguration(final int minX, final int minY,
839 final int width, final int height,
840 final int visualMinX,
841 final int visualMinY,
842 final int visualWidth,
843 final int visualHeight,
844 final float dpi) {
845 this.minX = minX;
846 this.minY = minY;
847 this.width = width;
848 this.height = height;
849 this.visualMinX = visualMinX;
850 this.visualMinY = visualMinY;
851 this.visualWidth = visualWidth;
852 this.visualHeight = visualHeight;
853 this.dpi = dpi;
854 this.scale = 1; // TODO: add a constructor that takes scale
855 }
856
857 public int getMinX() {
858 return minX;
859 }
860
861 public int getMinY() {
862 return minY;
863 }
864
865 public int getWidth() {
866 return width;
867 }
868
869 public int getHeight() {
870 return height;
871 }
872
873 public int getVisualMinX() {
874 return visualMinX;
875 }
876
877 public int getVisualMinY() {
878 return visualMinY;
879 }
880
881 public int getVisualWidth() {
882 return visualWidth;
883 }
884
885 public int getVisualHeight() {
886 return visualHeight;
887 }
888
889 public float getDPI() {
890 return dpi;
891 }
892
893 public float getScale() {
894 return scale;
895 }
896 }
897
898 public static class StubSystemMenu implements TKSystemMenu {
899
900 private List<MenuBase> menus = null;
901
902 @Override
903 public boolean isSupported() {
904 // Although not all platforms have a system menu, the only real
905 // interaction with the system menu is this TKSystemMenu instance
906 // so we'll return true on all platforms.
907 return true;
908 // final String os = System.getProperty("os.name");
909 // return (os != null && os.startsWith("Mac"));
910 }
911
912 @Override
913 public void setMenus(List<MenuBase> menus) {
914 this.menus = menus;
915 }
916
917 // make menus accessible to unit tests
918 public List<MenuBase> getMenus() {
919 return menus;
920 }
921
922 }
923 }
--- EOF ---