开发者

KeyEventDispatcher works in one application, but not another

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.

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:

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:

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 = Keyboar开发者_运维技巧dFocusManager.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.

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?


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.

Zistack

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