我一方面是一个复杂的多线程应用程序,另一方面是我希望用来调试第一个应用程序的单线程测试应用程序。我正在尝试使用A KeyEventDispatcher
作为keylistener
种类,但无论我怎么努力,我都无法在较大的应用程序中触发dispatchKeyEvent
,但较小的应用程序可以工作在第一次尝试时,他们都使用相同的KeyEventDispatcher
类。我已经鞭打互联网寻求解决方案,或者至少是解释,但我基本上没有发现任何问题。
以下是较小应用程序的代码:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import zistack.AoD.*;
public class KeyEventDispatcherTest extends JFrame implements Runnable{
static KeyEventDispatcherTest test;
BufferedImage buffer;
Graphics2D g2d;
AoDKeyboard ked;
boolean b = false;
public KeyEventDispatcherTest(){
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
buffer = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
g2d = buffer.createGraphics();
ked = new AoDKeyboard();
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(ked);
new Thread(this).start();
}
public static void main(String[] args){
test = new KeyEventDispatcherTest();
}
public void run() {
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, 500, 500);
this.repaint();
this.setSize(500, 500);
this.setVisible(true);
while(true){
this.repaint();
try{
Thread.sleep(20);
}
catch(InterruptedException e){
e.printStackTrace();
}
}
}
public void paint(Graphics g){
g.drawImage(buffer, 0, 0, null);
g.setColor(Color.CYAN);
g.drawString("" + ked.test, 0, 0);
for(int i = 0; i < ked.keypressed.length; i++) g.drawString("" + ked.keypressed[i], 0 + ((i % 5) * 100), 15 + ((i / 5) * 15));
}
}
以下是KeyEventDispatcher(AoDKeyboard)
类的代码:
package zistack.AoD;
import java.awt.*;
import java.awt.event.*;
public class AoDKeyboard implements KeyEventDispatcher{
public final int[] keycode = {KeyEvent.VK_0, KeyEvent.VK_1, KeyEvent.VK_2, KeyEvent.VK_3, KeyEvent.VK_4, KeyEvent.VK_5,
KeyEvent.VK_6, KeyEvent.VK_7, KeyEvent.VK_8, KeyEvent.VK_9, KeyEvent.VK_A, KeyEvent.VK_B, KeyEvent.VK_C,
KeyEvent.VK_D, KeyEvent.VK_E, KeyEvent.VK_F, KeyEvent.VK_G, KeyEvent.VK_H, KeyEvent.VK_I, KeyEvent.VK_J,
KeyEvent.VK_K, KeyEvent.VK_L, KeyEvent.VK_M, KeyEvent.VK_N, KeyEvent.VK_O, KeyEvent.VK_P, KeyEvent.VK_Q,
KeyEvent.VK_R, KeyEvent.VK_S, KeyEvent.VK_T, KeyEvent.VK_U, KeyEvent.VK_V, KeyEvent.VK_W, KeyEvent.VK_X,
KeyEvent.VK_Y, KeyEvent.VK_Z, KeyEvent.VK_UP, KeyEvent.VK_DOWN, KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT,
KeyEvent.VK_F1, KeyEvent.VK_F2, KeyEvent.VK_F3, KeyEvent.VK_F4, KeyEvent.VK_F5, KeyEvent.VK_F6, KeyEvent.VK_F7,
KeyEvent.VK_F8, KeyEvent.VK_F9, KeyEvent.VK_F10, KeyEvent.VK_F11, KeyEvent.VK_F12};
public boolean[] keypressed = new boolean[keycode.length];
public boolean test = false;
public AoDKeyboard(){
for(int i = 0; i < keypressed.length; i++) keypressed[i] = false;
}
public boolean dispatchKeyEvent(KeyEvent e){
if(e.getID() == e.KEY_PRESSED) for(int i = 0; i < keycode.length; i++) if(e.getKeyCode() == keycode[i]) keypressed[i] = true;
if(e.getID() == e.KEY_RELEASED) for(int i = 0; i < keycode.length; i++) if(e.getKeyCode() == keycode[i]) keypressed[i] = false;
test = true;
return false;
}
}
最后,这是包含KeyEventDispatcher
不起作用的大型应用程序代码的一部分:
package zistack.AoD;
import zistack.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.util.Vector;
public class AoDGraphicUpdater implements Runnable{
KeyboardFocusManager keymanager;
BufferedImage backbuffer;
Graphics2D g2d;
protected Vector gameobjects;
protected GameWindow gwindow;
protected Thread updater;
protected long timer = 0;
protected int fademode, fadealpha;
public final int DARK = 0, FADE_TO_CLEAR = 1, CLEAR = 2, FADE_TO_DARK = 3;
AoDKeyboard keyboard;//////////////create keydispatcher
public AoDGraphicUpdater(Vector v, GameWindow gw){
keyboard = new AoDKeyboard();///////////
keymanager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
keymanager.addKeyEventDispatcher(keyboard);//////////add dispatcher to qeue
gameobjects = v;
gwindow = gw;
backbuffer = new BufferedImage(gwindow.getWidth(), gwindow.getHeight(), BufferedImage.TYPE_INT_RGB);
g2d = backbuffer.createGraphics();
g2d.setComposite(AlphaComposite.SrcOver);
fademode = DARK;
fadealpha = 255;
updater = new Thread(this);
updater.start();
}
public void run(){
g2d.setFont(new Font("Dialog", Font.PLAIN, 10));
while(true){
wipeScreen(g2d);
g2d.setColor(Color.CYAN);
//UPDATE OBJECTS
((GameView)gameobjects.firstElement()).update();
((AoDMenuHandler)gameobjects.elementAt(2)).update();
//DRAW OBJECTS
if(fadeMode() != DARK){
//draw anything under fade layer
((AoDSpaceGenerator)gameobjects.elementAt(1)).graphicUpdate(g2d);
}
if(fadeMode() == FADE_TO_CLEAR){
g2d.setColor(new Color(0, 0, 0, fadeAlpha()));
g2d.fillRect(0, 0, backbuffer.getWidth(), backbuffer.getHeight());
setFadeAlpha(fadeAlpha() - 15);
if(fadeAlpha() <= 0)setFadeMode(CLEAR);
}
else if(fadeMode() == FADE_TO_DARK){
g2d.setColor(new Color(0, 0, 0, fadeAlpha()));
g2d.fillRect(0, 0, backbuffer.getWidth(), backbuffer.getHeight());
setFadeAlpha(fadeAlpha() + 15);
if(fadeAlpha() >= 255)setFadeMode(DARK);
}
//draw anything on top of the fade layer
((AoDMenuHandler)gameobjects.elementAt(2)).graphicUpdate(g2d);
///////////////////////////DEBUG DISPLAY///////////////////////////////
//g2d.drawString("Debug2: " + blah, 100, 150);
g2d.drawString("" + keyboard.test, 100, 100);//draws whether or not the method has fired to the screen
g2d.drawString("" + keymanager, 100, 125);
while(timer > System.currentTimeMillis());
timer = System.currentTimeMillis() + 20;
gwindow.setBuffer(backbuffer);
}
}
public void setFadeMode(int mode){
this.fademode = mode;
if(fadeMode() == DARK)setFadeAlpha(255);
if(fadeMode() == CLEAR)setFadeAlpha(0);
}
public void setFadeAlpha(int b){
this.fadealpha = b;
}
public int fadeMode(){
return fademode;
}
public int fadeAlpha(){
return fadealpha;
}
protected void wipeScreen(Graphics2D g2d){
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, gwindow.getWidth(), gwindow.getHeight());
}
}
当我运行更大的应用程序时,也会发生一些有趣的事情;我按下的任何键都输入到我的编译器(eclipse)中,好像我的键盘焦点一直在编译器上。
现在我对问题的最佳猜测是KeyEventDispatcher
被添加到队列中太远,所以任何关键事件都会在他们到达我的调度员时处理,但我可能完全错了。我想我的问题是,为什么KeyEventDispatcher
在一个应用程序而不是另一个应用程序中工作,我怎样才能让它在两个应用程序中都有效?
答案 0 :(得分:0)
所以我最终想通了,因为我使用的是一个没有主人的JWindow,我的程序无法抓住键盘焦点,因此没有任何事件要发送。切换到未修饰的JFrame就可以了。
Zistack