Java/2D Graphics GUI/Clip

Материал из Java эксперт
Версия от 06:54, 1 июня 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Clip another area

   
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.TitledBorder;
public class ClipArea extends JFrame {
  MyCanvas canvas;
  JRadioButton clipButton, clipFurButton;
  public ClipArea() {
    super();
    Container contentPane = getContentPane();
    canvas = new MyCanvas();
    contentPane.add(canvas);
    JPanel panel = new JPanel();
    panel.setLayout(new GridLayout(1, 2));
    clipButton = new JRadioButton("Clip", true);
    clipButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        canvas.clip = true;
        canvas.clipFurther = false;
        canvas.repaint();
      }
    });
    clipFurButton = new JRadioButton("Clip Further");
    clipFurButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        canvas.clipFurther = true;
        canvas.repaint();
      }
    });
    ButtonGroup group = new ButtonGroup();
    group.add(clipButton);
    group.add(clipFurButton);
    panel.add(clipButton);
    panel.add(clipFurButton);
    contentPane.add(BorderLayout.SOUTH, panel);
    // 4. Add a window listener to close the frame properly.
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    pack(); 
    setVisible(true); 
  }
  public static void main(String arg[]) {
    new ClipArea();
  }
}
class MyCanvas extends JPanel{
  boolean clip = true;
  boolean clipFurther = false;
  MyCanvas() {
    setSize(300, 300);
    setBackground(Color.white);
  }
  public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    int w = getSize().width;
    int h = getSize().height;
    if (clip) {
      Ellipse2D e = new Ellipse2D.Float(w / 4.0f, h / 4.0f, w / 2.0f,
          h / 2.0f);
      g2.setClip(e);
      g2.setColor(Color.yellow);
      g2.fillRect(0, 0, w, h);
    }
    if (clipFurther) {
      Rectangle r = new Rectangle(w / 2, h / 2, w / 2, h / 2);
      g2.clip(r);
      g2.setColor(Color.green);
      g2.fillRect(0, 0, w, h);
    }
  }
}



Clip Image

   
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.swing.JApplet;
import javax.swing.JFrame;
public class ClipImage extends JApplet implements Runnable {
  private Image img;
  private final double OINC[] = { 5.0, 3.0 };
  private final double SINC[] = { 5.0, 5.0 };
  private double x, y;
  private double ix = OINC[0];
  private double iy = OINC[1];
  private double iw = SINC[0];
  private double ih = SINC[1];
  private double ew, eh; // ellipse width & height
  private GeneralPath p = new GeneralPath();
  private AffineTransform at = new AffineTransform();
  private BasicStroke bs = new BasicStroke(20.0f);
  private Arc2D arc = new Arc2D.Float();
  private Ellipse2D ellipse = new Ellipse2D.Float();
  private RoundRectangle2D roundRect = new RoundRectangle2D.Float();
  private Rectangle2D rect = new Rectangle2D.Float();
  private Color redBlend = new Color(255, 0, 0, 120);
  private Color greenBlend = new Color(0, 255, 0, 120);
  private Thread thread;
  private BufferedImage offImg;
  private int w, h;
  private boolean newBufferedImage;
  public void init() {
    img = getImage(getURL("largejexpLogo.GIF"));
    try {
      MediaTracker tracker = new MediaTracker(this);
      tracker.addImage(img, 0);
      tracker.waitForID(0);
    } catch (Exception e) {
    }
  }
  public void drawDemo(Graphics2D g2) {
    if (newBufferedImage) {
      x = Math.random() * w;
      y = Math.random() * h;
      ew = (Math.random() * w) / 2;
      eh = (Math.random() * h) / 2;
    }
    x += ix;
    y += iy;
    ew += iw;
    eh += ih;
    if (ew > w / 2) {
      ew = w / 2;
      iw = Math.random() * -w / 16 - 1;
    }
    if (ew < w / 8) {
      ew = w / 8;
      iw = Math.random() * w / 16 + 1;
    }
    if (eh > h / 2) {
      eh = h / 2;
      ih = Math.random() * -h / 16 - 1;
    }
    if (eh < h / 8) {
      eh = h / 8;
      ih = Math.random() * h / 16 + 1;
    }
    if ((x + ew) > w) {
      x = (w - ew) - 1;
      ix = Math.random() * -w / 32 - 1;
    }
    if (x < 0) {
      x = 2;
      ix = Math.random() * w / 32 + 1;
    }
    if ((y + eh) > h) {
      y = (h - eh) - 2;
      iy = Math.random() * -h / 32 - 1;
    }
    if (y < 0) {
      y = 2;
      iy = Math.random() * h / 32 + 1;
    }
    ellipse.setFrame(x, y, ew, eh);
    g2.setClip(ellipse);
    rect.setRect(x + 5, y + 5, ew - 10, eh - 10);
    g2.clip(rect);
    g2.drawImage(img, 0, 0, w, h, this);
    p.reset();
    p.moveTo(-w / 2.0f, -h / 8.0f);
    p.lineTo(+w / 2.0f, -h / 8.0f);
    p.lineTo(-w / 4.0f, +h / 2.0f);
    p.lineTo(+0.0f, -h / 2.0f);
    p.lineTo(+w / 4.0f, +h / 2.0f);
    p.closePath();
    at.setToIdentity();
    at.translate(w * .5f, h * .5f);
    g2.transform(at);
    g2.setStroke(bs);
    g2.setPaint(redBlend);
    g2.draw(p);
    at.setToIdentity();
    g2.setTransform(at);
    g2.setPaint(greenBlend);
    for (int yy = 0; yy < h; yy += 50) {
      for (int xx = 0, i = 0; xx < w; i++, xx += 50) {
        switch (i) {
        case 0:
          arc.setArc(xx, yy, 25, 25, 45, 270, Arc2D.PIE);
          g2.fill(arc);
          break;
        case 1:
          ellipse.setFrame(xx, yy, 25, 25);
          g2.fill(ellipse);
          break;
        case 2:
          roundRect.setRoundRect(xx, yy, 25, 25, 4, 4);
          g2.fill(roundRect);
          break;
        case 3:
          rect.setRect(xx, yy, 25, 25);
          g2.fill(rect);
          i = -1;
        }
      }
    }
  }
  public Graphics2D createDemoGraphics2D(Graphics g) {
    Graphics2D g2 = null;
    if (offImg == null || offImg.getWidth() != w || offImg.getHeight() != h) {
      offImg = (BufferedImage) createImage(w, h);
      newBufferedImage = true;
    }
    if (offImg != null) {
      g2 = offImg.createGraphics();
      g2.setBackground(getBackground());
    }
    // .. set attributes ..
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setRenderingHint(RenderingHints.KEY_RENDERING,
        RenderingHints.VALUE_RENDER_QUALITY);
    // .. clear canvas ..
    g2.clearRect(0, 0, w, h);
    return g2;
  }
  public void paint(Graphics g) {
    w = getWidth();
    h = getHeight();
    if (w <= 0 || h <= 0)
      return;
    Graphics2D g2 = createDemoGraphics2D(g);
    drawDemo(g2);
    g2.dispose();
    if (offImg != null && isShowing()) {
      g.drawImage(offImg, 0, 0, this);
    }
    newBufferedImage = false;
  }
  public void start() {
    thread = new Thread(this);
    thread.start();
  }
  public synchronized void stop() {
    thread = null;
  }
  public void run() {
    Thread me = Thread.currentThread();
    while (thread == me && isShowing()) {
      Graphics g = getGraphics();
      paint(g);
      g.dispose();
      thread.yield();
    }
    thread = null;
  }
  protected URL getURL(String filename) {
    URL codeBase = this.getCodeBase();
    URL url = null;
    try {
      url = new URL(codeBase, filename);
    } catch (java.net.MalformedURLException e) {
      System.out.println("Couldn"t create image: "
          + "badly specified URL");
      return null;
    }
    return url;
  }
  public static void main(String s[]) {
    final ClipImage demo = new ClipImage();
    WindowListener l = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
      public void windowDeiconified(WindowEvent e) {
        demo.start();
      }
      public void windowIconified(WindowEvent e) {
        demo.stop();
      }
    };
    JFrame f = new JFrame("Java 2D Demo - ClipImage");
    f.addWindowListener(l);
    f.getContentPane().add("Center", demo);
    f.setSize(new Dimension(400, 300));
    f.show();
    demo.start();
  }
}



Clipping is restricting of drawing to a certain area.

    
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Clipping extends JPanel implements ActionListener {
  int x = 8, y = 8, radius = 90;
  Timer timer;
  Image image = new ImageIcon("yourImage.png").getImage();
  double delta[] = { 3, 3 };
  public Clipping() {
    timer = new Timer(15, this);
    timer.start();
  }
  public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setClip(new Ellipse2D.Double(x, y, radius, radius));
    g2d.drawImage(image, 5, 5, null);
  }
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.add(new Clipping());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 400);
    frame.setVisible(true);
  }
  public void actionPerformed(ActionEvent e) {
    int w = 400;
    int h = 400;
    if (x < 0) {
      delta[0] = Math.random() % 4 + 5;
    } else if (x > w - radius) {
      delta[0] = -(Math.random() % 4 + 5);
    }
    if (y < 0) {
      delta[1] = Math.random() % 4 + 5;
    } else if (y > h - radius) {
      delta[1] = -(Math.random() % 4 + 5);
    }
    x += delta[0];
    y += delta[1];
    repaint();
  }
}



Clips the specified line to the given rectangle.

  
/* 
 * JFreeChart : a free chart library for the Java(tm) platform
 * 
 *
 * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
 *
 * Project Info:  http://www.jfree.org/jfreechart/index.html
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
 * USA.
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
 * in the United States and other countries.]
 *
 * ------------------
 * LineUtilities.java
 * ------------------
 * (C) Copyright 2008, by Object Refinery Limited and Contributors.
 *
 * Original Author:  David Gilbert (for Object Refinery Limited);
 * Contributor(s):   -;
 *
 * Changes
 * -------
 * 05-Nov-2008 : Version 1 (DG);
 *
 */

