⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 display.java

📁 用applet实现很多应用小程序
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    /**
     * Saves a copy of this display as an image to the specified output stream.
     * @param output the output stream to write to.
     * @param format the image format (e.g., "JPG", "PNG"). The number and kind
     * of available formats varies by platform. See
     * {@link javax.imageio.ImageIO} and related classes for more.
     * @param scale how much to scale the image by. For example, a value of 2.0
     * will result in an image with twice the pixel width and height of this
     * Display.
     * @return true if image was successfully saved, false if an error occurred.
     */
    public boolean saveImage(OutputStream output, String format, double scale)
    {
        try {
            // get an image to draw into
            Dimension d = new Dimension((int)(scale*getWidth()),
                                        (int)(scale*getHeight()));
            BufferedImage img = getNewOffscreenBuffer(d.width, d.height);
            Graphics2D g = (Graphics2D)img.getGraphics();
            
            // set up the display, render, then revert to normal settings
            Point2D p = new Point2D.Double(0,0);
            zoom(p, scale); // also takes care of damage report
            boolean q = isHighQuality();
            setHighQuality(true);
            paintDisplay(g, d);
            setHighQuality(q);
            zoom(p, 1/scale); // also takes care of damage report
            
            // save the image and return
            ImageIO.write(img, format, output);
            return true;
        } catch ( Exception e ) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @see java.awt.Component#update(java.awt.Graphics)
     */
    public void update(Graphics g) {
        paint(g);
    }
    
    /**
     * Paints the offscreen buffer to the provided graphics context.
     * @param g the Graphics context to paint to
     */
    protected void paintBufferToScreen(Graphics g) {
        synchronized ( this ) {
            g.drawImage(m_offscreen, 0, 0, null);
        }
    }

    /**
     * Immediately repaints the contents of the offscreen buffer
     * to the screen. This bypasses the usual rendering loop.
     */
    public void repaintImmediate() {
        Graphics g = this.getGraphics();
        if (g != null && m_offscreen != null) {
            paintBufferToScreen(g);
        }
    }

    /**
     * Sets the transform of the provided Graphics context to be the
     * transform of this Display and sets the desired rendering hints.
     * @param g the Graphics context to prepare.
     */
    protected void prepareGraphics(Graphics2D g) {
        if ( m_transform != null )
            g.transform(m_transform);
        setRenderingHints(g);
    }
    
    /**
     * Sets the rendering hints that should be used while drawing
     * the visualization to the screen. Subclasses can override
     * this method to set hints as desired. Such subclasses should
     * consider honoring the high quality flag in one form or another.
     * @param g the Graphics context on which to set the rendering hints
     */
    protected void setRenderingHints(Graphics2D g) {
        if ( m_highQuality ) {
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
        } else {
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_OFF);
        }
        g.setRenderingHint(
            RenderingHints.KEY_RENDERING,
            RenderingHints.VALUE_RENDER_QUALITY);
        g.setRenderingHint(
            RenderingHints.KEY_INTERPOLATION,
            RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    }


    /**
     * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
     */
    public void paintComponent(Graphics g) {
        if (m_offscreen == null) {
            m_offscreen = getNewOffscreenBuffer(getWidth(), getHeight());
            damageReport();
        }
        Graphics2D g2D = (Graphics2D)g;
        Graphics2D buf_g2D = (Graphics2D) m_offscreen.getGraphics();
        
        // Why not fire a pre-paint event here?
        // Pre-paint events are fired by the clearRegion method
        
        // paint the visualization
        paintDisplay(buf_g2D, getSize());
        paintBufferToScreen(g2D);       
        
        // fire post-paint events to any painters
        firePostPaint(g2D);
        
        buf_g2D.dispose();
        
        // compute frame rate
        nframes++;
        if ( mark < 0 ) {
            mark = System.currentTimeMillis();
            nframes = 0;
        } else if ( nframes == sampleInterval ){
            long t = System.currentTimeMillis();
            frameRate = (1000.0*nframes)/(t-mark);
            mark = t;
            nframes = 0;
        }
    }
    
    /**
     * Renders the display within the given graphics context and size bounds.
     * @param g2D the <code>Graphics2D</code> context to use for rendering
     * @param d the rendering width and height of the Display
     */
    public void paintDisplay(Graphics2D g2D, Dimension d) {
        // if double-locking *ALWAYS* lock on the visualization first
        synchronized ( m_vis ) {
        synchronized ( this ) {
            
            if ( m_clip.isEmpty() )
                return; // no damage, no render
            
            // map the screen bounds to absolute coords
            m_screen.setClip(0, 0, d.width+1, d.height+1);
            m_screen.transform(m_itransform);
            
            // compute the approximate size of an "absolute pixel"
            // values too large are OK (though cause unnecessary rendering)
            // values too small will cause incorrect rendering
            double pixel = 1.0 + 1.0/getScale();
            
            if ( m_damageRedraw ) {  
                if ( m_clip.isInvalid() ) {
                    // if clip is invalid, we clip to the entire screen
                    m_clip.setClip(m_screen);
                } else {
                    // otherwise intersect damaged region with display bounds
                    m_clip.intersection(m_screen);
                }
  
                // expand the clip by the extra pixel margin
                m_clip.expand(pixel);
                
                // set the transform, rendering keys, etc
                prepareGraphics(g2D);
                
                // now set the actual rendering clip
                m_rclip.setFrameFromDiagonal(
                        m_clip.getMinX(), m_clip.getMinY(), 
                        m_clip.getMaxX(), m_clip.getMaxY());
                g2D.setClip(m_rclip);
                
                // finally, we want to clear the region we'll redraw. we clear
                // a slightly larger area than the clip. if we don't do this,
                // we sometimes get rendering artifacts, possibly due to
                // scaling mismatches in the Java2D implementation
                m_rclip.setFrameFromDiagonal(
                        m_clip.getMinX()-pixel, m_clip.getMinY()-pixel,
                        m_clip.getMaxX()+pixel, m_clip.getMaxY()+pixel);

            } else {
                // set the background region to clear
                m_rclip.setFrame(m_screen.getMinX(),  m_screen.getMinY(),
                                 m_screen.getWidth(), m_screen.getHeight());
                
                // set the item clip to the current screen
                m_clip.setClip(m_screen);
                
                // set the transform, rendering keys, etc
                prepareGraphics(g2D);
            }

            // now clear the region
            clearRegion(g2D, m_rclip);            
            
            // -- render ----------------------------
            // the actual rendering  loop
            
            // copy current item bounds into m_rclip, reset item bounds
            getItemBounds(m_rclip);
            m_bounds.reset();
            
            // fill the rendering and picking queues
            m_queue.clear();   // clear the queue
            Iterator items = m_vis.items(m_predicate);
            for ( m_visibleCount=0; items.hasNext(); ++m_visibleCount ) {
                VisualItem item = (VisualItem)items.next();
                Rectangle2D bounds = item.getBounds();
                m_bounds.union(bounds); // add to item bounds
                
                if ( m_clip.intersects(bounds, pixel) )
                    m_queue.addToRenderQueue(item);
                if ( item.isInteractive() )
                    m_queue.addToPickingQueue(item);
            }
            
            // sort the rendering queue
            m_queue.sortRenderQueue();
            
            // render each visual item
            for ( int i=0; i<m_queue.rsize; ++i ) {
                m_queue.ritems[i].render(g2D);
            }
            
            // no more damage so reset the clip
            if ( m_damageRedraw )
                m_clip.reset();
            
            // fire bounds change, if appropriate
            checkItemBoundsChanged(m_rclip);
            
        }} // end synchronized block
    }
    
    /**
     * Immediately render the given VisualItem to the screen. This method
     * bypasses the Display's offscreen buffer.
     * @param item the VisualItem to render immediately
     */
    public void renderImmediate(VisualItem item) {
        Graphics2D g2D = (Graphics2D)this.getGraphics();
        prepareGraphics(g2D);
        item.render(g2D);
    }
    
    /**
     * Paints the graph to the provided graphics context, for output to a
     * printer.  This method does not double buffer the painting, in order to
     * provide the maximum print quality.
     * 
     * <b>This method may not be working correctly,
     * and will be repaired at a later date.</b>
     * 
     * @param g the printer graphics context.
     */
    protected void printComponent(Graphics g) {
        boolean wasHighQuality = m_highQuality;
        try {
            // Set the quality to high for the duration of the printing.
            m_highQuality = true;
            // Paint directly to the print graphics context.
            paintDisplay((Graphics2D) g, getSize());
        } finally {
            // Reset the quality to the state it was in before printing.
            m_highQuality = wasHighQuality;
        }
    }
    
    /**
     * Clears the specified region of the display
     * in the display's offscreen buffer.
     */    
    protected void clearRegion(Graphics2D g, Rectangle2D r) {
        g.setColor(getBackground());
        g.fill(r);
        // fire pre-paint events to any painters
        firePrePaint(g);
    }

    // ------------------------------------------------------------------------
    // Transformations
    
    /**
     * Set the 2D AffineTransform (e.g., scale, shear, pan, rotate) used by
     * this display before rendering visual items. The provided transform
     * must be invertible, otherwise an expection will be thrown. For simple
     * panning and zooming transforms, you can instead use the provided
     * pan() and zoom() methods.
     */
    public synchronized void setTransform(AffineTransform transform) 
        throws NoninvertibleTransformException
    {
        damageReport();
        m_transform = transform;
        m_itransform = m_transform.createInverse();
    }
    
    /**
     * Returns a reference to the AffineTransformation used by this Display.
     * Changes made to this reference WILL corrupt the state of 
     * this display. Use setTransform() to safely update the transform state.
     * @return the AffineTransform
     */
    public AffineTransform getTransform() {
        return m_transform;
    }
    
    /**
     * Returns a reference to the inverse of the AffineTransformation used by
     * this display. Direct changes made to this reference WILL corrupt the
     * state of this display.
     * @return the inverse AffineTransform
     */
    public AffineTransform getInverseTransform() {
        return m_itransform;
    }
    
    /**
     * Gets the absolute co-ordinate corresponding to the given screen
     * co-ordinate.
     * @param screen the screen co-ordinate to transform
     * @param abs a reference to put the result in. If this is the same
     *  object as the screen co-ordinate, it will be overridden safely. If
     *  this value is null, a new Point2D instance will be created and 
     *  returned.
     * @return the point in absolute co-ordinates
     */
    public Point2D getAbsoluteCoordinate(Point2D screen, Point2D abs) {
        return m_itransform.transform(screen, abs);
    }
    
    /**
     * Returns the current scale (zoom) value.
     * @return the current scale. This is the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -