2

i'm making a poker game for a uni assignment and i was wondering if there is any way to have a method that does as follows ( Note: very roughly written up code )

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");

Theres many many more instances i want to use this throughout my program, and just wondered if there is any way to do this.

Thanks in advance

EDIT: Not looking to use Thread.sleep() as it doesn't work well with gui. EDIT2: I want the pokerHand.setVisibility(true), and other methods in my code to execute AFTER the delay, ( using a timer doesn't do this ).

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Ryan Turnbull
  • 3,766
  • 1
  • 25
  • 35

2 Answers2

6

Not looking to use Thread.sleep() as it doesn't work well with gui.

Good, use a Swing Timer instead

I want the pokerHand.setVisibility(true), and other methods in my code to execute AFTER the delay, ( using a timer doesn't do this ).

Yes it does, you're just not using it properly, but since you've not provided any actual code, I can't say "how" you're not using it properly, only from the sounds of it, you are.

Start by taking a look at How to use Swing Timers for more details

The following is very simple example, it uses a Timer to calculate and print the amount of time between the time you clicked the button.

The example updates the UI AFTER the Timer is started, but until the Timer completes, the calculation and result are not generated

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");
                }
            });
        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
1

First, your code seems to be imperative ("ask user what to do", "game loop goes here") instead of event-driven ("when this happens, do that"). Read up on event-driven programming, which is used on all GUIs, sooner rather than later.

In event-driven code, there is no big difference between "user clicks a button" and "timeout expires" - both will cause events that your code can react to. So start by rewriting your code so that, once you press a button, the "next thing" happens. Then change it again so that once a timer expires, the same "next thing" happens.

Assuming that you have the following code:

// 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
}

You can now associate it to a button using:

// 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

And you can associate it to a timer as:

// launch a timer that will ring the nextThingListener every 2 seconds
new Timer(2000, nextThingListener).start();

If you want to have the timer ring only once, you can use

// launch a timer that will ring the nextThingListener after 2 seconds
Timer t = new Timer(2000, nextThingListener);
t.setRepeats(false);
t.start();
tucuxi
  • 17,561
  • 2
  • 43
  • 74