Advertisement
Luninariel

289 - Image Renderer

Apr 8th, 2019
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.70 KB | None | 0 0
  1. //
  2. //  ImageRenderer.java
  3. //  SwingEasel
  4. //
  5. //  Created by Philip Rhodes on 9/2/05.
  6. //  Copyright 2005 Philip J Rhodes. All rights reserved.
  7. //
  8.  
  9. import java.awt.*;
  10. import java.awt.image.*;
  11.  
  12. /** This abstract class provides a VolatileImage for double buffering. Although
  13.  *  Swing provides double buffering by default, using a VolatileImage allows
  14.  *  the Java Virtual Machine (JVM) to take advantage of hardware acceleration.
  15.  *  Even if a particular JVM doesn't do this, or if there is no 3D graphics card
  16.  *  installed, there may still be an advantage to using an image, because each
  17.  *  drawing operation may be slightly faster.
  18.  */
  19. public abstract class ImageRenderer extends Renderer{
  20.  
  21.    protected Image backingImage;
  22.    protected boolean wasPainted = false;
  23.    protected Graphics imageGraphics;
  24.    
  25.    protected int imageWidth;
  26.    protected int imageHeight;
  27.    
  28.    protected boolean showFPS;
  29.    protected long lastRenderTime;
  30.  
  31.  
  32.  
  33.    /** Create a VolatileImageRenderer to render the shapes in the World w.*/
  34.    ImageRenderer(World w, int width, int height, boolean showFPS){
  35.      
  36.       super(w, false);
  37.       this.setOpaque(true);
  38.       super.setSize(width, height);
  39.      
  40.       this.showFPS = showFPS;
  41.      
  42.       this.imageWidth = width;
  43.       this.imageHeight = height;
  44.    }
  45.    
  46.    /** Creates the image and associated Graphics object.
  47.     */
  48.    public abstract void init();
  49.    
  50.    
  51.    
  52.  
  53.    /** Draw the volatile image to the screen. */
  54.    public void paintComponent(Graphics g){
  55.    
  56.       // Let's not class the superclass version, since we are going to
  57.       // fill the entire JPanel, anyway. No need to erase underneath.
  58.       //super.paintComponent(g);
  59.      
  60.       if(this.backingImage == null){
  61.          
  62.          this.init();
  63.            
  64.       } else {
  65.      
  66.          // This line makes sure that when we call g.drawImage(), it will be
  67.          // the only thread using the backingImage object.
  68.          synchronized(this.backingImage) {
  69.          
  70.             // Only paint the backing image if it has not already
  71.             // been painted.
  72.             if ( ! this.wasPainted) {
  73.            
  74.                // Draw the backign image to the screen.
  75.                g.drawImage(this.backingImage, 0 ,0, this);
  76.                this.wasPainted = true;
  77.                
  78.                // Erase the backing image.
  79.                clear();
  80.             }
  81.            
  82.             // A child class render method may be waiting for this method to finish
  83.             // via the waitUntilPainted() method, so we'll let it know that we're done.
  84.             this.backingImage.notify();
  85.          }
  86.      
  87.          
  88.       }
  89.    }
  90.  
  91.    /** This method is meant to be called by a child class render method, and
  92.     *  assumes that the current thread has a lock on this.backingImage. In other
  93.     *  words, it should be called inside a "synchronized" block. waitUntilPainted()
  94.     *  checks to see if the backing image has been painted to the screen yet.
  95.     *  If it has not, then the current thread is put to sleep, and will wake
  96.     *  up after the backing image has been painted. This method then terminates
  97.     *  so that execution of the child render method can continue.
  98.     */
  99.    protected void waitUntilPainted(){
  100.  
  101.          // If the backing image hasn't been painted to the screen yet, then
  102.          // we'll wait until ImageRenderer.paintComponent() has finished.
  103.          if(! this.wasPainted){
  104.             try{
  105.            
  106.                this.backingImage.wait();
  107.            
  108.             } catch(Exception e){
  109.            
  110.                System.out.println("ImageRenderer.waitUntilPainted():"+e);
  111.                System.exit(1);
  112.             }
  113.          }
  114.    
  115.    }
  116.  
  117.    /** This method is meant to be called by a child class render method, and
  118.     *  assumes that the current thread has a lock on this.backingImage. In other
  119.     *  words, it should be called inside a "synchronized" block. readyForPainting()
  120.     *  should be called at the end of the render method, just before the end
  121.     *  of the "synchronized" block. It indicates that the backing image is now
  122.     *  ready to be painted to the screen. This method calls repaint().
  123.     */
  124.    protected void readyForPainting(){
  125.  
  126.       // This is an optional display of fps. It generates string objects, so
  127.       // it will trigger garbage collection eventually.
  128.       if (this.showFPS){
  129.      
  130.          long now = System.currentTimeMillis();
  131.          this.imageGraphics.drawString(new String("fps= " + ((int) ( 10 *  (1000.0 / (now - lastRenderTime)) ) ) / 10.0 ), 10, 12);
  132.          this.lastRenderTime = now;
  133.       }
  134.      
  135.       // the backing image should be painted the next time
  136.       // paintComponent() is called.
  137.       this.wasPainted = false;
  138.       this.repaint();
  139.    }
  140.  
  141.  
  142.    /** Erase the volatile image being used as a backing image. */
  143.    public void clear(){
  144.        
  145.       if(this.imageGraphics != null){
  146.          
  147.          this.imageGraphics.setColor(Color.white);
  148.          this.imageGraphics.fillRect(0, 0, this.imageWidth, this.imageHeight);
  149.       }
  150.    }
  151.    
  152.    
  153.    /** Render triangles to the backing image. Child classes must override
  154.     *  this implementation, but should call the superclass version at the
  155.     *  beginning of their implementation.
  156.     */
  157.    public void render(){
  158.      
  159.       if(this.imageGraphics == null){
  160.          
  161.          this.init();
  162.       }
  163.      
  164.    }
  165.    
  166.    
  167.    
  168.    /** Set the size of this JPanel and the backing image to the specified
  169.      * dimensions.
  170.      */
  171.    public void setSize(int width, int height){
  172.      
  173.       super.setSize(width, height);
  174.      
  175.       this.imageWidth = width;
  176.       this.imageHeight = height;
  177.    }
  178.  
  179.  
  180. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement