java按钮随机移动_Java在按住按钮的同时使对象移动

您需要考虑许多重要的考虑因素.

>按钮并非按这种方式工作.它们被设计为在单击(按下和释放)时触发和动作事件,因此您不能使用常规的动作API.对我们来说幸运的是,还有其他方法可以确定按钮的状态.本示例在ButtonModel上使用ChangeListener并根据模型的状态执行操作.

>组件通常在布局管理器的控制下.这意味着为了能够移动组件,我们需要将其关闭(也称为空布局或绝对布局).通常,我不建议这样做,但这是唯一可行的方法.然而.删除布局管理器后,您有责任确保正确放置组件并调整其大小……这不能掉以轻心.您想要实现的目标的更多上下文将产生更好的答案

>当按钮被“按下”时,我们需要一种方法来确定移动组件的方法.本示例使用一个简单的枚举来确定移动组件的方向.您可以轻松地使用x / yDelta并直接修改组件的x / y位置.两者都应该工作正常.

> Swing是一个单线程环境.也就是说,对UI的所有交互和修改都应在事件调度线程的上下文中执行.但是,任何阻止EDT的操作都将阻止UI开始更新或阻止任何新事件开始处理.这意味着,为了移动组件,我们不能简单地使用while循环,因为它永远不会结束(不会处理任何新事件).相反,此示例使用javax.swing.Timer,它在后台等待并在EDT上下文中的每个刻度上引发ActionEvent.出现勾号时,我们修改面板的位置

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Container;

import java.awt.Dimension;

import java.awt.EventQueue;

import java.awt.GridBagConstraints;

import java.awt.GridBagLayout;

import java.awt.Point;

import java.awt.Rectangle;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.ItemEvent;

import java.awt.event.ItemListener;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import javax.swing.ButtonModel;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.Timer;

import javax.swing.UIManager;

import javax.swing.UnsupportedLookAndFeelException;

import javax.swing.event.ChangeEvent;

import javax.swing.event.ChangeListener;

public class MovePane {

public static void main(String[] args) {

new MovePane();

}

public MovePane() {

EventQueue.invokeLater(new Runnable() {

@Override

public void run() {

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {

}

JFrame frame = new JFrame("Testing");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setLayout(new BorderLayout());

frame.add(new TestPane());

frame.pack();

frame.setLocationRelativeTo(null);

frame.setVisible(true);

}

});

}

public enum Direction {

None, Up, Down, Left, Right;

}

public class TestPane extends JPanel {

private JPanel mobby;

private Timer moveTimer;

private Direction moveDirection = Direction.None;

public TestPane() {

mobby = new JPanel();

mobby.setBackground(Color.RED);

mobby.setSize(50, 50);;

setLayout(new BorderLayout());

JPanel pool = new JPanel(null);

pool.add(mobby);

add(pool);

JPanel buttons = new JPanel(new GridBagLayout());

JButton up = new JButton("Up");

JButton dwn = new JButton("Down");

JButton lft = new JButton("Left");

JButton rgt = new JButton("Right");

GridBagConstraints gbc = new GridBagConstraints();

gbc.fill = GridBagConstraints.HORIZONTAL;

gbc.gridx = 1;

gbc.gridy = 0;

buttons.add(up, gbc);

gbc.gridx = 1;

gbc.gridy = 2;

buttons.add(dwn, gbc);

gbc.gridx = 0;

gbc.gridy = 1;

buttons.add(lft, gbc);

gbc.gridx = 2;

gbc.gridy = 1;

buttons.add(rgt, gbc);

add(buttons, BorderLayout.SOUTH);

up.getModel().addChangeListener(new ChangeHandler(Direction.Up));

dwn.getModel().addChangeListener(new ChangeHandler(Direction.Down));

lft.getModel().addChangeListener(new ChangeHandler(Direction.Left));

rgt.getModel().addChangeListener(new ChangeHandler(Direction.Right));

moveTimer = new Timer(40, new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

Container parent = mobby.getParent();

Rectangle bounds = mobby.getBounds();

switch (moveDirection) {

case Up:

bounds.y--;

break;

case Down:

bounds.y++;

break;

case Left:

bounds.x--;

break;

case Right:

bounds.x++;

break;

}

if (bounds.x < 0) {

bounds.x = 0;

} else if (bounds.x + bounds.width > parent.getWidth()) {

bounds.x = parent.getWidth() - bounds.width;

}

if (bounds.y < 0) {

bounds.y = 0;

} else if (bounds.y + bounds.height > parent.getHeight()) {

bounds.y = parent.getHeight() - bounds.height;

}

mobby.setBounds(bounds);

}

});

moveTimer.setInitialDelay(0);

}

@Override

public Dimension getPreferredSize() {

return new Dimension(400, 400);

}

