Draw curve with mouse

Saturday, July 18th, 2009

import java.awt.BasicStroke;
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.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Line2D;
import java.awt.geom.QuadCurve2D;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class CubicCurveMouse extends JFrame {
  DrawingCanvas canvas;

  JLabel label = new JLabel("Mouse Location (x, y):  "); 
  JLabel coords = new JLabel("");

  public CubicCurveMouse() {
    super();
    Container container = getContentPane();

    JPanel panel = new JPanel();
    panel.setLayout(new GridLayout(1, 2));
    
    panel.add(label);
    panel.add(label);

    panel.add(coords);

    container.add(panel, BorderLayout.SOUTH);

    canvas = new DrawingCanvas();
    container.add(canvas);

    addWindowListener(new WindowEventHandler());
        setSize(300,300);
    setVisible(true);
  }

  class WindowEventHandler extends WindowAdapter {
    public void windowClosing(WindowEvent e) {
      System.exit(0);
    }
  }

  public static void main(String arg[]) {
    new CubicCurveMouse();
  }

  class DrawingCanvas extends Canvas {
    float x1, y1, xc1cur, yc1cur, xc1new, yc1new, xc2cur, yc2cur, xc2new,
        yc2new, x4cur, y4cur, x4new, y4new;

    int pressNo = 0;

    int dragFlag1 = -1;

    int dragFlag2 = -1;

    boolean clearFlag = false;

    float dashes[] = { 5f, 5f };

    BasicStroke stroke;

    public DrawingCanvas() {
      setBackground(Color.white);
      addMouseListener(new MyMouseListener());
      addMouseMotionListener(new MyMouseListener());
      setSize(400, 400);
      stroke = new BasicStroke(1f, BasicStroke.CAP_BUTT,
          BasicStroke.JOIN_BEVEL, 10f, dashes, 0f);
    }

    public void update(Graphics g) {
      paint(g);
    }

    public void paint(Graphics g) {
      Graphics2D g2D = (Graphics2D) g;

      if (pressNo == 1) {
        g2D.setXORMode(getBackground());
        g2D.setColor(Color.black);
        g2D.setStroke(stroke);

        // Erase the currently existing line
        g2D.draw(new Line2D.Float(x1, y1, x4cur, y4cur));
        // Draw the new line
        g2D.draw(new Line2D.Float(x1, y1, x4new, y4new));

        // Update the currently existing coordinate values
        x4cur = x4new;
        y4cur = y4new;
      }else if (pressNo == 2) {
        g2D.setXORMode(getBackground());
        g2D.setColor(Color.black);
        g2D.setStroke(stroke);

        if (dragFlag1 != -1) {
          g2D.draw(new QuadCurve2D.Float(x1, y1, xc1cur, yc1cur,
              x4new, y4new));
        }
        dragFlag1++; // Reset the drag-flag

        g2D.draw(new QuadCurve2D.Float(x1, y1, xc1new, yc1new, x4new,
            y4new));

        xc1cur = xc1new;
        yc1cur = yc1new;
      }else if (pressNo == 3) {
        g2D.setXORMode(getBackground());
        g2D.setColor(Color.black);

        if (dragFlag2 != -1) {
          g2D.draw(new CubicCurve2D.Float(x1, y1, xc1new, yc1new,
              xc2cur, yc2cur, x4new, y4new));
        }
        dragFlag2++; // Reset the drag flag
        g2D.draw(new CubicCurve2D.Float(x1, y1, xc1new, yc1new, xc2new,
            yc2new, x4new, y4new));
        xc2cur = xc2new;
        yc2cur = yc2new;
      }
      if (clearFlag) {
        g2D.setXORMode(getBackground());
        g2D.setColor(Color.black);
        g2D.setStroke(stroke);

        g2D.draw(new Line2D.Float(x1, y1, x4new, y4new));
        g2D.draw(new QuadCurve2D.Float(x1, y1, xc1new, yc1new, x4new,
            y4new));
        clearFlag = false;
      }
    }

    class MyMouseListener extends MouseAdapter implements MouseMotionListener {
      public void mousePressed(MouseEvent e) {
        if (pressNo == 0) { 
          pressNo++;
          x1 = x4cur = e.getX();
          y1 = y4cur = e.getY();
        } else if (pressNo == 1) {
          pressNo++;
          xc1cur = e.getX();
          yc1cur = e.getY();
        } else if (pressNo == 2) {
          pressNo++;
          xc2cur = e.getX();
          yc2cur = e.getY();
        }
      }
      public void mouseReleased(MouseEvent e) {
        if (pressNo == 1) {
          x4new = e.getX();
          y4new = e.getY();
          canvas.repaint();
        } else if (pressNo == 2) {
          xc1new = e.getX();
          yc1new = e.getY();
          canvas.repaint();
        } else if (pressNo == 3) {
          xc2new = e.getX();
          yc2new = e.getY();
          canvas.repaint();
          pressNo = 0;
          dragFlag1 = -1;
          dragFlag2 = -1;
          clearFlag = true;
        }
      }
      public void mouseDragged(MouseEvent e) {
        if (pressNo == 1) {
          x4new = e.getX();
          y4new = e.getY();
          String string = "(" + Integer.toString(e.getX()) + ", "
              + Integer.toString(e.getY()) + ")";
          coords.setText(string);
          canvas.repaint();
        } else if (pressNo == 2) {
          xc1new = e.getX();
          yc1new = e.getY();

          String string = "(" + Integer.toString(e.getX()) + ", "
              + Integer.toString(e.getY()) + ")";
          coords.setText(string);
          canvas.repaint();
        } else if (pressNo == 3) {
          xc2new = e.getX();
          yc2new = e.getY();
          String string = "(" + Integer.toString(e.getX()) + ", "
              + Integer.toString(e.getY()) + ")";
          coords.setText(string);
          canvas.repaint();
        }
      }

      public void mouseMoved(MouseEvent e) {
        String string = "(" + Integer.toString(e.getX()) + ", "
            + Integer.toString(e.getY()) + ")";
        coords.setText(string);
      }
    }
  }
}

           
       

