使用按键绑定进行 JLabel 移动

2023-12-29

我在 swing 中制作了一个简短的脚本,人们不断告诉我,我需要使用按键绑定来让 Jlabel 移动,但我不知道该怎么做。任何人都知道如何以不使用按键侦听器的方式实现按键绑定,或者如果我添加按钮,这将是一个问题?

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.border.EmptyBorder;
import java.awt.CardLayout;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.ActionEvent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.SwingConstants;
import java.awt.Color;
import java.awt.Font;

public class Screen extends JFrame {

    private JPanel contentPane;
    int x,y;

    /**
     * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Screen frame = new Screen();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Screen() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(new CardLayout(0, 0));

    JPanel panel = new JPanel();
    contentPane.add(panel, "p1");
    panel.setLayout(null);

    JButton btnPlay = new JButton("Play");
    btnPlay.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            CardLayout c =(CardLayout)(contentPane.getLayout());
            c.show(contentPane, "p2");
        }
    });
    btnPlay.setBounds(185, 164, 53, 23);
    panel.add(btnPlay);

    JLabel lblGame = new JLabel("Game");
    lblGame.setHorizontalAlignment(SwingConstants.CENTER);
    lblGame.setBounds(189, 28, 46, 14);
    panel.add(lblGame);

    JPanel panel_1 = new JPanel();
    contentPane.add(panel_1, "p2");
    panel_1.setLayout(null);

    JLabel player = new JLabel("P");
    player.setHorizontalAlignment(SwingConstants.CENTER);
    player.setFont(new Font("Tahoma", Font.BOLD, 27));
    player.setForeground(Color.BLACK);
    player.setBackground(Color.BLACK);
    player.setBounds(x, y, 51, 40);
        panel_1.add(player);
}
}

与大多数事情一样,开始查看教程,如何使用按键绑定 https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html,因为几乎任何答案都将基于这些

你可以做这样简单的事情......

import com.sun.glass.events.KeyEvent;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

    public Test() {
        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 TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public interface Movable {
        public void changeLocation(int xDelta, int yDelta);
    }

    public class TestPane extends JPanel implements Movable {

        private JLabel player;

        public TestPane() {
            setLayout(null);
            player = new JLabel("X");
            player.setSize(player.getPreferredSize());
            add(player);

            setupKeyBindings();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void setupKeyBindings() {
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "up");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "down");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right");

            int xDelta = player.getWidth();
            int yDelta = player.getHeight();

            am.put("up", new MoveAction(this, 0, -yDelta));
            am.put("down", new MoveAction(this, 0, yDelta));
            am.put("left", new MoveAction(this, -xDelta, 0));
            am.put("right", new MoveAction(this, xDelta, 0));
        }

        @Override
        public void changeLocation(int xDelta, int yDelta) {
            int xPos = player.getX() + xDelta;
            int yPos = player.getY() + yDelta;
            if (xPos + player.getWidth() > getWidth()) {
                xPos = getWidth() - player.getWidth();
            } else if (xPos < 0) {
                xPos = 0;
            }
            if (yPos + player.getHeight() > getHeight()) {
                yPos = getHeight() - player.getHeight();
            } else if (xPos < 0) {
                yPos = 0;
            }
            player.setLocation(xPos, yPos);
        }

    }

    public class MoveAction extends AbstractAction{
        private Movable movable;
        private int xDelta;
        private int yDelta;

        public MoveAction(Movable movable, int xDelta, int yDelta) {
            this.movable = movable;
            this.xDelta = xDelta;
            this.yDelta = yDelta;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            movable.changeLocation(xDelta, yDelta);
        }

    }

}

免责声明...

正如我多次告诉您或您的同学,您不应该以这种方式使用组件。相反,您应该遵循自定义绘画路线 https://docs.oracle.com/javase/tutorial/uiswing/painting/index.html,从长远来看,这将为您提供更大的灵活性和更少的问题。

import com.sun.glass.events.KeyEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
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.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

    public Test() {
        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 TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public interface Movable {

        public void changeLocation(int xDelta, int yDelta);
    }

    public class TestPane extends JPanel implements Movable {

        private Rectangle player;

        public TestPane() {
            String text = "X";
            FontMetrics fm = getFontMetrics(getFont());
            int width = fm.stringWidth(text);
            int height = fm.getHeight();

            player = new Rectangle(0, 0, width, height);

            setupKeyBindings();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void setupKeyBindings() {
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "up");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "down");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right");

            int xDelta = player.width;
            int yDelta = player.height;

            am.put("up", new MoveAction(this, 0, -yDelta));
            am.put("down", new MoveAction(this, 0, yDelta));
            am.put("left", new MoveAction(this, -xDelta, 0));
            am.put("right", new MoveAction(this, xDelta, 0));
        }

        @Override
        public void changeLocation(int xDelta, int yDelta) {
            int xPos = player.x + xDelta;
            int yPos = player.y + yDelta;
            if (xPos + player.width > getWidth()) {
                xPos = getWidth() - player.width;
            } else if (xPos < 0) {
                xPos = 0;
            }
            if (yPos + player.height > getHeight()) {
                yPos = getHeight() - player.height;
            } else if (xPos < 0) {
                yPos = 0;
            }
            player.setLocation(xPos, yPos);
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.RED);
            g2d.draw(player);
            FontMetrics fm = g2d.getFontMetrics();
            g2d.drawString("X", player.x, player.y + fm.getAscent());
            g2d.dispose();
        }

    }

    public class MoveAction extends AbstractAction {

        private Movable movable;
        private int xDelta;
        private int yDelta;

        public MoveAction(Movable movable, int xDelta, int yDelta) {
            this.movable = movable;
            this.xDelta = xDelta;
            this.yDelta = yDelta;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            movable.changeLocation(xDelta, yDelta);
        }

    }

}

您还应该适当使用布局管理器。这些将为您节省大量的头发和时间。

See 在容器内布置组件 https://docs.oracle.com/javase/tutorial/uiswing/layout/index.html更多细节

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用按键绑定进行 JLabel 移动 的相关文章

随机推荐

  • 在 C# 中将时间转换为格式化字符串

    Time ToString 0 0 显示为十进制 1 5 而不是 1 30 如何让它以时间格式显示 private void xTripSeventyMilesRadioButton CheckedChanged object sender
  • 无法通过 tor ConnectionRefusedError 发出 python 请求:[WinError 10061]

    我试图通过 tor 使用 python 请求发出请求 但收到错误 ConnectionRefusedError WinError 10061 无法建立连接 因为目标计算机主动拒绝它 这是我正在使用的代码 import requests de
  • 长 iPhone 应用程序名称将显示在多行中

    我的应用程序名称长度为 17 个字符 当安装在设备上时 它看起来像应用程序 名称 有没有办法在多行上显示应用程序名称 请帮忙 不 你不能 我认为 iPad 支持 15 个字符来完整显示应用程序名称 iPhone 支持 14 个字符 iPho
  • Matplotlib:光标捕捉到带有日期时间轴的绘制数据

    我有一个由 3 个数据集组成的图 其中 x 轴上有日期时间对象 我想要一个可以捕捉数据并显示精确的 x 和 y 值的光标 我已经有一个 捕捉光标 但这只适用于标量 x 轴 谁能帮我修改捕捉光标 使其也适用于日期时间 x 轴 Here are
  • 计算appwidget的高度

    我无法通过谷歌搜索这个问题找出或找到解决方案 我有一个带有 appwidget 的 Android 应用程序 看起来像http www livescorewidget eu img screendumps widget png http w
  • 具有外部域注册商的 Route 53?

    我创建了一个 Route 53 托管区域 其中包含 SOA NS 记录和 A 记录 A 记录指向我在 AWS 上托管的 Web 实例 在注册商上 我需要使用什么才能让域使用 Amazon Route 53 仅仅是名称服务器吗 或者我需要 A
  • 创建事件是否是将 XF OnAppearing 变成异步方法的有效方法?

    我最近看到了关于如何将应用程序 OnStart 变成异步 OnStart 的建议 protected override void OnStart this started onStarted Subscribe to event start
  • 创建配置节处理程序时出错

    我有一个 dot NET 4 0 Web 应用程序 定义了自定义部分
  • 具有单行 TabPanel 和溢出面板的 TabControl

    我想将 WPF TabControl 的功能更改为仅生成一行 并为每个其他项目 如 ToolBar ToolBarOverflowPanel 创建一个溢出弹出窗口 目前 VisualStudio 中选项卡的显示方式相同 这就是我得到的
  • Swift 3 GCD 锁定变量和 block_and_release 错误

    我正在使用 Swift 3 GCD 来在我的代码中执行一些操作 但我越来越 dispatch call block and release经常出错 我想这个错误背后的原因是因为不同的线程修改相同的变量 但我不知道如何解决问题 这是我的代码和
  • 从参数化测试访问夹具(例如,capsys)

    我在参数化测试中访问固定装置 在本例中为 capsys 时遇到问题 目前我正在使用一个虚拟夹具来完成这项工作 import pytest pytest fixture def params request from collections
  • 如何在 Swift 中从文件(而不是整个文件)读取数据块

    假设我有一个 8 字节长的文件 仅包含 ASCII 字符 brownfox 我不想加载 2 个字节的块 而不是加载整个文件并处理 if UInt8 并对 2 字节大小的块进行操作 因此操作如下 load br从文件 和not整个文件 对数据
  • 云代码函数运行两次

    我写了一个运行良好的云函数 有时 同一用户会多次执行此函数 我确保客户端 Android 应用程序只请求一个请求 经过一些调试后 我注意到如果连接不良就会出现此问题 我可能是正确的 也可能不正确 如何克服这样的问题 正如评论中所述 我也不相
  • 如何使用 php 在数据库中插入和检索图像

    我正在尝试上传会员个人资料的图像并使用 php 将其存储在数据库中 然后检索它 但它对我不起作用 这就是我尝试插入图像的方法
  • 通过删除 numpy 数组来释放内存

    我编写了一个带有 GUI 的疲劳分析程序 该程序获取有限元模型每个元素的单位载荷的应变信息 使用 np genfromtxt loadcasefilename txt 读取载荷工况 然后进行一些疲劳分析并将每个元素的结果保存在另一个数组中
  • 多个 CSS @media 条件似乎不起作用

    我正在尝试修改 CSS 中的几个类以适应不同的屏幕分辨率 我的目标是 默认应用的 CSS 宽度为 1200 嵌入在 CSS 中的媒体查询 用于 601 到 601 之间的分辨率 1199 px 这不起作用 嵌入在 CSS 中的媒体查询 分辨
  • django 的递归查询集

    我有这个模型引用自身以允许构建一棵树 class PartCategory models Model parent models ForeignKey PartCategory on delete models DO NOTHING nul
  • 如何合并同一列中的单元格,应用行跨度?

    在我的报告的 jrxml 设计中 我的详细信息部分有一列为特定组打印相同的内容 例如 如果我有一个国家列美国 下一列包含其州 每个条目都会重复 美国国家 地区 所以我需要合并具有美国价值的国家 地区单元格 我需要合并列中具有相同值的所有单元
  • 为什么使用 from __future__ import print_function 会破坏 Python2 风格的打印? [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我是Python编程新手 我试图用分隔符和结尾打印出来 但它仍然给我一个语法错误 我正在使用Python 2 7 这是我的代码 f
  • 使用按键绑定进行 JLabel 移动

    我在 swing 中制作了一个简短的脚本 人们不断告诉我 我需要使用按键绑定来让 Jlabel 移动 但我不知道该怎么做 任何人都知道如何以不使用按键侦听器的方式实现按键绑定 或者如果我添加按钮 这将是一个问题 import java aw