Making labels invisible after some time NetBeans - java

I am making a program in which I am supposed to make visibility of labels false after, say, 1 sec intervals
The program is pretty long and complex to quote so I am explaining it. I have an array of labels and each time a label is setVisible(false), slp() method is executed.
public void slp()
{
try{
Thread.sleep(1000);
}
catch(Exception e)
{
System.out.println(e);
}
}
But I am facing a problem. The method just increases the time of execution of thread and all the labels become invisible together at last. I need animation effect, and that is not coming.
What would be a good solution to my problem? Can a timer serve me?

First, your method slp should probably take a JLabel as argument, so you can modify the visibility of a specific label. Otherwise, the method would not know which label to hide.
Second, in order not to block the main thread (or whatever thread that class slp()), the Thread.sleep(1000) should be run in its own thread. That's why the code below uses new Thread(....).start(); to create a new thread that will do the actual work.
Third, as the waiting now is in a separate thread, changing the labels visibility must be done again on the Swing Events thread. For this, we use SwingUtilities.invokeLater() where we then set the label's visibility.
All together, the code could look like this:
public void slp(JLabel label) {
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
label.setVisible(false);
}
});
}
}).start();
}
The code could be further "cleaned up" by using lambda-expressions as available since Java 8:
public void slp(JLabel label) {
new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(() -> label.setVisible(false));
}).start();
}

Related

Is there a way to do a proper Thread.sleep in a #Scheduled(fixedDelay) block?

I'm trying to do a Thread.sleep within a #Scheduled(fixedDelay) block, but so far no luck. From what i read and saw, Thread.sleep doesn't work under #Scheduled.
I can think of a while loop but i don't feel that confident on that approach. Do you guys have any other suggestions ?
I'm running multiple tasks under this scheduler and I need to put some delays in between some of them. There is no question of splitting these tasks into multiple schedulers. Everything has to be done under the same one.
Thanks
You can create atomic flag that will signal if thread should be slept.
private static final AtomicBoolean sleep = new AtomicBoolean(false);
#Scheduled(...)
public void schedule() {
sleep.set(true);
}
public void process() {
new Thread(() -> {
while (true) {
if (sleep.get()) {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
sleep.set(false);
}
doSmth();
}
}).start();
}

Wait until the thread finish

I have a function that has inside thread that do something
public static void animate(int column,Image image)
{
new Thread(new Runnable() {
public void run() {
try {
/* Code */
repaint();
Thread.sleep(500);
repaint();
} catch (InterruptedException ex) {
}
}
}).start();
}
The animation function I summon in the updateBoard function and after this do i++.
I want to make the function animate not continue to I++ until the thread end
Inside animate fucntion i used repaint() function from swing, When i try to use .join() its block repaint() thread.
public static void updateBoard(int column, Image image) {
int i = 0;
animate(column,image);
i++;
}
Like this:
Thread t = new Thread(new Runnable(){...});
t.start();
t.join();
However, this is kind of pointless. If you are going to start a thread and immediately block waiting for it to finish you are NOT going to get any parallelism. You may as well just call the Runnable::run method in the current thread ... and avoid the (not insignificant!) overhead of creating / starting a thread.
You have a already existing thread executing updateBoard() method. Let this thread be T1.
You invoke animate() and create another thread, let this thread be T2. Now as per your question, you want to have T1 not run further until T2 completes the execution.
Thread.java defines a method join(), it allows one thread to wait for the completion of another. In your code it can be done like this.
static Thread animationThread = new Thread(new Runnable() {
public void run() {
try {
/* Code */
Thread.sleep(500);
} catch (InterruptedException ex) {}
}
});
public static void updateBoard(int column, Image image) {
int i = 0;
animate(column,image);
animationThread.join(); // this will make the thread executing updateBoard to wait until the completion of animationThread.
i++;
}
public static void animate(int column,Image image){
animationThread .start();
}
But now every thing runs one after the other, there is no use of having two threads in this case. This is similar to
public static void updateBoard(int column, Image image) {
int i = 0;
animate(column,image);
i++;
}
public static void animate(int column,Image image){
try {
/* Code */
Thread.sleep(500);
} catch (InterruptedException ex) {}
}
In this case also until unless animate method completes (without 2nd thread), i++ will not be executed. Hence for the use case in your question having a separate thread for animate does not make sense, it only adds to the overhead of creating a separate thread and context switching. Although having a separate thread for animation seems a good idea but for that you got to restructure the program you have so as the logic is based on parallel execution so as having multiple threads makes sense.

ConcurrentModificationException when updating sprite images