import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
/**
 * Some utility methods for {@link Line2D} objects.
 *
 * @since 1.0.12
 */
public class LineUtilities {
    /**
     * Clips the specified line to the given rectangle.
     *
     * @param line  the line (<code>null</code> not permitted).
     * @param rect  the clipping rectangle (<code>null</code> not permitted).
     *
     * @return <code>true</code> if the clipped line is visible, and
     *     <code>false</code> otherwise.
     */
    public static boolean clipLine(Line2D line, Rectangle2D rect) {
        double x1 = line.getX1();
        double y1 = line.getY1();
        double x2 = line.getX2();
        double y2 = line.getY2();
        double minX = rect.getMinX();
        double maxX = rect.getMaxX();
        double minY = rect.getMinY();
        double maxY = rect.getMaxY();
        int f1 = rect.outcode(x1, y1);
        int f2 = rect.outcode(x2, y2);
        while ((f1 | f2) != 0) {
            if ((f1 & f2) != 0) {
                return false;
            }
            double dx = (x2 - x1);
            double dy = (y2 - y1);
            // update (x1, y1), (x2, y2) and f1 and f2 using intersections
            // then recheck
            if (f1 != 0) {
                // first point is outside, so we update it against one of the
                // four sides then continue
                if ((f1 & Rectangle2D.OUT_LEFT) == Rectangle2D.OUT_LEFT
                        && dx != 0.0) {
                    y1 = y1 + (minX - x1) * dy / dx;
                    x1 = minX;
                }
                else if ((f1 & Rectangle2D.OUT_RIGHT) == Rectangle2D.OUT_RIGHT
                        && dx != 0.0) {
                    y1 = y1 + (maxX - x1) * dy / dx;
                    x1 = maxX;
                }
                else if ((f1 & Rectangle2D.OUT_BOTTOM) == Rectangle2D.OUT_BOTTOM
                        && dy != 0.0) {
                    x1 = x1 + (maxY - y1) * dx / dy;
                    y1 = maxY;
                }
                else if ((f1 & Rectangle2D.OUT_TOP) == Rectangle2D.OUT_TOP
                        && dy != 0.0) {
                    x1 = x1 + (minY - y1) * dx / dy;
                    y1 = minY;
                }
                f1 = rect.outcode(x1, y1);
            }
            else if (f2 != 0) {
                // second point is outside, so we update it against one of the
                // four sides then continue
                if ((f2 & Rectangle2D.OUT_LEFT) == Rectangle2D.OUT_LEFT
                        && dx != 0.0) {
                    y2 = y2 + (minX - x2) * dy / dx;
                    x2 = minX;
                }
                else if ((f2 & Rectangle2D.OUT_RIGHT) == Rectangle2D.OUT_RIGHT
                        && dx != 0.0) {
                    y2 = y2 + (maxX - x2) * dy / dx;
                    x2 = maxX;
                }
                else if ((f2 & Rectangle2D.OUT_BOTTOM) == Rectangle2D.OUT_BOTTOM
                        && dy != 0.0) {
                    x2 = x2 + (maxY - y2) * dx / dy;
                    y2 = maxY;
                }
                else if ((f2 & Rectangle2D.OUT_TOP) == Rectangle2D.OUT_TOP
                        && dy != 0.0) {
                    x2 = x2 + (minY - y2) * dx / dy;
                    y2 = minY;
                }
                f2 = rect.outcode(x2, y2);
            }
        }
        line.setLine(x1, y1, x2, y2);
        return true;  // the line is visible - if it wasn"t, we"d have
                      // returned false from within the while loop above
    }
}



