Exiting fom actionlistener - java

How do I exit my program from an actionlistener. I have two threads, thread1 and thread2. One thread is in actionlistener. but i want the other thread to exit this actionlistener and manage rest of the code.. How can I do it?
sendtkttgt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Thread thread1= new Thread(){
public void run(){
SendingLogictoTGT obj=new SendingLogictoTGT();
try {
try {
obj.main(null);
} catch (InterruptedException ex) {
}
} catch (IOException ex) {
// System.exit(1);
}
}
};
/*Thread thread2= new Thread(){
public void run(){
//I want to exit from this actionlistener
}
};
*/
thread1.start();
}
});

interrupt() would be your best choice.

Related

How to stop a java swing timer

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.

Why do wait and notify function not working properly on same class lock

Why do wait and notify function not working properly on same class lock?
Please see check below code for wait and notify functionality and its output.
Output:
Thread-1
Thread-2
Thread-2 after notify
Expected Result:
Thread-1
Thread-2
Thread-2 after notify
Thread-1 after wait
Code:
public class WaitAndNotify1 {
public static void main(String[] args) {
Thread t1=new Thread(new Runnable(){
#Override
public void run(){
System.out.println("Thread-1");
try {
synchronized (this) {
wait();
System.out.println("Thread-1 after wait");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2=new Thread(new Runnable(){
#Override
public void run(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread-2");
synchronized (this) {
notify();
System.out.println("Thread-2 after notify");
}
}
});
t1.start();
t2.start();
}
}
You're using this from an anonymous inner class - so it refers to the instance of that anonymous inner class. There are two different instances (of different anonymous inner classes) so you're calling wait() on a different object from the one you're calling notify() on.
You don't actually have an instance of WaitAndNotify1 to synchronize on at the moment. You could move the code to an instance method, then use WaitAndNotify1.this to refer to the instance - at which point you'll get your expected output:
public class WaitAndNotify1 {
public static void main(String[] args) {
new WaitAndNotify1().test();
}
public void test() {
Thread t1=new Thread(new Runnable(){
#Override
public void run(){
System.out.println("Thread-1");
try {
synchronized (WaitAndNotify1.this) {
WaitAndNotify1.this.wait();
System.out.println("Thread-1 after wait");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2=new Thread(new Runnable(){
#Override
public void run(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread-2");
synchronized (WaitAndNotify1.this) {
WaitAndNotify1.this.notify();
System.out.println("Thread-2 after notify");
}
}
});
t1.start();
t2.start();
}
}

JOptionPane doesn't disappear until next JOptionPane appears

I have a process that shows confirm messages from JOptionPane. This process is called from SwingUtilities.invokeLater(runnable) that is inside an Actionlistener for a JMenuItem. The code for the runnable is this:
SwingUtilities.invokeLater(new Runnable(){
public void run(){
MyClass c=new MyClass(file)
try {
c.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
this.finalize();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
In MyClass there's this method:
private boolean userInput(){
String message="yes or no?";
JCheckBox checkbox = new JCheckBox("Do this for all.");
Object[] params={message,checkbox};
int n=JOptionPane.showConfirmDialog(null,params,"message",JOptionPane.YES_NO_OPTION);
boolean answer=(n==JOptionPane.YES_OPTION)?true:false;
if(checkbox.isSelected()){
nextQ=false;
nextA=answer;
}
return answer;
}
which is called many times. When a JOptionPane message is displayed, I click its button(yes/no), but the message won't disappear until the next message is displayed. What might be the problem? Does this has to do with the method invokeLater ?
I found the way to solve this. I had to create a new Thread inside the SwingUrtilities.invokeLater method. This is the new code:
SwingUtilities.invokeLater(new Runnable(){
public void run(){
Thread t=new Thread(new Runnable(){
MyClass c=new MyClass(file)
public void run(){
c.start();
}
});
t.start();
}
});

I can't finish thread (runnable), how it is?

Thread thread;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_yippi);
final Handler hn=new Handler();
final TextView text=(TextView)findViewById(R.id.TextView01);
final Runnable r = new Runnable()
{
public void run()
{
text.settext("hi");
}
};
thread = new Thread()
{
#Override
public void run() {
try {
while(true) {
sleep(1750);
hn.post(r);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
thread.stop();}
The code here. I can not stop the runnable thread. Also, thread.stop() and thread.destroy() are deprecated. Can somebody help me? And also I don't understand how to stop the thread with the thread.interrupt() method. What's wrong?
The JavaDoc for Thread.stop() lists the following article as explanation for why stop() is deprecated: http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Most uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized).
interrupt() is more suitable to stop some Thread from waiting for something, that is probably not coming anymore. If you want to end the thread, it's best to let its run() method return.
Create a boolean variable to stop the thread and use it in while(boolean) instead of while(true).
You can use Thread.interrupt() to trigger the InterruptedException within your thread. I've added code below that demonstrates the behavior. The mainThread is where your code would be and the timer Thread is just used to demonstrate delayed triggering of the interrupt.
public class Test {
public static void main(String[] args) {
final Thread mainThread = new Thread() {
#Override
public void run() {
boolean continueExecution = true;
while (continueExecution) {
try {
sleep(100);
System.out.println("Executing");
} catch (InterruptedException e) {
continueExecution = false;
}
}
}
};
mainThread.start();
Thread timer = new Thread() {
#Override
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Stopping recurring execution");
mainThread.interrupt();
}
};
timer.start();
}
}
You can use interrupt method of Thread to try stop a thread, like below code.
May be it`s useful to you.
public class InterruptThread {
public static void main(String args[]){
Thread thread = new Thread()
{
#Override
public void run() {
try {
while(true) {
System.out.println("Thread is Runing......");
sleep(1000);
}
} catch (InterruptedException e) {
// restore interrupted status
System.out.println("Thread is interrupting");
Thread.currentThread().interrupt();
}
}
};
thread.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Will Interrupt thread");
thread.interrupt();
}
}

Why is it so hard to stop a thread in Java?

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

Categories