Image Processing Test

Thursday, July 16th, 2009

/**
 * @version 1.0 1999-09-12
 * @author Cay Horstmann
 */

import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ByteLookupTable;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.LookupOp;
import java.awt.image.RescaleOp;
import java.io.File;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

public class ImageProcessingTest {
  public static void main(String[] args) {
    JFrame frame = new ImageProcessingFrame();
    frame.show();
  }
}

class ImageProcessingFrame extends JFrame implements ActionListener {
  public ImageProcessingFrame() {
    setTitle("ImageProcessingTest");
    setSize(300, 400);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });

    Container contentPane = getContentPane();
    panel = new ImageProcessingPanel();
    contentPane.add(panel, "Center");

    JMenu fileMenu = new JMenu("File");
    openItem = new JMenuItem("Open");
    openItem.addActionListener(this);
    fileMenu.add(openItem);

    exitItem = new JMenuItem("Exit");
    exitItem.addActionListener(this);
    fileMenu.add(exitItem);

    JMenu editMenu = new JMenu("Edit");
    blurItem = new JMenuItem("Blur");
    blurItem.addActionListener(this);
    editMenu.add(blurItem);

    sharpenItem = new JMenuItem("Sharpen");
    sharpenItem.addActionListener(this);
    editMenu.add(sharpenItem);

    brightenItem = new JMenuItem("Brighten");
    brightenItem.addActionListener(this);
    editMenu.add(brightenItem);

    edgeDetectItem = new JMenuItem("Edge detect");
    edgeDetectItem.addActionListener(this);
    editMenu.add(edgeDetectItem);

    negativeItem = new JMenuItem("Negative");
    negativeItem.addActionListener(this);
    editMenu.add(negativeItem);

    rotateItem = new JMenuItem("Rotate");
    rotateItem.addActionListener(this);
    editMenu.add(rotateItem);

    JMenuBar menuBar = new JMenuBar();
    menuBar.add(fileMenu);
    menuBar.add(editMenu);
    setJMenuBar(menuBar);
  }

  public void actionPerformed(ActionEvent evt) {
    Object source = evt.getSource();
    if (source == openItem) {
      JFileChooser chooser = new JFileChooser();
      chooser.setCurrentDirectory(new File("."));

      chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
        public boolean accept(File f) {
          String name = f.getName().toLowerCase();
          return name.endsWith(".gif") || name.endsWith(".jpg")
              || name.endsWith(".jpeg") || f.isDirectory();
        }

        public String getDescription() {
          return "Image files";
        }
      });

      int r = chooser.showOpenDialog(this);
      if (r == JFileChooser.APPROVE_OPTION) {
        String name = chooser.getSelectedFile().getAbsolutePath();
        panel.loadImage(name);
      }
    } else if (source == exitItem)
      System.exit(0);
    else if (source == blurItem)
      panel.blur();
    else if (source == sharpenItem)
      panel.sharpen();
    else if (source == brightenItem)
      panel.brighten();
    else if (source == edgeDetectItem)
      panel.edgeDetect();
    else if (source == negativeItem)
      panel.negative();
    else if (source == rotateItem)
      panel.rotate();
  }

  private ImageProcessingPanel panel;

  private JMenuItem openItem;

  private JMenuItem exitItem;

  private JMenuItem blurItem;

  private JMenuItem sharpenItem;

  private JMenuItem brightenItem;

  private JMenuItem edgeDetectItem;

  private JMenuItem negativeItem;

  private JMenuItem rotateItem;
}

