001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.content.slideshow; 031 032import java.awt.GraphicsDevice; 033import java.awt.GraphicsEnvironment; 034import java.awt.Window; 035import java.lang.reflect.Method; 036 037import javax.swing.JFrame; 038 039import org.apache.commons.lang.SystemUtils; 040 041/** 042 * Utility class for dealing with fullscreen Swing applications. 043 * 044 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 045 * 046 */ 047public class FullscreenUtility { 048 protected JFrame window; 049 protected boolean fullscreen = false; 050 051 /** 052 * Construct with the given JFrame. The utility will allow the frame to be 053 * toggled between windowed and fullscreen mode. 054 * 055 * @param frame 056 * The frame. 057 */ 058 public FullscreenUtility(JFrame frame) { 059 this.window = frame; 060 061 if (SystemUtils.IS_OS_MAC_OSX) { 062 // if we're on a mac, we'll add the fullscreen hint to the window so 063 // the standard controls work 064 try { 065 final Class<?> util = Class.forName("com.apple.eawt.FullScreenUtilities"); 066 final Class<?> params[] = new Class[] { Window.class, Boolean.TYPE }; 067 final Method method = util.getMethod("setWindowCanFullScreen", params); 068 069 method.invoke(util, window, true); 070 } catch (final Exception e) { 071 // ignore 072 } 073 } 074 } 075 076 /** 077 * Method allows changing whether this window is displayed in fullscreen or 078 * windowed mode. 079 * 080 * @param fullscreen 081 * true = change to fullscreen, false = change to windowed 082 */ 083 public void setFullscreen(boolean fullscreen) { 084 if (this.fullscreen != fullscreen) { 085 if (SystemUtils.IS_OS_MAC_OSX) { 086 setFullscreenOSX(fullscreen); 087 } else { 088 setFullscreenAWT(fullscreen); 089 } 090 } 091 } 092 093 // See https://bugs.openjdk.java.net/browse/JDK-8013547 094 // basically AWT fullscreen has big problems (with comboboxes and 095 // keylisteners) on OSX with Java 7 & 8 (and maybe later versions of 6). 096 // We'll try and use the EAWT fullscreen stuff if possible and fall back if 097 // not... 098 private void setFullscreenOSX(boolean fullscreen) { 099 // 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}