I keep getting a ConcurrentModificationException when running my game which utilizes multithreading to create new sprites and move them. The main problem appears to happen with the creation and/or movement of "Fireballs".
I've been able to run my program successfully with no exceptions appearing by commenting out the createNewFireballs method. However, whenever I do utilize the createNewFireballs method, the error commonly appears whenever I call a function that updates the image of the Fireball Sprite (and doesn't ever happen for any other type of sprite.) I was wondering if anyone could help me locate the source of my problem and potentially solve the issue.
public synchronized void createNewFireball() {
new Thread(new Runnable() {
public void run() {
while (gameNotPaused && hero.isNotDead()) {
fireball = new Fireball(dragon.getX(), dragon.getY());
fireballs.add(fireball);
try
{
Thread.sleep(100); //Waits for .1 second
}
catch(InterruptedException e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
}).start();
}
//The problem commonly occurs in the update method,
//specifically the line "FireballIter.next().updateImage(g);"
public synchronized void update(Graphics g) {
Iterator<Sprite> FireballIter = fireballs.iterator();
Iterator<Sprite> arrowIter = arrows.iterator();
while (arrowIter.hasNext()) {
arrowIter.next().updateImage(g);
}
Iterator<Sprite> iterator = sprites.iterator();
while (iterator.hasNext()) {
iterator.next().updateImage(g);
}
while (FireballIter.hasNext()) {
FireballIter.next().updateImage(g);
}
}
//Although sometimes it occurs as a result of updateScene, which is
//called in another method which moves all the "projectile" sprites
public synchronized void updateScene(int width, int height) {
Iterator<Sprite> arrowIter = arrows.iterator();
while(arrowIter.hasNext()) {
Sprite spriteObject = arrowIter.next();
((Arrow) spriteObject).updateState();
if (spriteObject.overlaps(dragon, 350, 350)) {
dragon.arrowHit();
System.out.printf("Dragon was hit at %d, %d%n, while arrow was at %d,%d%n", dragon.getX(), dragon.getY(), spriteObject.getX(), spriteObject.getY());
arrowIter.remove();
}
}
Iterator<Sprite> fireballIter = fireballs.iterator();
while(fireballIter.hasNext()) {
Sprite spriteObject = fireballIter.next();
((Fireball) spriteObject).updateState();
}
}
#Override
public synchronized void run() {
while (model.getGameNotPaused()) {
model.updateScene(view.getWidth(), view.getHeight());
view.repaint();
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
JOptionPane.showMessageDialog(null, "Press R to resume game.");
}
}
}
Making createNewFireball synchronized does nothing useful: the synchronization only applies to the execution of that method, not the runnable executed by the thread (which is good, because otherwise none of the other methods would be able to execute until the while loop finished).
Put the fireballs.add into a synchronized block, taking care to ensure you are synchronizing on the right thing:
If you simply use synchronized (this), you would be synchronizing on the Runnable.
Instead, use synchronized (TheContainingClass.this) (where TheContainingClass is the name of the class containing these methods).
Assuming your fireballs is an ArrayList<Fireball>, you could also consider switching it to CopyOnWriteArrayList , a thread-safe variant of ArrayList

How to wait in loop in Vaadin?

Im trying to display series of photos on one page with time interval. In countinuos while loop i got:
while(true){
if (zmienna == fa.length) zmienna = 0;
Image obrazek = new Image("",pliki[zmienna]);
layout.replaceComponent(staryObrazek, obrazek);
obrazek.requestRepaint();
staryObrazek = obrazek;
zmienna++;
try {
Thread.sleep(2000) ;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
It showing only waiting icon, dispaying mwthod works fine without loop. Do anyone has an idea how I should fic this issue?
In all modern UI systems you will have to not suspend the main thread, but use a background thread to update the UI. Otherwise you block the whole UI.
In Vaadin 7 you can enable server push and then use a background thread to change the image every 2 seconds.
Enabling push is described in the book of vaadin https://vaadin.com/de/book/vaadin7/-/page/advanced.push.html
Your code could look like this:
public class PushyUI extends UI {
#Override
protected void init(VaadinRequest request) {
// Set first component/image
setContent(chart);
// Start the update thread
new ImgUpdThread().start();
}
class ImgUpdThread extends Thread {
#Override
public void run()
{
// Update the data for a while
while (count < 100) {
Thread.sleep(1000);
access(new Runnable() {
#Override
public void run() {
//update the UI as in your code above
}
});
}
}
It is important to use the access(...) method to sync access to the UI elements.

how to run 2 threads in JFrame

Hi i got following problem...
I have main jframe started like this:
public static void main (String args[]){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Form3 myF=new Form3();
}
});
};
in the jframe i have Jpanels. On jpanel i want to start 2nd thread.
I tried it like this:
try {
while (DBAccess.haveResult("ASS"+harnessId)==null&&cancelCycle == 0) {
thread1.sleep(3*1000);
System.out.println("+++++++++");
System.out.println(DBAccess.haveResult("ASS"+harnessId));
res = DBAccess.haveResult("ASS"+harnessId);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
but I am unable to stop that thread and cant even cancel it, because main window stops reacting
to clarify my problem:
i have "Test" button on JPanel, which is starting test process. Test process consists of loop whiuch is repeating every 3 seconds, this loop checks database status. Problem is I am unable to stop this loop until the status appears in db (while condition), because window is busy after i click on "test". Even implementing runnable and putting test method into "run()" doesnt worked.
testbutton source code:
if (e.getActionCommand().equals("Test")){
run();}
run method:
#Override
public final void run() {
test();
}
test method:
Map result_row = DBAccess.addRow("ASS"+harnessId,htOperList.get(seqNumber-1).getNametestprogram(),"",null);
if(result_row.containsKey("ADDROW")){System.out.println("Record inserted" );}
Database db = null;
Map res = null;
try {
while (DBAccess.haveResult("ASS"+harnessId)==null&&cancelCycle == 0) {
thread1.sleep(3*1000);
System.out.println(DBAccess.haveResult("ASS"+harnessId));
res = DBAccess.haveResult("ASS"+harnessId);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
You are blocking the event dispatch thread. Use a SwingWorker for heavy tasks. Put the main DB operation in doInBackround(), and use publish() for the interim results.
If you need to stop it before doInBackround() completes, you can use cancel(). See here for notes about that.

Categories