我有个简短的脚本,人们不断告诉我,我需要使用Key绑定来移动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); } }
与大多数事情一样,开始看看教程“ 如何使用键绑定”,几乎所有答案都将基于这些内容。
您可以做这样简单的事情…
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); } } }
正如我反复告诉您或您的同班同学一样,您不应该以这种方式使用组件。相反,您应该遵循自定义的绘画路线,从长远来看,它将为您提供更大的灵活性和更少的问题。
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); } } }
您还应该适当地使用布局管理器。这些可以保护您的头发和时间。
有关更多详细信息,请参见在容器中布置组件