View Javadoc

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 }