class ImageProcessingPanel extends JPanel {
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (image != null)
      g.drawImage(image, 0, 0, null);
  }

  public void loadImage(String name) {
    Image loadedImage = Toolkit.getDefaultToolkit().getImage(name);
    MediaTracker tracker = new MediaTracker(this);
    tracker.addImage(loadedImage, 0);
    try {
      tracker.waitForID(0);
    } catch (InterruptedException e) {
    }
    image = new BufferedImage(loadedImage.getWidth(null), loadedImage
        .getHeight(null), BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = image.createGraphics();
    g2.drawImage(loadedImage, 0, 0, null);

    repaint();
  }

  private void filter(BufferedImageOp op) {
    BufferedImage filteredImage = new BufferedImage(image.getWidth(), image
        .getHeight(), image.getType());
    op.filter(image, filteredImage);
    image = filteredImage;
    repaint();
  }

  private void convolve(float[] elements) {
    Kernel kernel = new Kernel(3, 3, elements);
    ConvolveOp op = new ConvolveOp(kernel);
    filter(op);
  }

  public void blur() {
    float weight = 1.0f / 9.0f;
    float[] elements = new float[9];
    for (int i = 0; i < 9; i++)
      elements[i] = weight;
    convolve(elements);
  }

  public void sharpen() {
    float[] elements = { 0.0f, -1.0f, 0.0f, -1.0f, 5.f, -1.0f, 0.0f, -1.0f,
        0.0f };
    convolve(elements);
  }

  void edgeDetect() {
    float[] elements = { 0.0f, -1.0f, 0.0f, -1.0f, 4.f, -1.0f, 0.0f, -1.0f,
        0.0f };
    convolve(elements);
  }

  public void brighten() {
    float a = 1.5f;
    float b = -20.0f;
    RescaleOp op = new RescaleOp(a, b, null);
    filter(op);
  }

  void negative() {
    byte negative[] = new byte[256];
    for (int i = 0; i < 256; i++)
      negative[i] = (byte) (255 - i);
    ByteLookupTable table = new ByteLookupTable(0, negative);
    LookupOp op = new LookupOp(table, null);
    filter(op);
  }

  void rotate() {
    AffineTransform transform = AffineTransform.getRotateInstance(Math
        .toRadians(5), image.getWidth() / 2, image.getHeight() / 2);
    AffineTransformOp op = new AffineTransformOp(transform,
        AffineTransformOp.TYPE_BILINEAR);
    filter(op);
  }

  private BufferedImage image;
}

           
       

Xsplinefun displays colorful moving splines in a window

Tuesday, June 30th, 2009

/**
 * Xsplinefun displays colorful moving splines in a window.
 * 
 * Taken from xsplinefun, Distribution of 02may92, by Jef Poskanzer,
 * jef@netcom.com, jef@well.sf.ca.us
 * 
 * @copyright (C) 1992 by Jef Poskanzer
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation. This software is provided "as is" without express or implied
 * warranty.
 * 
 * First step in converting to Java was to junk all the X Windows stuff; in the
 * process we lost all the customization (need to re-add with getopt?).
 */
public class XSplineFun {
  public static final int POINTS = 20;
  public static final int DEFAULT_MAX_COLORS = 20;

  /* Spline-fun smarts. */

  static int x[] = new int [POINTS]; 
    static int y[]= new int [POINTS];
         static int  dx[] = new int [POINTS];
                static int dy[]= new int [POINTS];
  static int nred, ngreen, nblue, dred, dgreen, dblue;
  static int color;
  static Color xcolors[] = new Color[DEFAULT_MAX_COLORS];

