2013-04-12 26 views
1

该类用于启动当您按空间时创建的游戏,然后在游戏屏幕上按空格时重新启动空间。这是我第一次按空格键并按照预期启动游戏,但当我通过屏幕进入游戏并按空格键时,什么都不会发生。我试图扩展JFrame而不是JApplet,然后它工作得很好。KeyBindings在JApplet中无法正常工作

这是我的代码:

package Game; 

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class GameTest extends JApplet{ 
    private PAPITest papi; 
    private TestPane panel; 
    private boolean inMenu = true; 
    private ImageIcon ii; 
    private Image image; 

    public void init(){ 
     setFocusable(true); 
     requestFocusInWindow(); 
     requestFocus(); 
     ii = new ImageIcon("Ball Jump.png"); 
     image = ii.getImage(); 
     papi = new PAPITest(); 
     panel = new TestPane(); 
     add(panel); 
     setSize(600,600); 
     setVisible(true); 
    } 

    public void paint(Graphics g){ 
     if(inMenu == true){ 
      Graphics2D g2D = (Graphics2D) g; 
      g2D.drawImage(image, 0, 0, this); 
      repaint(); 
     } 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); 
      ActionMap am = getActionMap(); 

      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), "pressed"); 
      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), "released"); 

      am.put("pressed", new AbstractAction() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if(inMenu == true){ 
         inMenu = false; 
         remove(panel); 
         papi.setSize(600,600); 
         papi.setAlive(true); 
         add(papi);    
         setVisible(true); 
        } 

        if (papi.isAlive() != true){ 
         remove(papi); 
         papi = new PAPITest(); 
         papi.setSize(600,600); 
         add(papi); 
         setVisible(true); 
         repaint();  
        } 
       } 
      }); 

      am.put("released", new AbstractAction() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if(inMenu == true){ 
         inMenu = false; 
         remove(panel); 
         papi.setSize(600,600); 
         papi.setAlive(true); 
         add(papi);    
         setVisible(true); 
        } 

        if (papi.isAlive() != true){ 
         remove(papi); 
         papi = new PAPITest(); 
         papi.setSize(600,600); 
         add(papi); 
         setVisible(true); 
         repaint();  
        } 
       } 
      }); 

      setFocusable(true); 
      requestFocusInWindow();   
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(600, 600); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2D = (Graphics2D) g; 
      g2D.drawImage(image, 0, 0, this); 
      repaint(); 
     } 
    } 
} 

回答

1

JPanel是块当他们注册的组件是可聚焦和焦点的KeyListener

KeyListener只会对事件做出响应。

您应该使用Key Bindings来代替。即使他们注册的组件没有直接关注,他们也允许您注册密钥。

此外,您应该打电话super.paint,实际上,您不应该重写顶级容器的paint方法。

创建自定义JPanel并重写它的paintComponent方法(确保你打电话super.paintComponent)和替换为您添加到该applet

工作实例

该面板是基于工作示例关于你提供的代码,现在有编码丢失,所以我不得不将它评论出来,但也有一大堆东西,只是...怪异...

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagLayout; 
import java.awt.Image; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import javax.swing.AbstractAction; 
import javax.swing.ActionMap; 
import javax.swing.ImageIcon; 
import javax.swing.InputMap; 
import javax.swing.JApplet; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 

public class GameTest extends JApplet { 

// private PAPITest papi; 
    private TestPane panel; 
    private boolean inMenu = true; 
    private ImageIcon ii; 
    private Image image; 

    public void init() { 
// Don't need any of this, this will still focus from our control pane 
//  setFocusable(true); 
//  requestFocusInWindow(); 
//  requestFocus(); 
     setLayout(new BorderLayout()); 
     ii = new ImageIcon("Ball Jump.png"); 
     image = ii.getImage(); 
//  papi = new PAPITest(); 
     panel = new TestPane(); 
     add(panel); 
     // Useless, the size of applet is actually normally defined by the html tags 
//  setSize(600, 600); 
//  setVisible(true); 
    } 

// This is a very bad idea 
// This is not double buffered and you are over painting the applets 
// content. Use a CardLayout and a series of JPanels to provide this 
// functionality or the Glass Pane... 
// You MUST call super.paint!! 
// public void paint(Graphics g) { 
//  if (inMenu == true) { 
//   Graphics2D g2D = (Graphics2D) g; 
//   g2D.drawImage(image, 0, 0, this); 
//   repaint(); 
//  } 
// } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); 
      ActionMap am = getActionMap(); 

      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), "pressed"); 
      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), "released"); 

      am.put("pressed", new AbstractAction() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("Space Pressed"); 
        if (inMenu == true) { 
         inMenu = false; 
//      Removing the panel will remove the key binings... 
//      remove(panel); 

//      Don't have this code... 
//      Set size will have no effect as the layout manager 
//      apply it's own sizing based on the components 
//      preferred size... 
//      papi.setSize(600, 600); 
//      papi.setAlive(true); 
//      This seems a bit pointless, cause you just removed the "panel" 
//      which this now been added to... 
//      add(papi); 

//      Why call this when you've just removed it?? 
//      setVisible(true); 
        } 

//     if (papi.isAlive() != true) { 
//      remove(papi); 
//      papi = new PAPITest(); 
//      papi.setSize(600, 600); 
//      add(papi); 
//      setVisible(true); 
//      repaint(); 
//     } 
       } 
      }); 

      am.put("released", new AbstractAction() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("Space Released"); 
        if (inMenu == true) { 
         inMenu = false; 
//      remove(panel); 
//      papi.setSize(600, 600); 
//      papi.setAlive(true); 
//      add(papi); 
//      setVisible(true); 
        } 

//     if (papi.isAlive() != true) { 
//      remove(papi); 
//      papi = new PAPITest(); 
//      papi.setSize(600, 600); 
//      add(papi); 
//      setVisible(true); 
//      repaint(); 
//     } 
       } 
      }); 

      setFocusable(true); 
      requestFocusInWindow(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(600, 600); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2D = (Graphics2D) g; 
//   Don't have the image... 
//   g2D.drawImage(image, 0, 0, this); 
      repaint(); 
     } 
    } 
} 
+0

我现在使用KeyBindings,但它仍然不起作用。 – programmer

1

请勿重写JApplet的paint()方法。

public void paint(Graphics g){ 
    if(inMenu == true){ 
     Graphics2D g2D = (Graphics2D) g; 
     g2D.drawImage(image, 0, 0, this); 
     repaint(); 
    } 
} 

自定义绘画是在您的JPanel的paintComponent()方法中完成的。