Java 如何在JLabel上使用密钥绑定?
我是java编程的初学者(英语也是),我正在尝试用eclipse制作一个乒乓球游戏。 我的问题是,我不知道如何通过按键盘上的不同键来制作moove我的两个球拍(JLabel)。 我第一次尝试使用KeyListener,但没有成功,所以现在我尝试使用keyBinding,我读了很多教程,但我并不真正理解 因此,我如何简单地通过按箭头键使我的两个球拍发出嗡嗡声 下面是代码的一部分:Java 如何在JLabel上使用密钥绑定?,java,swing,jlabel,key-bindings,key-events,Java,Swing,Jlabel,Key Bindings,Key Events,我是java编程的初学者(英语也是),我正在尝试用eclipse制作一个乒乓球游戏。 我的问题是,我不知道如何通过按键盘上的不同键来制作moove我的两个球拍(JLabel)。 我第一次尝试使用KeyListener,但没有成功,所以现在我尝试使用keyBinding,我读了很多教程,但我并不真正理解 因此,我如何简单地通过按箭头键使我的两个球拍发出嗡嗡声 下面是代码的一部分: import java.awt.Color; import javax.swing.*; import java.aw
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);
键绑定和
KeyListener
之间有区别,一般来说,键绑定是首选的
有关详细信息,请参阅和
要使用密钥绑定API,首先需要某种操作来响应密钥绑定。因为您只需要两个JLabel
s向上或向下移动,所以这实际上非常简单
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();
}
}
接下来需要做的事情是使用操作注册按键笔划(将它们绑定在一起)
例如
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();
}
}
}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Point;
导入java.awt.event.ActionEvent;
导入java.awt.event.KeyEvent;
导入javax.swing.AbstractAction;
导入javax.swing.ActionMap;
导入javax.swing.InputMap;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JLayeredPane;
导入javax.swing.JPanel;
导入javax.swing.KeyStroke;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公共类Pongg扩展了JPanel{
私有JLabel Racket1;//Racket 1:
球拍1.立根(5020016100);//球拍2:
球拍2.立根(90020016100);
球拍2.背景(颜色:白色);
Racket2.set不透明(true);
found.add(Racket1);
found.add(Racket2);
InputMap im=Racket1.getInputMap(在聚焦窗口中时);
ActionMap am=Racket1.getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W,0),“Left.down.up”);
am.put(“左。下。上”,新动作(RACKT1,-4));
}
@凌驾
公共维度getPreferredSize(){
返回新维度(1000600);
}
公共类MoveAction扩展了AbstractAction{
私人标签;
私人国际酒店;
公共行动(JLabel标签,int yDelta){
this.label=标签;
this.yDelta=yDelta;
}
@凌驾
已执行的公共无效操作(操作事件e){
System.out.println(“…”);
点p=label.getLocation();
p、 y+=yDelta;
标签设置位置(p);
label.getParent().repaint();
}
}
}
你认为第三次很幸运……我希望是的,我在这段代码上写了三天。我不知道如何使用键绑定)
-你不知道如何使用键绑定是什么意思?在你的最后一个问题中,我给了你完整的工作代码!你注意到我给你的链接了吗?您下载了示例代码了吗?代码甚至使用了两个标签来表示您的敲诈。是的,我说过,因为键绑定比keylistener更复杂,在阅读了您发送给我的代码后,我并不真正理解如何使用键绑定,但是程序员帮助我将键绑定调整到我的程序中,现在我更好地理解了它的工作原理,但是谢谢你的支持answer@Silver,那么您对给出的答案的后续问题在哪里?你不明白代码的哪一部分?我们怎样才能读懂你的心思,猜出你不懂的东西?该代码还创建了一个自定义操作
。然后在击键和动作之间创建绑定。如果你完全忽略所提供的帮助,并且在不解释所提供的帮助让你感到困惑的地方时,就同一主题问3个问题,这会让人感到恼火。谢谢你花时间帮助我,我要尝试一下你给我的信息。只是一些我不明白的事情:我们放置公共静态void main(String[]args){的顺序重要吗?我真的不明白为什么你要将JFrame放置在公共静态void main(String[]args)中{最后,Event.Queue是用于同时使用两个动作的吗?static void main
在主类中的位置并不重要,我个人喜欢它位于顶部,这样我就可以看到入口点。我在main
方法中创建了框架,因为JPanel
不应该创建它自己的框架,至少不在构造函数中,因为您永远不知道可能要将组件放置在何处。EventQueue.invokeLater
确保在EDT上下文中创建UI,以防止可能出现的问题和违反Swing的单线程性质
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();
}
}
}