我正在制作一个单一任务的扑克游戏,我想知道是否有任何方法可以使用如下方法(注意:非常粗略地编写代码)
JTextArea textArea = new JTextArea();
public void printer(String s){
//I want to delay here, for 2 seconds each time i print to the jtextarea
textArea.append(s);
}
public void runGame(){
printer("Dealing cards...");
//I want to delay to add to an effect of the time it takes to actually deal the cards
pokerHand.setVisibility(true);
printer("What you like to do?");
//
//Code here containing running the game
//
printer("Daniel Negreanu folds");
//I want to have a delay here for the time it takes to make a decision.
printer("Phil Hellmuth folds");
我想在整个程序中使用这个实例,还有很多实例,只是想知道是否有办法做到这一点。
提前致谢
编辑:不想使用Thread.sleep(),因为它与gui不兼容。 EDIT2:我想要pokerHand.setVisibility(true),以及我的代码中的其他方法在延迟后执行,(使用计时器不会这样做)。
答案 0 :(得分:5)
不希望使用Thread.sleep(),因为它不能与gui一起使用。
好,请使用Swing Timer
代替
我想要pokerHand.setVisibility(true),以及我的代码中的其他方法在延迟后执行(使用计时器不会这样做)。
是的,你没有正确使用它,但由于你没有提供任何实际的代码,我不能说"如何"你没有正确使用它,只能听到它的声音,你是。
首先查看How to use Swing Timers了解更多详情
以下是一个非常简单的示例,它使用Timer
来计算和打印单击按钮之间的时间量。
该示例在Timer
启动后更新UI,但在Timer
完成之前,不会生成计算和结果
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.LocalTime;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.Timer;
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 class TestPane extends JPanel {
private JTextArea ta;
private JButton btn;
private Timer timer;
private LocalTime startTime, endTime;
public TestPane() {
setLayout(new BorderLayout());
ta = new JTextArea(10, 20);
add(new JScrollPane(ta));
btn = new JButton("Click");
add(btn, BorderLayout.SOUTH);
timer = new Timer(2000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
endTime = LocalTime.now();
Duration duration = Duration.between(startTime, endTime);
ta.append("Ended @ " + endTime + "\n");
ta.append("Took " + (duration.toMillis() / 1000) + " seconds\n");
}
});
timer.setRepeats(false);
ta.setEditable(false);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
timer.start();
startTime = LocalTime.now();
btn.setEnabled(false);
ta.append("Start @ " + startTime + "\n");
}
});
}
}
}
答案 1 :(得分:1)
首先,你的代码似乎势在必行(#34;要求用户做什么","游戏循环在这里")而不是事件驱动("当这发生时,做那")。阅读所有GUI上使用的event-driven programming,而不是迟早。
在事件驱动的代码中,"用户点击按钮"之间没有太大的区别。和"超时到期" - 两者都会导致代码可以做出反应的事件。所以首先要重写你的代码,这样,一旦你按下按钮,接下来的事情"发生。然后再次更改它,以便一旦计时器到期,相同的"接下来的事情"发生的情况。
假设您有以下代码:
// an ActionListener for both clicks and timer-expired events
private nextThingListener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
doNextThing();
}
};
// method that does the next thing
public void doNextThing() {
// change the UI in some way
// if using timers, may also start the next timer
}
现在可以使用以下方法将其与按钮关联:
// create a button and have it do the "next thing" when clicked
JButton jb = new JButton("do next thing");
jb.addActionListener(nextThingListener);
myInterface.add(jb); // <-- display it in the interface somehow
您可以将它与计时器关联为:
// launch a timer that will ring the nextThingListener every 2 seconds
new Timer(2000, nextThingListener).start();
如果您只想让定时器响铃一次,可以使用
// launch a timer that will ring the nextThingListener after 2 seconds
Timer t = new Timer(2000, nextThingListener);
t.setRepeats(false);
t.start();