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 }