public class Signal2NoiseRatio
{
public ImagePlus SingleSNR(ImagePlus imagePlus) throws InterruptedException
{
new Thread()
{
#Override public void run()
{
JFrame imageFrame = new JFrame("ROI");
Container imageFrame_Container = imageFrame.getContentPane();
IIImagePanel imagePanel = new IIImagePanel();
imageFrame_Container.add(imagePanel);
imagePanel.setImage(imagePlus.getImage());
imagePanel.getDisplayedImage();
imageFrame.setVisible(true);
final SNRSingleImageListener sNRSingleListener = new SNRSingleImageListener(imagePanel);
imagePanel.addMouseListener(sNRSingleListener);
imagePanel.addMouseMotionListener(sNRSingleListener);
}
}.start();
new Thread()
{
#Override public void run()
{
for (int i = 0; i <= 2000; i++)
{
System.out.println("schleife "+i);
// ask if useractions are done ..
}
synchronized( Signal2NoiseRatio.this )
{
Signal2NoiseRatio.this.notifyAll();
}
}
}.start();
synchronized (this)
{
this.wait();
// if userinteractions are done, go on
}
return imagePlusToProcess;
}
}
The first new Thread() perform a frame which presents an image in it. My intention was to present the image in a new thread to wait for some user interactions on the image. But the code leads the frame to a white window and the image is not visible and the frame is not usable.
In the second thread I want ask in a short interval if the user actions are done.
It is not really a nice solution but it is be possible? what's wrong here?
Thank you stackoverflow!
I can see a few problems here:
1.If this
synchronized (this)
{
this.wait();
// if userinteractions are done, go on
}
is happening on the UI thread, then you will block it from receiving user input (or doing anything else) until the object is signaled.
2.This part seems pretty much overcomplicated:
new Thread() {
#Override
public void run() {
for (int i = 0; i <= 2000; i++) {
System.out.println("schleife " + i);
// ask if useractions are done ..
}
synchronized (Signal2NoiseRatio.this) {
Signal2NoiseRatio.this.notifyAll();
}
}
}.start();
synchronized (this) {
this.wait();
// if userinteractions are done, go on
}
Just use:
Thread t = new Thread() {
#Override
public void run() {
for (int i = 0; i <= 2000; i++) {
System.out.println("schleife " + i);
// ask if useractions are done ..
}
}
}.start();
t.join();
Unless you're signaling more than what you had above. But again, this is redundant, since starting a thread only to wait for it to finish does not make much sense...
Problem solved.
The invoker of the method was an AWT-Thread. I created a new Thread for the invoker and so the AWT-Thread was not blocked and the then frame and image could present correctly.
Thank you all for your help.
Related
Need To Do One Animation, Sleep 1000 Then Do The Next Sleep 1000 And So On, Instead It Sleeps For The Entire Time Then Plays All Animations At Once. No Idea What Im Doing.
Tried Timers, Running The Animation Before The tread.sleep And Using A While Loop Instead Of A For.
private void playLaunchAnimation()
{
final Animation animation = AnimationUtils.loadAnimation(this, R.anim.fadein);
for(int i=0; i < buttons.size();i++)
{
try {
Thread.sleep(1000);
buttons.get(i).startAnimation(animation);
} catch (Exception e){
/*
main declares that it throws InterruptedException. This is an exception that sleep throws when another thread interrupts the current thread while sleep is active. Since this application has not defined another thread to cause the interrupt, it doesn't bother to catch InterruptedException.
*/
}
}
}
Hi, Make sure this code helps you
public static void main(String[] args) throws Exception {
for(int i=0; i < 10;i++) {
try {
Thread.sleep(1000);
System.out.println(i);
if(i==9) {
i=0;
}
} catch (Exception e){
System.out.println("error");
}
}
}
(Answer assumes Android which wasn't entirely clear in OP.)
This is somewhat of a lazy way to do it - but maybe get you thinking. It would
be more interesting to have the handler invoke the next handler so only one handler is declared - but that would be a little more work.
private void playLaunchAnimation() {
final Animation animation = AnimationUtils.loadAnimation(this, R.anim.fadein);
for(int i=0; i < buttons.size();i++)
{
// Create a handler on the UI thread to execute after a delay.
// The delay is a function of loop index.
//
// It may be necessary to declare buttons final - but your
// OP did not list where it is defined.
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
buttons.get(i).startAnimation(animation);
}
}, ((i+1)*1000));
}
}
References:
How to call a method after a delay in Android
Android basics: running code in the UI thread
It sounds like you are calling Thread.Sleep from the User Interface thread. This will ultimately result in the entire User Interface freezing up for the duration of the sleep. What you really want is to launch sleep from a background thread.
For example:
AsyncTask.execute(new Runnable() {
#Override
public void run() {
for(int i=0; i < buttons.size();i++)
{
try {
Thread.sleep(1000);
activity.runOnUiThread(new Runnable() {
buttons.get(i).startAnimation(animation);
});
} catch (Exception e){}
}
});
Another way you could do this using post delay:
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
buttons.get(i).startAnimation(animation);
new android.os.Handler().postDelayed(this, 1000);
}
},
1000);
I have a thread that is used to spin an imageview as other things happen in the background. It works great for spinning, but I've noticed as I turn it on and off (based on the spinningMain variable) the button starts to spin faster and faster and faster.
I'm unsure what the cause of this is as the thread is told to sleep every 100ms.
If it helps I also have another thread (runnable thread) which runs the main code in between, which I was wondering whether it was disrupting the thread?
The imageView update thread is:
final Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(100);
runOnUiThread(new Runnable() {
#Override
public void run() {
if (spinningMain == true) {
// update TextView here!
if (spinningAngleMain >= 360) {
spinningAngleMain = 0;
} else {
spinningAngleMain += 5;
}
imageButton.setRotation(spinningAngleMain);
}
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
And the Second thread is pretty much made as follows
new Thread(new Runnable() {
#Override
public void run() {
if (searchStateButton == true) {
//do all my stuff
}
My boolean variables are set to volatile if that helps as well.
So my JProgressBar I have set up doesn't work the way I want it. So whenever I run the program it just goes from 0 to 100 instantly. I tried using a ProgressMonitor, a Task, and tried a SwingWorker but nothing I tried works.
Here is my program:
int max = 10;
for (int i = 0; i <= max; i++) {
final int progress = (int)Math.round(
100.0 * ((double)i / (double)max)
);
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(BandListGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
jProgressBar2.setValue(progress);
}
});
}
#MadProgrammer Here is my attempt at making a swing worker and writing each name to the document and updating the progress bar. The program gets to around 86 percent and stops, never creating the finished document. The program creates a blank document. Here are the two methods first is the SwingWorker object I made:
public class GreenWorker extends SwingWorker<Object, Object> {
#Override
protected Object doInBackground() throws Exception {
int max = greenList.size();
XWPFParagraph tmpParagraph;
XWPFRun tmpRun;
FileInputStream file =
new FileInputStream(location + "GreenBandList.docx");
gDocument = new XWPFDocument(OPCPackage.open(file));
for (int i = 0; i < max; i++) {
tmpParagraph = gDocument.getParagraphs().get(0);
tmpRun = tmpParagraph.createRun();
if (greenList.get(i).length() == 1) {
tmpRun.setBold(true);
tmpRun.setText(greenList.get(i));
tmpRun.setBold(false);
} else {
tmpRun.setText(greenList.get(i));//Write the names to the Word Doc
}
int progress = Math.round(((float) i / max) * 100f);
setProgress(progress);
}
return null;
}
}
And here is the code for the button that starts it and has my property change event.
private void GenerateGreenList() throws IOException, InterruptedException {
//Need to fix the bug that removes the Letter Header in Yellow Band list
//********************************************************************\\
//Delete the old list and make a new one
File templateFile = new File(location + "\\backup\\GreenTemplate.docx");
FileUtils.deleteQuietly(new File(location + "GreenBandList.docx"));
FileUtils.copyFile(templateFile, new File(location +
"GreenBandList.docx"));
//Get the New Entries
String[] entries = jTextPane3.getText().split("\n");
for (String s : entries) {
if (s != null) {
greenList.add(s);
}
}
//Resort the list
Collections.sort(greenList);
//Write the names to the document
GreenWorker worker = new GreenWorker();
worker.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
jProgressBar2.setValue((Integer) evt.getNewValue());
}
}
});
worker.execute();
if (worker.isDone()) {
try {
gDocument.write(new FileOutputStream(new File(location + "GreenBandList.docx")));
////////////////////////////////////////////////////////////
} catch (IOException ex) {
Logger.getLogger(BandListGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
JOptionPane.showMessageDialog(null, "Green Band List Created!");
jProgressBar2.setValue(0);
}
}
I used the property change listener from one of your other posts but I don't really understand what the one you wrote does or what it does in general?
Swing is a single threaded environment, that is, there is a single thread which is responsible for processing all the events that occur within the system, including repaint events. Should anything block this thread for any reason, it will prevent Swing from processing any new events, including, repaint events...
So all this ...
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(BandListGenerator.class.getName()).log(Level.SEVERE, null, ex); }
jProgressBar2.setValue(progress);
}
});
Is constantly pausing the Event Dispatching Thread, preventing it from actually doing any updates (or at least spacing them randomly)...
It's also likely that your outer loop is been run from within the context of the EDT, meaning that until it exists, nothing in the Event Queue will be processed. All your repaint requests will be consolidated down to a single paint request and voila, instant filled progress bar...
You really should use a SwingWorker - I know you said you tried one, but you've not shown any code as to your attempt in this regards, so it's difficult to know why it didn't work, however...
SwingWorker and JProgressBar example
SwingWorker and JProgressBar example
SwingWorker and JProgressBar example
SwingWorker and JProgressBar example
SwingWorker and dual welding JProgressBar example
SwingWorker and JProgressBar example
And forgive me if we haven't said this a few times before :P
You are evoking Thread.sleep inside the EvokeLater which means that it is running on another thread than your for loop. i.e., your for loop is completing instantaneously (well, however long it takes to loop from 1 to 100, which is almost instantaneously).
Move Thread.sleep outside of EvokeLater and it should work as you intend.
int max = 10;
for (int i = 0; i <= max; i++) {
final int progress = (int)Math.round(
100.0 * ((double)i / (double)max)
);
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
jProgressBar2.setValue(progress);
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(BandListGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
}
Edit: agree with #MadProgrammer. It appears this is just an illustrative question, but you should make sure whatever you're trying to accomplish here you use a SwingWorker for.
I am following a guide that shows how to create a Pong game. There is a part, where I am supposed to create a Thread, and call a function that moves the ball.
This is the code I created:
package com.ozadari.pingpong;
public class PingPongGame extends Thread {
private Ball gameBall;
private PingPongView gameView;
public PingPongGame(Ball theBall,PingPongView mainView)
{
this.gameBall = theBall;
this.gameView = mainView;
}
#Override
public void run()
{
while(true)
{
this.gameBall.moveBall();
this.gameView.postInvalidate();
try
{
PingPongGame.sleep(5);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}}
The thread is called and working, but it doesn't print anything. I tried to cancel the infinte loop and make the loop run 100 times. After I wait a while, it prints to the screen as it should be after 100 runs, but it doesn't print anything in the middle.
What is the problem? How can I fix it?
Unsure from the code you've posted but anyway, you can use a handler and have it run once every second like so (change the time to what you want):
Handler handler = new Handler();
final Runnable r = new Runnable()
{
public void run()
{
//do your stuff here
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
http://developer.android.com/reference/android/os/Handler.html
You can also use a normal thread, and call start at the end.
Thread thread = new Thread()
{
#Override
public void run() {
try {
while(true) {
sleep(1000);
handler.post(r);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
In the following lines of code when Button1 is pressed the Jframe becomes unresponsive till the execution of the encode() method is completed. But I need to update a progress bar in the Jframe displaying the progress.
private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
if (flagState == 0) {
WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode());
} else if (flagState == 1) {
WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode());
}
} catch (WavFileException | IOException e) {
notes.setText(e.getMessage());
}
}
I thought of doing this
private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
if (flagState == 0) {
Thread t = new Thread(new Runnable() {
public void run() {
WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode());
}
};)
t.start();
} else if (flagState == 1) {
Thread t = new Thread(new Runnable() {
public void run() {
WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode());
}
};)
t.start();
}
} catch (WavFileException | IOException e) {
notes.setText(e.getMessage());
}
}
and update the progress bar from the encode() method.
But I understand that it will a strong coupling between the modules and i dont want that.
I also dont think that calling a new thread every time is a good idea ( thought of ExecutorService but not sure how to use it).
What should I do to make this into a decent piece code??
Threading is definitely something you have to introduce here. Anything that takes a significant amount of time to complete should not be run in the awt event thread.
Spawning a new thread each time the button is clicked is not inherently a problem. You should consider, though, that it may be possible to spawn many threads doing the same thing before even the first completes. You could use an Executor if you want, but it probably is not necessary.
As for tracking progress, I would add another thread that periodically queries the other thread and updates the progress bar as necessary. Here's how I would structure it:
private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {
disableButton1();
final Thread t;
if (flagState == 0) {
t = new Thread(new Runnable() {
public void run() {
try {
WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode());
} catch (WavFileException | IOException e) {
notes.setText(e.getMessage());
}
}
});
} else if (flagState == 1) {
t = new Thread(new Runnable() {
public void run() {
try {
WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode());
} catch (WavFileException | IOException e) {
notes.setText(e.getMessage());
}
}
});
}
Thread monitor = new Thread(new Runnable() {
public void run() {
try {
while (notComplete(t)) {
setProgressBar(getProgress(t));
Thread.sleep(SLEEP_TIME);
}
t.join();
} finally {
enableButton1();
}
}
});
t.start();
monitor.start();
}
n the following lines of code when Button1 is pressed the Jframe becomes unresponsive till the execution of the encode() method is completed. But I need to update a progress bar in the Jframe displaying the progress.
you have issue with Concurency in Swing, you block the EDT, caused unresponsive GUI, until code ended
have look at SwingWorker for JProgressBar
use most scallable Swing Action instread of ActionListener
use implemented setEnabled() instead of if (flagState == 0) {
Multithreading is what you need, there is no other nice way i can think of don't worry about calling new threads, that's what they are there for, jvm has a thread pool ready to be used, this sort of things runs really good with threads, try it out!
Create a class that extends Runnable, implement the run method or make it call your current method, that should be enough to do this.
Also you could just make it sleep for a short time and check the status each time the sleep time goes out, if the process finished you can continue, if not, back to sleep for another short time, that way you don't have to ask that many times.
I hope it helps.