Clip the area

   
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class ClipDemo extends JComponent {
  private static Color red = new Color(255, 0, 0, 150);
  private static Color green = new Color(0, 255, 0, 150);
  private static Color blue = new Color(0, 0, 255, 150);
  private static Font monoFont = new Font("Monospaced", Font.BOLD
      | Font.ITALIC, 36);
  private static Font sanFont = new Font("SanSerif", Font.PLAIN, 12);
  private static Font serifFont = new Font("Serif", Font.BOLD, 24);
  private static ImageIcon jexpLogo = new ImageIcon("jexpLogo.gif");
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    // get damaged region
    Rectangle clipRect = g.getClipBounds();
    int clipx = clipRect.x;
    int clipy = clipRect.y;
    int clipw = clipRect.width;
    int cliph = clipRect.height;
    // fill damaged region only
    g.setColor(Color.white);
    g.fillRect(clipx, clipy, clipw, cliph);
    if (clipx <= 240 && clipy <= 240) {
      g.setColor(Color.yellow);
      g.fillOval(0, 0, 240, 240);
      System.out.println(" yellow Oval repainted.");
    }
    if (clipx + clipw >= 160 && clipx <= 400 && clipy + cliph >= 160
        && clipy <= 400) {
      g.setColor(Color.magenta);
      g.fillOval(160, 160, 240, 240);
      System.out.println(" magenta Oval repainted.");
    }
    int iconWidth = jexpLogo.getIconWidth();
    int iconHeight = jexpLogo.getIconHeight();
    if (clipx + clipw >= 280 - (iconWidth / 2) && clipx <= (280 + (iconWidth / 2))
        && clipy + cliph >= 120 - (iconHeight / 2) && clipy <= (120 + (iconHeight / 2))) {
      jexpLogo.paintIcon(this, g, 280 - (iconWidth / 2), 120 - (iconHeight / 2));
      System.out.println(" logo below blue Rect repainted.");
    }
    if (clipx + clipw >= 120 - (iconWidth / 2) && clipx <= (120 + (iconWidth / 2))
        && clipy + cliph >= 280 - (iconHeight / 2) && clipy <= (280 + (iconHeight / 2))) {
      jexpLogo.paintIcon(this, g, 120 - (iconWidth / 2), 280 - (iconHeight / 2));
      System.out.println(" logo below red Rect repainted.");
    }
    if (clipx + clipw >= 60 && clipx <= 180 && clipy + cliph >= 220
        && clipy <= 340) {
      g.setColor(red);
      g.fillRect(60, 220, 120, 120);
      System.out.println(" red Rect repainted.");
    }
    if (clipx + clipw > 140 && clipx < 260 && clipy + cliph > 140
        && clipy < 260) {
      g.setColor(green);
      g.fillOval(140, 140, 120, 120);
      System.out.println(" green Oval repainted.");
    }
    if (clipx + clipw > 220 && clipx < 380 && clipy + cliph > 60
        && clipy < 180) {
      g.setColor(blue);
      g.fillRect(220, 60, 120, 120);
      System.out.println(" blue Rect repainted.");
    }
    g.setColor(Color.black);
    g.setFont(monoFont);
    FontMetrics fm = g.getFontMetrics();
    iconWidth = fm.stringWidth("Java Source");
    iconHeight = fm.getAscent();
    int d = fm.getDescent();
    if (clipx + clipw > 120 - (iconWidth / 2) && clipx < (120 + (iconWidth / 2))
        && clipy + cliph > (120 + (iconHeight / 4)) - iconHeight
        && clipy < (120 + (iconHeight / 4)) + d) {
      g.drawString("Java Source", 120 - (iconWidth / 2), 120 + (iconHeight / 4));
      System.out.println(" Java Source repainted.");
    }
    g.setFont(sanFont);
    fm = g.getFontMetrics();
    iconWidth = fm.stringWidth("and");
    iconHeight = fm.getAscent();
    d = fm.getDescent();
    if (clipx + clipw > 200 - (iconWidth / 2) && clipx < (200 + (iconWidth / 2))
        && clipy + cliph > (200 + (iconHeight / 4)) - iconHeight
        && clipy < (200 + (iconHeight / 4)) + d) {
      g.drawString("and", 200 - (iconWidth / 2), 200 + (iconHeight / 4));
      System.out.println(" and repainted.");
    }
    g.setFont(serifFont);
    fm = g.getFontMetrics();
    iconWidth = fm.stringWidth("Support.");
    iconHeight = fm.getAscent();
    d = fm.getDescent();
    if (clipx + clipw > 280 - (iconWidth / 2) && clipx < (280 + (iconWidth / 2))
        && clipy + cliph > (280 + (iconHeight / 4)) - iconHeight
        && clipy < (280 + (iconHeight / 4)) + d) {
      g.drawString("Support.", 280 - (iconWidth / 2), 280 + (iconHeight / 4));
      System.out.println(" Support. repainted.");
    }
  }
  public Dimension getPreferredSize() {
    return new Dimension(400, 400);
  }
  public Dimension getMinimumSize() {
    return getPreferredSize();
  }
  public static void main(String args[]) {
    JFrame mainFrame = new JFrame();
    mainFrame.getContentPane().add(new ClipDemo());
    mainFrame.pack();
    mainFrame.setVisible(true);
  }
}



Copy Area Performance

   
 

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
/*
 * CopyAreaPerformance.java
 *
 * Created on May 1, 2007, 4:24 PM
 *
 * Copyright (c) 2007, Sun Microsystems, Inc
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the TimingFramework project nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * 
 * @author Chet
 */