  public static void main(String[] av) {
    Frame f = new Frame("Spline Fun");
    XSplineFun xf = new XSplineFun();
    xf.init_splines();
    f.add(xf);
    while(true)
      try {
        xf.move_splines();
        Thread.sleep(150);    // msec
      } catch (Exception e) {
        System.out.println(e);
      }
  }

  static void
  init_splines()
  {
    int i;

    /* Initialize points. */
    for ( i = 0; i < POINTS; ++i )
    {
    x[i] = random() % width;
    y[i] = random() % height;
    dx[i] = random() % ( MAX_DELTA * 2 ) - MAX_DELTA;
    if ( dx[i] <= 0 ) –dx[i];
    dy[i] = random() % ( MAX_DELTA * 2 ) - MAX_DELTA;
    if ( dy[i] <= 0 ) –dy[i];
    }

    /* Initalize colors. */
    for ( color = 0; color < ncolors; ++color )
    {
    xcolors[color].red = xcolors[color].green = xcolors[color].blue = 0;
    xcolors[color].pixel = pixels[color];
    xcolors[color].flags = DoRed|DoGreen|DoBlue;
    }
    color = 0;
    nred = ngreen = nblue = 0;
    dred = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
    if ( dred <= 0 ) –dred;
    dgreen = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
    if ( dgreen <= 0 ) –dgreen;
    dblue = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
    if ( dblue <= 0 ) –dblue;
  }

  static void
  rotate_colormap()
  {
    int t, i;

    if ( forwards )
    {
    t = xcolors[0].pixel;
    for ( i = 0; i < ncolors - 1; ++i )
      xcolors[i].pixel = xcolors[i + 1].pixel;
    xcolors[ncolors - 1].pixel = t;
    XStoreColors(display, cmap, xcolors, ncolors );
    }
    else if ( backwards )
    {
    t = xcolors[ncolors - 1].pixel;
    for ( i = ncolors - 1; i > 0; –i )
      xcolors[i].pixel = xcolors[i - 1].pixel;
    xcolors[0].pixel = t;
    XStoreColors(display, cmap, xcolors, ncolors );
    }
  }

  static void
  new_color()
  {
    int t;

    for ( ; ; )
    {
    t = (int) nred + dred;
    if ( t >= 0 && t < 65536 ) break;
    dred = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
    if ( dred <= 0 ) –dred;
    }
    xcolors[color].red = nred = t;
    for ( ; ; )
    {
    t = (int) ngreen + dgreen;
    if ( t >= 0 && t < 65536 ) break;
    dgreen = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
    if ( dgreen <= 0 ) –dgreen;
    }
    xcolors[color].green = ngreen = t;
    for ( ; ; )
    {
    t = (int) nblue + dblue;
    if ( t >= 0 && t < 65536 ) break;
    dblue = random() % ( MAX_COLOR_DELTA * 2 ) - MAX_COLOR_DELTA;
    if ( dblue <= 0 ) –dblue;
    }
    xcolors[color].blue = nblue = t;
    XStoreColor(display, cmap, &(xcolors[color]) );
    XSetForeground( display, gc, xcolors[color].pixel );
    if ( ++color >= ncolors ) color -= ncolors;
  }

  static void
  move_splines()
  {
    int i, t, px, py, zx, zy, nx, ny;

    /* Rotate colormap if necessary. */
    rotate_colormap();

    /* Choose new color. */
    new_color();

    /* Backwards rotation requires two new colors each loop. */
    if ( backwards )
    new_color();

    /* Move the points. */
    for ( i = 0; i < POINTS; i++ )
    {
    for ( ; ; )
      {
      t = x[i] + dx[i];
      if ( t >= 0 && t < width ) break;
      dx[i] = random() % ( MAX_DELTA * 2 ) - MAX_DELTA;
      if ( dx[i] <= 0 ) –dx[i];
      }
    x[i] = t;
    for ( ; ; )
      {
      t = y[i] + dy[i];
      if ( t >= 0 && t < height ) break;
      dy[i] = random() % ( MAX_DELTA * 2 ) - MAX_DELTA;
      if ( dy[i] <= 0 ) –dy[i];
      }
    y[i] = t;
    }

    /* Draw the figure. */
    px = zx = ( x[0] + x[POINTS-1] ) / 2;
    py = zy = ( y[0] + y[POINTS-1] ) / 2;
    for ( i = 0; i < POINTS-1; ++i )
    {
    nx = ( x[i+1] + x[i] ) / 2;
    ny = ( y[i+1] + y[i] ) / 2;
    XDrawSpline(g, px, py, x[i], y[i], nx, ny );
    px = nx;
    py = ny;
    }
    XDrawSpline(g, px, py, x[POINTS-1], y[POINTS-1], zx, zy );
  }

