delay doesn`t wotk for java gui(java) - java

I want to put a delay on a gui. I put 2 for loops, and I repaint a label, but those 2 for loops execute one after one and label is repaint just to the final.
What can I do?
for(int i=0; i<100000; i++){
System.out.println(i);
}
label.setBackground(Color.RED);
for(int i=0; i<100000; i++){
System.out.println(i);
}
label.setBackground(Color.green);

You might want to take a look at
docs.oracle.com/javase/7/docs/api/javax/swing/Timer
It's a link to using timers in Java, which helps to remove the for loops from your program.
You can use this instead:
Timer t = new Timer(2000, YourActionListener);
t.start();
}//End of method
public void paintComponent()
{
super.paintComponent(g);
if(c%2==0)
{
label.setBackground(Color.RED);
}
else
{
label.setBackground(Color.GREEN);
}
c++;
}
...
public void actionPerformed(ActionEvent) // How your YourActionListener method looks like
{
repaint();
}

There are several ways to do a delay in a Java program. Simplest option is to do
Thread.sleep(2000);
Which simply puts the current thread to sleep for 2 seconds. Depending on what you are trying to accomplish though you may need to consider some more complex options.
This option makes your program unresponsive for the sleep time. As you have a (I assume) swing application you can use a Timer instead.

Related

JProgressBar moves instantly and not gradually (java)

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.

Java/Processing mousePressed in loop not working

So I was making a simple game in Java + Processing where there were buttons and loops in draw(). Apparently the PApplet function mousePressed() doesn't work constantly if there is a loop, so I tried putting my own checkmouse() function to be checked during the loop. However, it still doesn't work. How do I make it so that I can run a game with while-loops and constantly check for mousePressed at the same time?
//draw() func
public void draw() {
for (int i = 0; i < 10000; i++) { //to simulate a while loop
//do something, like run some other functions that create the buttons
checkmouse();
}
}
//checkmouse function
public void checkmouse() {
if (mousePressed) {
System.out.println("x");
}
}
When I click the mouse in the processing window, it never shows "x" even though checkmouse() runs every time it loops, so theoretically it should be checking it pretty constantly while the loop runs.
Also could someone explain why this doesn't work?
boolean esc = false;
while (!esc) {
if (mousePressed) {
System.out.println("x");
esc = true;
}
}
The event variables (mousePressed, keyPressed, etc.) are updated between calls to the draw() function.
In other words: the mousePressed function will never change within a call to the draw() function. You need to let the draw() function complete and then be called again if you want the event variables to be updated.
Behind the scenes, this is because Processing is single-threaded. (This is by design, because multi-threaded UI programs are a nightmare.)
Taking a step back, you probably don't want to include a long loop inside your draw() function. Take advantage of the 60 FPS loop that's implemented by Processing instead.

JLabel Icon not updating with setIcon (or other redundancies)

Two different versions of code I'm using, as noted, the first one works fine, without any problems what so ever, the second one, the only thing that doesn't happen is the updating of the image (have verified through step debugging and debug printing to verify all values and conditionals by hand)
/* properly updates dice[] JLabel icons */
for (int i = 0; i < game.getToRoll(); i ++){
//sets rolled dice to actual values
dice[i].setIcon(dicePic[(game.getDice(i).getFaceValue())]);
}
/* loops properly, generates properly, does not update icons */
Die x = new Die();
int animate = 0;
while(animate < 10){
for (int i = 0; i < 6; i++ ){
x.roll();
if (i <= (game.getToRoll() -1))
dice[i].setIcon(dicePic[x.getFaceValue()]);
else
dice[i].setIcon(dicePic[0]);
}
panel[1].repaint();
panel[1].validate();
animate++;
try{
Thread.sleep(100);
}
catch(Exception e){
e.printStackTrace();
}
}
I've been looking around for some kind of idea of what it is that's causing the problem, and I've not run into anything other than that "sometimes repaint and validate will fix things that don't work."
As stated above, debug is giving me the greenlight on code flow working entirely as expected, just null image icons in the second example.
The problem is the Thread.sleep(100); The icon does change but you don't see the change because you blocked the UI thread.
So the rule is: never sleep the EventDispatchThread!
My advice is to use a Timer:
new javax.swing.Timer(200, new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
//do an icon change
}
}).start();

Where should I use thread.sleep in a java swing program?

Right now I've programmed a method for use in a swing program that is supposed to slow down the speed the method it's called in is run (via thread.sleep(x) ) and instead of slowing down the speed of refresh it's just causing the whole program to hang and the screen to refresh at the end of the methods execution.
Here's my code:
public final void doBubbleSort(String numbers[], JButton numButton[]){
for (int k = 0; k < numbers.length - 1; k++){
String str1 = "";
boolean isSorted = true;
for (int i = 1; i < numbers.length - k; i++){
if (Integer.parseInt(numbers[i]) < Integer.parseInt(numbers[i - 1]) ){
try{
String tempVariable = numbers[i];
numbers[i] = numbers[i - 1];
numbers[i - 1] = tempVariable;
isSorted = false;
str1 = numButton[i].getText();
numButton[i].setText(numButton[i-1].getText());
Thread.sleep(100);
}catch(Exception e){ System.err.println("Error: " +e.getMessage()); }
numButton[i-1].setText(str1);
}
}
if (isSorted)
break;
}
}
If anyone can tell me where I should be putting thread.sleep() to make it delay the display of items being swapped I would be greatly appreciate it.
Thanks!
You should never sleep in the event dispatch thread.
Create a model, (in your case a list)
Create a view (your swing gui)
Make sure the view gets updated once the model changes (by adding a listener for instance)
Create a separate thread that updates the model regularly (using Thread.sleep if you so like)
When changing "speed" change the sleep times for the updater-thread
You may want to have a look at the Timer class (which provides a nicer interface for doing things at a regular interval) or the Swing Workers.
You cannot do animation by putting a loop in an event handler like this. You must do it by using a separate thread, either explicitly or by using the javax.swing.Timer class. If you loop and sleep on the event thread, as you're doing, then during the entire time the loop is running, the event thread is unavailable to perform its other duties, like painting the screen.
See this article for information about using the Swing timer class.

How to use a sleep/wait function to display a countdown

I want my program to start off using a countdown timer that will be displayed to the user. The only way I can think to do that is to label.setText() and Thread.sleep(). I've tried for about 20min trying to get it to work, but can't seem to crack it. Help?
Use a Swing timer. Basically you create a class that implements ActionListener, create a javax.swing.Timer, and the actionPerformed method of the ActionListener gets called at an interval you specify. In your actionPerformed method, check the time, and update the value to be displayed when appropropriate, and call repaint(). Use an interval of 0.1 second, and your countdown will be smooth and accurate enough.
I wouldn't count on the accuracy of Thread.sleep, but:
for(int i = 20; i >= 0; i--) {
label.setText(i + " seconds remaining");
Thread.sleep(1000);
}
This will, of course, block the UI thread while sleeping, so you probably need to run it on a separate thread. This means you will need something like SwingUtilities.InvokeLater to update the UI, since you are using a thread different than the UI one:
for(int i = 20; i >= 0; i--) {
SwingUtilities.InvokeLater(new Runnable() {
public void run() {
label.setText(i + " seconds remaining");
}
});
Thread.sleep(1000);
}

Categories

Resources