2017-02-11 14 views
0

Я пытаюсь создать игру на Java, где нажатие пробела перемещает окно в окне. Я использую Key Binding для выполнения этой задачи. Проблема в том, что я не могу понять, как использовать ActionListener на самом ящике, который является JLabel. Вот код ниже:Я не могу переместить мой JLabel с привязкой клавиш?

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 

import javax.swing.AbstractAction; 
import javax.swing.Action; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 

public class Game { 

private static JFrame frame  = new JFrame(); 
private static JPanel gamePanel = new JPanel(); 
private static Action playerAction = new PlayerListener(); 
private static JLabel box = new JLabel(); 
private static int x = 250; 
private static int y = 250; 

public static void main(String[] args) { 

    frame.add(boxPanel()); 
    frame.setTitle("Block Game"); 
    frame.setSize(500,500); 
    frame.setLocationRelativeTo(null); 
    frame.setFocusable(true); 

    box.addActionListener(playerAction); 

    frame.setVisible(true); 

} 

static JPanel boxPanel() { 
    ImageIcon boxIcon = new ImageIcon("box.png"); 
    box.setIcon(boxIcon); 

    box.setSize(30,30); 
    box.setLocation(x,y); 

    box.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "doPlayerAction"); 
    box.getActionMap().put("doPlayerAction", playerAction); 

    gamePanel.setLayout(null); 
    gamePanel.add(box); 
    frame.add(gamePanel); 

    return gamePanel; 
} 

static class PlayerListener extends AbstractAction { 

    public void actionPerformed(ActionEvent e) { 

     System.out.println("SPACEBAR"); 

    } 

} 
} 

Я попытался изменить коробку к JButton и работать с этим вместо этого, но я обнаружил, что «ПРОБЕЛ» печатает только, когда я нажимаю на самой коробке. Любая помощь приветствуется. Благодаря!

+0

вместо расширения '' AbstractAction' реализации KeyListener'. [Следовать этому] (http://stackoverflow.com/questions/2077168/moving-jlabel-with-arrow -keys) –

+0

@jackjay KeyBindings не страдают от проблем, связанных с фокусом, поскольку KeyListener делает и представляет собой функцию многократного использования, которая может быть применена к другим методам ввода, в отличие от KeyListener, и это скорее вопрос макета – MadProgrammer

+0

@MadProgrammer. Но поскольку OP говорит, что выход идет, когда OP щелкает ярлык, поэтому я думал, что это может быть проблема с фокусом. –

ответ

3

Ваша «основная» проблема вращается вокруг box.getInputMap(), измените ее на что-то более похожее на box.getInputMap(WHEN_IN_FOCUSED_WINDOW), что будет означать, что API будет реагировать на ключевые события всякий раз, когда в фокусе окна, независимо от того, какие другие компоненты могут иметь фокус.

Я также suggestsomething больше как box.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "doPlayerAction"), как механизм, который KeyStroke использует для разбора String к KeyStroke является более сложным, то это может показаться, как правило, требуется дополнительная информация, как pressed, released или typed, это просто легче использовать виртуальные ключи

Я бы также привязал ключи к gamePanel в качестве общего предпочтения, так как это должен быть контейнер, принимающий решения о том, что делать, но это только я.

Посмотрите How to Use Key Bindings для получения более подробной информации

+0

Это исправлено. Спасибо чувак! Я обязательно буду следовать вашим предложениям здесь :) – SputnicK