/* * SubpixelView.java */ package subpixel; import com.sun.net.ssl.internal.ssl.Debug; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import org.jdesktop.application.SingleFrameApplication; import org.jdesktop.application.FrameView; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.JComponent; /** * The application's main frame. */ public class SubpixelView extends FrameView { public SubpixelView(SingleFrameApplication app) { super(app); initComponents(); /* create / add our component */ SubPixelCanvas d = new SubPixelCanvas(0, 0, 200, 200); mainPanel.add(d); /* get ball image */ try { d.image = ImageIO.read(new URL("http://icons.iconseeker.com/png/48/scrap/aqua-ball.png")); } catch (IOException ex) { /* */ } /* start the threaded repaint */ d.start(); } class SubPixelCanvas extends JComponent implements Runnable { private Point2D.Float ball = new Point2D.Float(0, 0); private double width, height; private BufferedImage image, scene; public Graphics2D g2d; private SubPixelCanvas(int x, int y, int w, int h) { width = w; height = h; /* setup the memory image, which supports sub-pixel (double) precision */ scene = new BufferedImage(w, h, 1); g2d = scene.createGraphics(); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); /* setup the ui component */ this.setLocation(x, y); this.setSize(w, h); } /* overrides the paint method */ @Override public void paint(Graphics g) { /* clear scene buffer */ g2d.clearRect(0, 0, (int)width, (int)height); /* draw ball image to the memory image with transformed x/y double values */ AffineTransform t = new AffineTransform(); t.translate(ball.x, ball.y); // x/y set here t.scale(1, 1); // scale = 1 g2d.drawImage(image, t, null); // draw the scene (double percision image) to the ui component g.drawImage(scene, 0, 0, this); } /* thread run function, all animation is done here */ public void run() { double i = 0; int speed = 5; double maxX = width-image.getWidth(); double maxY = height-image.getHeight(); try { while(true) { while (i < maxX && i0) { ball.setLocation(i, i); mainPanel.repaint(); Thread.sleep(speed); } } } catch (Exception ex) { Debug.println("...", ex.toString()); } } private void start() { Thread t = new Thread(this); t.start(); } } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // private void initComponents() { mainPanel = new javax.swing.JPanel(); mainPanel.setName("mainPanel"); // NOI18N mainPanel.addComponentListener(new java.awt.event.ComponentAdapter() { public void componentShown(java.awt.event.ComponentEvent evt) { mainPanelComponentShown(evt); } }); javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel); mainPanel.setLayout(mainPanelLayout); mainPanelLayout.setHorizontalGroup( mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 400, Short.MAX_VALUE) ); mainPanelLayout.setVerticalGroup( mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 300, Short.MAX_VALUE) ); setComponent(mainPanel); }// private void mainPanelComponentShown(java.awt.event.ComponentEvent evt) { } // Variables declaration - do not modify private javax.swing.JPanel mainPanel; // End of variables declaration }