public class CopyAreaPerformance extends JComponent implements KeyListener {
  private static final int SMILEY_SIZE = 10;
  private static final int PADDING = 2;
  private static final int MIN_COLOR = 0;
  private static final int CANVAS_W = SMILEY_SIZE * (256 - MIN_COLOR);
  private static final int CANVAS_H = SMILEY_SIZE * (256 - MIN_COLOR);
  private static final int SCROLL_SIZE = 100;
  private int viewX = CANVAS_W / 2;
  private int viewY = CANVAS_H / 2;
  private boolean useCopyArea = false;
  private boolean useClip = false;
  int prevVX;
  int prevVY;
  /** Creates a new instance of CopyAreaPerformance */
  public CopyAreaPerformance() {
    setOpaque(true);
  }
  private void drawSmiley(Graphics g, Color faceColor, int x, int y) {
    // fill face color
    g.setColor(faceColor);
    g.fillOval(x, y, SMILEY_SIZE, SMILEY_SIZE);
    g.setColor(Color.BLACK);
    // draw head
    g.drawOval(x, y, SMILEY_SIZE, SMILEY_SIZE);
    // draw smile
    g.drawArc(x + (int) ((SMILEY_SIZE * .2)), (int) (y + (SMILEY_SIZE * .2)),
        (int) (SMILEY_SIZE * .6), (int) (SMILEY_SIZE * .6), 200, 140);
    // draw eyes
    int eyeSize = Math.max(2, (int) (SMILEY_SIZE * .1));
    g.fillOval(x + (int) ((SMILEY_SIZE * .5) - (SMILEY_SIZE * .1) - eyeSize), y
        + (int) (SMILEY_SIZE * .3), eyeSize, eyeSize);
    g.fillOval(x + (int) ((SMILEY_SIZE * .5) + (SMILEY_SIZE * .1)), y + (int) (SMILEY_SIZE * .3),
        eyeSize, eyeSize);
  }
  protected void paintComponent(Graphics g) {
    long startTime = System.nanoTime();
    // prevVX is set to -10000 when first enabled
    if (useCopyArea && prevVX > -9999) {
      // Most of this code determines the proper areas to copy and clip
      int scrollX = viewX - prevVX;
      int scrollY = viewY - prevVY;
      int copyFromY, copyFromX;
      int clipFromY, clipFromX;
      if (scrollX == 0) {
        // vertical scroll
        if (scrollY < 0) {
          copyFromY = 0;
          clipFromY = 0;
        } else {
          copyFromY = scrollY;
          clipFromY = getHeight() - scrollY;
        }
        // copy the old content, set the clip to the new area
        g.copyArea(0, copyFromY, getWidth(), getHeight() - Math.abs(scrollY), 0, -scrollY);
        g.setClip(0, clipFromY, getWidth(), Math.abs(scrollY));
      } else {
        // horizontal scroll
        if (scrollX < 0) {
          copyFromX = 0;
          clipFromX = 0;
        } else {
          copyFromX = scrollX;
          clipFromX = getWidth() - scrollX;
        }
        // copy the old content, set the clip to the new area
        g.copyArea(copyFromX, 0, getWidth() - Math.abs(scrollX), getHeight(), -scrollX, 0);
        g.setClip(clipFromX, 0, Math.abs(scrollX), getHeight());
      }
    }
    // Track previous view position for next scrolling operation
    prevVX = viewX;
    prevVY = viewY;
    // Get the clip in case we need it later
    Rectangle clipRect = g.getClip().getBounds();
    int clipL = (int) (clipRect.getX());
    int clipT = (int) (clipRect.getY());
    int clipR = (int) (clipRect.getMaxX());
    int clipB = (int) (clipRect.getMaxY());
    g.setColor(Color.WHITE);
    g.fillRect(clipL, clipT, (int) clipRect.getWidth(), (int) clipRect.getHeight());
    for (int column = 0; column < 256; ++column) {
      int x = column * (SMILEY_SIZE + PADDING) - viewX;
      if (useClip) {
        if (x > clipR || (x + (SMILEY_SIZE + PADDING)) < clipL) {
          // trivial reject; outside to the left or right
          continue;
        }
      }
      for (int row = 0; row < 256; ++row) {
        int y = row * (SMILEY_SIZE + PADDING) - viewY;
        if (useClip) {
          if (y > clipB || (y + (SMILEY_SIZE + PADDING)) < clipT) {
            // trivial reject; outside to the top or bottom
            continue;
          }
        }
        Color faceColor = new Color(column, row, 0);
        drawSmiley(g, faceColor, x, y);
      }
    }
    long stopTime = System.nanoTime();
    System.out.println("Painted in " + ((stopTime - startTime) / 1000000) + " ms");
  }
  private void scroll(int scrollX, int scrollY) {
    viewX += scrollX;
    viewY += scrollY;
    viewX = Math.max(viewX, 0);
    viewX = Math.min(viewX, CANVAS_W - viewX);
    viewY = Math.max(viewY, 0);
    viewY = Math.min(viewY, CANVAS_H - viewY);
    repaint();
  }
  // KeyListener methods
  /**
   * Arrow keys scroll the view around. The "c" key toggles clip area
   * optimization. The "a" key toggles copyArea optimization.
   */
  public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
      scroll(SCROLL_SIZE, 0);
    } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
      scroll(-SCROLL_SIZE, 0);
    } else if (e.getKeyCode() == KeyEvent.VK_UP) {
      scroll(0, -SCROLL_SIZE);
    } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
      scroll(0, SCROLL_SIZE);
    } else if (e.getKeyCode() == KeyEvent.VK_C) {
      useClip = !useClip;
      System.out.println("useClip = " + useClip);
    } else if (e.getKeyCode() == KeyEvent.VK_A) {
      useCopyArea = !useCopyArea;
      prevVX = -10000;
      System.out.println("useCopyArea = " + useCopyArea);
    }
  }
  public void keyReleased(KeyEvent e) {
  }
  public void keyTyped(KeyEvent e) {
  }
  private static void createAndShowGUI() {
    JFrame f = new JFrame("CopyAreaPerformance");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(600, 600);
    CopyAreaPerformance component = new CopyAreaPerformance();
    f.add(component);
    f.addKeyListener(component);
    f.setVisible(true);
  }
  public static void main(String args[]) {
    Runnable doCreateAndShowGUI = new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    };
    SwingUtilities.invokeLater(doCreateAndShowGUI);
  }
}