  /* X spline routine. */

  int abs(x) {
    return x < 0 ? -x : x;
  }

  static void
  XDrawSpline(Graphics g, int x0, y0, x1, y1, x2, y2) {
    register int xa, ya, xb, yb, xc, yc, xp, yp;

    xa = ( x0 + x1 ) / 2;
    ya = ( y0 + y1 ) / 2;
    xc = ( x1 + x2 ) / 2;
    yc = ( y1 + y2 ) / 2;
    xb = ( xa + xc ) / 2;
    yb = ( ya + yc ) / 2;

    xp = ( x0 + xb ) / 2;
    yp = ( y0 + yb ) / 2;
    if ( abs( xa - xp ) + abs( ya - yp ) > SPLINE_THRESH )
    XDrawSpline( display, d, gc, x0, y0, xa, ya, xb, yb );
    else
    XDrawLine( display, d, gc, x0, y0, xb, yb );

    xp = ( x2 + xb ) / 2;
    yp = ( y2 + yb ) / 2;
    if ( abs( xc - xp ) + abs( yc - yp ) > SPLINE_THRESH )
    XDrawSpline( display, d, gc, xb, yb, xc, yc, x2, y2 );
    else
    XDrawLine( display, d, gc, xb, yb, x2, y2 );
  }
}

           
       

Bad vs. Good Primitive Rendering

Saturday, June 27th, 2009

 
 

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
/*
 * OptimalPrimitives.java
 *
 * Created on May 2, 2007, 11:06 AM
 *
 * 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 OptimalPrimitives extends JComponent {
    
    private static final int LINE_X = 100;
    private static final int RECT_X = 200;
    private static final int TEXT_X = 250;
    private static final int BAD_Y = 60;
    private static final int GOOD_Y = 160;
    private static final int ITERATIONS = 1000;
    
    /** Creates a new instance of OptimalPrimitives */
    public OptimalPrimitives() {
    }
    
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g;
        long startTime, endTime, totalTime;
        
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.BLACK);
        
        g.drawString("Bad vs. Good Primitive Rendering", 50, 20);
        g.drawString("(" + ITERATIONS + " iterations)", 100, 35);
        g.drawString("Bad: ", 10, BAD_Y + 30);
        g.drawString("Good: ", 10, GOOD_Y + 30);
        
        // Bad line
        Shape line = new Line2D.Double(LINE_X, BAD_Y, LINE_X + 50, 
                BAD_Y + 50);
        startTime = System.nanoTime();
        for (int i = 0; i < ITERATIONS; ++i) {
            g2d.draw(line);
        }
        endTime = System.nanoTime();
        totalTime = (endTime - startTime) / 1000000;
        System.out.println("bad line = " + totalTime);
        g.drawString(totalTime + " ms", LINE_X, BAD_Y + 70);
        
        // Good line
        startTime = System.nanoTime();
        for (int i = 0; i < ITERATIONS; ++i) {
            g.drawLine(LINE_X, GOOD_Y, LINE_X + 50, GOOD_Y + 50);
        }
        endTime = System.nanoTime();
        totalTime = (endTime - startTime) / 1000000;
        System.out.println("good line = " + totalTime);
        g.drawString(totalTime + " ms", LINE_X, GOOD_Y + 70);
        
        
        // Bad rect
        Shape rect = new Rectangle(RECT_X, BAD_Y, 50, 50);
        startTime = System.nanoTime();
        for (int i = 0; i < ITERATIONS; ++i) {
            g2d.fill(rect);
        }
        endTime = System.nanoTime();
        totalTime = (endTime - startTime) / 1000000;
        System.out.println("bad rect = " + totalTime);
        g.drawString(totalTime + " ms", RECT_X, BAD_Y + 70);
        
        // Good rect
        startTime = System.nanoTime();
        for (int i = 0; i < ITERATIONS; ++i) {
            g.fillRect(RECT_X, GOOD_Y, 50, 50);
        }
        endTime = System.nanoTime();
        totalTime = (endTime - startTime) / 1000000;
        System.out.println("good rect = " + totalTime);
        g.drawString(totalTime + " ms", RECT_X, GOOD_Y + 70);
    }
    
    private static void createAndShowGUI() {    
        JFrame f = new JFrame("OptimalPrimitives");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(320, 300);
        f.add(new OptimalPrimitives());
        f.setVisible(true);
    }
    
    public static void main(String args[]) {
        Runnable doCreateAndShowGUI = new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        };
        SwingUtilities.invokeLater(doCreateAndShowGUI);
    }
}

 

 

