This application has 2 threads the one shown here calls a method that pauses an auto clicker method every 4 seconds(just for ease) to do some mouse movement. I want it to stop the timer when you click the gui stop button.
Right now when you hit stop and then start again it then has two timers that will execute the code; and so on.
Action Listener Stuff.
class MyButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(view.getBtnStart()))
{
autoClick.unTerminate();
bool = true;
getInfo();
}
if (e.getSource().equals(view.getBtnExit()))
{
System.exit(0);
}
if (e.getSource().equals(view.getBtnStop()))
{
bool = false;
autoClick.terminate();
}
}//end of actionPerformed
}//end of inner class
Thread
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
Timer timer = new Timer(4000, new ActionListener() {//301000 5minutes and 1second
#Override
public void actionPerformed(ActionEvent evt) {
autoClick.timeOverload();
}
});
//if (!bool){timer.stop();}
timer.setRepeats(true); //false only repeates once
timer.start();
}
});//end of t2
It calls the timeOverload method repeatedly.
Thanks for your time and helping a newbie out :).
Here is a quick sample of how to declare a instance outside of your thread and be able to control it outside of it.
public static void main(String[] args){
final Timer timer = new Timer(500, new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("tick");
}
});
timer.setRepeats(true);
Thread t = new Thread(new Runnable() {
public void run() {
timer.start();
}
});
t.start();
try {
Thread.sleep(2600);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
timer.stop();
}
Basicly, you need to set the instance final to be used in a anonymous class (the ActionListener implementation).
Here, I just start the thread then pause the process for a few seconds and stop the timer.
Note that here, the Thread don't do anything else so it ends directly. You will need to tweek this a bit to match your needs but you have a working example.
EDIT : (DevilsHnd, if you post your answer, notify me, I will remove this part)
Using a flag (here in a Class)
public class Main {
public static void main(String[] args){
new Main();
}
boolean running = true;
public Main(){
final Timer timer = new Timer(500, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!running){
((Timer)e.getSource()).stop();
} else {
System.out.println("tick");
}
}
});
timer.setRepeats(true);
timer.start();
try {
Thread.sleep(2600);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
stop();
}
public void stop(){
running = false;
}
}
Calling the Main.stop() will set the flag to false, on each action performed, you check this flag, if it is false, you get the timer from the event (in the source) and stop it.
How can I implement a timer in Java 8? I prefer one simple method for this. I want to do something every 15 min or 30 min. Any idea?
you can use
Thread.sleep(milliseconds)
call the function you want and put it inside Runnable .
Example :
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(3000); // 3
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
//your Function
}
});
}
}).start();
OR
Thread t = new Thread(new Runnable() {
public void run() {
// stuff here
}});
t.start();
How can I use a timer to delay a calling a method once by a random time?
if(getDropPickup())
{
Timer timer = new Timer(getDelayTime(), new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
collectItems();
}
});
timer.setRepeats(false);
timer.start();
}
When I try to do something like this I have problems with the timer constructor being undefined. What is the best way to call a method after an amount of time without delaying the main thread?
You can create a Thread which uses Thread.sleep() so you wont block your main thread
while using the sleep method.
sample:
if(getDropPickup())
{
Thread t = new Thread(new Runnable() {
#Override
public void run() {
int delay = getDelayTime();
Thread.sleep(delay);
collectItems();
}
});
t.start();
}
here is my exemple of making a circular loading bar with Jlayer but now the layer start and stop after the execution of the btnLoad.addActionListener() and stop after a while of determinated timer (4000) so my problem that I need it to start when I click the button load
and stop after complete the loading of the file !!!
final WaitLayerUI layerUI = new WaitLayerUI();
jlayer = new JLayer<JPanel>(this, layerUI);
final Timer stopper = new Timer(4000,new ActionListener() {
public void actionPerformed(ActionEvent ae) {
layerUI.stop();
}
});
stopper.setRepeats(false);
if (!stopper.isRunning()) {
stopper.start();
}
btnLoad.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent ae) {
layerUI.start();
DataManager dataManager = new DataManager();
try {
dataManager.loadFromFile("C:/Users/*****PC/Downloads/****.csv");
} catch (Exception e) {
e.printStackTrace();
}
}
}
);
You should load the file on another Thread and not the Event Dispatch Thread. Assuming your loadFromFile method blocks until it loads the file, you can then hide the layer, but you must hide on the Event Dispatch Thread and not the new Thread you started for loading the file.
Remove your timer and replace your try block with this:
try {
new Thread(new Runnable(){
public void run() {
dataManager.loadFromFile("C:/Users/*****PC/Downloads/****.csv");
EventQueue.invokeLater(new Runnable(){
public void run() {
layerUI.stop();
}
});
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
I've come again in one of THOSE situations where it is just impossible to stop/destroy/suspend a thread. .interrupt() doesn't do the trick and .stop() and .suspend() are deprecated.
Very simple example:
public class TimerThread extends Thread {
private JPanel colorPanel;
public TimerThread(JPanel colorPanel) {
this.colorPanel = colorPanel;
}
public void run() {
while (true) {
try {
Thread.sleep(1000);
colorPanel.repaint();
} catch (Exception ex) {
//do Nothing
}
}
}
}
What this does is repaint a certain JPanel every second to change its colour. I want to start and stop the thread like this from another class:
timer = new Thread(new TimerThread(colorPanel));
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.interrupt();
}
});
Obviously (?) this doesn't work... I know I could use a Timer, a SwingWorker or declare the timer as timer = new TimerThread(colorPanel); and use a boolean instead of "true" in the run method, but I've been asked to declare timer as a "Thread" and nothing else.
To my surprise (or is this that stupid?), even this didn't work:
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer = new Thread(new TimerThread(colorPanel));
timer.start();
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.interrupt();
timer = null;
}
});
So my question is simple: How do you make threads Start/Pause/Resume/Stop in Java?
when you get an interrupt you should start the cleanup and return a.s.a.p. (or at the very least reset the interrupted status)
while (true) {
try {
Thread.sleep(1000);
colorPanel.repaint();
} catch(InterruptedException e){//from sleep
return;//i.e. stop
} catch (Exception ex) {
//do Nothing
}
}
another way is to check Thread.interrupted() in the condition (but you'll need to reset the interrupted status in the catch of InterruptedException
however in swing you can use javax.swing.Timer to let an event run every so often and stop that with the api of that
javax.swing.Timer timer = new Timer(1000,new ActionListener() {
public void actionPerformed(ActionEvent e) {
colorPanel.repaint();
}
});
timer.setRepeats(true);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.stop();
}
});
Try this:
public class TimerThread extends Thread {
private volatile boolean stop = false;
private JPanel colorPanel;
public TimerThread(JPanel colorPanel) {
this.colorPanel = colorPanel;
}
public void stopTimer() {
stop = true;
}
public void run() {
while (stop == false) {
try {
Thread.sleep(1000);
colorPanel.repaint();
} catch (Exception ex) {
//do Nothing
}
}
}
}
// Why new Thread(new TimerThread(...))?
// timer = new Thread(new TimerThread(colorPanel));
timer = new TimerThread(colorPanel)
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.stopTimer();
}
});
Also have a look at here to see how you can replicate stop now that it's deprecated.
You make them co-operate, basically. You have some shared flags to let them see what they should be doing, and whenever you would sleep, instead you wait on some shared monitor. Then when you want to control the thread, you set the appropriate flag and notify the monitor so that if the thread was waiting, it will wake up and notice that it should suspend/stop/whatever. Obviously you need to take the normal sort of care around shared state, using volatile variables, Atomic* objects or locking to make sure that every thread sees the updates made by every other thread.
Anything non-cooperative is risky due to the chance of corrupting state half way through an operation.
It is dangerous to stop threads pre-emptively. Doing so leads to deadlocks, resource leaks and so on. Instead you should use a cooperative signaling mechanism.
Signal to the thread that you want it to stop, and then wait for it to do so. The thread should regularly check whether it needs to stop and react accordingly.
Instead of looping while (true), you should loop while the thread is not interrupted:
#Override public void void() {
// some kind of initialization...
while (!Thread.currentThread().isInterrupted()) {
try { ...
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // ensure interrupt flag is set
}
}
// some kind of cleanup
}
If InterruptedException is not thrown by anything inside your while block, either you don't use blocking operations (and simply calling Thread.interrupt() on this thread would stop it the next iteration) or you use some blocking calls that are not well behaved (there are many such examples in the JCL itself!).
The correct way to do this is indeed to have a variable that determines when the Thread should be stopped, exiting from its run method. You can find more information about how to do this properly here
With this solution you won't get "instantaneous" updates that you could get with wait/notify or interrupt, but if you don't mind the fraction of a second delay, it should do the job.
volatile boolean stopped = false;
volatile boolean paused = false;
pauseButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
paused = true;
}
});
resumeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
paused = false;
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
stopped = true;
}
});
... TimerThread
public void run() {
while (stopped == false) {
try {
Thread.sleep(1000);
if (stopped)
break;
if (!paused)
colorPanel.repaint();
} catch (Exception ex) {
//do Nothing
}
}
}