Canvas的监听器问题

时间:2013-11-27 11:02:47

标签: java swing listener

我正在尝试用Java进行多人AirHockey游戏。我已经有服务器/客户端套接字工作了。
我的框架有一个带有2个面板的cardLayout,画布和jtable 我想进行局域网扫描以查找服务器,然后选择我想要的服务器 我做了这个扫描并将它放在cardLayout中的JTable中 当我启动服务器时,它会直接显示画布卡,听众没问题 但是当我启动客户端时,它会检查局域网,然后显示jtable卡。选择服务器后,我会显示画布并连接到服务器。这是问题,没有听众工作,我的windowListener和keyListener都没有。

我做了很多事但没有成功。

编辑: 我刚刚就此问题制作了一个SSCCE:

public class test extends Canvas{
public static final int SERVEUR = 10, CLIENT = 20;
public static int STATUT;
JFrame frame;
CardLayout cardsC = new CardLayout();
Container container;
JPanel servPanel = null;
public BufferStrategy strategy;

public test() {
    Object[] options = {"SERVER", "CLIENT"};
    int answer = JOptionPane.showOptionDialog(null, "Choisissez une option:", "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]);
    if(answer == 0){
        STATUT = SERVEUR;
        newFrame();
        frame.setVisible(true);
        gameLoop();
    }else if(answer == 1){
        STATUT = CLIENT;
        newFrame(); 
        frame.setVisible(true); 
        cardsC.show(container, "servs");
    }
}

public void connection(){
    if(servPanel != null) servPanel.removeAll();
    cardsC.show(container, "canvas");
    gameLoop();
}

private void gameLoop() {
    while(true){
        try {Thread.sleep(10);}catch (InterruptedException e){e.printStackTrace();}
    }

}

public void newFrame(){
    frame = new JFrame("Space Invaders 101");
    frame.setPreferredSize(new Dimension(600,750));

    container = frame.getContentPane();
    container.setLayout(cardsC);

    setBounds(0, 0, 600, 750);
    container.add(this, "canvas");

    setIgnoreRepaint(true);

    frame.pack();
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);

    if(STATUT == CLIENT){
        servPanel = new JPanel();
        JButton button = new JButton("Valider");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                connection();

            }
        });
        servPanel.add(button);
        container.add(servPanel, "servs");
    }

    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
    manager.addKeyEventDispatcher(new MyDispatcher());

    requestFocusInWindow();
    requestFocus();

    createBufferStrategy(2);
    strategy = getBufferStrategy();
    cardsC.show(container, "servs");
    cardsC.show(container, "canvas");
}

private class MyDispatcher implements KeyEventDispatcher {
    @Override
    public boolean dispatchKeyEvent(KeyEvent e) {
        if (e.getID() == KeyEvent.KEY_TYPED){
            System.out.println(e.getKeyChar());
        }
        return false;
    }
}

public static void main(String argv[]) {
    new test();
}

}

所以,您可以尝试一下,当您选择SERVER时,keyListener正在工作,而如果您选择了CLIENT则不然。 我想通了如果我不进入gameLoop,keylistener就可以了。 此外,当显示另一张卡(而不是画布卡)时,keyListener可以正常工作。

如果我首先显示jtable卡,我想知道如何让听众工作。

如果您需要更多信息。

提前致谢,

1 个答案:

答案 0 :(得分:0)

使用CardLayout交换面板时,新卡无法获得焦点,因此KeyListener无法正常工作。有关详细信息和解决方案,请参阅Card Layout Focus

但是,更好的解决方案是不使用KeyListener。相反,您应该使用Key Bindings来侦听在游戏中调用Actions的特定键。

此外,默认情况下,Swing是双缓冲的。没有必要使用带有BufferStrategy的Canvas。