2013-04-12 3 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) и заменить на панели вы добавляете в апплет

Рабочий пример

Это рабочий пример, основанный по коду, который вы предоставили, теперь отсутствовала кодировка, поэтому мне пришлось прокомментировать это, но есть также целая куча вещей, которые просто ... странные ...

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

Не переопределяйте метод paint() JApplet.

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

Нестандартная покраска выполняется в методе paintComponent() вашего JPanel.