Represents a clipping rectangle in a prefuse Display

   
//revised from prefuse display;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.logging.Logger;
/**
 * Represents a clipping rectangle in a prefuse <code>Display</code>.
 *
 * @author 
 */
public class Clip {
    
    private static final byte EMPTY   = 0;
    private static final byte INUSE   = 1;
    private static final byte INVALID = 2;
    
    private double[] clip = new double[8];
    private byte status = INVALID;
    
    /**
     * Reset the clip to an empty status.
     */
    public void reset() {
        status = EMPTY;
    }
    
    /**
     * Invalidate the clip. In this state, the clip contents have no meaning.
     */
    public void invalidate() {
        status = INVALID;
    }
       
    /**
     * Set the clip contents, and set the status to valid and in use.
     * @param c the clip whose contents should be copied
     */
    public void setClip(Clip c) {
        status = INUSE;
        System.arraycopy(c.clip, 0, clip, 0, clip.length);
    }
    
    /**
     * Set the clip contents, and set the status to valid and in use.
     * @param r the clip contents to copy
     */
    public void setClip(Rectangle2D r) {
        setClip(r.getX(),r.getY(),r.getWidth(),r.getHeight());
    }
    
    /**
     * Set the clip contents, and set the status to valid and in use.
     * @param x the minimum x-coordinate
     * @param y the minimum y-coorindate
     * @param w the clip width
     * @param h the clip height
     */
    public void setClip(double x, double y, double w, double h) {
        status = INUSE;
        clip[0] = x;
        clip[1] = y;
        clip[6] = x+w;
        clip[7] = y+h;
    }
    
    /**
     * Transform the clip contents. A new clip region will be created
     * which is the bounding box of the transformed region.
     * @param at the affine transform
     */
    public void transform(AffineTransform at) {
        // make the extra corner points valid
        clip[2] = clip[0]; clip[3] = clip[7];
        clip[4] = clip[6]; clip[5] = clip[1];
        
        // transform the points
        at.transform(clip,0,clip,0,4);
        
        // make safe against rotation
        double xmin = clip[0], ymin = clip[1];
        double xmax = clip[6], ymax = clip[7];
        for ( int i=0; i<7; i+=2 ) {
            if ( clip[i] < xmin )
                xmin = clip[i];
            if ( clip[i] > xmax )
                xmax = clip[i];
            if ( clip[i+1] < ymin )
                ymin = clip[i+1];
            if ( clip[i+1] > ymax )
                ymax = clip[i+1];
        }
        clip[0] = xmin; clip[1] = ymin;
        clip[6] = xmax; clip[7] = ymax;
    }
    
    /**
     * Limit the clip such that it fits within the specified region.
     * @param x1 the minimum x-coordinate
     * @param y1 the minimum y-coorindate
     * @param x2 the maximum x-coordinate
     * @param y2 the maximum y-coorindate
     */
    public void limit(double x1, double y1, double x2, double y2) {
        clip[0] = Math.max(clip[0],x1);
        clip[1] = Math.max(clip[1],y1);
        clip[6] = Math.min(clip[6],x2);
        clip[7] = Math.min(clip[7],y2);
    }
    
    /**
     * Indicates if this Clip intersects the given rectangle expanded
     * by the additional margin pace.
     * @param r the rectangle to test for intersect
     * @param margin additional margin "bleed" to include in the intersection
     * @return true if the clip intersects the expanded region, false otherwise
     */
    public boolean intersects(Rectangle2D r, double margin) {
        double tw = clip[6]-clip[0];
        double th = clip[7]-clip[1];
        double rw = r.getWidth();
        double rh = r.getHeight();
        if (rw < 0 || rh < 0 || tw < 0 || th < 0) {
            return false;
        }
        double tx = clip[0];
        double ty = clip[1];
        double rx = r.getX()-margin;
        double ry = r.getY()-margin;
        rw += rx+2*margin;
        rh += ry+2*margin;
        tw += tx;
        th += ty;
        //      overflow || intersect
        return ((rw < rx || rw > tx) &&
                (rh < ry || rh > ty) &&
                (tw < tx || tw > rx) &&
                (th < ty || th > ry));
    }
      