public class ChangeHandler implements ChangeListener {

private Direction direction;

public ChangeHandler(Direction direction) {

this.direction = direction;

}

@Override

public void stateChanged(ChangeEvent e) {

ButtonModel b = (ButtonModel) e.getSource();

if (b.isPressed()) {

moveDirection = direction;

moveTimer.start();

} else {

moveTimer.stop();

}

}

}

}

}

根据OP的输入进行了更新

令人惊讶的是,使用按键而不是按钮.您有一个开始操作和一个结束操作,您只需要弄清楚如何应用这些状态.

强烈建议您在KeyListener上使用Key Bindings.主要原因是KeyListener遭受焦点问题困扰,键绑定API具有克服或控制焦点的能力.

基本前提是,您要在按键和释放键上注册一个按键动作.使用键绑定API相对容易实现.

警告:此示例一次只允许一个方向.例如,如果按“向上”和“向下”,则向下操作将获胜.这是因为我正在使用枚举作为方向.您可以改为使用xDelta和yDelta值来轻松更改此设置,这将允许您同时修改垂直和水平方向…但是不能为您做任何事情;)

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Container;

import java.awt.Dimension;

import java.awt.EventQueue;

import java.awt.GridBagConstraints;

import java.awt.GridBagLayout;

import java.awt.Point;

import java.awt.Rectangle;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.ItemEvent;

import java.awt.event.ItemListener;

import java.awt.event.KeyEvent;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import javax.swing.AbstractAction;

import javax.swing.ActionMap;

import javax.swing.ButtonModel;

import javax.swing.InputMap;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.KeyStroke;

import javax.swing.Timer;

import javax.swing.UIManager;

import javax.swing.UnsupportedLookAndFeelException;

import javax.swing.event.ChangeEvent;

import javax.swing.event.ChangeListener;

public class MovePane {

public static void main(String[] args) {

new MovePane();

}

public MovePane() {

EventQueue.invokeLater(new Runnable() {

@Override

public void run() {

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {

}

JFrame frame = new JFrame("Testing");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setLayout(new BorderLayout());

frame.add(new TestPane());

frame.pack();

frame.setLocationRelativeTo(null);

frame.setVisible(true);

}

});

}

public enum Direction {

None, Up, Down, Left, Right;

}

public class TestPane extends JPanel {

private JPanel mobby;

private Timer moveTimer;

private Direction moveDirection = Direction.None;

public TestPane() {

mobby = new JPanel();

mobby.setBackground(Color.RED);

mobby.setSize(50, 50);;

setLayout(new BorderLayout());

JPanel pool = new JPanel(null);

pool.add(mobby);

add(pool);

moveTimer = new Timer(40, new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

Container parent = mobby.getParent();

Rectangle bounds = mobby.getBounds();

switch (moveDirection) {

case Up:

bounds.y--;

break;

case Down:

bounds.y++;

break;

case Left:

bounds.x--;

break;

case Right:

bounds.x++;

break;

}

if (bounds.x < 0) {

bounds.x = 0;

} else if (bounds.x + bounds.width > parent.getWidth()) {

bounds.x = parent.getWidth() - bounds.width;

}

if (bounds.y < 0) {

bounds.y = 0;

} else if (bounds.y + bounds.height > parent.getHeight()) {

bounds.y = parent.getHeight() - bounds.height;

}

mobby.setBounds(bounds);

}

});

moveTimer.setInitialDelay(0);

InputMap im = pool.getInputMap(WHEN_IN_FOCUSED_WINDOW);

ActionMap am = pool.getActionMap();

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "UpPressed");

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "UpReleased");

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "DownPressed");

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "DownReleased");

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "LeftPressed");

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "LeftReleased");

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "RightPressed");

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "RightReleased");

KeyUpAction keyUpAction = new KeyUpAction();

am.put("UpReleased", keyUpAction);

am.put("DownReleased", keyUpAction);

am.put("LeftReleased", keyUpAction);

am.put("RightReleased", keyUpAction);

am.put("UpPressed", new MoveAction(Direction.Up));

am.put("DownPressed", new MoveAction(Direction.Down));

am.put("LeftPressed", new MoveAction(Direction.Left));

am.put("RightPressed", new MoveAction(Direction.Right));

}

@Override

public Dimension getPreferredSize() {

return new Dimension(400, 400);

}

public class KeyUpAction extends AbstractAction {

@Override

public void actionPerformed(ActionEvent e) {

moveTimer.stop();

moveDirection = Direction.None;

}

}

public class MoveAction extends AbstractAction {

private Direction direction;

public MoveAction(Direction direction) {

this.direction = direction;

}

@Override

public void actionPerformed(ActionEvent e) {

moveDirection = direction;

moveTimer.start();

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值