问题
EDIT 1/16/2013: The original question has been deleted. This seems to be a bug with the JDK 7 on mac OSX. I have filed a bug report with Sun (Oracle).
The file below uses the awt class GraphicsEnvironment and the method setFullScreenWindow to display an image to fullscreen. No images are included, so the screen will be gray when running the code. The key bindings should, however, still work.
There are two key bindings. Pressing 'ENTER' should print "Enter was pressed." to stdout. Pressing 'ESCAPE' should print "Program Terminated by ESC Key" to stdout and quit the program.
Using Windows 7 64 and JDK Java SE 6 AND 7 these key bindings work as expected.
Using Mac OSX 10.7 Lion and JDK Java SE 6 these key bindings work as expected.
Using Mac OSX 10.7 Lion and JDK Java SE 7 these key bindings stop working.
Rolling back to JDK Java SE 6 causes them to start working again.
I don't know if it affects other OSs.
I have tried all versions of JComponent.WHEN_IN_FOCUS etc... and none of these options fixes the problem.
Below is an SSCCE that will reproduce the error only if you are using Mac OSX 10.7 and JDK Java SE 7.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class FullScreen extends JFrame
{
/*
* screenImage is never set in this code. It can be set to any image
* the error will still be present. Images have been omitted to simplify
* the example case.
*/
private Image screenImage;
private int width;
private int height;
//Create panel for displaying images using paintComponent()
private PaintPanel mainImagePanel;
//Used for keybinding
private Action enterAction;
private Action escapeAction;
private static final String enter = "ENTER";
private static final String escape = "ESCAPE";
public FullScreen()
{
/**********************************************
******THE BELOW LINES CAUSE THE ERROR*********
**********************************************/
/******************************************
* Removes window framing and sets fullscreen mode.
******************************************/
this.setUndecorated(true);
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(this);
/**********************************************
******THE ABOVE LINES CAUSE THE ERROR*********
**********************************************/
width = this.getWidth();
height = this.getHeight();
//Create panel so that I can use key binding which requires JComponent
mainImagePanel = new PaintPanel();
add(mainImagePanel);
/******************************************
* Key Binding
******************************************/
// Key bound AbstractAction items
enterAction = new EnterAction();
escapeAction = new EscapeAction();
// Gets the mainImagePanel InputMap and pairs the key to the action
mainImagePanel.getInputMap().put(KeyStroke.getKeyStroke(enter), "doEnterAction");
mainImagePanel.getInputMap().put(KeyStroke.getKeyStroke(escape), "doEscapeAction");
// This line pairs the AbstractAction enterAction to the action "doEnterAction"
mainImagePanel.getActionMap().put("doEnterAction", enterAction);
mainImagePanel.getActionMap().put("doEscapeAction", escapeAction);
/******************************************
* End Key Binding
******************************************/
}
//Stretches and displays images in fullscreen window
private class PaintPanel extends JPanel
{
@Override
public void paintComponent(Graphics g)
{
if(screenImage != null)
{
super.paintComponent(g);
g.drawImage(screenImage, 0, 0, width, height, this);
}
}
}
/******************************************
* User Input
******************************************/
private class EnterAction extends AbstractAction
{
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println("Enter was pressed.");
}
}
private class EscapeAction extends AbstractAction
{
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println("Program Terminated by ESC Key");
System.exit(0);
}
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run()
{
FullScreen show = new FullScreen();
show.setVisible(true);
}
});
}
}
So the below two lines are causing the problem.
this.setUndecorated(true);
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(this);
回答1:
http://mail.openjdk.java.net/pipermail/macosx-port-dev/2012-November/005109.html
There is a workaround!
After you make it fullscreen, do frame.setVisible(false);
then frame.setVisible(true)
. Why does it work? Consult the above link.
回答2:
As noted here, some static final variables may be effectively inlined in a dependent class. Key bindings, which implicitly connect a KeyStroke
to a String
and that same String
to an Action
, may exhibit this behavior if the String
is defined statically in another class. One simple expedient, suggested here, is to do a full build. If that resolves the problem, you may be able to work backward to mitigate the dependency.
回答3:
On a mac system that had functional key binding with this code I installed jdk-7u11-macosx-x64.dmg. The key bindings no longer function after the installation. At this point I'm pretty confident that this is a bug with the new version of JDK for OSX and will be reporting it.
Thanks everyone for trying to help solve this, but it turns out the code is fine.
来源:https://stackoverflow.com/questions/14317352/bug-java-swing-key-bindings-lose-function-with-jdk-7-in-osx-with-awt-setfullscr