    /**
     * Union this clip with another clip. As a result, this clip
     * will become a bounding box around the two original clips.
     * @param c the clip to union with
     */
    public void union(Clip c) {
        if ( status == INVALID )
            return;
        if ( status == EMPTY ) {
            setClip(c);
            status = INUSE;
            return;
        }
        clip[0] = Math.min(clip[0], c.clip[0]);
        clip[1] = Math.min(clip[1], c.clip[1]);
        clip[6] = Math.max(clip[6], c.clip[6]);
        clip[7] = Math.max(clip[7], c.clip[7]);
    }
    
    /**
     * Union this clip with another region. As a result, this clip
     * will become a bounding box around the two original regions.
     * @param r the rectangle to union with
     */
    public void union(Rectangle2D r) {
        if ( status == INVALID )
            return;
        
        double minx = r.getMinX();
        double miny = r.getMinY();
        double maxx = r.getMaxX();
        double maxy = r.getMaxY();
        
        if ( Double.isNaN(minx) || Double.isNaN(miny) ||
             Double.isNaN(maxx) || Double.isNaN(maxy) ) {
            Logger.getLogger(getClass().getName()).warning(
                "Union with invalid clip region: "+r);
            return;
        }
        
        if ( status == EMPTY ) {
            setClip(r);
            status = INUSE;
            return;
        }
        clip[0] = Math.min(clip[0], minx);
        clip[1] = Math.min(clip[1], miny);
        clip[6] = Math.max(clip[6], maxx);
        clip[7] = Math.max(clip[7], maxy);
    }
    
    /**
     * Union this clip with another region. As a result, this clip
     * will become a bounding box around the two original regions.
     * @param x the x-coordinate of the region to union with
     * @param y the y-coordinate of the region to union with
     * @param w the width of the region to union with
     * @param h the height of the region to union with
     */
    public void union(double x, double y, double w, double h) {
        if ( status == INVALID )
            return;
        if ( status == EMPTY ) {
            setClip(x,y,w,h);
            status = INUSE;
            return;
        }
        clip[0] = Math.min(clip[0], x);
        clip[1] = Math.min(clip[1], y);
        clip[6] = Math.max(clip[6], x+w);
        clip[7] = Math.max(clip[7], y+h);
    }
    
    /**
     * Intersect this clip with another region. As a result, this
     * clip will become the intersecting area of the two regions.
     * @param c the clip to intersect with
     */
    public void intersection(Clip c) {
        if ( status == INVALID )
            return;
        if ( status == EMPTY ) {
            setClip(c);
            status = INUSE;
            return;
        }
        clip[0] = Math.max(clip[0], c.clip[0]);
        clip[1] = Math.max(clip[1], c.clip[1]);
        clip[6] = Math.min(clip[6], c.clip[6]);
        clip[7] = Math.min(clip[7], c.clip[7]);
    }
    
    /**
     * Intersect this clip with another region. As a result, this
     * clip will become the intersecting area of the two regions.
     * @param r the rectangle to intersect with
     */
    public void intersection(Rectangle2D r) {
        if ( status == INVALID )
            return;
        if ( status == EMPTY ) {
            setClip(r);
            status = INUSE;
            return;
        }
        clip[0] = Math.max(clip[0], r.getMinX());
        clip[1] = Math.max(clip[1], r.getMinY());
        clip[6] = Math.min(clip[6], r.getMaxX());
        clip[7] = Math.min(clip[7], r.getMaxY());
    }
    
    /**
     * Intersect this clip with another region. As a result, this
     * clip will become the intersecting area of the two regions.
     * @param x the x-coordinate of the region to intersect with
     * @param y the y-coordinate of the region to intersect with
     * @param w the width of the region to intersect with
     * @param h the height of the region to intersect with
     */
    public void intersection(double x, double y, double w, double h) {
        if ( status == INVALID )
            return;
        if ( status == EMPTY ) {
            setClip(x,y,w,h);
            status = INUSE;
            return;
        }
        clip[0] = Math.max(clip[0], x);
        clip[1] = Math.max(clip[1], y);
        clip[6] = Math.min(clip[6], x+w);
        clip[7] = Math.min(clip[7], y+h);
    }
    
    /**
     * Minimally expand the clip such that each coordinate is an integer.
     */
    public void expandToIntegerLimits() {
        clip[0] = Math.floor(clip[0]);
        clip[1] = Math.floor(clip[1]);
        clip[6] = Math.ceil(clip[6]);
        clip[7] = Math.ceil(clip[7]);
    }
    
