gpt4 book ai didi

java - 暂停 timerTask

转载 作者:行者123 更新时间:2023-11-30 05:55:48 25 4
gpt4 key购买 nike

我又碰壁了。让我的键输入工作后,我已经绞尽脑汁几个小时,我想创建一个暂停功能,这样如果再次按下同一个键,timertask 将停止运行(即游戏暂停)

JPanel component = (JPanel)frame.getContentPane();
component.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "space");
component.getActionMap().put("space", (new AbstractAction(){
public void actionPerformed(ActionEvent e){

Timer timer = new Timer();

timer.scheduleAtFixedRate(new TimerTask(){
public void run(){
grid.stepGame();
}
},250, 250);



}}));


}

问题是我不能使用全局 boolean 值 isRunning var 并在每次按下键时切换它,因为嵌套类中的 timerTask 方法(因此必须将 boolean 值 isRunning 声明为 final 才能访问...)。关于如何检测键是否再次按下或者游戏是否已经在运行以便我可以暂停/取消我的 timerTask 的任何想法。

非常感谢山姆

最佳答案

由于这是一个 Swing 游戏,您应该使用 javax.swing.Timer 或 Swing Timer 而不是 java.util.Timer。通过使用 Swing 计时器,您可以保证在 EDT 上调用间歇性调用的代码,这是 Swing 应用程序的一个关键问题,并且它还有一个暂停计时器的停止方法。您还可以为您的匿名 AbstractAction 类提供一个私有(private) boolean 字段,以检查该键是否是第一次按下。

此外,使用键绑定(bind)而不是 KeyListener 的荣誉和 1+。

例如,

  JPanel component = (JPanel) frame.getContentPane();
component.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "space");
component.getActionMap().put("space", (new AbstractAction() {
private boolean firstPress = true;
private int timerDelay = 250;
private javax.swing.Timer keyTimer = new javax.swing.Timer(timerDelay , new ActionListener() {

// Swing Timer's actionPerformed
public void actionPerformed(ActionEvent e) {
grid.stepGame();
}
});

// key binding AbstractAction's actionPerformed
public void actionPerformed(ActionEvent e) {
if (firstPress) {
keyTimer.start();
} else {
keyTimer.stop();
}

firstPress = !firstPress;
}
}));

另一个有用的选项是在按键按下时执行重复任务并在按键释放时停止,这可以通过获取按下和释放时的击键轻松完成:

KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true) // for key release
KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false) // for key press

例如:

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

public class SwingTimerEg2 {
private JFrame frame;
private Grid2 grid = new Grid2(this);
private JTextArea textarea = new JTextArea(20, 20);
private int stepCount = 0;

public SwingTimerEg2() {
frame = new JFrame();

textarea.setEditable(false);
frame.add(new JScrollPane(textarea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
setUpKeyBinding();
}

void setUpKeyBinding() {
final int timerDelay = 250;
final Timer keyTimer = new Timer(timerDelay, new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
grid.stepGame();
}
});
JPanel component = (JPanel) frame.getContentPane();
final int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
final String spaceDown = "space down";
final String spaceUp = "space up";
component.getInputMap(condition).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), spaceDown);
component.getActionMap().put(spaceDown, (new AbstractAction() {
public void actionPerformed(ActionEvent e) {
keyTimer.start();
}
}));
component.getInputMap(condition).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), spaceUp);
component.getActionMap().put(spaceUp, (new AbstractAction() {
public void actionPerformed(ActionEvent e) {
keyTimer.stop();
}
}));

}

public void doSomething() {
textarea.append(String.format("Zap %d!!!%n", stepCount));
stepCount ++;
}

private static void createAndShowGui() {
new SwingTimerEg2();
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}

}

class Grid2 {
private SwingTimerEg2 stEg;

public Grid2(SwingTimerEg2 stEg) {
this.stEg = stEg;
}

void stepGame() {
stEg.doSomething();
}
}

关于java - 暂停 timerTask,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7859656/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com