Here is my loop code (This is the only code relating to my loop):
while(true)
{
try {
Thread.sleep(20);
System.out.println("1");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
When I launch the applet, it white screens and I cannot close it unless I press the "Terminate" button in eclipse.
You're blocking the UI Thread with an infinite while loop. You don't say whether you're using an AWT or Swing applet, either way the result will be the same. If you're using a Swing applet, use a Swing Timer. If you're using the old heavyweight AWT, convert it to Swing and follow the previous advice.
As said you made an infinity loop with:
while(true){
//something
}
There is no break; So why or what should stop the loop except of a thrown exception?
To see when a InterruptedException is thrown you should read the JavaDoc:
http://docs.oracle.com/javase/7/docs/api/java/lang/InterruptedException.html
You are hogging the applets EDT. You need to run your loop in another thread. Try adding Thread gameThread; as a variable and use
gameThread = new Thread() {
public void run() {
while (condition) {
//code here
}
}
}
and then gameThread.start() both in your applet start method and gameThread.join() in your applet stop method.
Related
I want to make a ProgressBar move gradually using a Jbutton. To achieve this I am using a for loop and the method Thread.sleep. The problem is that insted of moving a tiny bit every second (the progress bar) after pressing the button, the program waits until the loop finishes and then does instantly move the progress up. When I take the loop outside of the button listener it works as I want but I really need it to work when pressing the button. Here is the code:
progressBar.setOrientation(SwingConstants.VERTICAL);
progressBar.setMinimum(0);
progressBar.setMaximum(100);
progressBar.setValue(50);
panel1.setLayout(null);
panel1.add(progressBar);
progressBar.setBounds(40,6,100,100);
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int counter = 5;
for (int i = 0; i < 5; i++) {
progressBar.setValue(progressBar.getValue() + counter);
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
});
If anyone can help me I will be very grateful!
Your code runs on the Event Dispatcher Thread (EDT). That thread is responsible for handling events, but also for repainting. Because it's just one thread, the repainting only occurs after your method ends.
There are some ways to solve this. In your case, a javax.swing.Timer would probably be easiest. Instead of running the loop in a single method, the button click starts a timer that runs every second. When it's done the timer can cancel itself. A slightly more difficult alternative is to use a SwingWorker. You could publish data in the doInBackGround method, and override process to perform the updates to the progress bar.
For more information, please read Concurrency in Swing.
I am having issues setting up a computer vs computer loop in my java game applet. I have been trying for 3 days now to effectively add a one second delay between the two computer-player turns, while also repainting the board. I have tried try/catch/thread.sleep and wait and a few other tricks, however none have been successful. In the program's current state, when a computer vs computer game is initiated, the program freezes for the duration of the game (with one second delays between moves) and then displays the final board when the game has finished. How can I make it so the program repaints/delays after each move? From all of the reading I have done, I am aware that the following implementation will not work but my issue is I cannot figure out how to do it any other way.
Thanks in advance!
The following code is inside my actionPerformed listener method
if (event.getSource() == startAIvAI)
{
drawing.clear();
while (drawing.hasWon() == -1 && !drawing.isFull())
{
go1();
repaint();
try {
Thread.sleep(1000);
} catch (Exception e) {}
go2();
repaint();
try {
Thread.sleep(1000);
} catch (Exception e) {}
}
}
When you invoke Thread.sleep(1000); which Thread do you think you're pausing? Probable the one handling event given your code start with if (event.getSource() == startAIvAI).
You should read this to understand what to do: Sleep method locks my GUI
I'm trying to visualize various graph-algorithms. I want to make it so, that after every 2 seconds the graph get updated and gets repainted. I have tried using the Thread.sleep() method but it just freezes the GUI and then after a while is done with the complete algorithm.
(I am fairly new to Java so don't be to harsh with the code)
The Code in question:
else if(ae.getSource() == fordFulkersonButton){
dinicButton.setEnabled(false);
edmondsKarpButton.setEnabled(false);
gtButton.setEnabled(false);
if(checkbox.isEnabled()){
fordFulkersonButton.setEnabled(false);
while(!fordFulkerson.getIsDone()){
flowNetwork = fordFulkerson.algoFF(flowNetwork);
popupText.setVisible(true);
Integer i = new Integer(flowNetwork.getCurrentFlow());
String s = i.toString();
popupText.setText("Aktueller Fluß: "+s);
graphDrawer.setFlowNetwork(flowNetwork);
this.showFrame();
try {
Thread.sleep(2 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Integer in = new Integer(flowNetwork.getCurrentFlow());
String st = in.toString();
popupText.setText("Algorithmus is beendet mit Fluss: "+st);
}
flowNetwork = fordFulkerson.algoFF(flowNetwork);
popupText.setVisible(true);
Integer i = new Integer(flowNetwork.getCurrentFlow());
String s = i.toString();
if(fordFulkerson.getIsDone()){
popupText.setText("Algorithmuss beednet mit maximalen Fluß: "+s);
}else{
popupText.setText("Aktueller Fluß: "+s);
}
graphDrawer.setFlowNetwork(flowNetwork);
this.showFrame();
}
Doing huge amounts of work in a UI thread freezes the UI. If you want to do animations or complex work, use a worker thread or a Swing timer.
You must not call Thread.sleep() in Swing UI code. Instead, you need to think like an animator: Show one frame of the animation at a time. Some external source will call your code to show the next frame. The external source is the Swing timer. Your code draws the next frame and returns. That way, you never block the UI thread for long.
Google for "swing animation". Interesting results are:
http://www.java2s.com/Tutorial/Java/0240__Swing/Timerbasedanimation.htm
http://zetcode.com/tutorials/javagamestutorial/animation/
I am using a Canvas in a SurfaceView Class which runs on a thread. The SurfaceView is called by an Activity (setContentView(surfaceview)). When the screen turns off, it goes through a pause() method which turns off all loop variables and so on.
The strange thing is: while on my tablet (Android 4.4.2) the Thread pauses and resumes correctly (the thread starts all over), however on my phone (Android 4.2.2) and on other people's phone (CM 11) the app hangs (it doesn't crash! it just hangs) and I have to kill it. LogCat doesn't print anything - however I tried to find out what happens using Log.i, it seems that after the pause method finishes, the pause method starts again, and this is where the app hangs.
I have checked before and the pause/resume methods are getting called correctly (override of onPause/onResume of the Activity using super.onPause()/Resume() and then surfaceview.pause()/resume())
My pause/resume methods:
public void resume() {
countdown = true; // this one,
threadRun = true; // this one and
finishWait = true; // this one each are loop controllers
won = false;
hitCount = 0;
thread = new Thread(this);
thread.start();
}
public void pause() {
Log.i("codeflow", "Pause method start");
// all loop controllers have been set to false
countdown = false;
threadRun = false;
finishWait = false;
/* Log.i("CodeFlow", "drawablank");
drawABlankScreen(); // to hide everything drawn */
while (true) {
try {
Log.i("codeflow", "Thread.join() loop");
thread.join();
break;
} catch(InterruptedException e) {
Log.i("codeflow", "InterruptedException");
e.printStackTrace();
}
}
thread = null;
Log.i("codeflow", "Thread is killed");
if (won && !lost) { // !lost IS necessary
Log.i("CodeFlow", "save highscore");
saveHighscore(highscore);
}
}
The pause method goes through everything the way it should, but then it starts again (another "Pause method start") and goes either to drawABlankScreen() or, when this linke is commented, it prints "Thread.join() loop" once and then the app hangs.
The thing that bugs me the most it that it hangs on my phone while it doesn't hang on my tablet.
Can anyone please help me, I've searched for hours and found nothing....
Joining the UI thread to a background thread in onPause() is probably what's causing your problem.
Instead, you should kill the thread.
"thread.join()" will hangs the thread which execute this sentence, until thread run over. Strangly, if execute in Android UI thread, Android would not crash.(sorry for my full of mistakes English).
I am trying to stop a for loop that is initiated by pressing a button. The only problem I have found is that the application is literally non-responsive once the start button is pressed. How would I go about making the stop button? At the moment the only way I can stop the application outside of my IDE is to go into task manager and forcibly delete it.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String L = "Hello";
int Num = Integer.parseInt(m1.getText());
int Num2 = Integer.parseInt(m2.getText());
nu = Num;
for (int kk = nu; nu > 0; nu--) {
if (O1.isSelected()) {
for (int num3 = nu; nu > 0; nu--) {
try {
try {
Thread.sleep(Num2 * 1000);
} catch (InterruptedException ex) {}
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_F);
} catch (AWTException e) {
e.printStackTrace();
}
}
}
}
This is the code I have, I have been looking around and I think I need to use the SwingWorker class. I am not sure how to implement it though.
Have you put your loop inside the button action handler?
If so remove it and put it in a thread. Else it will block the EDT and app will become unresponsive. Use buttons only to trigger start and stop.
Without code it is hard to determine, but you are probably performing the loop on AWT thread, hence your UI is blocked and you can not press a button.
You should move your endless loop to another Thread, and then the button will work
You are entering in an infinite loop any how. I would suggest to put your loop in a separate thread and when you want to stop it just interrupt that thread on button click.
Move the code into a dedicated thread and use a variable check to end the loop externally.
The first problem is that you're performing this loop inside the Event Dispatch Thread (EDT). This is a thread which is dedicated to handling the user interface. Since you are looping and sleeping in this thread, it is unavailable to handle any other user interactions. So effectively you are locking yourself out of your own program.
The proper way to shut this down is to create a shutdown() method on the loop which will modify a variable that is checked in each iteration of the loop. Then, when you want to shut it down, you just call this method on the Runnable and the loop shuts down.
public class KeyPressRunnable implements Runnable {
private boolean isRunning = true;
public void shutdown() {
this.isRunning = false;
}
#Override
public void run() {
// put your loop in here, and include this code in the loop:
if (!this.isRunning) break;
}
}