/* * @(#)BufferedPanel.java 1.3 02/08/21 * * Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved. */ package com.sun.media.ui; import java.awt.*; import java.awt.event.*; import java.util.*; import java.io.*; public class BufferedPanel extends Panel { public BufferedPanel(LayoutManager layout) { // super(layout); super (); this.setLayout ( layout ); buffered = true; autoFlushing = true; background = null; windowCreated = false; buffer = null; bufferGraphics = null; damage = new Region(); } public BufferedPanel() { this(null); } public boolean isBuffered() { return buffered; } public void setBuffered(boolean buffered) { if (buffered != this.buffered) { this.buffered = buffered; if (buffered) { repaint(); } } } public boolean isAutoFlushing() { return autoFlushing; } public void setAutoFlushing(boolean flushing) { if (flushing != autoFlushing) { autoFlushing = flushing; } } public Image getBackgroundTile() { return background; } public void setBackgroundTile(Image background) { this.background = background; repaint(); } public void addNotify() { super.addNotify(); windowCreated = true; if (buffered) { createBufferImage(); repaint(); } } public void reshape(int x, int y, int width, int height) { Rectangle old = getBounds(); super.reshape(x, y, width, height); if (windowCreated && ((width != old.width) || (height != old.height))) { if (buffered) { // Resize the image createBufferImage(); repaint(); } } } public void flushBuffer() { Dimension size = getSize(); super.repaint(0, 0, 0, size.width, size.height); } void createBufferImage() { Dimension size = getSize(); if ((size.width > 0) && (size.height > 0)) { buffer = createImage(size.width, size.height); if (buffer != null) { bufferGraphics = buffer.getGraphics(); } } } protected void renderBuffer() { Region rects; Rectangle rect; // Anything need repainting? if (damage.isEmpty()) { return; } // Make sure we have a buffer to flush if (buffer == null) { return; } // Keep a copy of the damage region and then reset it synchronized(damage) { rects = damage; damage = new Region(); } // Cycle through each damage rectangle and paint the children // back to front into the buffer image for (Enumeration e = rects.rectangles(); e.hasMoreElements(); ) { rect = (Rectangle)(e.nextElement()); render(rect); } } protected void render(Rectangle rect) { Rectangle clip; Component children[] = getComponents(); Component child; Graphics g; synchronized(buffer) { // Clear the background bufferGraphics.setClip(rect); paintBackground(bufferGraphics); bufferGraphics.setColor(getForeground()); // Paint the children if they are visible and intersect // the current rectangle for (int c = children.length - 1; c >= 0; c--) { child = children[c]; if (isLightweight(child) && child.isVisible()) { clip = child.getBounds(); if (clip.intersects(rect)) { g = bufferGraphics.create(clip.x, clip.y, clip.width, clip.height); child.paint(g); g.dispose(); } } } bufferGraphics.setClip(0, 0, getSize().width, getSize().height); } } protected void paintBackground(Graphics g) { Dimension size = getSize(); if (background == null) { // Just fill with the background color g.setColor(getBackground()); g.fillRect(0, 0, size.width, size.height); } else { // Tile the background image to cover the window Rectangle tile = new Rectangle(0, 0, background.getWidth(this), background.getHeight(this)); Rectangle clip = g.getClipBounds(); while (tile.y < size.height) { while (tile.x < size.width) { if ((clip == null) || (clip.intersects(tile))) { g.drawImage(background, tile.x, tile.y, this); } tile.x += tile.width; } tile.x = 0; tile.y += tile.height; } } } boolean isLightweight(Component comp) { return comp.getPeer() instanceof java.awt.peer.LightweightPeer; } public void repaint(long time, int x, int y, int width, int height) { if (buffered) { synchronized(damage) { damage.addRectangle(new Rectangle(x, y, width, height)); } if (autoFlushing) { flushBuffer(); } } else { super.repaint(time, x, y, width, height); } } public void update(Graphics g) { // It is not necessary to have the system clear the background // for us... if (buffered) { paint(g); } else { super.update(g); } } public void paint(Graphics g) { if ((buffered) && (buffer != null)) { renderBuffer(); g.drawImage(buffer, 0, 0, this); } else { super.paint(g); } } protected boolean buffered; protected boolean autoFlushing; protected Image background; protected boolean windowCreated; protected transient Image buffer; protected transient Graphics bufferGraphics; protected transient Region damage; protected Object lock = new Object(); private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException { is.defaultReadObject(); damage = new Region(); } }