5

This problem is very weird. The issue does not occur on every platform. It occurs for me in Google Chrome, using MacOSX, but it doesn't occur in Safari. For a friend that uses Windows, on Google Chrome it works perfectly. I also have a friend that uses MacOSX and for him it blinks on Chrome, Safari and Firefox. We both have MacOSX Lion. I don't see any link. Can you people please test it and report if it happens or not, and what your platform is (it should occur within 30 seconds at most)?


I found this thread on Oracle's forums. Apparently, it is a well-known problem on MacOSX, due to Java creating a child process and Safari not allowing this as a security feature. However the problem also occurs in Chrome and Firefox on Mac (and doesn't on Safari as for me). Go figure… I would be glad to hear anyone's opinion on this.


I am currently making a small Java Tetris game and my problem is that the screen occasionally blinks in the applet version (extending JApplet). Everything works fine when I run it in a JFrame on my computer.

The applet can be viewed and used on this site: http://mtetris.herokuapp.com/ (I am not trying to advertise or promote anything, I just put it so that people can actually see what the problem is).

(There is also another problem which is that the applet does not get the mouse focus properly when it is not loaded automatically – i.e. when the browser blocks it and asks the user if it is allowed to load it. If the "start level" numbers don't get properly highlighted, that's why.)

Here are the things that I've tried which did not fix the blinking issue:

  • Setting to background of the applet, the root pane, the content pane, of every component in the applet to black.
  • Overriding the applet's paint() method and doing double buffering in it (I commented this part in the current code since it was not improving anything)
  • Overriding the applet's update() method and directly calling paint() in it (this problem has been fixed now according to the method description in the official documentation)

The whole source code can be found on github at this page. The class extending JApplet is TetrisApplication. The source code is not very clean yet, so, sorry for that.


This is how I implemented the double buffering

public class TetrisApplication extends JApplet {

    //  the dimension of the applet
    private Dimension dimension;
    // image used for double buffering
    Image offscreen;
    // the second buffer
    Graphics bufferGraphics;

    public void init() {
        super.init();
        dimension = getSize();
        offscreen = createImage(dimension.width, dimension.height);
        bufferGraphics = offscreen.getGraphics();
        ...
    }

    public void paint(Graphics g){
        bufferGraphics.clearRect(0, 0, dimension.width, dimension.height);
        super.paint(bufferGraphics);
        g.drawImage(offscreen, 0, 0, this);
    }
    ...
}
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Rez
  • 615
  • 1
  • 6
  • 9
  • I'm assuming this is fixed now? I played your game for about 10 minutes and didn't see a single flicker. – Danation Apr 26 '12 at 00:22
  • @Danation Thank you very much for testing it. Please see my EDIT 2 just above (at the beginning of the post). The problem doesn't happen for everybody. I don't get it at all. – Rez Apr 26 '12 at 01:42
  • I always get an error, while trying to open that Game Page, why is that so, this is what I am getting [ERROR](https://www.dropbox.com/s/871msprt8crhj7k/error.gif), with these [DETAILS](https://www.dropbox.com/s/0x6jtqyd5fy5xjk/error1.gif) – nIcE cOw Apr 26 '12 at 03:07
  • @nIcEcOw Drag select the content of the console and it can be copied. OP are you using `getResourceAsStream` in the code? As to the error shown, even a trusted applet is not allowed to exit the VM. Do you launch any frames, and set the default close operation? Otherwise where does that call come from? – Andrew Thompson Apr 26 '12 at 05:22
  • @nIcEcOw Just fixed this issue, which was due to the input stream not always supporting mark/reset (when loading audio data). See [here](http://stackoverflow.com/questions/5529754/java-io-ioexception-mark-reset-not-supported). Can you try it again and see if fixes the problem? – Rez Apr 26 '12 at 12:40
  • @Rez : Ahha, exactly that's what I looked at yesterday, but since that thingy belongs to you, so couldn't help myself. Let me try now :-) , But had you changed the link too, in your question, since it's giving me the same error still :( – nIcE cOw Apr 26 '12 at 13:02
  • @nIcEcOw The applet is still on the [same page](http://mtetris.herokuapp.com/). I think I did upload the corrected version, but I'm not sure. Anyway, I just re-uploaded it. Can you try it again *please* ^_^? (sorry to disturb). I do load all audio in a BufferedInputStream now (source code on github is updated), so if it doesn't work, well I don't know :-(. – Rez Apr 26 '12 at 14:17
  • @Rez : Ahha, I forgot to clear my cache, before retry, now it's working fine, :-) Congrats – nIcE cOw Apr 26 '12 at 14:25
  • @nIcEcOw Glad to hear that :). Thanks a lot! I'm not sure I would've fixed this anytime soon if you didn't tell me. – Rez Apr 26 '12 at 14:47
  • As suggested by @trashgod, `JPanel` is the best way to do that with `paintComponent(...)`, since if you override `paint(...)`, a lot of unnecessary painting happens from the parent to the child, of the said container/component, whereas in the former, only the said component gets painted. So might be the flickering is because of this extra load, though as adviced by him, `JPanel/JComponent`. is the way to go :-) Hehe, for the REST, we are all here to HELP each other, I simply told you a small bug, and it gets sorted out too easily, just remember KEEP SMILING :-) – nIcE cOw Apr 26 '12 at 14:49
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/10554/discussion-between-rez-and-nice-cow) – Rez Apr 26 '12 at 14:54

3 Answers3

3

For smoother drawing, override the paintComponent() method of JPanel, which is double buffered by default. This answer discusses an example.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I think that's what I did but I'm not sure I understood you completely. I do the custom painting in paintComponent() of JPanels, as you can see [here](https://github.com/rez-antlion/musical_tetris/blob/master/BoardPanel.java) (where I draw the game board, pieces and blocks), [here](https://github.com/rez-antlion/musical_tetris/blob/master/SidePanel.java) (the side panel). I don't override the paint() method of the applet as you can check [here](https://github.com/rez-antlion/musical_tetris/blob/master/TetrisApplication.java). Am I doing it right? – Rez Apr 26 '12 at 15:10
0

To stop flicking you need to double buffer your drawing surface. Are you sure you implemented it correctly the first time?

Maybe this will help: https://gamedev.stackexchange.com/questions/18661/how-do-i-prevent-flickering-when-drawing-to-a-jpanel

Community
  • 1
  • 1
asawyer
  • 17,642
  • 8
  • 59
  • 87
  • Thanks for your answer. However I used exactly your source to implement double buffering. I just edited my post so that you can see what I did, can you check it and see if it is correct? Thanks again – Rez Apr 25 '12 at 22:24
  • @Rez Sadly I don't know the swing api, it was just an educated guess. – asawyer Apr 25 '12 at 22:25
0

I notice that in GameController you are using a background thread (in a SwingWorker) to update the state. I suspect you may be having synchronization issues when the update happens during a paint() of GamePanel.

A better approach might be to push everything onto the EDT, using a java.swing.Timer that fires every frame and causes a state update and then a repaint(). Then there's no synchronization issue.

Russell Zahniser
  • 16,188
  • 39
  • 30
  • Ok, I'm going to try this and see if it helps, thanks. I see how that may cause synchronization issues, however I don't see how it can cause blinking (which means that a totally white screen appears)? What I expect is that one piece can be partially drawn in a position and partially drawn in an other (since the state can be updated during the painting) but not having a blank screen? – Rez Apr 25 '12 at 22:29
  • I just did what you advised me to do – do everything in the EDT using Swing Timers. It did not fix the problem :-(. I updated my code at github (so you can check that I've done it right if you want) and updated the applet at the site I gave. However I'm going to keep my game like that I think (all in the EDT) since it works just as well if not better. So, thank you for that :). – Rez Apr 25 '12 at 23:00