    /**
     * Expand the clip in all directions by the given value.
     * @param b the value to expand by
     */
    public void expand(double b) {
        clip[0] -= b; clip[1] -= b;
        clip[6] += b; clip[7] += b;
    }
    /**
     * Grow the clip width and height by the given value. The minimum
     * coordinates will be unchanged.
     * @param b the value to grow the width and height by
     */
    public void grow(double b) {
        clip[6] += b; clip[7] += b;
    }
    
    /**
     * Get the minimum x-coordinate.
     * @return the minimum x-coordinate
     */
    public double getMinX() {
        return clip[0];
    }
    
    /**
     * Get the minimum y-coordinate.
     * @return the minimum y-coordinate
     */
    public double getMinY() {
        return clip[1];
    }
    
    /**
     * Get the maximum x-coordinate.
     * @return the maximum x-coordinate
     */
    public double getMaxX() {
        return clip[6];
    }
    
    /**
     * Get the maximum y-coordinate.
     * @return the maximum y-coordinate
     */
    public double getMaxY() {
        return clip[7];
    }
    
    /**
     * Get the clip"s width
     * @return the clip width
     */
    public double getWidth() {
        return clip[6]-clip[0];
    }
    /**
     * Get the clip"s height
     * @return the clip height
     */
    public double getHeight() {
        return clip[7]-clip[1];
    }
    
    /**
     * Indicates if the clip is set to an empty status.
     * @return true if the clip is set to empty, false otherwise
     */
    public boolean isEmpty() {
        return status==EMPTY;
    }
    
    /**
     * Indicates if the clip is set to an invalid status.
     * @return true if the clip is set to invalid, false otherwise
     */
    public boolean isInvalid() {
        return status==INVALID;
    }
    
    // ------------------------------------------------------------------------
    
    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object o) {
        if ( o instanceof Rectangle2D ) {
            Rectangle2D r = (Rectangle2D)o;
            return ( r.getMinX()==clip[0] && r.getMinY()==clip[1] &&
                     r.getMaxX()==clip[6] && r.getMaxY()==clip[7] );
        } else if ( o instanceof Clip ) {
            Clip r = (Clip)o;
            if ( r.status == status ) {
                if ( status == Clip.INUSE )
                    return ( r.clip[0]==clip[0] && r.clip[1]==clip[1] &&
                            r.clip[6]==clip[6] && r.clip[7]==clip[7] );
                else
                    return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    
    /**
     * @see java.lang.Object#toString()
     */
    public String toString() {
        StringBuffer sb = new StringBuffer(20);
        sb.append("Clip[");
        switch (status) {
        case INVALID:
            sb.append("invalid");
            break;
        case EMPTY:
            sb.append("empty");
            break;
        default:
            sb.append(clip[0]).append(",");
            sb.append(clip[1]).append(",");
            sb.append(clip[6]).append(",");
            sb.append(clip[7]);
        }
        sb.append("]");
        return sb.toString();
    }
    
} // end of class Clip



set Clip and get Clip

   
/*
 * Java2DUtils.java
 * 
 * Created on Aug 30, 2007, 11:40:18 AM
 * 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
//Revised from jaspersoft ireport designer
import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.util.Stack;
/**
 *
 * @author gtoffoli
 */
public class Java2DUtils
{
  private static Stack clipBoundsStack = new Stack();
  private static Stack transforms = new Stack();
  public static void setClip(Graphics g, int x, int y, int width, int height)
  {
    setClip(g, new Rectangle(x, y, width, height));
  }
    @SuppressWarnings("unchecked")
  public static void setClip(Graphics g, Rectangle clipBounds)
  {
    Rectangle currentClipBounds;
    clipBounds = new Rectangle(clipBounds);
    clipBounds.width += 1;
    clipBounds.height += 1;
    currentClipBounds = g.getClipBounds();
    if(currentClipBounds != null)
    {
      clipBounds = clipBounds.intersection(g.getClipBounds());
    }
    clipBoundsStack.push(currentClipBounds);
    g.setClip(clipBounds);
  }
  public static void resetClip(Graphics g)
  {
    g.setClip((Shape) clipBoundsStack.pop());
  }
  
    @SuppressWarnings("unchecked")
    public static void setTransform(Graphics2D g2, AffineTransform transform)
  {
    AffineTransform current;

    current = g2.getTransform();
    transforms.push(current);
    g2.setTransform(transform);
  }

  public static void resetTransform(Graphics2D g2)
  {
    if(transforms.empty())
    {
      return;
    }

    g2.setTransform((AffineTransform) transforms.pop());
  }
  
}



Setting the Clipping Area with a Shape

    
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class BasicDraw {
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.add(new MyComponent());
    frame.setSize(300, 300);
    frame.setVisible(true);
  }
}
class MyComponent extends JComponent {
  public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    Shape shape = new java.awt.geom.Ellipse2D.Float(20, 20, 200,200);
    g2d.setClip(shape);
    int x = 0;
    int y = 0;
    g2d.drawImage(new ImageIcon("a.png").getImage(), x, y, this);
  }
}