2015-10-14 3 views
3

У меня были проблемы с ключевыми слушателями на Java из-за проблем с фокусировкой, поэтому я прочитал об этом, и многие веб-сайты рекомендуют использовать привязки клавиш. Мой код ниже, и я пытаюсь сопоставить клавишу пробела с действием TestAction. Объект панели является просто расширением JPanel.Java-код компилируется, но действие не распознается

public class Template_Main { 

static Boolean quit = false; 

public static void main(String[] args) {  
    Window window = new Window(); 
    while(!quit) { 
     window.update(); 
    } 
    System.exit(0); 
} 

} 

.

import java.awt.Image; 
import java.awt.Toolkit; 
import javax.swing.Action; 
import javax.swing.ImageIcon; 
import javax.swing.JLabel; 
import javax.swing.KeyStroke; 

public class Window { 

public Frame frame; 
public Panel panel; 

public Window() { 
    frame = new Frame(); 
    panel = new Panel();  

    Action pressedAction = new TestAction(); 
    Action releasedAction = new TestAction(); 

    pressedAction.setEnabled(true); 
    releasedAction.setEnabled(true); 

    panel.getInputMap().put(KeyStroke.getKeyStroke("SPACE"),"pressed"); 
    panel.getInputMap().put(KeyStroke.getKeyStroke("released SPACE"),"released"); 

    panel.getActionMap().put("pressed",pressedAction); 
    panel.getActionMap().put("released",releasedAction); 

    frame.add(panel); 
    frame.pack(); 
} 

public void update() { 
    Logic.update(); 
    updateImages(); 
    sleep(); 
} 

public void updateImages() { 
    panel.removeAll(); 
    for (int i = 0; i < Imgs.array.size(); ++i) { 
     Img img = Imgs.get(i); 
     addImage(img.name, img.x, img.y, img.width, img.height); 
    } 
    panel.repaint(); 
} 

public void addImage(String name, int x, int y, int width, int height) { 
    panel.add(newImageLabel(name, x, y, width, height)); 
} 

public static JLabel newImageLabel(String imageName, int x, int y, int width, int height) { 
    Toolkit toolkit = Toolkit.getDefaultToolkit(); 
    java.net.URL iconUrl = ClassLoader.getSystemResource("resources/"+imageName); 
    Image image = toolkit.createImage(iconUrl); 
    JLabel label = new JLabel(new ImageIcon(image)); 
    label.setBounds(x, y, width, height); 
    return label; 
} 

static void sleep() { 
    try { 
     Thread.sleep(Math.round(10)); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

} 

.

import javax.swing.JFrame; 

public class Frame extends JFrame { 

public Frame() { 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    setTitle(Config.TITLE); 
    setResizable(Config.RESIZABLE); 
    setVisible(true); 
} 

} 

.

import java.awt.Dimension; 
import javax.swing.JPanel; 

public class Panel extends JPanel { 

public Panel() { 
    setPreferredSize(new Dimension(Config.WIDTH,Config.HEIGHT)); 
    setLayout(null); 
    setBackground(Config.BG_COLOR); 
    setFocusable(true); 
} 

} 

.

import java.awt.event.ActionEvent; 
import javax.swing.AbstractAction; 

public class TestAction extends AbstractAction { 

public TestAction() { 

} 

@Override 
public void actionPerformed(ActionEvent arg0) { 
    System.out.println("ACTION PERFORMED"); 
} 

} 

Проблема в том, что хотя она компилируется без ошибок, ничего не происходит, когда я нажимаю клавишу пробела.

+0

Имеет ли ваша панель фокус при нажатии пробела? –

+0

Да, я так считаю ... – k13ran

+0

Ваш код слишком большой, чтобы опубликовать его полностью? Или, может быть, короткий компилируемый пример? Я не вижу ничего очевидного, что вы здесь делаете неправильно. –

ответ

1

Я думаю, что ваша проблема заключается в том, что Уильям Моррисон заявил, что JPanel не фокусируется.

Попробуйте бросить вызов requestFocus(), когда панель будет добавлена. Если бы вы могли опубликовать небольшой пример кода, мы могли бы помочь вам больше.

0

Использование вашего кода в качестве базы, это работает.

import java.awt.event.ActionEvent; 
import javax.swing.AbstractAction; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 

public class App extends JFrame 
{ 

    public static void main(String args[]) 
    { 
     new App(); 
    } 

    public App() 
    { 
     super("Test App"); 
     setLocationRelativeTo(null); 
     setSize(600, 450); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     getContentPane().add(new KeyBindingPane()); 
     setVisible(true); 
    } 

    private class KeyBindingPane extends JPanel 
    { 
     public KeyBindingPane() 
     { 
      this.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressed"); 
      this.getInputMap().put(KeyStroke.getKeyStroke("released SPACE"), "released"); 

      getActionMap().put("pressed", new SpaceBarAction()); 
      getActionMap().put("released", new SpaceBarAction()); 

      requestFocus(); 
     } 
    } 

    public class SpaceBarAction extends AbstractAction 
    { 
     @Override 
     public void actionPerformed(ActionEvent e) 
     { 
      System.out.println("ACTION PERFORMED (SPACE BAR)"); 
     } 
    } 
} 
1

Спасибо всем за вашу помощь!

Вы правы, панель не фокусировалась, рама содержала его. Добавление panel.requestFocus(); исправлено!

Смежные вопросы