0

I have a this loop in class collection which repaint() JPanel continiously

    while(loop) {
        imageicon = (ImageIcon) ois.readObject();
        image = imageicon.getImage();
        cjpanel.tempimage = image;
        cjpanel.repaint();
        Thread.sleep(100);
    }

and cjpanel extends JPanel where i have overridden paintComponent() and i am using Double buffering

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
tempimage.getScaledInstance(dim.width, dim.height, Image.SCALE_FAST);
bufferGraphics.clearRect(0,0,dim.width,dim.width);
bufferGraphics.drawImage(tempimage,0,0,dim.width,dim.height, null);
g.drawImage(offscreen,0,0,this);
}

my problem is repaint is always two frames behind while loop. i.e if image 4 is in while loop then paintComponent() is drawing `image 2.

So how can i Speed up repaint or stop new repaint before previous repaint is done?

UPDATE

when I changed the size of image from ObjectInputStream it is working fine. I think it has to do something with image size..

N Kumar
  • 1,302
  • 1
  • 18
  • 25
  • 1
    Where is your `while` loop located? Where is the code that uses `image`? Also, you are calling `tempimage.getScaledInstance` but you're ignoring the returned scaled image. Also, keeping the same `bufferGraphics` object "open" should work in theory, but has a bad code smell to it, in my opinion. Finally, JPanel does its own double-buffering, so you probably should pass your image to a `drawImage` method which takes four int arguments, rather then scaling it yourself. – VGR Oct 21 '15 at 16:33
  • @VGR please see my updated question.. i am using `cjpanel` to display images – N Kumar Oct 21 '15 at 16:40
  • 2
    "*and i am using Double buffering*" Swing is already double buffering, you don't need to do anything. – user1803551 Oct 21 '15 at 16:52
  • @user1803551 yes Swing is already double buffering.. – N Kumar Oct 21 '15 at 17:01

2 Answers2

2
  1. You should not be re-reading images within your while loop. Read the images in once and store them in a variable, likely a collection such as an ArrayList.
  2. Store them as Images or Icons depending on how you are using them. No need to call getImage() on an Icon when you can store the images as Images.
  3. Don't use a while loop but rather a Swing Timer so as not to run afoul of Swing threading rules.
  4. You're asking for debugging help, essentially, "why isn't this code working as expected?" help, and so if general advice doesn't help, you really must strongly consider creating and posting the shortest code necessary for us to be able to compile, run and help identify your problem, a minimal example program (please check the link). Else, we're not going to be able to help well other than to give general advice, as I've done above. And I agree that what I'm requesting would not be an easy or quick thing to do as it would require quite a bit of effort on your part, but if you remain stuck and need a solution to this, it would be effort well spent. Up to you, and depends solely on your need.
Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • `tempimage` in `paintComponent` is image so i have to getImage() – N Kumar Oct 21 '15 at 16:22
  • @reenleedr: You're asking for debugging help, essentially, "why isn't this code working as expected?" help, and so if general advice doesn't help, you really must create and post the shortest code necessary for us to be able to compile, run and help identify your problem. Else, we're not going to be able to help well other than to give general advice, as I've done above. – Hovercraft Full Of Eels Oct 21 '15 at 16:43
  • sir, i am trying to find shortest example but my application is too complicated.. – N Kumar Oct 21 '15 at 16:46
  • 2
    @reenleedr: I agree that what I'm requesting would not be an easy or quick thing to do as it would require quite a bit of effort on your part, but if you remain stuck and need a solution to this, it would be effort well spent. Up to you, and depends solely on your need. Regardless, good luck! – Hovercraft Full Of Eels Oct 21 '15 at 17:03
  • 1
    @reenleedr: for an example of using a Swing Timer and an ArrayList of images, please look at my code answer in [this recent program](http://stackoverflow.com/a/33219497/522444). In it, I create an `ArrayList` to hold ImageIcons of increasing sizes of an image. Then when the mouse hovers over the button a Swing Timer is triggered that swaps the icons in succession, showing a growing image. The reverse happens when the mouse leaves the button. – Hovercraft Full Of Eels Oct 21 '15 at 21:40
2

The repaint manager can collapse sequential call to repaint so that if you paint one frame for each image some images might not show. You can use paintImmediately to force the repaint:

Paints the specified region in this component and all of its descendants that overlap the region, immediately.

It's rarely necessary to call this method. In most cases it's more efficient to call repaint, which defers the actual painting and can collapse redundant requests into a single paint call. This method is useful if one needs to update the display while the current event is being dispatched.

As for

when I changed the size of image from ObjectInputStream it is working fine.

It might factor into the repaint manager's calculation of how / which repaint calls to collapse.

I suggest you try this method and see if it works, though it is more difficult to implement (read the API carefully).

Credit to this post for refreshing my memory.

Community
  • 1
  • 1
user1803551
  • 12,965
  • 5
  • 47
  • 74
  • @HovercraftFullOfEels Thanks. I think that if this is the solution then this question should be marked as a duplicate of the one i linked. – user1803551 Oct 21 '15 at 17:09
  • Is `paintImmediately` called after `repaint()` or should it be manually called like OBJ.paintImmediately(rectangle r) – N Kumar Oct 21 '15 at 17:14
  • @reenleedr The latter (didn't test myself). – user1803551 Oct 21 '15 at 17:22
  • does `paintImmediately` calls `paintComponent`?? – N Kumar Oct 21 '15 at 17:25
  • @reenleedr I think it calls `paint`. See [this](http://stackoverflow.com/questions/14031653/how-does-jcomponent-paintimmediately-work-in-java-swing). Will have to look at the source code to know for sure. – user1803551 Oct 21 '15 at 17:30