KeyEventDispatcher在一个应用程序中工作,但不在另一个应用程序中

时间:2022-06-22 12:04:38

I have on one hand a complex, multi-threaded application, and on the other a single threaded test application that I was hoping to use to debug the first one. I am trying to use A KeyEventDispatcher as a keylistener of sorts, but no matter how hard I try, I cannot get the dispatchKeyEvent to fire in the larger application, yet the smaller application worked on the first try, and they both use the same KeyEventDispatcher class. I have scourged the Internet for a solution, or at least an explanation, but I've found basically nothing.

我一方面是一个复杂的多线程应用程序,另一方面是我希望用来调试第一个应用程序的单线程测试应用程序。我试图使用A KeyEventDispatcher作为排序的keylistener,但无论我怎么努力,我都无法在更大的应用程序中启动dispatchKeyEvent,但是较小的应用程序在第一次尝试时工作,并且它们都使用相同的KeyEventDispatcher类。我抨击互联网寻求解决方案,或者至少是解释,但我基本上没有发现任何问题。

Here's the code for the smaller application:

这是较小应用程序的代码:

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));

    }

}

Here's the code for the KeyEventDispatcher(AoDKeyboard) class:

这是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;

    }

}

And finally, here's a portion of the large application's code that contains the KeyEventDispatcher that doesn't work:

最后,这是大型应用程序代码的一部分,其中包含不起作用的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());

    }

}

Something interesting also happens when I run the larger application; any keys I press are typed into my compiler(eclipse), as if my keyboard focus were on the compiler the entire time.

当我运行更大的应用程序时,也会发生一些有趣的事情我按下的任何键都输入到我的编译器(eclipse)中,好像我的键盘焦点一直在编译器上。

Right now my best guess as to the problem is that the KeyEventDispatcher is being added too far down the queue, so that any keyevents are handled by the time they get to my dispatcher, but I could be totally wrong. I guess my question is, why does KeyEventDispatcher work in one application and not another, and how can I get it to work in both?

现在我对问题的最好猜测是KeyEventDispatcher被添加到队列太远的位置,因此任何关键事件都会在他们到达我的调度员时处理,但我可能完全错了。我想我的问题是,为什么KeyEventDispatcher在一个应用程序而不是另一个应用程序中工作,我怎样才能让它在两个应用程序中工作?

1 个解决方案

#1


0  

So I eventually figured out that, because I was using an owner-less JWindow, my program could not grab the keyboard focus, thus not having any events to dispatch. Switching to an undecorated JFrame did the trick.

所以我最终想通了,因为我使用的是无主的JWindow,我的程序无法抓住键盘焦点,因此没有任何事件要发送。切换到未修饰的JFrame就可以了。

Zistack

#1


0  

So I eventually figured out that, because I was using an owner-less JWindow, my program could not grab the keyboard focus, thus not having any events to dispatch. Switching to an undecorated JFrame did the trick.

所以我最终想通了,因为我使用的是无主的JWindow,我的程序无法抓住键盘焦点,因此没有任何事件要发送。切换到未修饰的JFrame就可以了。

Zistack