package psychWithJava;
/*
* Final version: FullScreen.java
*
* currently final is based
* on FullScreen3 from ch10.
*
*
* 38+ methods
*
* hb, 06.06.02+
*
* FullScreen is a class, which contains methods to present stimuli to observers
* and get their behavioral responses in a psychophysics experiment. Requires
* JRE 1.5+.
*
* Copyright (C) 2005-2006 Huseyin Boyaci
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version. This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details. (http://www.gnu.org) You
* should have received a copy of the GNU General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place -
* Suite 330, Boston, MA 02111-1307, USA.
*
*/
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
/**
* FullScreen
class provides methods to display visual stimuli
* and interact with the observer in full screen exclusive mode (FSEM).
*
* FullScreen
is capable of chosing the best available mode and
* strategy on a particular software (OS) and hardware. By default the
* user does not
* have to change any of these strategies. However it provides
* methods for expert users who wish to modify those strategies. Requires Java
* SE 6.0 or higher.
*
* Methods provided include: displayImage()
to display images,
* displayText()
to display text, and
* getKeyPressed()
to get observer's keyboard responses. Because it
* is inherited from the Java core class JFrame
, all its methods
* are also available, such as setForeground()
.
*
* See * Psychophysics Programming with Java * for more information and sample demo programs. *
* FullScreen
class utilizes the
* Full screen exclusive mode (FSEM), a feature of Java (after J2SE 1.4)
* that allows
* programmers to suspend the windowing system of the underlying OS, and
* directly access the video card and draw on the screen. If exclusive full
* screen is not supported a regular window is positioned at (0,0) and resized
* to fit the whole screen to mimic full screen exclusive mode. Whether in full
* screen exclusive mode or not, FullScreen
usues active
* rendering as opposed to passive rendering - in passive rendering the
* underlying OS may intervene and send directives to the rendering program,
* whereas in active rendering the program itself is responsible of drawing and
* re-drawing the contents on the screen without the intervention of
* OS's directives.
*
* For more details, developers can see JSE API definitions at http://java.sun.com. See also * * Java 2D API, * * Full-Screen Exclusive Mode API tutorial, * Programmer's Guide to the Java 2D API, * * Painting in AWT and Swing, * * Trail: 2D Graphics, and * Java 2D new features in J2SE 5.0. *
* Note: Java 2D API (and rest of the entire platform) is improved with JSE 5.0,
* and the FullScreen
requires at least edition 6.0.
* Java SE 6.0 is available on all
* platforms (Linux, Mac OS X (only Tiger and later), and MS Windows).
*
* Note: Real full screen exclusive mode is not supported on Linux in Java SE
* 5.0, but it simulates the exclusive mode. However this situation is fixed
* in edition 6. Now FSEM
* on Linux works fine especially with opengl pipeline enabled.
* To enable opengl pipeline user must specify the following
* system property on the command line:
* -Dsun.java2d.opengl=True
. More information is available
* at Psychophysics programming with Java.
*
* Matlab and Mathematica development:
*
* If the specified wait time is
* positive: This method either (i) returns the top element in the
* keyTyped queue immediately if there is
* at least one element in the keyTyped event queue or
* (ii) waits up to the specified amount of time for an element
* to become available. If no key is typed
* within the specified amount of time
* it returns null.
*
* If the specified time is zero: Returns the top element in
* the keyTyped event queue or null if queue is empty.
*
* If the specified wait time is negative: This method
* either returns the top element in the queue or if the queue is
* empty it waits indefinetely untill the observer types a character.
*
* In all cases, the element returned is removed from the event queue.
*
*
* General principles of event handling in FullScreen:
* FullScreen captures the key events in a seperate Thread and stores
* them in Thread safe BlockingQueue objects. Anytime observer
* types, presses or releases a key, that key and the time of the
* event are inserted to the end (tail)
* of the respective queues. When one of the getKeyTyped(), getKeyPressed()
* or getKeyReleased() methods is invoked, the top (head) of the respective
* queue is retrived and removed. Similarly, getWhenKeyTyped(),
* getWhenKeyPressed() and getWhenKeyReleased() methods retrive and remove
* the head in event time queues. flushKeyTyped(), flushKeyPressed() and
* flushKeyReleased() methods clear all queues, including the event time queues.
*
* For more information and examples see
* Psychophysics programming with Java.
*
* @param ms time in milliseconds to wait for a response
*
* @return the key typed
*
* @see #getKeyTyped()
* @see #flushKeyTyped()
* @see #getWhenKeyTyped()
*/
public String getKeyTyped(long ms) {
String c = null;
try {
if (ms < 0)
c = keyTyped.take();
else
c = keyTyped.poll(ms, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
return c;
}
/**
* Returns the key typed by the observer.
* Returns the top element in keyTyped
* queue or null if queue is empty. Equivelent to invoking getKeyTyped(0).
*
* The element returned is removed from the event queue. See also
* general principles of event handling in FullScreen
* above.
*
* For more information and examples see
* Psychophysics programming with Java.
*
* @return the key typed
*
* @see #getKeyTyped(long)
* @see #flushKeyTyped()
* @see #getWhenKeyTyped()
*/
public String getKeyTyped() {
return keyTyped.poll();
}
/**
* Returns the time of the key typed event.
* Returns the top element in the whenKeyTyped queue,
* null if queue is empty.
*
* The element returned is removed from the event queue. See also
* general principles of event handling in FullScreen
* above.
*
* For more information see
* Psychophysics programming with Java.
*
* @return the time of key typed event
*
* @see #getKeyTyped(long)
* @see #flushKeyTyped()
*/
public Long getWhenKeyTyped() {
return whenKeyTyped.poll();
}
/**
* Clears both keyTyped and whenKeyTyped queues. See also
* general principles of event handling in FullScreen
* above.
*
* For more information and examples see
* Psychophysics programming with Java.
*
* @see #getKeyTyped(long)
* @see #getWhenKeyTyped()
*/
public void flushKeyTyped() {
keyTyped.clear();
whenKeyTyped.clear();
}
/**
* Returns the key pressed by the observer within a specified amount of time.
*
* If the specified wait time is
* positive: This method either (i) returns the top element in the
* keyPressed queue immediately if there is
* at least one element in the keyPressed event queue or
* (ii) waits up to the specified amount of time for an element
* to become available. If no key is pressed
* within the specified amount of time
* it returns null.
*
* If the specified time is zero: Returns the top element in
* the keyPressed event queue or null if queue is empty.
*
* If the specified wait time is negative: This method
* either returns the top element in the queue or if the queue is
* empty it waits indefinetely untill the observer presses a key.
*
* In all cases, the element returned is removed from the event queue.
* See also
* general principles of event handling in FullScreen
* above.
*
* For more information and examples see
* Psychophysics programming with Java.
*
* @param ms time in milliseconds to wait for a response
*
* @return numeric code of the key pressed
*
* @see #getKeyPressed()
* @see #flushKeyPressed
* @see #getWhenKeyPressed()
*/
public Integer getKeyPressed(long ms) {
Integer c = null;
try {
if (ms < 0)
c = keyPressed.take();
else
c = keyPressed.poll(ms, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
return c;
}
/**
* Returns the key pressed by the observer.
* Returns the top element in keyPressed
* queue or null if queue is empty. Equivelent to invoking getKeyPressed(0).
*
* The element returned is removed from the event queue. See also
* general principles of event handling in FullScreen
* above.
*
* For more information and examples see
* Psychophysics programming with Java.
*
* @return numeric code of the key pressed
*
* @see #getKeyPressed(long)
* @see #flushKeyPressed()
* @see #getWhenKeyPressed()
*/
public Integer getKeyPressed() {
return keyPressed.poll();
}
/**
* Returns the time of the key pressed event.
* Returns the top element in the whenKeyPressed queue,
* null if queue is empty.
*
* The element returned is removed from the event queue. See also
* general principles of event handling in FullScreen
* above.
*
* For more information and examples see
* Psychophysics programming with Java.
*
* @return the time of key pressed event
*
* @see #getKeyPressed(long)
* @see #flushKeyPressed()
*/
public Long getWhenKeyPressed() {
return whenKeyPressed.poll();
}
/**
* Clears both key pressed and when key pressed queues.
* See also
* general principles of event handling in FullScreen
* above.
*
* For more information and examples see
* Psychophysics programming with Java.
*
* @see #getKeyPressed(long)
* @see #getWhenKeyPressed()
*/
public void flushKeyPressed() {
keyPressed.clear();
whenKeyPressed.clear();
}
/**
* Returns the key released by the observer within a specified amount of time.
*
* If the specified wait time is
* positive: This method either (i) returns the top element in the
* keyReleased queue immediately if there is
* at least one element in the keyReleased event queue or
* (ii) waits up to the specified amount of time for an element
* to become available. If no key is released
* within the specified amount of time
* it returns null.
*
* If the specified time is zero: Returns the top element in
* the keyReleased event queue or null if queue is empty.
*
* If the specified wait time is negative: This method
* either returns the top element in the queue or if the queue is
* empty it waits indefinetely untill the observer releases a key.
*
* In all cases, the element returned is removed from the event queue.
* See also
* general principles of event handling in FullScreen
* above.
*
* For more information and examples see
* Psychophysics programming with Java.
*
* @param ms time in milliseconds to wait for a response
*
* @return numerical code of the key released
*
* @see #getKeyReleased()
* @see #flushKeyReleased
* @see #getWhenKeyReleased()
*/
public Integer getKeyReleased(long ms) {
Integer c = null;
try {
if (ms < 0)
c = keyReleased.take();
else
c = keyReleased.poll(ms, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
return c;
}
/**
* Returns the key released by the observer.
* Returns the top element in keyReleased
* queue or null if queue is empty. Equivelent to invoking getKeyReleased(0).
*
* The element returned is removed from the event queue. See also
* general principles of event handling in FullScreen
* above.
*
* For more information and examples see
* Psychophysics programming with Java.
*
* @return numerical code of the key released
*
* @see #getKeyReleased(long)
* @see #flushKeyReleased()
* @see #getWhenKeyReleased()
*/
public Integer getKeyReleased() {
return keyReleased.poll();
}
/**
* Returns the time of the key released event.
* Returns the top element in the whenKeyReleased queue,
* null if queue is empty.
*
* The element returned is removed from the event queue. See also
* general principles of event handling in FullScreen
* above.
*
* For more information and examples see
* Psychophysics programming with Java.
*
* @return the time of key released event
*
* @see #getKeyReleased(long)
* @see #flushKeyReleased()
*/
public Long getWhenKeyReleased() {
return whenKeyReleased.poll();
}
/**
* Clears both key released and when key released queues.
* See also
* general principles of event handling in FullScreen
* above.
*
* For more information and examples see
* Psychophysics programming with Java.
*
* @see #getKeyReleased(long)
* @see #getWhenKeyReleased()
*/
public void flushKeyReleased() {
keyReleased.clear();
whenKeyReleased.clear();
}
/**
* Returns whether or not Full Screen Exclusive Mode (FSEM) is
* supported on client's system.
*
* @return true if full screen exclusive mode is supported
*/
public boolean isFullScreenSupported() {
return gDevice.isFullScreenSupported();
}
/**
* Sets a new DisplayMode: secreen resolution, vertical synchronization rate,
* and color depth. If the requested DisplayMode is not applicable or
* DisplayMode change is not supported it causes the
* termination of the user's program, in order to avoid an erronous
* experimental session.
*
* @param dm new display mode to apply
*
* @see #isDisplayChangeSupported()
* @see #isDisplayModeAvailable(DisplayMode)
*/
public void setDisplayMode(DisplayMode dm) {
if (displayMode.equals(dm))
return;
else if (!gDevice.isDisplayChangeSupported() || dm == null) {
System.err.println("Exception in FullScreen.setDisplayMode(): "
+ "Display Change not Supported or DisplayMode is null");
closeScreen();
System.exit(0);
}
else if (!isDisplayModeAvailable(dm)) {
System.err.println("Exception in FullScreen.setDisplayMode(): "
+ "DisplayMode not available");
System.err.println("");
System.err.println("Supported DisplayModes are:");
String[] dms = reportDisplayModes();
for (int i = 0; i < dms.length; i++) {
System.err.print(dms[i]);
if ((i + 1) % 4 == 0)
System.err.println();
}
closeScreen();
System.exit(0);
}
else {
try {
gDevice.setDisplayMode(dm);
displayMode = dm;
setBounds(0, 0, dm.getWidth(), dm.getHeight());
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (RuntimeException e) {
System.err.println("Exception in FullScreen.setDisplayMode(): "
+ "DisplayMode not available or " + "Display Change not Supported");
System.err.println("");
System.err.println("Supported DisplayModes are:");
String[] dms = reportDisplayModes();
for (int i = 0; i < dms.length; i++) {
System.err.println(dms[i]);
if ((i + 1) % 4 == 0)
System.err.println();
}
closeScreen();
System.exit(0);
}
}
}
/**
* Returns whether or not given DisplayMode is applicable to client's screen.
*
* @param dm DisplayMode to check
*
* @return whether dm is applicable or not
*/
public boolean isDisplayModeAvailable(DisplayMode dm) {
DisplayMode[] mds = gDevice.getDisplayModes();
for (int i = 0; i < mds.length; i++) {
if (mds[i].getWidth() == dm.getWidth()
&& mds[i].getHeight() == dm.getHeight()
&& mds[i].getBitDepth() == dm.getBitDepth()
&& mds[i].getRefreshRate() == dm.getRefreshRate())
return true;
}
return false;
}
/**
* Returns the current screen resolution, vertical
* synchronization rate and color depth in a readable
* form.
*
* @return current DisplayMode in readable form
*/
public String reportDisplayMode() {
StringBuilder message = new StringBuilder();
if (displayMode.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI)
message.append(" Bit Depth = -1 (MULTIPLE) \n");
else
message.append(" Bit Depth = " + displayMode.getBitDepth() + "\n");
message.append(" Width = " + displayMode.getWidth() + "\n");
message.append(" Height = " + displayMode.getHeight() + "\n");
if (displayMode.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN)
message.append(" Refresh Rate = 0 (unknown/unmodifiable) \n");
else
message.append(" Refresh Rate = " + displayMode.getRefreshRate() + "\n");
return message.toString();
}
/**
* Returns the current DisplayMode.
*
* @return current DisplayMode
*/
public DisplayMode getDisplayMode() {
return displayMode;
}
/**
* Returns whether or not DisplayMode change is available on
* client's system.
*
* @return true if DisplayMode change is available
*/
public boolean isDisplayChangeSupported() {
return gDevice.isDisplayChangeSupported();
}
/**
* Reports all available DisplayMode parameters in a readable
* format.
*
* @return all available DisplayMode parameters.
*/
public String[] reportDisplayModes() {
DisplayMode[] dms = getDisplayModes();
String[] message = new String[dms.length];
for (int i = 0; i < dms.length; i++) {
StringBuilder m = new StringBuilder("(" + dms[i].getWidth() + ","
+ dms[i].getHeight() + "," + dms[i].getBitDepth() + ","
+ dms[i].getRefreshRate() + ") ");
message[i] = m.toString();
}
return message;
}
/**
* Returns all available DisplayModes on client's system.
*
* @return all available DisplayModes.
*/
public DisplayMode[] getDisplayModes() {
return gDevice.getDisplayModes();
}
}
* It is possible to create Java objects from within Matlab and Mathematica. You
* can, therefore, create a Java object in Matlab or Mathematica and
* invoke its methods. In other words, if you choose, you could use this package
* with Matlab or Mathematica as a tool for psychophysics programming in a way much like the well known Psychtoolbox package is used with Matlab.
* See
* Psychophysics Programming with Java for more information.
*
* @see NormalWindow
* @see BitsPP
*
* @author Huseyin Boyaci
*/
public class FullScreen extends JFrame implements KeyListener {
private static final GraphicsEnvironment gEnvironment = GraphicsEnvironment
.getLocalGraphicsEnvironment();
private static final GraphicsDevice[] gDevices = gEnvironment
.getScreenDevices();
private GraphicsDevice gDevice;
private GraphicsConfiguration gConfiguration;
private final static int defaultNBuffers = 1;
private final static Color defaultBgColor = Color.BLACK;
private final static Color defaultFgColor = Color.LIGHT_GRAY;
private final Font defaultFont = new Font("SansSerif", Font.BOLD, 36);
private int nBuffers;
private Color bgColor;
private DisplayMode oldDisplayMode;
private DisplayMode displayMode;
private BlockingQueuecloseScreen()
.
*
* @param displayID a numerical id indicating the screen device
*
* @see #setDisplayMode(DisplayMode)
* @see #setNBuffers(int)
* @see #closeScreen()
*
*/
public FullScreen(int displayID) {
super(gDevices[displayID].getDefaultConfiguration());
// apple.awt.fullscreencapturealldisplays = false;
gDevice = gDevices[displayID];
gConfiguration = gDevice.getDefaultConfiguration();
oldDisplayMode = gDevice.getDisplayMode();
displayMode = gDevice.getDisplayMode();
try {
setUndecorated(true);
setIgnoreRepaint(true);
setResizable(false);
setBackground(defaultBgColor);
super.setBackground(defaultBgColor);
setFont(defaultFont);
setForeground(defaultFgColor);
gDevice.setFullScreenWindow(this);
setNBuffers(defaultNBuffers);
Rectangle gcBounds = gConfiguration.getBounds();
int xoffs = gcBounds.x;
int yoffs = gcBounds.y;
int width = gcBounds.width;
int height = gcBounds.height;
setBounds(xoffs, yoffs, width, height);
keyTyped = new LinkedBlockingQueuecloseScreen()
.
*
* @see #setDisplayMode(DisplayMode)
* @see #setNBuffers(int)
* @see #closeScreen()
*/
public FullScreen() {
this(0);
}
/**
* Sets number of video buffers (including the front (visible) one).
* If the number is 1, it implies no back buffer. 2 implies
* one front one back buffer (double buffering).
*
* @param n number of buffers requested; must not be less than 1
*
* @see #getNBuffers()
*/
public void setNBuffers(int n) {
try {
createBufferStrategy(n);
nBuffers = n;
} catch (IllegalArgumentException e) {
System.err.println("Exception in FullScreen.setNBuffers(): "
+ "requested number of Buffers is illegal - falling back to default");
createBufferStrategy(defaultNBuffers);
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
/**
* Returns number of video buffers (including the front (visible) one)
* currently used
* by this FullScreen object.
*
* @return number of video buffers used by this FullScreen object
*
* @see #setNBuffers(int)
*/
public int getNBuffers() {
return nBuffers;
}
/**
* Updates the entire screen by bringing the back video buffer front (if there
* exists a back buffer, if not it has no effect).
* The methods in FullScreen class (displayImage(), displayText()
* or blankScreen(), see below) always manipulate the video bufer, not
* necessarily the screen.
* In case there is a back video buffer those methods affect only the
* back (invisible) buffer. After invoking those methods
* user has to invoke the updateScreen() method to actually
* bring the back buffer to front, in other words to make it actually visible
* on the screen device.
*
* @see #displayImage(int, int, BufferedImage)
* @see #displayText(int, int, String)
* @see #blankScreen()
*
*/
public void updateScreen() {
if (getBufferStrategy().contentsLost())
setNBuffers(nBuffers);
getBufferStrategy().show();
}
/**
* Displays a BufferedImage at the center of the screen.
* Note that, in case there is a back video buffer
* this method draws the image on the back buffer. In that case
* user has to invoke the updateScreen() method
* to actually display the image on the screen.
*
* @param bi BufferedImage to display
*
* @see #displayImage(int, int, BufferedImage)
* @see #updateScreen()
*/
public void displayImage(BufferedImage bi) {
if (bi != null) {
double x = (getWidth() - bi.getWidth()) / 2;
double y = (getHeight() - bi.getHeight()) / 2;
displayImage((int) x, (int) y, bi);
}
}
/**
* Displays a BufferedImage at the specified position.
* Note that, in case there is a back video buffer
* this method draws the image on the back buffer. In that case
* user has to invoke the updateScreen() method
* to actually display the image on the screen.
*
* @param x horizontal offset of the upper left corner of the image from the
* upper left corner of the screen
* @param y vertical offset of the upper left corner of the image from the
* upper left corner of the screen
* @param bi BufferedImage to display
*
* @see #displayImage(BufferedImage)
* @see #updateScreen()
*/
public void displayImage(int x, int y, BufferedImage bi) {
Graphics2D g = (Graphics2D) getBufferStrategy().getDrawGraphics();
try {
if (g != null && bi != null)
g.drawImage(bi, x, y, null);
}
finally {
g.dispose();
}
}
/**
* Displays text at the center of the screen.
* Note that, in case there is a back video buffer
* this method draws the text on the back buffer. In that case
* user has to invoke the updateScreen() method
* to actually display the text on the screen.
*
* @param text a text message to display
*
* @see #displayText(int, int, String)
* @see #updateScreen()
*/
public void displayText(String text) {
Graphics2D g = (Graphics2D) getBufferStrategy().getDrawGraphics();
if (g != null && text != null) {
Font font = getFont();
g.setFont(font);
FontRenderContext context = g.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(text, context);
double x = (getWidth() - bounds.getWidth()) / 2;
double y = (getHeight() - bounds.getHeight()) / 2;
double ascent = -bounds.getY();
double baseY = y + ascent;
displayText((int) x, (int) baseY, text);
}
g.dispose();
}
/**
* Displays text at the specified position.
* Note that, in case there is a back video buffer
* this method draws the text on the back buffer. In that case
* user has to invoke the updateScreen() method
* to actually display the text on the screen.
*
* @param x horizontal offset of the upper left corner of the text from the
* upper left corner of the screen
* @param y vertical offset of the upper left corner of the text from the
* upper left corner of the screen
* @param text a text message to display
*
* @see #displayText(String)
* @see #updateScreen()
*/
public void displayText(int x, int y, String text) {
Graphics2D g = (Graphics2D) getBufferStrategy().getDrawGraphics();
try {
if (g != null && text != null) {
g.setFont(getFont());
g.setColor(getForeground());
g.drawString(text, x, y);
}
}
finally {
g.dispose();
}
}
/**
* Blanks the whole screen using the current background color.
* Note that, in case there is a back video buffer
* this method blanks the back buffer. In that case
* user has to invoke the updateScreen() method
* to actually blank the screen.
*
* @see #updateScreen()
*
*/
public void blankScreen() {
Graphics2D g = (Graphics2D) getBufferStrategy().getDrawGraphics();
try {
if (g != null) {
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
}
finally {
g.dispose();
}
}
/**
* Returns the current background color.
*
* @return current background color
*
* @see #setBackground(Color)
*
*/
public Color getBackground() {
return bgColor;
}
/**
* Sets the background color.
*
* @param bg new background color
*
* @see #getBackground()
*/
public void setBackground(Color bg) {
bgColor = bg;
}
/**
* Renders the cursor invisible.
*
* @see #showCursor()
*
*/
public void hideCursor() {
Cursor noCursor = null;
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension d = tk.getBestCursorSize(1, 1);
if ((d.width | d.height) != 0)
noCursor = tk.createCustomCursor(new BufferedImage(d.width, d.height,
BufferedImage.TYPE_INT_ARGB), new Point(0, 0), "noCursor");
setCursor(noCursor);
}
/**
* Renders the cursor visible using default cursor
*
* @see #hideCursor()
*
*/
public void showCursor() {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
/**
* Closes the full screen exclusive mode screen.
* This method performs also the
* following additional steps:
* It switches the resolution back to system setting (if it was altered),
* releases all the screen resources to the operating system.
* User must invoke this method to re-gain access to normal desktop.
*
* @see #FullScreen(int)
* @see #FullScreen()
*
*/
public void closeScreen() {
if (gDevice.isDisplayChangeSupported())
setDisplayMode(oldDisplayMode);
gDevice.setFullScreenWindow(null);
dispose();
}
/**
* Returns the key typed by the observer within a specified amount of time.
*