1 /**
2 * Copyright (c) 2011, The University of Southampton and the individual contributors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * * Neither the name of the University of Southampton nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 package org.openimaj.content.slideshow;
31
32 import java.awt.GraphicsDevice;
33 import java.awt.GraphicsEnvironment;
34 import java.awt.Window;
35 import java.lang.reflect.Method;
36
37 import javax.swing.JFrame;
38
39 import org.apache.commons.lang.SystemUtils;
40
41 /**
42 * Utility class for dealing with fullscreen Swing applications.
43 *
44 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
45 *
46 */
47 public class FullscreenUtility {
48 protected JFrame window;
49 protected boolean fullscreen = false;
50
51 /**
52 * Construct with the given JFrame. The utility will allow the frame to be
53 * toggled between windowed and fullscreen mode.
54 *
55 * @param frame
56 * The frame.
57 */
58 public FullscreenUtility(JFrame frame) {
59 this.window = frame;
60
61 if (SystemUtils.IS_OS_MAC_OSX) {
62 // if we're on a mac, we'll add the fullscreen hint to the window so
63 // the standard controls work
64 try {
65 final Class<?> util = Class.forName("com.apple.eawt.FullScreenUtilities");
66 final Class<?> params[] = new Class[] { Window.class, Boolean.TYPE };
67 final Method method = util.getMethod("setWindowCanFullScreen", params);
68
69 method.invoke(util, window, true);
70 } catch (final Exception e) {
71 // ignore
72 }
73 }
74 }
75
76 /**
77 * Method allows changing whether this window is displayed in fullscreen or
78 * windowed mode.
79 *
80 * @param fullscreen
81 * true = change to fullscreen, false = change to windowed
82 */
83 public void setFullscreen(boolean fullscreen) {
84 if (this.fullscreen != fullscreen) {
85 if (SystemUtils.IS_OS_MAC_OSX) {
86 setFullscreenOSX(fullscreen);
87 } else {
88 setFullscreenAWT(fullscreen);
89 }
90 }
91 }
92
93 // See https://bugs.openjdk.java.net/browse/JDK-8013547
94 // basically AWT fullscreen has big problems (with comboboxes and
95 // keylisteners) on OSX with Java 7 & 8 (and maybe later versions of 6).
96 // We'll try and use the EAWT fullscreen stuff if possible and fall back if
97 // not...
98 private void setFullscreenOSX(boolean fullscreen) {
99 // change modes
100 this.fullscreen = fullscreen;
101
102 try {
103 final Class<?> appClz = Class.forName("com.apple.eawt.Application");
104 final Method getApp = appClz.getMethod("getApplication");
105 final Object app = getApp.invoke(appClz);
106 final Class<?> params[] = new Class[] { Window.class };
107 final Method reqFS = appClz.getMethod("requestToggleFullScreen", params);
108 reqFS.invoke(app, window);
109 } catch (final ClassNotFoundException e1) {
110 } catch (final Exception e) {
111 // revert mode change
112 this.fullscreen = !fullscreen;
113 setFullscreenAWT(fullscreen);
114 }
115 }
116
117 private void setFullscreenAWT(boolean fullscreen)
118 {
119 // get a reference to the device.
120 final GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
121
122 // change modes.
123 this.fullscreen = fullscreen;
124 // toggle fullscreen mode
125 if (!fullscreen)
126 {
127 // hide the frame so we can change it.
128 window.setVisible(false);
129 // remove the frame from being displayable.
130 window.dispose();
131 // put the borders back on the frame.
132 window.setUndecorated(false);
133 // needed to unset this window as the fullscreen window.
134 device.setFullScreenWindow(null);
135 // recenter window
136 window.setLocationRelativeTo(null);
137 window.setResizable(true);
138
139 // reset the display mode to what it was before
140 // we changed it.
141 window.setVisible(true);
142 }
143 else
144 { // change to fullscreen.
145 // hide everything
146 window.setVisible(false);
147 // remove the frame from being displayable.
148 window.dispose();
149 // remove borders around the frame
150 window.setUndecorated(true);
151 // attempt to change the screen resolution.
152 window.setResizable(false);
153 window.setAlwaysOnTop(false);
154 // make the window fullscreen.
155 device.setFullScreenWindow(window);
156
157 if (SystemUtils.IS_JAVA_1_7 && SystemUtils.IS_OS_MAC_OSX) {
158 System.err.println("Applying first responder fix");
159 // OSX first responder bug:
160 // http://mail.openjdk.java.net/pipermail/macosx-port-dev/2012-November/005109.html
161 // unfortunately this might not be a complete fix...
162 window.setVisible(false);
163 }
164 // show the frame
165 window.setVisible(true);
166 }
167 // make sure that the screen is refreshed.
168 window.repaint();
169 }
170 }