问题
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 callingpaint()
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);
}
...
}
回答1:
For smoother drawing, override the paintComponent()
method of JPanel
, which is double buffered by default. This answer discusses an example.
回答2:
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
回答3:
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.
来源:https://stackoverflow.com/questions/10324444/java-applet-blinking-on-mac