java - Screen flickers when setting background -
i'm trying make simple gui program without using jcomponents. currently, have bufferedimage draw off screen doesn't flicker (or thought).
i made new program here replicate issue:
package main; import java.awt.color; import java.awt.dimension; import java.awt.graphics; import java.awt.image.bufferedimage; import javax.swing.*; public class main { private final static jframe frame = new jframe(); private final static panel panel = new panel(); public static void main(string[] args) { frame.setdefaultcloseoperation(jframe.exit_on_close); panel.setpreferredsize(new dimension(1000, 750)); frame.setcontentpane(panel); frame.pack(); frame.setvisible(true); while (true) { panel.setbackgroundcolour(color.white); panel.setbackgroundcolour(color.black); panel.repaint(); } } private static class panel extends jpanel { private final bufferedimage offscreen = new bufferedimage(1000, 750, bufferedimage.type_int_argb); private final graphics graphics = offscreen.getgraphics(); @override protected void paintcomponent(graphics graphics) { graphics.drawimage(offscreen, 0, 0, null); } public void setbackgroundcolour(color colour) { graphics.setcolor(colour); graphics.fillrect(0, 0, 1000, 750); } }
}
in example above, made screen turn black, , white (offscreen). i'd expect paintcomponent() displays white screen. instead, black screen showed well, flickered.
am using graphics2d incorrectly, or should use bufferstrategy incorporate double buffering needs?
my best guess have race condition, while-loop
trying update bufferedimage
, swing trying paint it, meaning getting dirty updates between them. also, might thrashing event dispatching thread, have it's own, long term issues.
after playing around, able work...
import java.awt.color; import java.awt.dimension; import java.awt.eventqueue; import java.awt.graphics; import java.awt.graphicsconfiguration; import java.awt.graphicsenvironment; import java.awt.image.bufferedimage; import java.util.logging.level; import java.util.logging.logger; import javax.swing.jframe; import javax.swing.jpanel; import javax.swing.uimanager; import javax.swing.unsupportedlookandfeelexception; public class main { private final static jframe frame = new jframe(); private final static panel panel = new panel(); public static void main(string[] args) { new main(); } public main() { eventqueue.invokelater(new runnable() { @override public void run() { try { uimanager.setlookandfeel(uimanager.getsystemlookandfeelclassname()); } catch (classnotfoundexception | instantiationexception | illegalaccessexception | unsupportedlookandfeelexception ex) { ex.printstacktrace(); } frame.setdefaultcloseoperation(jframe.exit_on_close); panel.setpreferredsize(new dimension(1000, 750)); frame.setcontentpane(panel); frame.pack(); frame.setvisible(true); } }); while (true) { panel.setbackgroundcolour(color.white); panel.setbackgroundcolour(color.black); panel.repaint(); try { thread.sleep(40); } catch (interruptedexception ex) { logger.getlogger(main.class.getname()).log(level.severe, null, ex); } } } private static class panel extends jpanel { private bufferedimage offscreen = new bufferedimage(1000, 700, bufferedimage.type_int_argb); @override protected void paintcomponent(graphics graphics) { super.paintcomponent(graphics); graphics.drawimage(offscreen, 0, 0, this); } public void setbackgroundcolour(color colour) { graphics graphics = offscreen.getgraphics(); graphics.setcolor(colour); graphics.fillrect(0, 0, 1000, 700); graphics.dispose(); } } public static bufferedimage createcompatibleimage(int width, int height, int transparency) { bufferedimage image = getgraphicsconfiguration().createcompatibleimage(width, height, transparency); image.coercedata(true); return image; } public static graphicsconfiguration getgraphicsconfiguration() { return graphicsenvironment.getlocalgraphicsenvironment().getdefaultscreendevice().getdefaultconfiguration(); } }
all injects small delay (25fps) between updates, allowing swing time render result.
you have remember @ 2 things swing, repaint
doesn't happen , may not happen @ all, depending on repaintmanager
decides do. second, don't control painting process.
swing uses passive rendering algorithm, meaning painting occur when it's needed, many times without knowledge or intervention. best can make suggestions framework when want updated
see painting in awt , swing , performing custom painting more details.
Comments
Post a Comment