使用Java Applet实现键盘侦听器

时间:2016-02-28 22:03:38

标签: java swing keylistener japplet

我正在尝试用Java创建一个简单的游戏。我正在使用BlueJ IDE,我的代码目前如下:

import java.util.*;
import java.awt.*;
import javax.swing.*;    

public class GameGraphic extends JApplet
{

    // Variable initialization
    private Board board;
    private Dice dice;
    private ArrayList<Player> players; 
    private Player currentPlayer;

    // etc..

    public void init()
    {
        setSize(600,800);

        // Code to initialize game, load images
        // etc..

    }

    // Game method etc..

    public void paint(Graphics g)
    {
        // Drawing game board etc..

        turn++;
        int diceRoll = dice.roll();


        advancePlayer(currentPlayer, steps);
        changeCoins(currentPlayer, diceRoll);

        whoseTurn = (whoseTurn+1)%players.size();

        while(command=="w") {
        }

        try {
        Thread.sleep(3000);
        } catch(InterruptedException ex) {
        Thread.currentThread().interrupt();
        } 

        revalidate();
        repaint();
    }
}

现在,它被用于模拟,一切运行良好,每3秒进入下一个回合。我想要做的是使用键盘输入转到下一回合。我希望它基本上绘制板,等到字符输入,如果字符是“n”然后前进一转(基本上运行paint()一次迭代并再次等待)。 实现这个的最佳方法是什么?我尝试使用KeyListener,但看起来它不适用于AWT。非常感谢你:))

2 个答案:

答案 0 :(得分:2)

让我们开始吧,小程序是正式的死技术,我不会浪费时间试图让它们工作,相反,我会把你的精力集中在API的其他方面。有关详细信息,请参阅Java Plugin support deprecatedMoving to a Plugin-Free Web

您不应该在事件调度线程的上下文中调用Thread.sleep(或执行任何其他长时间运行或阻塞操作),尤其不要在paint方法的上下文中调用Timer。有关详细信息,请参阅Concurrency in Java

你永远不应该调用任何可以直接或间接产生重画的方法,绘画是用于绘画而不是其他任何东西,这样做可能会使EDT挨饿并导致程序无响应。

在Swing中执行动画的一个简单解决方案是使用Swing KeyListener,它不会阻止EDT,但会触发它在EDT内容中的更新,从而可以安全地从内部更新UI

有关详细信息,请参阅How to use Swing Timers

我还建议您查看Painting in AWT and SwingPerforming Custom Painting,因为如果您打算进行任何类型的自定义绘画,您应该了解绘画过程的工作原理。

Timer是一个低级API,它遇到键盘焦点问题(如果它注册的组件没有键盘焦点,它不会生成事件),相反,你应该使用{{ 3}} API代替。

在以下示例中,发生了两件事。是turn更新“运行时间”值,当您按 N 键时,它会更新import java.awt.Dimension; import java.awt.EventQueue; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; 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.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class GameGraphic { public static void main(String[] args) { new GameGraphic(); } public GameGraphic() { 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 GamePane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class GamePane extends JPanel { private int turn = 0; private long runtime; public GamePane() { InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW); ActionMap actionMap = getActionMap(); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_N, 0), "next"); actionMap.put("next", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { System.out.println("..."); turn++; repaint(); } }); long startTime = System.currentTimeMillis(); Timer timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { runtime = System.currentTimeMillis() - startTime; repaint(); } }); timer.start(); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); int width = getWidth(); int height = getHeight(); FontMetrics fm = g2d.getFontMetrics(); String text = Integer.toString(turn); int x = (width - fm.stringWidth(text)) / 2; int y = ((height - fm.getHeight()) / 2) + fm.getAscent(); g2d.drawString(text, x, y); text = Long.toString(runtime); x = width - fm.stringWidth(text); y = height - fm.getHeight() + fm.getAscent(); g2d.drawString(text, x, y); g2d.dispose(); } } } 变量

Given I open "google.com" simultaneously in both FF and IE
When I type "stackoverflow" and submit
Then I should see the desired results

答案 1 :(得分:0)

在java中有一个名为 KeyListener 的接口(接口意味着面向对象编程中的概念)

您将KeyListener添加到对象,这是一个示例:

https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html

这是一个包含java游戏示例http://www.edu4java.com/en/game/game4.html的网站(非常好......)