This jSlider code causes the application to hang.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try {
for(int i=0;i<100;i++)
{
jSlider1.setValue(i);
Thread.sleep(3000);
}
} catch (InterruptedException ex) {
Logger.getLogger(AsdView.class.getName()).log(Level.SEVERE, null, ex);
}
}
thank you guys i am updating the answer
Timer time = new Timer(100, new ActionListener() {
int percent = 0;
#Override
public void actionPerformed(ActionEvent e) {
percent++;
if (percent>100)
percent = 0;
jSlider1.setValue((int)(100*(percent/600.0)));
}
});
time.start();
I am guessing you are trying to do some kind of smooth scroll.
That code freezes because the event thread that handles the window painting, sizing, etc..., is being frozen by you executing Thread.sleep(3000), 100 times.
I would recommend that you use a Swing timer that changes the scroll bar little by little.
i don't know why you put the sleep for 3 secs and that too in for loop of 100
3*100 = 5 mins so it will hang upto 5 mins
remove Thread.sleep(3000);
it will work fine and won't hang
When you say your application 'hangs', that generally means that you have some sort of deadlock that prevents your threads from making progress. Is that what you're observing in your program? The way it's currently written, the current thread of execution will take at least 300 seconds to complete. Is this work being done on the main thread of execution? If so, you may want to consider creating a new Thread to do this work.
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.
So I have a little puzzle made in Java, and let's just say there are buttons too on this puzzle which represent the puzzle. There is a solving method where a series of buttons are clicked to find a "solution", and it takes around 1 minute to solve it, so that is 1 minute of just clicking buttons
During this one minute, you notice the buttons being clicked by the computer as it changes color and shape during the program flow, I was wondering if there was a way to freeze the jframe before the solving() method is invoked and then unfreezes into the solution when the method is over?
I am a little confused to exactly what you are asking, but I would suggest using this code to do what I believe you are asking for
private static boolean solveDone = false; //This should go in a the class, not here.
//Create a new thread to handle processes while the JFrame is frozen
SwingUtilities.invokeLater(new Thread(){
public void run(){
//Code to run while the JFrame is frozen should be put here.
main.solveDone = true;
}
});
//Sleep the program until the process is done.
try{
while(!solveDone) {
Thread.sleep(10); //Interval in milliseconds to check if the puzzle is done goes here.
}
solveDone = false;
}catch(InterruptedException e){
e.printStackTrace();
System.exit(-1);
}
//Code to run after solving goes here.
Now, this isn't the cleanest way to do this type of thing, but I believe it should work.
On the other hand, if you know exactly how much time it is going to take, you could do this.
SwingUtilities.invokeLater(new Thread(){
public void run(){
//Code to run while the JFrame is frozen should be put here.
}
});
try{
Thread.sleep(1000); //The time in milliseconds to sleep the JFrame
}catch(InterruptedException e){
e.printStackTrace();
System.exit(-1);
}
//Code to run after solving goes here.
For some reason even though I am using the exact code example from oracle's website for the Swing Timer it is not waiting for 1 second. It just skips to the JOptionPane that says "Your score was etc etc".
Here is my source code for a school project. Why is this not working and not waiting for 1 second before running the rest of the code?
//Check to see if user has enetered anything
if(!answered)
{
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();
afk = true;
incorrect += 1;
answered = true; //This breakes it out of the loop
}
A timer is used to run a callback after a specific amount of time. If you simply want to delay, you can either move the code to be run after the delay into the taskPerformer action listener.
Thread.sleep(1000) is not ideal here, because it will cause the UI to completely freeze as you will make the UI thread sleep.
I have this loop
while (true) {
game.update();
view.repaint();
Thread.sleep(DELAY);
}
In the game.update various components of the game have their position changed and those updates are reflected when the repaint() method is called on the view. The view extends JComponent and loops through the game objects and calls their print methods.
What I want to do is have a boolean called nextLevel in the game and if it's true Flash text on the screen for the player to notify them that they're going onto the next level. Maybe flash 4-5 times. Then continue the game.
Is this possible? I have been playing around with Thead.Sleep() but this only seems to pause the displaying and in the background the game is still going on.
Any ideas on how to do this?
Maybe you want to avoid threading by using a Timer object.
an example like that could be
int flashTimer = 0;
if(nextLevel) {
Timer timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
//flash something method here
flashTimer++;
}
});
timer.start();
}
and then check your flashTimer if it reaches the number you want then just stop the timer by timer.stop();
Just an idea which seems to me a bit simpler. the 1000 value is milliseconds which is passed and executes the code inside the actionPerformed method every 1 sec.
Hope it helped
I'm attempting to get an animation working in a game I'm developing. The animation works by setting a button size to very small, then gradually growing it to its normal size again. I have it working, except I'm having timing issues.
Sometimes the button will grow almost instantly, sometimes it goes VERY slow. I'm looking for something inbetween, and I need it to ALWAYS grow at that size, not some times fast sometimes slow.
I've looked into it and I found this pseudocode:
distance_for_dt = speed * delta_time
new_position = old_position + distance_for_dt
Unfortunately I don't understand what's being said, and I don't know how to apply this to my code. Can anyone help with that or explain what's being said in the above pseudocode?
Here's my timer code, timer is already defined above as a Timer, and z[] is just a pair of coordinates:
timer = new Timer(18, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Dimension dim = button[z[0]][z[1]].getSize();
if (dim.getHeight() < 79.9) {
button[z[0]][z[1]].setSize((int) (dim.getWidth() + 6), (int) (dim.getHeight() + 6));
} else {
button[z[0]][z[1]].setSize(80, 80);
timer.stop();
}
}
});
timer.start();
Depending on how many updates you're calling on your Swing application, it may be getting "backed up" and slowing down. For instance, if you wanted to accomplish the animation without a Timer, you could just do something like this:
// example method to do animation
public void animateButton(final int wait){
Thread thread = new Thread(){
public void run(){
// some loop structure to define how long to run animation
Dimension dim = button[z[0]][z[1]].getSize();
while (dim.getHeight() < 79.9){
SwingUtilities.invokeLater(new Runnable(){
//update Swing components here
});
try{ Thread.Sleep(wait); }
catch(Exception e){}
}
}
}
}
thread.start();
}
I think this may be similar to how a Timer updates the GUI, as Timers run on a separate thread. I would look into whether or not you need to use invokeLater(new Runnable) inside a timer to properly schedule the task. I had to do this to allow a project I was working on to keep responsive during long tasks. If you really needed to ensure the speed and maybe DROP updates to adjust for system lag, then you'll need to be calculating how complete the animation is vs how much time has passed, using a method call such as System.currentTimeMillis() or System.nanoTime(). Then, adjust accordingly for each step of the animation.