如何在JLabel上使用键绑定?

时间:2015-04-18 09:54:00

标签: java swing jlabel key-bindings key-events

我是一个用java编码的初学者(在英语中也是如此),我试图用eclipse打乒乓球。 我的问题是,我不知道如何通过按键盘上的不同键来制作我的2个球拍(JLabel)。 我首先尝试使用KeyListener,但我没有成功,所以现在我尝试使用keyBinding,我阅读了很多教程,但我并不理解。

那么我怎样才能通过按箭头键让我的两个球拍移动。

这是代码的一部分:

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

public class Pongg extends JPanel implements KeyListener {


private JLabel Racket1;                   // <----- Déclaration des JLabel/JLayeredPane ici pour pouvoir les utiliser (KeyListener)
private JLabel Racket2;                   //


public Pongg() {


    //Création de la fenetre
    JFrame fenetre = new JFrame("Fenetre");
    fenetre.setLocationRelativeTo (null);
    fenetre.setVisible(true);
    fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    fenetre.setSize(1000,600);

    //Box Main + JLayeredPane (fond noir)
    Box main=Box.createVerticalBox();
    JLayeredPane Fond = new JLayeredPane();
    Fond.setBackground(Color.black);        
    Fond.setOpaque(true);
    Fond.setVisible(true);

    main.add(Fond);
    fenetre.add(main);

    //Plateformes
    JLabel Racket1 = new JLabel();
    JLabel Racket2 = new JLabel();      

    //--->Racket 1 :        
    Racket1.setBounds(50, 200, 16, 100);   //<----- setBounds (Placer position du JLabel x,y + taille de la plateforme x,y)
    Racket1.setBackground(Color.white);
    Racket1.setOpaque(true);



    //--->Racket 2 :

    Racket2.setBounds(900, 200, 16, 100);
    Racket2.setBackground(Color.white);
    Racket2.setOpaque(true);

    Fond.add(Racket1); 
    Fond.add(Racket2);

EDDIT:我在这里尝试使用keyListener(我不知道如何使用keyBinding):

private Set appuye = new HashSet();

    public void keyTyped(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        appuye.add(e.getKeyCode()); // On ajoute le nombre correspondant à la touche pressée à la liste
            if (appuye.contains(KeyEvent.VK_UP)) { // la liste contient-elle cette touche ? (c'est un int static, donc utilisable à partir de la classe, même sans objet)
                Racket1.setLocation(Racket1.getX(), Racket1.getY() - 16);
            }
            if (appuye.contains(KeyEvent.VK_DOWN)) {
                Racket1.setLocation(Racket1.getX(), Racket1.getY() + 16);
            }
            if (appuye.contains(KeyEvent.VK_A)) {
                Racket2.setLocation(Racket2.getX(), Racket2.getY() - 16);
            }
            if (appuye.contains(KeyEvent.VK_Q)) {
                Racket2.setLocation(Racket2.getX(), Racket2.getY() + 16);
            }
    }

    public void keyReleased(KeyEvent e) {
        appuye.remove(e.getKeyCode()); // Lorsque la touche est relachée, on retire son numéro de la liste.

}           

1 个答案:

答案 0 :(得分:1)

键绑定与KeyListener之间存在差异,一般来说,键绑定是首选。

有关详细信息,请参阅How to write a KeyListenerHow to use key bindings

要使用密钥绑定API,您首先想要的是某种Action来响应密钥绑定。既然你只想让两个JLabel向上或向下移动,这实际上很容易......

public class MoveAction extends AbstractAction {

    private JLabel label;
    private int yDelta;

    public MoveAction(JLabel label, int yDelta) {
        this.label = label;
        this.yDelta = yDelta;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("...");
        Point p = label.getLocation();
        p.y += yDelta;
        label.setLocation(p);

        label.getParent().repaint();
    }

}

接下来你需要做的是用Action注册关键笔划(将它们绑定在一起)

InputMap im = Racket1.getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = Racket1.getActionMap();

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "Left.down.up");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "Left.down.down");
am.put("Left.down.up", new MoveAction(Racket1, -4));
am.put("Left.down.down", new MoveAction(Racket1, 4));

例如......

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Pongg extends JPanel {

    private JLabel Racket1;                                  // <----- Déclaration des JLabel/JLayeredPane ici pour pouvoir les utiliser (KeyListener)
    private JLabel Racket2;                                  //

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
            }

            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new Pongg());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
        });
    }

    public Pongg() {

        setLayout(new BorderLayout());

        //Box Main + JLayeredPane (fond noir)
        JLayeredPane Fond = new JLayeredPane();
        Fond.setBackground(Color.black);
        Fond.setOpaque(true);
        Fond.setVisible(true);

        add(Fond);

        //Plateformes
        JLabel Racket1 = new JLabel();
        JLabel Racket2 = new JLabel();

        //--->Racket 1 :                
        Racket1.setBounds(50, 200, 16, 100);     //<----- setBounds (Placer position du JLabel x,y + taille de la plateforme x,y)
        Racket1.setBackground(Color.white);
        Racket1.setOpaque(true);

        //--->Racket 2 :
        Racket2.setBounds(900, 200, 16, 100);
        Racket2.setBackground(Color.white);
        Racket2.setOpaque(true);

        Fond.add(Racket1);
        Fond.add(Racket2);

        InputMap im = Racket1.getInputMap(WHEN_IN_FOCUSED_WINDOW);
        ActionMap am = Racket1.getActionMap();

        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "Left.down.up");
        am.put("Left.down.up", new MoveAction(Racket1, -4));
    }

    @Override
    public Dimension getPreferredSize() {

        return new Dimension(1000, 600);

    }



    public class MoveAction extends AbstractAction {

        private JLabel label;
        private int yDelta;

        public MoveAction(JLabel label, int yDelta) {
            this.label = label;
            this.yDelta = yDelta;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("...");
            Point p = label.getLocation();
            p.y += yDelta;
            label.setLocation(p);

            label.getParent().repaint();
        }

    }
}