任何延迟Java GUI中的操作的方法

时间:2016-05-30 08:50:10

标签: java swing jtextarea

我正在制作一个单一任务的扑克游戏,我想知道是否有任何方法可以使用如下方法(注意:非常粗略地编写代码)

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),以及我的代码中的其他方法在延迟后执行,(使用计时器不会这样做)。

2 个答案:

答案 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();