事件处理程序和循环
我有一个全屏幕窗口,播放一个简单的动画,我想这样做,当我按任意键时,全屏恢复,程序停止。 关键听众类看起来像这样:事件处理程序和循环
import java.awt.event。*;
公共类键器具的KeyListener {
private framerun animation=new framerun();
public void keyPressed(KeyEvent e){}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){
animation.x=false;
}
}
动画的方法运行,运行,具有while循环看起来像这样:
public void run(DisplayMode dm){
Screen s=new Screen();
s.setFullScreen(dm, this);
while(true){
try{
System.out.println(x);
Thread.sleep(300);
}catch(Exception e){}
if(!x)
s.RestoreScreen();
repaint();
}
}
PS:X是一个初始值为true的布尔值,在构造函数中启动。
这是主要的方法:
public static void main(String args []){
DisplayMode dm=new DisplayMode(800, 600, 16,DisplayMode.REFRESH_RATE_UNKNOWN);
framerun f=new framerun();
key k=new key();
f.addKeyListener(k);
f.run(dm);
}
现在这个完美的作品,如果没有while循环。全屏关闭,程序停止。但是用while循环时,按下某个键时没有响应。按预期x的值不会更改为false。 想法?
我不能让DisplayMode
切换工作,但它应该没有区别。
基本上,KeyListener
很蠢。它要求它所连接的组件具有可聚焦性并且具有焦点。
下面的例子基本上都采用的requestFocusInWindow
和setFocusable
组合上JPanel
,试图迫使集中到JPanel
,这样,当一个键被输入时,JPanel
都可以对其回应...
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.EventQueue;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
private DisplayMode defaultMode;
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
defaultMode = gd.getDisplayMode();
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
// DisplayMode dm = new DisplayMode(800, 600, 16, DisplayMode.BIT_DEPTH_MULTI);
// gd.setDisplayMode(dm);
gd.setFullScreenWindow(frame);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setFocusable(true);
setLayout(new GridBagLayout());
add(new JLabel("Test"));
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
requestFocusInWindow();
}
});
addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
try {
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
// gd.setDisplayMode(defaultMode);
gd.setFullScreenWindow(null);
} catch (Throwable exp) {
exp.printStackTrace();
}
SwingUtilities.windowForComponent(TestPane.this).dispose();
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Personlly,我推荐使用的键绑定API,How to Use Key Bindings,但侧重于结合一个关键规定动作,但克服了相关KeyListener
我觉得这比这更简单。 While循环和事件侦听器通常不兼容? – 2015-02-06 00:04:25
取决于循环的运行位置。 Swing是单线程环境,这意味着如果您在事件分派线程的上下文中运行循环,则由于EDT不能再处理事件队列,UI将停止响应。 – MadProgrammer 2015-02-06 00:06:58
您可以推荐一些满足我的目标的东西对于像我这样的初学者来说难道不会让人难以理解吗?有些东西可以让我的动画播放,但仍然可以让我使用按键来阻止它。 – 2015-02-06 00:25:33
为什么你就不能调用's.RestoreScreen'焦点问题来自MouseList ener'? – MadProgrammer 2015-02-05 22:39:21
我试了一下,但好像它在我按下按键时甚至没有注意到该操作。它甚至不会将x的值更改为false。那就是问题所在。 while循环与事件侦听器冲突吗? – 2015-02-05 22:41:43