I have 6 objects in the class GUI which are moving through the code:
Anim anim = new Anim();
Timer timer = new Timer();
timer.scheduleAtFixedRate(anim, 30, 30);
When an object comes to a point I want to stop it. In class Anim I'm doing:
public class Anim extends TimerTask {
#Override
public void run() {
if (t1.x == 300 && t1.y == 300) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
It stops application, and I want have stayed at a concrete object. How to do it?
EDIT:
Ok, now it works well, does not interfere with other objects. But the object is moving on and after 1 second back to the starting position. I wish the whole time he was in the same position when a sleep.
if (Main.auto1.x == 700 && Main.auto1.y == 350) {
timer = new javax.swing.Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
Main.auto1.x = 700;
Main.auto1.y = 350;
}
});
timer.setRepeats(false);
timer.start();
Use Swing Timer instead of Thread.sleep() and Java Timer in a Swing application that sometime hangs the Swing applicaion.
Read more How to Use Swing Timers
Sample code:
private Timer timer;
...
timer = new javax.swing.Timer(3000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
//do what ever you want to do
// call timer.stop() when the condition is matched
}
});
timer.setRepeats(true);
timer.start();
EDIT
Please have a look at my another post How to fix animation lags in Java?
Related
(V1) I have a countdown object that deals with displaying a countdown on the JFrame by using a timer. Once the countdown goes to 0, I want the timer to stop and the game to start. However, I realized that even when my countdown isn't finished, my startGame() method is being run, and I cannot find a solution to make it so that the startGame() method only runs after the timer is stopped. So, my question is: is there anyway to make sure the startGame() only runs AFTER the countdown hits zero?
(V2) I tried using countdown.getTimer.isRunning()in the init() method to check whether or not the timer is running (if not then call startGame()) but that didn't seem to work. I'm guessing this is because at the time the if block is called, the timer is still running, so that's why startGame() isn't called... Is this why?
A little explanation of the code: the startCountdown() method tries to display the next image while hiding the last, so I have the catch for the first case where it tries to hide a non-existant image at an index that is out of bounds. Each time the timer ticks, I decrement sec by 1 until it is 0, and then the timer stops.
V1
public void init() {
countdown.startCountdown();
countdown.getTimer().start();
startGame();
}
public void startCountdown() {
timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
if (sec == 0) {
countdownIcons.get(0).setVisible(false);
timer.stop();
}
countdownIcons.get(sec - 1).setVisible(true);
countdownIcons.get(sec).setVisible(false);
} catch (IndexOutOfBoundsException exception) {
if (sec == 0) {
timer.stop();
}
}
sec--;
System.out.println(sec);
}
});
}
V2
public void init() {
countdown.startCountdown();
countdown.getTimer().start();
if (!countdown.getTimer().isRunning()) {
startGame();
}
}
The problem is that the Timer method runs on a separate thread, different from your main thread.
The way I see it there are two possible solutions:
call your startGame() method inside startCountdown(), not inside init();
the second solution would be to pause your main thread and wait for startCountdown() to finish, something like this should work:
public void init() {
countdown.startCountdown();
countdown.getTimer().start();
// pause main thread until timer is notified
synchronized(timer){
timer.wait()
startGame();
}
}
public void startCountdown() {
timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
if (sec == 0) {
countdownIcons.get(0).setVisible(false);
timer.stop();
// notify your current thread that it can resume execution
synchronized(timer){
timer.notify();
}
}
countdownIcons.get(sec - 1).setVisible(true);
countdownIcons.get(sec).setVisible(false);
// try not to catch this runtime exception and fix what causes IndexOutOfBoundsException
} catch (IndexOutOfBoundsException exception) {
if (sec == 0) {
timer.stop();
}
}
sec--;
System.out.println(sec);
}
});
}
I'm trying to stop the program for a second using Swing Timer.
Timer timer = new Timer(10000,
new ActionListener(public void actionPerformed(ActionEvent e) {}));
didn't work
public class Card extends JButton implements ActionListener {
int numberClick = 0;
public card() {
addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
numberClick++;
if(numberClick == 2) {
Timer timer = new Timer(10000, );
timer.start();
numberClick = 0;
}
}
}
You seem to lack basic understanding of how the Timer works. Please read How to Use Swing Timers. The concept is fairly simple.
The first argument in the Timer constructor is the delay. Seems you have that part down. The second argument is the ActionListener that listens for the "Timer Events" (actually ActionEvents). An event is fired each delayed time. The callback (actionPerformed) contains what should be performed after that delay (tick). So whatever you want to happen after that second, put it in the actionPerformed of the timer's ActionListener.
Also if you only want it t occur once, you should call timer.setRepeats(false);. Also note, you are using 10000, which is in milliseconds, so it's 10 seconds, not 1. You should change it to 1000
Example Flow
JButton button = new JButton("Press Me");
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
Timer timer = new Timer(1000, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Print after one second");
}
});
timer.setRepeats(false);
timer.start();
}
});
Press Button → Wait One Second → Print Statement
I am trying to implement a Thread.sleep(6000) line but it seems to freeze in the applet. When I tried to use Timers, I wasn't sure how to use because I am not very good with event listeners. I am basically trying to call a method fetchUrl() every 6 seconds, after the user clicks the enter button. How can I implement this?
public void init() {
c = getContentPane();
c.setLayout(flow);
c.setBackground(forum);
question.setForeground(Color.white);
question.setFont(tnr);
question2.setForeground(Color.white);
question2.setFont(tnr);
result.setForeground(Color.white);
result.setFont(tnr);
resp.setBorder(BorderFactory.createBevelBorder(0));
timeLength.setBorder(BorderFactory.createBevelBorder(0));
c.add(question);
c.add(resp);
c.add(question2);
c.add(timeLength);
c.add(enter);
c.add(result);
resp.requestFocus();
enter.addActionListener(this);
t = new Timer(DELAY, this);
t.setInitialDelay(DELAY);
}
public void actionPerformed(ActionEvent e) {
final String n1;
int timeMin, timeSec, count = 0, maxCount;
timeMin = Integer.parseInt(timeLength.getText());
timeSec = timeMin * 60;
maxCount = (int)(timeSec/6);
if (e.getSource() == enter) { //user clicks enter
n1 = resp.getText();
while (count < maxCount) {
fetchUrl(n1); //this method called every 6 seconds
t.start();
count++;
}
}
}
First I would start by separating the ActionListener for the Timer and for the JButton.
Second nothing is happening logically with the Timer because you're swallowing it with the button source check.
Third you should understand how the timer works. Basically for every "tick" (in your case six seconds) the actionPerformed of the timer ActionListener is called. So if you want the fetch() method called, then that's what you should be visible/accessible to the in the Timer's actionPerformed.
The button's ActionListener should only handle the starting of the timer I believe. So just separate the listeners. Give each one an anonymous ActionListener and no need to make the class implement ActionListener.
For example
timer = new Timer(DELAY, new ActionListener(){
public void actionPerformed(ActionEvent e) {
// do some stuff every six seconds
fetchURL();
}
});
enter = new JButton(...);
enter.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
If you want some automatic stopping feature for the timer, you could do something like
timer = new Timer(DELAY, new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (someStoppingCondition()) {
timer.stop();
} else {
// do some stuff every six seconds
fetchURL();
}
// do some stuff every six second
}
});
You need to call a method after user clicks on button every 6 seconds, but you have not said how many times you want to call it.
For infinite number of times, try something like the following,
while(true){
new Thread(){
#Override
public void run(){
try{
Thread.sleep(6000);
fetchUrl(n1);
}catch(InterruptedException e){}
}
}.start();
}
If you will use Thread.sleep() in your applet, then your applet will be hanged for 6 seconds and so create a new thread for it.
I've been working on a simple game using a Java Applet in which the player's goal is to get as many points as possible within a 30 second timeframe. Right now, I'm using a Swing timer to count down from 30 seconds, and once the 0 mark is reached, a "game over" screen is displayed with the player's score. I have these instance variables:
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
screenState = 0;
repaint();
}
};
Timer displayTimer = new Timer(30000, listener);
When the player clicks the "play" button, I execute displayTimer.start();.
Then, I have this within the appropriate case in my paint class:
g.drawString("Time Remaining: " + displayTimer.getDelay()/1000, 650, 100);
So, obviously, right now it's just displaying a static "Time Remaining: 30", and the screens switches after 30 seconds. What I'm trying to figure out is how I can repaint this value every one second so that it's a live timer. The only help I've been able to find thus far is for people use components.
ActionListener listener = new ActionListener() {
int count = 0;
#Override
public void actionPerformed(ActionEvent e) {
if (count++==30) {
screenState = 0;
}
repaint();
}
};
Timer displayTimer = new Timer(1000, listener); // make it 30 times faster
You can use the a Thread that sleep it every one second using the sleep method of it
Here is a little sample that count to 30 with 1 second interval
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
int count = 0;
while(true)
{
if(count == 30) //end at 30 second
break;
try {
Thread.sleep(1000);
System.out.println("updated");
++count;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
}
I am making a simple target shooting game.I have a countdownTimer inside the label and an object that blinks in a random position inside the panel. Every time I click on the object,. the object's timer stops which makes that object stop too, but the countdown timer doesn't and that is my problem. I want the countdown timer should stop also.
Could someone help me about this matter?
Here's the code :
private void starting()
{
new Timer(TIMER_PERIOD, new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if (count++ < MAX_COUNT)
{
String text = "Time remaining: (" + (MAX_COUNT - count) + ") seconds left";
setCountDownLabelText(text);
Date date = new Date();
setCountDownPanelText(date);
}
else
{
((Timer) e.getSource()).stop();
randomTimer.stop();
JOptionPane.showMessageDialog(null, "Game Over");
System.exit(0);
}
}
}).start();
}
It strikes me that you don't understand the code at all, that you are unaware of the anonymous class created that is extending Timer, which (if you'd seen the documentation) has a function stop() which does what you ask.
You need to store a reference to the Timer.
private javax.swing.Timer timer;
private void starting() {
timer = new Timer(TIMER_PERIOD, new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
// do stuff
// stop the timer
timer.stop();
// do other stuff
}
}
}