0

複雑なマルチスレッド アプリケーションと、最初のアプリケーションのデバッグに使用したいと考えていたシングル スレッド テスト アプリケーションがあります。A を一種として使用しようとしていますKeyEventDispatcherkeylistener、どんなに頑張っても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あるアプリケーションで動作し、別のアプリケーションでは動作しないのか、そしてどうすれば両方で動作させることができるのでしょうか?

4

1 に答える 1

0

そのため、所有者のない JWindow を使用していたため、プログラムがキーボード フォーカスを取得できず、ディスパッチするイベントがないことが最終的にわかりました。装飾されていない JFrame に切り替えるとうまくいきました。

ジスタック

于 2012-05-27T18:34:00.823 に答える