如何在Main的Jframe中添加KeyListener对象的JLabel class
How to add JLabel of KeyListener object in Jframe of Main class
我对这个 Java 编码有点陌生。问题是我有一个不同的 class 用于 KeyListener 和一个我想在用户按下某个键时显示的图像,但该图像来自 JLabel,我想将它添加到主 [=22] 的 JFrame 中=] 但我不明白我会怎么做。
是的,我确实看到了另一个问题,这个问题:
How I add a JLabel to a JFrame on another class?
但我不能在我的代码中执行建议的方法,因为在主方法中调用时的 Key Listener 只会在调用时处理 KeyListening 部分: jframe.add(new KeyListener()) 类似的东西,但图像会不会添加,因为它包含在 JLabel 中,而 JLabel 不会添加到 JFrame 中。
这是我的 KeyListener 代码:
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.awt.*;
import javax.swing.*;
class MKeyListener extends KeyAdapter
{
static int n = 0;
@Override
public void keyPressed(KeyEvent event)
{
if (event.getKeyCode() == KeyEvent.VK_ESCAPE)
{
n += 1;
if(n % 2 == 1)
{
}
else
{
System.out.println("Not Quitting now");
}
}
else if(event.getKeyCode() == KeyEvent.VK_ENTER && n % 2 == 1)
{
System.out.println("Quitting now...");
try
{
Thread.sleep(200);
}
catch(Exception e)
{
}
System.exit(0);
}
}
}
这是我的主要方法
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.awt.*;
import javax.swing.*;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
public class Main
{
public static void main(String[] args) throws Exception
{
JTextField textField = new JTextField();
textField.addKeyListener(new MKeyListener());
JFrame jframe = new JFrame();
jframe.add(textField);
jframe.setSize(1000, 1000);
jframe.setTitle("First Development In JAVA Try : Day 3");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
}
}
有人可以建议一种在用户按键时添加该图像的方法吗?
您问题的“基本”答案是,您需要使用某种“观察者模式”。
目的是,您的“键处理程序”将监视某种键盘输入,当发生某些触发(按下特定键)时,它会通知所有感兴趣的观察者该动作。
Swing 将这些称为“侦听器”,因此,您已经在实际中看到了它们。
- 不要将
KeyListener
添加到 JTextField
,这只是个坏主意。如果要监视 JTextField
中的输入,请在字段的 Document
上使用 DocumentListener
。如果您想监视“一般”键盘输入,请改用 key bindings API。
- 不要从事件调度线程中调用
Thread.sleep
,这只会导致无穷无尽的问题(和愤怒的用户)
下面的例子使用快捷键API来监控Q,W,E , S, D, Z, X, C作为8个方向的简单表示。
该示例使用了一个简单的“侦听器”,它通知感兴趣的一方已按下某个方向。您不限于单一方法,例如,您可以将方法直接映射到特定操作,即 keyHandlerPerformExit
当某些“退出”键序列被触发时调用。
该示例还允许 Action
触发直接返回 KeyHanderListener
的回调,同样,您不需要这样做,您可以让 Action
调用返回 KeyHandler
中的一个方法,然后它可以执行一些额外的计算或操作,然后,根据你想做什么,然后通知监听器
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Map<KeyHandler.Direction, JPanel> mapPanels;
private KeyHandler keyHandler;
public TestPane() {
mapPanels = new HashMap<>();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
add(createPanel(KeyHandler.Direction.LEFT_UP), gbc);
gbc.gridx++;
add(createPanel(KeyHandler.Direction.UP), gbc);
gbc.gridx++;
add(createPanel(KeyHandler.Direction.RIGHT_UP), gbc);
gbc.gridx = 0;
gbc.gridy++;
add(createPanel(KeyHandler.Direction.LEFT), gbc);
gbc.gridx++;
add(createPanel(), gbc);
gbc.gridx++;
add(createPanel(KeyHandler.Direction.RIGHT), gbc);
gbc.gridx = 0;
gbc.gridy++;
add(createPanel(KeyHandler.Direction.LEFT_DOWN), gbc);
gbc.gridx++;
add(createPanel(KeyHandler.Direction.DOWN), gbc);
gbc.gridx++;
add(createPanel(KeyHandler.Direction.RIGHT_DOWN), gbc);
keyHandler = new KeyHandler(getInputMap(WHEN_IN_FOCUSED_WINDOW), getActionMap(), new KeyHandlerListener() {
@Override
public void keyHandlerDidPress(KeyHandler.Direction direction) {
activate(direction);
}
});
}
protected JPanel createPanel() {
JPanel panel = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
};
panel.setBorder(new LineBorder(Color.DARK_GRAY));
return panel;
}
protected JPanel createPanel(KeyHandler.Direction direction) {
JPanel panel = createPanel();
mapPanels.put(direction, panel);
return panel;
}
protected void activate(KeyHandler.Direction direction) {
JPanel panel = mapPanels.get(direction);
panel.setBackground(Color.BLUE);
Timer timer = new Timer(250, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
panel.setBackground(null);
}
});
timer.setRepeats(false);
timer.start();
}
}
public interface KeyHandlerListener {
public void keyHandlerDidPress(KeyHandler.Direction direction);
}
public class KeyHandler {
public enum Direction {
UP, DOWN, LEFT, RIGHT,
LEFT_UP, RIGHT_UP,
LEFT_DOWN, RIGHT_DOWN
}
public KeyHandler(InputMap inputMap, ActionMap actionMap, KeyHandlerListener listener) {
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), "Press.leftUp");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "Press.up");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_E, 0), "Press.rightUp");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "Press.left");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "Press.right");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0), "Press.leftDown");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, 0), "Press.down");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, 0), "Press.rightDown");
actionMap.put("Press.leftUp", new DirectionAction(Direction.LEFT_UP, listener));
actionMap.put("Press.up", new DirectionAction(Direction.UP, listener));
actionMap.put("Press.rightUp", new DirectionAction(Direction.RIGHT_UP, listener));
actionMap.put("Press.left", new DirectionAction(Direction.LEFT, listener));
actionMap.put("Press.right", new DirectionAction(Direction.RIGHT, listener));
actionMap.put("Press.leftDown", new DirectionAction(Direction.LEFT_DOWN, listener));
actionMap.put("Press.down", new DirectionAction(Direction.DOWN, listener));
actionMap.put("Press.rightDown", new DirectionAction(Direction.RIGHT_DOWN, listener));
}
protected class DirectionAction extends AbstractAction {
private Direction direction;
private KeyHandlerListener listener;
public DirectionAction(Direction direction, KeyHandlerListener listener) {
this.direction = direction;
this.listener = listener;
}
@Override
public void actionPerformed(ActionEvent e) {
listener.keyHandlerDidPress(direction);
}
}
}
}
我对这个 Java 编码有点陌生。问题是我有一个不同的 class 用于 KeyListener 和一个我想在用户按下某个键时显示的图像,但该图像来自 JLabel,我想将它添加到主 [=22] 的 JFrame 中=] 但我不明白我会怎么做。 是的,我确实看到了另一个问题,这个问题: How I add a JLabel to a JFrame on another class? 但我不能在我的代码中执行建议的方法,因为在主方法中调用时的 Key Listener 只会在调用时处理 KeyListening 部分: jframe.add(new KeyListener()) 类似的东西,但图像会不会添加,因为它包含在 JLabel 中,而 JLabel 不会添加到 JFrame 中。 这是我的 KeyListener 代码:
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.awt.*;
import javax.swing.*;
class MKeyListener extends KeyAdapter
{
static int n = 0;
@Override
public void keyPressed(KeyEvent event)
{
if (event.getKeyCode() == KeyEvent.VK_ESCAPE)
{
n += 1;
if(n % 2 == 1)
{
}
else
{
System.out.println("Not Quitting now");
}
}
else if(event.getKeyCode() == KeyEvent.VK_ENTER && n % 2 == 1)
{
System.out.println("Quitting now...");
try
{
Thread.sleep(200);
}
catch(Exception e)
{
}
System.exit(0);
}
}
}
这是我的主要方法
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.awt.*;
import javax.swing.*;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
public class Main
{
public static void main(String[] args) throws Exception
{
JTextField textField = new JTextField();
textField.addKeyListener(new MKeyListener());
JFrame jframe = new JFrame();
jframe.add(textField);
jframe.setSize(1000, 1000);
jframe.setTitle("First Development In JAVA Try : Day 3");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
}
}
有人可以建议一种在用户按键时添加该图像的方法吗?
您问题的“基本”答案是,您需要使用某种“观察者模式”。
目的是,您的“键处理程序”将监视某种键盘输入,当发生某些触发(按下特定键)时,它会通知所有感兴趣的观察者该动作。
Swing 将这些称为“侦听器”,因此,您已经在实际中看到了它们。
- 不要将
KeyListener
添加到JTextField
,这只是个坏主意。如果要监视JTextField
中的输入,请在字段的Document
上使用DocumentListener
。如果您想监视“一般”键盘输入,请改用 key bindings API。 - 不要从事件调度线程中调用
Thread.sleep
,这只会导致无穷无尽的问题(和愤怒的用户)
下面的例子使用快捷键API来监控Q,W,E , S, D, Z, X, C作为8个方向的简单表示。
该示例使用了一个简单的“侦听器”,它通知感兴趣的一方已按下某个方向。您不限于单一方法,例如,您可以将方法直接映射到特定操作,即 keyHandlerPerformExit
当某些“退出”键序列被触发时调用。
该示例还允许 Action
触发直接返回 KeyHanderListener
的回调,同样,您不需要这样做,您可以让 Action
调用返回 KeyHandler
中的一个方法,然后它可以执行一些额外的计算或操作,然后,根据你想做什么,然后通知监听器
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Map<KeyHandler.Direction, JPanel> mapPanels;
private KeyHandler keyHandler;
public TestPane() {
mapPanels = new HashMap<>();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
add(createPanel(KeyHandler.Direction.LEFT_UP), gbc);
gbc.gridx++;
add(createPanel(KeyHandler.Direction.UP), gbc);
gbc.gridx++;
add(createPanel(KeyHandler.Direction.RIGHT_UP), gbc);
gbc.gridx = 0;
gbc.gridy++;
add(createPanel(KeyHandler.Direction.LEFT), gbc);
gbc.gridx++;
add(createPanel(), gbc);
gbc.gridx++;
add(createPanel(KeyHandler.Direction.RIGHT), gbc);
gbc.gridx = 0;
gbc.gridy++;
add(createPanel(KeyHandler.Direction.LEFT_DOWN), gbc);
gbc.gridx++;
add(createPanel(KeyHandler.Direction.DOWN), gbc);
gbc.gridx++;
add(createPanel(KeyHandler.Direction.RIGHT_DOWN), gbc);
keyHandler = new KeyHandler(getInputMap(WHEN_IN_FOCUSED_WINDOW), getActionMap(), new KeyHandlerListener() {
@Override
public void keyHandlerDidPress(KeyHandler.Direction direction) {
activate(direction);
}
});
}
protected JPanel createPanel() {
JPanel panel = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
};
panel.setBorder(new LineBorder(Color.DARK_GRAY));
return panel;
}
protected JPanel createPanel(KeyHandler.Direction direction) {
JPanel panel = createPanel();
mapPanels.put(direction, panel);
return panel;
}
protected void activate(KeyHandler.Direction direction) {
JPanel panel = mapPanels.get(direction);
panel.setBackground(Color.BLUE);
Timer timer = new Timer(250, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
panel.setBackground(null);
}
});
timer.setRepeats(false);
timer.start();
}
}
public interface KeyHandlerListener {
public void keyHandlerDidPress(KeyHandler.Direction direction);
}
public class KeyHandler {
public enum Direction {
UP, DOWN, LEFT, RIGHT,
LEFT_UP, RIGHT_UP,
LEFT_DOWN, RIGHT_DOWN
}
public KeyHandler(InputMap inputMap, ActionMap actionMap, KeyHandlerListener listener) {
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), "Press.leftUp");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "Press.up");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_E, 0), "Press.rightUp");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "Press.left");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "Press.right");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0), "Press.leftDown");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, 0), "Press.down");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, 0), "Press.rightDown");
actionMap.put("Press.leftUp", new DirectionAction(Direction.LEFT_UP, listener));
actionMap.put("Press.up", new DirectionAction(Direction.UP, listener));
actionMap.put("Press.rightUp", new DirectionAction(Direction.RIGHT_UP, listener));
actionMap.put("Press.left", new DirectionAction(Direction.LEFT, listener));
actionMap.put("Press.right", new DirectionAction(Direction.RIGHT, listener));
actionMap.put("Press.leftDown", new DirectionAction(Direction.LEFT_DOWN, listener));
actionMap.put("Press.down", new DirectionAction(Direction.DOWN, listener));
actionMap.put("Press.rightDown", new DirectionAction(Direction.RIGHT_DOWN, listener));
}
protected class DirectionAction extends AbstractAction {
private Direction direction;
private KeyHandlerListener listener;
public DirectionAction(Direction direction, KeyHandlerListener listener) {
this.direction = direction;
this.listener = listener;
}
@Override
public void actionPerformed(ActionEvent e) {
listener.keyHandlerDidPress(direction);
}
}
}
}