Image doubleBuffer;
int clickCount;
private static final Dimension pSize = new Dimension(512, 512);
public void paint(Graphics g) {
long t1 = System.currentTimeMillis();
if (doubleBuffer == null) {
doubleBuffer = createImage(this.getWidth(), this.getHeight());
}
g.drawImage(doubleBuffer, 0, 0, null);
long t2 = System.currentTimeMillis();
System.out.println("Render consumed " + (t2 - t1) + " milliseconds");
}
public Dimension getPreferredSize()
{
return pSize;
}
public void changeInternalStatus()
{
Graphics g = doubleBuffer.getGraphics();
//更改绘图......;
g.drawLine(0, clickCount, doubleBuffer.getWidth(null), clickCount);
clickCount += 5;
for (int i = 0; i < 256; i ++) {
g.setColor(new Color(i, i / 2, i / 3));
g.drawRoundRect(i, i, this.getWidth() - i * 2, this.getHeight() - i * 2, i / 5, i / 10);
}
g.dispose();
repaint();
}
public static void main(String[] args) {
final MyPanel p = new MyPanel();
JFrame f = new JFrame();
JMenuBar mb = new JMenuBar();
JMenu m = new JMenu("Test");
mb.add(m);
JMenuItem mi = new JMenuItem("Draw in off screen");
m.add(mi);
mi.addActionListener(new ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent e) {
p.changeInternalStatus();
}
for (int i = 0; i < 256; i ++) {
g.setColor(new Color(i, i / 2, i / 3));
g.drawRoundRect(i, i, this.getWidth() - i * 2, this.getHeight() - i * 2, i / 5, i / 10);
}
public Dimension getPreferredSize()
{
return pSize;
}
public void changeInternalStatus()
{
clickCount += 5;
repaint();
}
public static void main(String[] args) {
final MyPanel p = new MyPanel();
JFrame f = new JFrame();
JMenuBar mb = new JMenuBar();
JMenu m = new JMenu("Test");
mb.add(m);
JMenuItem mi = new JMenuItem("Draw in off screen");
m.add(mi);
mi.addActionListener(new ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent e) {
p.changeInternalStatus();
}
public static void main(String[] args) {
final MyPanel p = new MyPanel();
JFrame f = new JFrame();
JMenuBar mb = new JMenuBar();
JMenu m = new JMenu("Test");
mb.add(m);
JMenuItem mi = new JMenuItem("Draw in off screen");
m.add(mi);
mi.addActionListener(new ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent e) {
p.changeInternalStatus();
}
One of the most notable features of Swing is that it builds support for double-buffering right into the toolkit. It does the by providing a "doubleBuffered" property on javax.swing.JComponent:
public boolean isDoubleBuffered()
public void setDoubleBuffered(boolean o)
Swing's double buffer mechanism uses a single offscreen buffer per containment hierarchy (usually per top-level window) where double-buffering has been enabled. And although this property can be set on a per-component basis, the result of setting it on a particular container will have the effect of causing all lightweight components underneath that container to be rendered into the offscreen buffer, regardless of their individual "doubleBuffered" property values.
By default, this property is set to true for all Swing components. But the setting that really matters is on JRootPane, because that setting effectively turns on double-buffering for everything underneath the top-level Swing component. For the most part, Swing programs don't need to do anything special to deal with double-buffering, except to decide whether it should be on or off (and for smooth GUI rendering, you'll want it on!). Swing ensures that the appropriate type of Graphics object (offscreen image Graphics for double-buffering, regular Graphics otherwise) is passed to the component's paint callback, so all the component needs to do is draw with it. This mechanism is explained in greater detail later in this article, in the section on Paint Processing.