我正在尝试用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卡,我想知道如何让听众工作。
如果您需要更多信息。
提前致谢,
答案 0 :(得分:0)
使用CardLayout交换面板时,新卡无法获得焦点,因此KeyListener无法正常工作。有关详细信息和解决方案,请参阅Card Layout Focus。
但是,更好的解决方案是不使用KeyListener。相反,您应该使用Key Bindings来侦听在游戏中调用Actions的特定键。
此外,默认情况下,Swing是双缓冲的。没有必要使用带有BufferStrategy的Canvas。