-1

I'm not sure I've really asked the question correctly...and I'm not even sure if I've relevantly phrased the question or not..So, I apologize in advance...but I'm quite stuck on this issue and appreciate all help.. Further, I'm frankly not an expert so...please be gentle, I'm not trying to be an idiot.

So, the point of my program, frankly, is a simple game, based off of a certain game show on TV which has lifelines.. This specific one is the "phone a friend" one... I have a quote on quote 'button' (really a JPanel that has a MouseListener). Once this button is pressed, I would like it to add, and paint a JLabel or JPanel onto the JFrame, whatever works to draw an animated gif (of a countdown) and to lock the other Components until 30 seconds have occurred. For the reference, I am not using a LayoutManager at the moment...

The way I've been attempting to do this, is:

ImageIcon CountdownImg = new ImageIcon("countdown.gif");
JLabel CountdownLbl = new JLabel(CountdownImg);
this.getContentPane().add(CountdownLbl);
CountdownLbl.setLocation(200, 200);
CountdownLbl.setSize(new Dimension(CountdownImg.getIconWidth(), CountdownImg.getIconHeight()));

long startTime = System.currentTimeMillis();
while(System.currentTimeMillis() < startTime + 30000) {
    ;
}

I know the problem exists with my while loop. Without the loop, the image renders successfully. With it, java waits until after the condition is met to render CountdownLbl. I've also tried creating another JFrame with a content pane that had the image, but (probably again, due to my own misunderstanding or poor threading..) but the Frame simply appears and does not render its contents. Sometimes while running it I notice that there is a Image Fetcher thread, I'm assuming that my very bad loop could be interfering with this thread, and that this thread is what is responsible for rendering my image.

So I guess the question should be...How can I really implement this...in a thread safe way? If that is correct?

Thank you for your time, patience and effort.

user99672
  • 3
  • 1
  • 2
    1) Please learn common [Java naming conventions](http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#73307) (specifically the case used for the names) for class, method & attribute names & use them consistently. 2) For better help sooner, post an [SSCCE](http://sscce.org/). 3) Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling `Thread.sleep(n)` implement a Swing `Timer` for repeating tasks or a `SwingWorker` for long running tasks. See [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/). – Andrew Thompson Jul 21 '13 at 18:53
  • *"also tried creating another `JFrame`"* See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/a/9554657/418556) – Andrew Thompson Jul 21 '13 at 19:20

3 Answers3

3

Use a SwingWorker to download images in the background. In this example, a single component is updated in done(), but you can publish() and process() images as they arrive. This related example outlines the approach.

Community
  • 1
  • 1
trashgod
  • 196,350
  • 25
  • 213
  • 918
1

Since you're question is tagged AWT, I suggest that you use a MediaTracker to load your images. See the docs for a good description of how to use this to wait until your images are loaded.

You can also try using ImageIO.read(URL) to retrieve a BufferedImage.

To create an ImageIcon from a URL, just use the constructor ImageIcon(URL).

Ted Hopp
  • 222,293
  • 47
  • 371
  • 489
0

The thread responsible for drawing the image icon is same as the thread which is executing the while loop in your case.There is something called EDT , event dispatcher thread which updates your swing UI.You are using the same EDT to wait the countdown.

You might want to look into this SwingUtilities.invokeLater()

EDIT:

Should have added more information : here it is , Using SwingWorker & SwingUtilities

Community
  • 1
  • 1
teon
  • 8,321
  • 10
  • 46
  • 83
  • 1
    How will using `SwingUtilitis.invokeLater()` help? – Hovercraft Full Of Eels Jul 21 '13 at 19:02
  • So should I first add the `Component` to my content pane, and put the timer in the new `Thread` created by `SwingUtilitis.invokeLater()`? Many thanks again – user99672 Jul 21 '13 at 19:11
  • @user99672: before you go down the wrong path, please understand that while Tito certainly means well, `SwingUtilitis.invokeLater()` does *not* create a new thread and certainly doesn't create a thread background from the Swing event thread. In other words, **don't** use it for trying to create a background thread, but instead use a SwingWorker. It may be used *inside* of an already created background thread to queue code onto the Swing event thread, but again this is only useful if you already are working in a background thread, and you're not there yet. – Hovercraft Full Of Eels Jul 21 '13 at 19:12
  • Ah ok..thank you. I should not have assumed that it would create a `Thread`...In the meantime I'll try to read the javadoc for `SwingWorker` and see if it helps. – user99672 Jul 21 '13 at 19:16
  • 1
    @user99672: read [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for the details on how to use a SwingWorker. If used correctly, and if you get your images correctly (I'd use `ImageIO.read(someResourceInputStream)`), it *will* work, trust me. – Hovercraft Full Of Eels Jul 21 '13 at 19:23