Book

Wednesday, June 24th, 2009

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

import javax.swing.JComponent;

public class Booker {
  public static void main(String[] args) {
    PrinterJob pj = PrinterJob.getPrinterJob();
    // Create two Printables.
    Component c1 = new PatchworkComponent("Printable 1");
    Component c2 = new PatchworkComponent("Printable 2");
    c1.setSize(500, 400);
    c2.setSize(500, 400);
    BookComponentPrintable printable1 = new BookComponentPrintable(c1);
    BookComponentPrintable printable2 = new BookComponentPrintable(c2);
    // Create two PageFormats.
    PageFormat pageFormat1 = pj.defaultPage();
    PageFormat pageFormat2 = (PageFormat) pageFormat1.clone();
    pageFormat2.setOrientation(PageFormat.LANDSCAPE);
    // Create a Book.
    Book book = new Book();
    book.append(printable1, pageFormat1);
    book.append(printable2, pageFormat2);
    // Print the Book.
    pj.setPageable(book);
    if (pj.printDialog()) {
      try {
        pj.print();
      } catch (PrinterException e) {
        System.out.println(e);
      }
    }
  }
}
class PatchworkComponent extends JComponent implements Printable {

  private float mSide = 36;

  private float mOffset = 36;

  private int mColumns = 8;

  private int mRows = 4;

  private String mString = "Java Source and Support";

  private Font mFont = new Font("Serif", Font.PLAIN, 64);

  private Paint mHorizontalGradient, mVerticalGradient;

  public PatchworkComponent() {
    float x = mOffset;
    float y = mOffset;
    float halfSide = mSide / 2;
    float x0 = x + halfSide;
    float y0 = y;
    float x1 = x + halfSide;
    float y1 = y + (mRows * mSide);
    mVerticalGradient = new GradientPaint(x0, y0, Color.darkGray, x1, y1,
        Color.lightGray, true);
    x0 = x;
    y0 = y + halfSide;
    x1 = x + (mColumns * mSide);
    y1 = y + halfSide;
    mHorizontalGradient = new GradientPaint(x0, y0, Color.darkGray, x1, y1,
        Color.lightGray, true);
  }

  public PatchworkComponent(String s) {
    this();
    mString = s;
  }

  public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;

    g2.rotate(Math.PI / 24, mOffset, mOffset);

    for (int row = 0; row < mRows; row++) {
      for (int column = 0; column < mColumns; column++) {
        float x = column * mSide + mOffset;
        float y = row * mSide + mOffset;

        if (((column + row) % 2) == 0)
          g2.setPaint(mVerticalGradient);
        else
          g2.setPaint(mHorizontalGradient);

        Rectangle2D r = new Rectangle2D.Float(x, y, mSide, mSide);
        g2.fill(r);
      }
    }

    FontRenderContext frc = g2.getFontRenderContext();
    float width = (float) mFont.getStringBounds(mString, frc).getWidth();
    LineMetrics lm = mFont.getLineMetrics(mString, frc);
    float x = ((mColumns * mSide) - width) / 2 + mOffset;
    float y = ((mRows * mSide) + lm.getAscent()) / 2 + mOffset;
    g2.setFont(mFont);
    g2.setPaint(Color.white);
    g2.drawString(mString, x, y);
  }

  public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
    if (pageIndex != 0)
      return NO_SUCH_PAGE;
    paintComponent(g);
    return PAGE_EXISTS;
  }
}

class BookComponentPrintable implements Printable {
  private Component mComponent;

  public BookComponentPrintable(Component c) {
    mComponent = c;
  }

  public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
    Graphics2D g2 = (Graphics2D) g;
    g2.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
    mComponent.paint(g2);
    return PAGE_EXISTS;
  }
}