diff --git a/draw9patch/src/main/java/com/android/draw9patch/ui/CorruptPatch.java b/draw9patch/src/main/java/com/android/draw9patch/ui/CorruptPatch.java
new file mode 100644
index 0000000..4f0763a
--- /dev/null
+++ b/draw9patch/src/main/java/com/android/draw9patch/ui/CorruptPatch.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.ui;
+
+import com.android.draw9patch.graphics.GraphicsUtilities;
+
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class CorruptPatch {
+    public static List<Rectangle> findBadPatches(BufferedImage image, PatchInfo patchInfo) {
+        List<Rectangle> corruptedPatches = new ArrayList<Rectangle>();
+
+        for (Rectangle patch : patchInfo.patches) {
+            if (corruptPatch(image, patch)) {
+                corruptedPatches.add(patch);
+            }
+        }
+
+        for (Rectangle patch : patchInfo.horizontalPatches) {
+            if (corruptHorizontalPatch(image, patch)) {
+                corruptedPatches.add(patch);
+            }
+        }
+
+        for (Rectangle patch : patchInfo.verticalPatches) {
+            if (corruptVerticalPatch(image, patch)) {
+                corruptedPatches.add(patch);
+            }
+        }
+
+        return corruptedPatches;
+    }
+
+    private static boolean corruptPatch(BufferedImage image, Rectangle patch) {
+        int[] pixels = GraphicsUtilities.getPixels(image, patch.x, patch.y,
+                patch.width, patch.height, null);
+
+        if (pixels.length > 0) {
+            int reference = pixels[0];
+            for (int pixel : pixels) {
+                if (pixel != reference) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private static boolean corruptHorizontalPatch(BufferedImage image, Rectangle patch) {
+        int[] reference = new int[patch.height];
+        int[] column = new int[patch.height];
+        reference = GraphicsUtilities.getPixels(image, patch.x, patch.y,
+                1, patch.height, reference);
+
+        for (int i = 1; i < patch.width; i++) {
+            column = GraphicsUtilities.getPixels(image, patch.x + i, patch.y,
+                    1, patch.height, column);
+            if (!Arrays.equals(reference, column)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private static boolean corruptVerticalPatch(BufferedImage image, Rectangle patch) {
+        int[] reference = new int[patch.width];
+        int[] row = new int[patch.width];
+        reference = GraphicsUtilities.getPixels(image, patch.x, patch.y,
+                patch.width, 1, reference);
+
+        for (int i = 1; i < patch.height; i++) {
+            row = GraphicsUtilities.getPixels(image, patch.x, patch.y + i, patch.width, 1, row);
+            if (!Arrays.equals(reference, row)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/draw9patch/src/main/java/com/android/draw9patch/ui/ImageEditorPanel.java b/draw9patch/src/main/java/com/android/draw9patch/ui/ImageEditorPanel.java
index 845ee54..c707c38 100644
--- a/draw9patch/src/main/java/com/android/draw9patch/ui/ImageEditorPanel.java
+++ b/draw9patch/src/main/java/com/android/draw9patch/ui/ImageEditorPanel.java
@@ -18,66 +18,36 @@
 
 import com.android.draw9patch.graphics.GraphicsUtilities;
 
-import javax.swing.JPanel;
-import javax.swing.JLabel;
-import javax.swing.BorderFactory;
-import javax.swing.JSlider;
-import javax.swing.JComponent;
-import javax.swing.JScrollPane;
-import javax.swing.JCheckBox;
-import javax.swing.Box;
-import javax.swing.JFileChooser;
-import javax.swing.JSplitPane;
-import javax.swing.JButton;
-import javax.swing.border.EmptyBorder;
-import javax.swing.event.AncestorEvent;
-import javax.swing.event.AncestorListener;
-import javax.swing.event.ChangeListener;
-import javax.swing.event.ChangeEvent;
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-import java.awt.Graphics2D;
 import java.awt.BorderLayout;
 import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Dimension;
-import java.awt.TexturePaint;
-import java.awt.Shape;
-import java.awt.BasicStroke;
-import java.awt.RenderingHints;
-import java.awt.Rectangle;
-import java.awt.GridBagLayout;
+import java.awt.Graphics2D;
 import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
 import java.awt.Insets;
-import java.awt.Toolkit;
-import java.awt.AWTEvent;
-import java.awt.event.MouseMotionAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.ActionListener;
+import java.awt.TexturePaint;
 import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.AWTEventListener;
+import java.awt.event.ActionListener;
 import java.awt.geom.Rectangle2D;
-import java.awt.geom.Line2D;
-import java.awt.geom.Area;
-import java.awt.geom.RoundRectangle2D;
-import java.io.IOException;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
 import java.io.File;
+import java.io.IOException;
 import java.net.URL;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
+
+import javax.swing.Box;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSlider;
+import javax.swing.JSplitPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 
 class ImageEditorPanel extends JPanel {
     private static final String EXTENSION_9PATCH = ".9.png";
-    private static final int DEFAULT_ZOOM = 8;
-    private static final float DEFAULT_SCALE = 2.0f;
-
-    // For stretch regions and padding
-    private static final int BLACK_TICK = 0xFF000000;
-    // For Layout Bounds
-    private static final int RED_TICK = 0xFFFF0000;
 
     private String name;
     private BufferedImage image;
@@ -90,30 +60,20 @@
 
     private TexturePaint texture;
 
-    private List<Rectangle> patches;
-    private List<Rectangle> horizontalPatches;
-    private List<Rectangle> verticalPatches;
-    private List<Rectangle> fixed;
-    private boolean verticalStartWithPatch;
-    private boolean horizontalStartWithPatch;
-
-    private Pair<Integer> horizontalPadding;
-    private Pair<Integer> verticalPadding;
-
     ImageEditorPanel(MainFrame mainFrame, BufferedImage image, String name) {
         this.image = image;
         this.name = name;
 
         setTransferHandler(new ImageTransferHandler(mainFrame));
 
-        checkImage();
-
         setOpaque(false);
         setLayout(new BorderLayout());
 
         loadSupport();
         buildImageViewer();
         buildStatusPanel();
+
+        checkImage();
     }
 
     private void loadSupport() {
@@ -128,7 +88,13 @@
     }
 
     private void buildImageViewer() {
-        viewer = new ImageViewer();
+        viewer = new ImageViewer(this, texture, image, new ImageViewer.StatusBar() {
+            @Override
+            public void setPointerLocation(int x, int y) {
+                xLabel.setText(x + " px");
+                yLabel.setText(y + " px");
+            }
+        });
 
         JSplitPane splitter = new JSplitPane();
         splitter.setContinuousLayout(true);
@@ -148,7 +114,7 @@
     }
 
     private JComponent buildStretchesViewer() {
-        stretchesViewer = new StretchesViewer();
+        stretchesViewer = new StretchesViewer(this, viewer, texture);
         JScrollPane scroller = new JScrollPane(stretchesViewer);
         scroller.setBorder(null);
         scroller.getViewport().setBorder(null);
@@ -177,7 +143,8 @@
                 GridBagConstraints.LINE_END, GridBagConstraints.NONE,
                 new Insets(0, 0, 0, 0), 0, 0));
 
-        JSlider zoomSlider = new JSlider(1, 16, DEFAULT_ZOOM);
+        JSlider zoomSlider = new JSlider(ImageViewer.MIN_ZOOM, ImageViewer.MAX_ZOOM,
+                ImageViewer.DEFAULT_ZOOM);
         zoomSlider.setSnapToTicks(true);
         zoomSlider.putClientProperty("JComponent.sizeVariant", "small");
         zoomSlider.addChangeListener(new ChangeListener() {
@@ -213,7 +180,7 @@
                 GridBagConstraints.LINE_END, GridBagConstraints.NONE,
                 new Insets(0, 0, 0, 0), 0, 0));
 
-        zoomSlider = new JSlider(200, 600, (int) (DEFAULT_SCALE * 100.0f));
+        zoomSlider = new JSlider(200, 600, (int) (StretchesViewer.DEFAULT_SCALE * 100.0f));
         zoomSlider.setSnapToTicks(true);
         zoomSlider.putClientProperty("JComponent.sizeVariant", "small");
         zoomSlider.addChangeListener(new ChangeListener() {
@@ -322,21 +289,21 @@
         int height = image.getHeight();
         for (int i = 0; i < width; i++) {
             int pixel = image.getRGB(i, 0);
-            if (pixel != 0 && pixel != BLACK_TICK && pixel != RED_TICK) {
+            if (pixel != 0 && pixel != PatchInfo.BLACK_TICK && pixel != PatchInfo.RED_TICK) {
                 image.setRGB(i, 0, 0);
             }
             pixel = image.getRGB(i, height - 1);
-            if (pixel != 0 && pixel != BLACK_TICK && pixel != RED_TICK) {
+            if (pixel != 0 && pixel != PatchInfo.BLACK_TICK && pixel != PatchInfo.RED_TICK) {
                 image.setRGB(i, height - 1, 0);
             }
         }
         for (int i = 0; i < height; i++) {
             int pixel = image.getRGB(0, i);
-            if (pixel != 0 && pixel != BLACK_TICK && pixel != RED_TICK) {
+            if (pixel != 0 && pixel != PatchInfo.BLACK_TICK && pixel != PatchInfo.RED_TICK) {
                 image.setRGB(0, i, 0);
             }
             pixel = image.getRGB(width - 1, i);
-            if (pixel != 0 && pixel != BLACK_TICK && pixel != RED_TICK) {
+            if (pixel != 0 && pixel != PatchInfo.BLACK_TICK && pixel != PatchInfo.RED_TICK) {
                 image.setRGB(width - 1, i, 0);
             }
         }
@@ -351,6 +318,7 @@
         g2.dispose();
 
         image = buffer;
+        viewer.setImage(image);
         name = name.substring(0, name.lastIndexOf('.')) + ".9.png";
     }
 
@@ -385,944 +353,4 @@
     RenderedImage getImage() {
         return image;
     }
-
-    private class StretchesViewer extends JPanel {
-        private static final int MARGIN = 24;
-
-        private StretchView horizontal;
-        private StretchView vertical;
-        private StretchView both;
-
-        private Dimension size;
-
-        private float horizontalPatchesSum;
-        private float verticalPatchesSum;
-
-        private boolean showPadding;
-
-        StretchesViewer() {
-            setOpaque(false);
-            setLayout(new GridBagLayout());
-            setBorder(BorderFactory.createEmptyBorder(MARGIN, MARGIN, MARGIN, MARGIN));
-
-            horizontal = new StretchView();
-            vertical = new StretchView();
-            both = new StretchView();
-
-            setScale(DEFAULT_SCALE);
-
-            add(vertical, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
-                    GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
-            add(horizontal, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
-                    GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
-            add(both, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
-                    GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
-        }
-
-        @Override
-        protected void paintComponent(Graphics g) {
-            Graphics2D g2 = (Graphics2D) g.create();
-            g2.setPaint(texture);
-            g2.fillRect(0, 0, getWidth(), getHeight());
-            g2.dispose();
-        }
-
-        void setScale(float scale) {
-            int patchWidth = image.getWidth() - 2;
-            int patchHeight = image.getHeight() - 2;
-
-            int scaledWidth = (int) (patchWidth * scale);
-            int scaledHeight = (int) (patchHeight * scale);
-
-            horizontal.scaledWidth = scaledWidth;
-            vertical.scaledHeight = scaledHeight;
-            both.scaledWidth = scaledWidth;
-            both.scaledHeight = scaledHeight;
-
-            size = new Dimension(scaledWidth, scaledHeight);
-
-            computePatches();
-        }
-
-        void computePatches() {
-            boolean measuredWidth = false;
-            boolean endRow = true;
-
-            int remainderHorizontal = 0;
-            int remainderVertical = 0;
-
-            if (fixed.size() > 0) {
-                int start = fixed.get(0).y;
-                for (Rectangle rect : fixed) {
-                    if (rect.y > start) {
-                        endRow = true;
-                        measuredWidth = true;
-                    }
-                    if (!measuredWidth) {
-                        remainderHorizontal += rect.width;
-                    }
-                    if (endRow) {
-                        remainderVertical += rect.height;
-                        endRow = false;
-                        start = rect.y;
-                    }
-                }
-            }
-
-            horizontal.remainderHorizontal = horizontal.scaledWidth - remainderHorizontal;
-            vertical.remainderHorizontal = vertical.scaledWidth - remainderHorizontal;
-            both.remainderHorizontal = both.scaledWidth - remainderHorizontal;
-
-            horizontal.remainderVertical = horizontal.scaledHeight - remainderVertical;
-            vertical.remainderVertical = vertical.scaledHeight - remainderVertical;
-            both.remainderVertical = both.scaledHeight - remainderVertical;
-
-            horizontalPatchesSum = 0;
-            if (horizontalPatches.size() > 0) {
-                int start = -1;
-                for (Rectangle rect : horizontalPatches) {
-                    if (rect.x > start) {
-                        horizontalPatchesSum += rect.width;
-                        start = rect.x;
-                    }
-                }
-            } else {
-                int start = -1;
-                for (Rectangle rect : patches) {
-                    if (rect.x > start) {
-                        horizontalPatchesSum += rect.width;
-                        start = rect.x;
-                    }
-                }
-            }
-
-            verticalPatchesSum = 0;
-            if (verticalPatches.size() > 0) {
-                int start = -1;
-                for (Rectangle rect : verticalPatches) {
-                    if (rect.y > start) {
-                        verticalPatchesSum += rect.height;
-                        start = rect.y;
-                    }
-                }
-            } else {
-                int start = -1;
-                for (Rectangle rect : patches) {
-                    if (rect.y > start) {
-                        verticalPatchesSum += rect.height;
-                        start = rect.y;
-                    }
-                }
-            }
-
-            setSize(size);
-            ImageEditorPanel.this.validate();
-            repaint();
-        }
-
-        void setPaddingVisible(boolean visible) {
-            showPadding = visible;
-            repaint();
-        }
-
-        private class StretchView extends JComponent {
-            private final Color PADDING_COLOR = new Color(0.37f, 0.37f, 1.0f, 0.5f);
-
-            int scaledWidth;
-            int scaledHeight;
-
-            int remainderHorizontal;
-            int remainderVertical;
-
-            StretchView() {
-                scaledWidth = image.getWidth();
-                scaledHeight = image.getHeight();
-            }
-
-            @Override
-            protected void paintComponent(Graphics g) {
-                int x = (getWidth() - scaledWidth) / 2;
-                int y = (getHeight() - scaledHeight) / 2;
-
-                Graphics2D g2 = (Graphics2D) g.create();
-                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-                g.translate(x, y);
-
-                x = 0;
-                y = 0;
-
-                if (patches.size() == 0) {
-                    g.drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
-                    g2.dispose();
-                    return;
-                }
-
-                int fixedIndex = 0;
-                int horizontalIndex = 0;
-                int verticalIndex = 0;
-                int patchIndex = 0;
-
-                boolean hStretch;
-                boolean vStretch;
-
-                float vWeightSum = 1.0f;
-                float vRemainder = remainderVertical;
-
-                vStretch = verticalStartWithPatch;
-                while (y < scaledHeight - 1) {
-                    hStretch = horizontalStartWithPatch;
-
-                    int height = 0;
-                    float vExtra = 0.0f;
-
-                    float hWeightSum = 1.0f;
-                    float hRemainder = remainderHorizontal;
-
-                    while (x < scaledWidth - 1) {
-                        Rectangle r;
-                        if (!vStretch) {
-                            if (hStretch) {
-                                r = horizontalPatches.get(horizontalIndex++);
-                                float extra = r.width / horizontalPatchesSum;
-                                int width = (int) (extra * hRemainder / hWeightSum);
-                                hWeightSum -= extra;
-                                hRemainder -= width;
-                                g.drawImage(image, x, y, x + width, y + r.height, r.x, r.y,
-                                        r.x + r.width, r.y + r.height, null);
-                                x += width;
-                            } else {
-                                r = fixed.get(fixedIndex++);
-                                g.drawImage(image, x, y, x + r.width, y + r.height, r.x, r.y,
-                                        r.x + r.width, r.y + r.height, null);
-                                x += r.width;
-                            }
-                            height = r.height;
-                        } else {
-                            if (hStretch) {
-                                r = patches.get(patchIndex++);
-                                vExtra = r.height / verticalPatchesSum;
-                                height = (int) (vExtra * vRemainder / vWeightSum);
-                                float extra = r.width / horizontalPatchesSum;
-                                int width = (int) (extra * hRemainder / hWeightSum);
-                                hWeightSum -= extra;
-                                hRemainder -= width;
-                                g.drawImage(image, x, y, x + width, y + height, r.x, r.y,
-                                        r.x + r.width, r.y + r.height, null);
-                                x += width;
-                            } else {
-                                r = verticalPatches.get(verticalIndex++);
-                                vExtra = r.height / verticalPatchesSum;
-                                height = (int) (vExtra * vRemainder / vWeightSum);
-                                g.drawImage(image, x, y, x + r.width, y + height, r.x, r.y,
-                                        r.x + r.width, r.y + r.height, null);
-                                x += r.width;
-                            }
-                            
-                        }
-                        hStretch = !hStretch;
-                    }
-                    x = 0;
-                    y += height;
-                    if (vStretch) {
-                        vWeightSum -= vExtra;
-                        vRemainder -= height;
-                    }
-                    vStretch = !vStretch;
-                }
-
-                if (showPadding) {
-                    g.setColor(PADDING_COLOR);
-                    g.fillRect(horizontalPadding.first, verticalPadding.first,
-                            scaledWidth - horizontalPadding.first - horizontalPadding.second,
-                            scaledHeight - verticalPadding.first - verticalPadding.second);
-                }
-
-                g2.dispose();
-            }
-
-            @Override
-            public Dimension getPreferredSize() {
-                return size;
-            }
-        }
-    }
-
-    private class ImageViewer extends JComponent {
-        private final Color CORRUPTED_COLOR = new Color(1.0f, 0.0f, 0.0f, 0.7f);
-        private final Color LOCK_COLOR = new Color(0.0f, 0.0f, 0.0f, 0.7f);
-        private final Color STRIPES_COLOR = new Color(1.0f, 0.0f, 0.0f, 0.5f);
-        private final Color BACK_COLOR = new Color(0xc0c0c0);
-        private final Color HELP_COLOR = new Color(0xffffe1);
-        private final Color PATCH_COLOR = new Color(1.0f, 0.37f, 0.99f, 0.5f);
-        private final Color PATCH_ONEWAY_COLOR = new Color(0.37f, 1.0f, 0.37f, 0.5f);
-
-        private static final float STRIPES_WIDTH = 4.0f;
-        private static final double STRIPES_SPACING = 6.0;
-        private static final int STRIPES_ANGLE = 45;
-
-        private int zoom = DEFAULT_ZOOM;
-        private boolean showPatches;
-        private boolean showLock = true;
-
-        private final Dimension size;
-
-        private boolean locked;
-
-        private int[] row;
-        private int[] column;
-
-        private int lastPositionX;
-        private int lastPositionY;
-        private int currentButton;
-        private boolean showCursor;
-
-        private JLabel helpLabel;
-        private boolean eraseMode;
-
-        private JButton checkButton;
-        private List<Rectangle> corruptedPatches;
-        private boolean showBadPatches;
-
-        private JPanel helpPanel;
-        private boolean drawingLine;
-        private int lineFromX;
-        private int lineFromY;
-        private int lineToX;
-        private int lineToY;
-        private boolean showDrawingLine;
-
-        ImageViewer() {
-            setLayout(new GridBagLayout());
-            helpPanel = new JPanel(new BorderLayout());
-            helpPanel.setBorder(new EmptyBorder(0, 6, 0, 6));
-            helpPanel.setBackground(HELP_COLOR);
-            helpLabel = new JLabel("Press Shift to erase pixels."
-                    + " Press Control to draw layout bounds");
-            helpLabel.putClientProperty("JComponent.sizeVariant", "small");            
-            helpPanel.add(helpLabel, BorderLayout.WEST);
-            checkButton = new JButton("Show bad patches");
-            checkButton.putClientProperty("JComponent.sizeVariant", "small");
-            checkButton.putClientProperty("JButton.buttonType", "roundRect");
-            helpPanel.add(checkButton, BorderLayout.EAST);
-
-            add(helpPanel, new GridBagConstraints(0, 0, 1, 1,
-                    1.0f, 1.0f, GridBagConstraints.FIRST_LINE_START, GridBagConstraints.HORIZONTAL,
-                    new Insets(0, 0, 0, 0), 0, 0));
-
-            setOpaque(true);
-
-            // Exact size will be set by setZoom() in AncestorListener#ancestorMoved.
-            size = new Dimension(0, 0);
-
-            addAncestorListener(new AncestorListener() {
-                @Override
-                public void ancestorRemoved(AncestorEvent event) {
-                }
-                @Override
-                public void ancestorMoved(AncestorEvent event) {
-                    // Set exactly size.
-                    viewer.setZoom(DEFAULT_ZOOM);
-                    viewer.removeAncestorListener(this);
-                }
-                @Override
-                public void ancestorAdded(AncestorEvent event) {
-                }
-            });
-
-            findPatches();
-
-            addMouseListener(new MouseAdapter() {
-                @Override
-                public void mousePressed(MouseEvent event) {
-                    // Store the button here instead of retrieving it again in MouseDragged
-                    // below, because on linux, calling MouseEvent.getButton() for the drag
-                    // event returns 0, which appears to be technically correct (no button
-                    // changed state).
-                    currentButton = event.isShiftDown() ? MouseEvent.BUTTON3 : event.getButton();
-                    currentButton = event.isControlDown() ? MouseEvent.BUTTON2 : currentButton;
-                    startDrawingLine(event.getX(), event.getY(), currentButton);
-                }
-
-                @Override
-                public void mouseReleased(MouseEvent event) {
-                    endDrawingLine();
-                }
-            });
-            addMouseMotionListener(new MouseMotionAdapter() {
-                @Override
-                public void mouseDragged(MouseEvent event) {
-                    if (!checkLockedRegion(event.getX(), event.getY())) {
-                        // use the stored button, see note above
-
-                        moveLine(event.getX(), event.getY());
-                    }
-                }
-
-                @Override
-                public void mouseMoved(MouseEvent event) {
-                    checkLockedRegion(event.getX(), event.getY());
-                }
-            });
-            Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
-                public void eventDispatched(AWTEvent event) {
-                    enableEraseMode((KeyEvent) event);
-                }
-            }, AWTEvent.KEY_EVENT_MASK);
-
-            checkButton.addActionListener(new ActionListener() {
-                public void actionPerformed(ActionEvent event) {
-                    if (!showBadPatches) {
-                        findBadPatches();
-                        checkButton.setText("Hide bad patches");
-                    } else {
-                        checkButton.setText("Show bad patches");
-                        corruptedPatches = null;
-                    }
-                    repaint();
-                    showBadPatches = !showBadPatches;
-                }
-            });
-        }
-
-        private void findBadPatches() {
-            corruptedPatches = new ArrayList<Rectangle>();
-
-            for (Rectangle patch : patches) {
-                if (corruptPatch(patch)) {
-                    corruptedPatches.add(patch);
-                }
-            }
-
-            for (Rectangle patch : horizontalPatches) {
-                if (corruptHorizontalPatch(patch)) {
-                    corruptedPatches.add(patch);
-                }
-            }
-
-            for (Rectangle patch : verticalPatches) {
-                if (corruptVerticalPatch(patch)) {
-                    corruptedPatches.add(patch);
-                }
-            }
-        }
-
-        private boolean corruptPatch(Rectangle patch) {
-            int[] pixels = GraphicsUtilities.getPixels(image, patch.x, patch.y,
-                    patch.width, patch.height, null);
-
-            if (pixels.length > 0) {
-                int reference = pixels[0];
-                for (int pixel : pixels) {
-                    if (pixel != reference) {
-                        return true;
-                    }
-                }
-            }
-
-            return false;
-        }
-
-        private boolean corruptHorizontalPatch(Rectangle patch) {
-            int[] reference = new int[patch.height];
-            int[] column = new int[patch.height];
-            reference = GraphicsUtilities.getPixels(image, patch.x, patch.y,
-                    1, patch.height, reference);
-
-            for (int i = 1; i < patch.width; i++) {
-                column = GraphicsUtilities.getPixels(image, patch.x + i, patch.y,
-                        1, patch.height, column);
-                if (!Arrays.equals(reference, column)) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-
-        private boolean corruptVerticalPatch(Rectangle patch) {
-            int[] reference = new int[patch.width];
-            int[] row = new int[patch.width];
-            reference = GraphicsUtilities.getPixels(image, patch.x, patch.y,
-                    patch.width, 1, reference);
-
-            for (int i = 1; i < patch.height; i++) {
-                row = GraphicsUtilities.getPixels(image, patch.x, patch.y + i, patch.width, 1, row);
-                if (!Arrays.equals(reference, row)) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-
-        private void enableEraseMode(KeyEvent event) {
-            boolean oldEraseMode = eraseMode;
-            eraseMode = event.isShiftDown();
-            if (eraseMode != oldEraseMode) {
-                if (eraseMode) {
-                    helpLabel.setText("Release Shift to draw pixels");
-                } else {
-                    helpLabel.setText("Press Shift to erase pixels."
-                                      + " Press Control to draw layout bounds");
-                }
-            }
-        }
-
-        private void startDrawingLine(int x, int y, int button) {
-            int left = (getWidth() - size.width) / 2;
-            int top = helpPanel.getHeight() + (getHeight() - size.height) / 2;
-
-            x = (x - left) / zoom;
-            y = (y - top) / zoom;
-
-            int width = image.getWidth();
-            int height = image.getHeight();
-            if (((x == 0 || x == width - 1) && (y > 0 && y < height - 1))
-                    || ((x > 0 && x < width - 1) && (y == 0 || y == height - 1))) {
-                drawingLine = true;
-                lineFromX = x;
-                lineFromY = y;
-                lineToX = x;
-                lineToY = y;
-
-                showDrawingLine = true;
-
-                showCursor = false;
-
-                repaint();
-            }
-        }
-
-        private void moveLine(int x, int y) {
-            if (drawingLine == false)
-                return;
-
-            int left = (getWidth() - size.width) / 2;
-            int top = helpPanel.getHeight() + (getHeight() - size.height) / 2;
-
-            x = (x - left) / zoom;
-            y = (y - top) / zoom;
-
-            int width = image.getWidth();
-            int height = image.getHeight();
-
-            showDrawingLine = false;
-
-            if (((x == lineFromX) && (y > 0 && y < height - 1))
-                    || ((x > 0 && x < width - 1) && (y == lineFromY))) {
-                if (x == lineFromX || y == lineFromY) {
-                    lineToX = x;
-                    lineToY = y;
-
-                    showDrawingLine = true;
-                }
-            }
-
-            repaint();
-        }
-
-        private void endDrawingLine() {
-            if (drawingLine == false)
-                return;
-
-            drawingLine = false;
-
-            if (showDrawingLine == false)
-                return;
-
-            int color;
-            switch (currentButton) {
-            case MouseEvent.BUTTON1:
-                color = BLACK_TICK;
-                break;
-            case MouseEvent.BUTTON2:
-                color = RED_TICK;
-                break;
-            case MouseEvent.BUTTON3:
-                color = 0;
-                break;
-            default:
-                return;
-            }
-
-            int x = lineFromX;
-            int y = lineFromY;
-
-            int dx = 0;
-            int dy = 0;
-
-            if (lineToX != lineFromX)
-                dx = lineToX > lineFromX ? 1 : -1;
-            else if (lineToY != lineFromY)
-                dy = lineToY > lineFromY ? 1 : -1;
-
-            do {
-                image.setRGB(x, y, color);
-
-                if (x == lineToX && y == lineToY)
-                    break;
-
-                x += dx;
-                y += dy;
-            } while (true);
-
-            findPatches();
-            stretchesViewer.computePatches();
-            if (showBadPatches) {
-                findBadPatches();
-            }
-
-            repaint();
-        }
-
-        private boolean checkLockedRegion(int x, int y) {
-            int oldX = lastPositionX;
-            int oldY = lastPositionY;
-            lastPositionX = x;
-            lastPositionY = y;
-
-            int left = (getWidth() - size.width) / 2;
-            int top = helpPanel.getHeight() + (getHeight() - size.height) / 2;
-
-            x = (x - left) / zoom;
-            y = (y - top) / zoom;
-
-            int width = image.getWidth();
-            int height = image.getHeight();
-
-            xLabel.setText(Math.max(0, Math.min(x, width - 1)) + " px");
-            yLabel.setText(Math.max(0, Math.min(y, height - 1)) + " px");
-
-            boolean previousLock = locked;
-            locked = x > 0 && x < width - 1 && y > 0 && y < height - 1;
-
-            boolean previousCursor = showCursor;
-            showCursor =
-                    !drawingLine &&
-                    ( ((x == 0 || x == width - 1) && (y > 0 && y < height - 1)) ||
-                      ((x > 0 && x < width - 1) && (y == 0 || y == height - 1)) );
-
-            if (locked != previousLock) {
-                repaint();
-            } else if (showCursor || (showCursor != previousCursor)) {
-                Rectangle clip = new Rectangle(lastPositionX - 1 - zoom / 2,
-                        lastPositionY - 1 - zoom / 2, zoom + 2, zoom + 2);
-                clip = clip.union(new Rectangle(oldX - 1 - zoom / 2,
-                        oldY - 1 - zoom / 2, zoom + 2, zoom + 2));
-                repaint(clip);
-            }
-
-            return locked;
-        }
-
-        @Override
-        protected void paintComponent(Graphics g) {
-            int x = (getWidth() - size.width) / 2;
-            int y = helpPanel.getHeight() + (getHeight() - size.height) / 2;
-
-            Graphics2D g2 = (Graphics2D) g.create();
-            g2.setColor(BACK_COLOR);
-            g2.fillRect(0, 0, getWidth(), getHeight());
-
-            g2.translate(x, y);
-            g2.setPaint(texture);
-            g2.fillRect(0, 0, size.width, size.height);
-            g2.scale(zoom, zoom);
-            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-                    RenderingHints.VALUE_ANTIALIAS_ON);
-            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                    RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
-            g2.drawImage(image, 0, 0, null);
-
-            if (showPatches) {
-                g2.setColor(PATCH_COLOR);
-                for (Rectangle patch : patches) {
-                    g2.fillRect(patch.x, patch.y, patch.width, patch.height);
-                }
-                g2.setColor(PATCH_ONEWAY_COLOR);
-                for (Rectangle patch : horizontalPatches) {
-                    g2.fillRect(patch.x, patch.y, patch.width, patch.height);
-                }
-                for (Rectangle patch : verticalPatches) {
-                    g2.fillRect(patch.x, patch.y, patch.width, patch.height);
-                }
-            }
-
-            if (corruptedPatches != null) {
-                g2.setColor(CORRUPTED_COLOR);
-                g2.setStroke(new BasicStroke(3.0f / zoom));
-                for (Rectangle patch : corruptedPatches) {
-                    g2.draw(new RoundRectangle2D.Float(patch.x - 2.0f / zoom, patch.y - 2.0f / zoom,
-                            patch.width + 2.0f / zoom, patch.height + 2.0f / zoom,
-                            6.0f / zoom, 6.0f / zoom));
-                }
-            }
-
-            if (showLock && locked) {
-                int width = image.getWidth();
-                int height = image.getHeight();
-
-                g2.setColor(LOCK_COLOR);
-                g2.fillRect(1, 1, width - 2, height - 2);
-
-                g2.setColor(STRIPES_COLOR);
-                g2.translate(1, 1);
-                paintStripes(g2, width - 2, height - 2);
-                g2.translate(-1, -1);
-            }
-
-            g2.dispose();
-
-            if (drawingLine && showDrawingLine) {
-                Graphics cursor = g.create();
-                cursor.setXORMode(Color.WHITE);
-                cursor.setColor(Color.BLACK);
-
-                x = Math.min(lineFromX, lineToX);
-                y = Math.min(lineFromY, lineToY);
-                int w = Math.abs(lineFromX - lineToX) + 1;
-                int h = Math.abs(lineFromY - lineToY) + 1;
-
-                x = x * zoom;
-                y = y * zoom;
-                w = w * zoom;
-                h = h * zoom;
-
-                int left = (getWidth() - size.width) / 2;
-                int top = helpPanel.getHeight() + (getHeight() - size.height)
-                        / 2;
-
-                x += left;
-                y += top;
-
-                cursor.drawRect(x, y, w, h);
-                cursor.dispose();
-            }
-
-            if (showCursor) {
-                Graphics cursor = g.create();
-                cursor.setXORMode(Color.WHITE);
-                cursor.setColor(Color.BLACK);
-                cursor.drawRect(lastPositionX - zoom / 2, lastPositionY - zoom / 2, zoom, zoom);
-                cursor.dispose();
-            }
-        }
-
-        private void paintStripes(Graphics2D g, int width, int height) {
-            //draws pinstripes at the angle specified in this class
-            //and at the given distance apart
-            Shape oldClip = g.getClip();
-            Area area = new Area(new Rectangle(0, 0, width, height));
-            if(oldClip != null) {
-                area = new Area(oldClip);
-            }
-            area.intersect(new Area(new Rectangle(0,0,width,height)));
-            g.setClip(area);
-
-            g.setStroke(new BasicStroke(STRIPES_WIDTH));
-
-            double hypLength = Math.sqrt((width * width) +
-                    (height * height));
-
-            double radians = Math.toRadians(STRIPES_ANGLE);
-            g.rotate(radians);
-
-            double spacing = STRIPES_SPACING;
-            spacing += STRIPES_WIDTH;
-            int numLines = (int)(hypLength / spacing);
-
-            for (int i=0; i<numLines; i++) {
-                double x = i * spacing;
-                Line2D line = new Line2D.Double(x, -hypLength, x, hypLength);
-                g.draw(line);
-            }
-            g.setClip(oldClip);
-        }
-
-        @Override
-        public Dimension getPreferredSize() {
-            return size;
-        }
-
-        void setZoom(int value) {
-            int width = image.getWidth();
-            int height = image.getHeight();
-
-            zoom = value;
-            if (size.height == 0 || (getHeight() - size.height) == 0) {
-                size.setSize(width * zoom, height * zoom + helpPanel.getHeight());
-            } else {
-                size.setSize(width * zoom, height * zoom);
-            }
-
-            if (!size.equals(getSize())) {
-                setSize(size);
-                ImageEditorPanel.this.validate();
-                repaint();
-            }
-        }
-
-        void setPatchesVisible(boolean visible) {
-            showPatches = visible;
-            findPatches();
-            repaint();
-        }
-
-        private void findPatches() {
-            int width = image.getWidth();
-            int height = image.getHeight();
-
-            row = GraphicsUtilities.getPixels(image, 0, 0, width, 1, row);
-            column = GraphicsUtilities.getPixels(image, 0, 0, 1, height, column);
-
-            boolean[] result = new boolean[1];
-            Pair<List<Pair<Integer>>> left = getPatches(column, result);
-            verticalStartWithPatch = result[0];
-
-            result = new boolean[1];
-            Pair<List<Pair<Integer>>> top = getPatches(row, result);
-            horizontalStartWithPatch = result[0];
-
-            fixed = getRectangles(left.first, top.first);
-            patches = getRectangles(left.second, top.second);
-
-            if (fixed.size() > 0) {
-                horizontalPatches = getRectangles(left.first, top.second);
-                verticalPatches = getRectangles(left.second, top.first);
-            } else {
-                if (top.first.size() > 0) {
-                    horizontalPatches = new ArrayList<Rectangle>(0);
-                    verticalPatches = getVerticalRectangles(top.first);
-                } else if (left.first.size() > 0) {
-                    horizontalPatches = getHorizontalRectangles(left.first);
-                    verticalPatches = new ArrayList<Rectangle>(0);
-                } else {
-                    horizontalPatches = verticalPatches = new ArrayList<Rectangle>(0);
-                }
-            }
-
-            row = GraphicsUtilities.getPixels(image, 0, height - 1, width, 1, row);
-            column = GraphicsUtilities.getPixels(image, width - 1, 0, 1, height, column);
-
-            top = getPatches(row, result);
-            horizontalPadding = getPadding(top.first);
-
-            left = getPatches(column, result);
-            verticalPadding = getPadding(left.first);
-        }
-
-        private List<Rectangle> getVerticalRectangles(List<Pair<Integer>> topPairs) {
-            List<Rectangle> rectangles = new ArrayList<Rectangle>();
-            for (Pair<Integer> top : topPairs) {
-                int x = top.first;
-                int width = top.second - top.first;
-
-                rectangles.add(new Rectangle(x, 1, width, image.getHeight() - 2));
-            }
-            return rectangles;
-        }
-
-        private List<Rectangle> getHorizontalRectangles(List<Pair<Integer>> leftPairs) {
-            List<Rectangle> rectangles = new ArrayList<Rectangle>();
-            for (Pair<Integer> left : leftPairs) {
-                int y = left.first;
-                int height = left.second - left.first;
-
-                rectangles.add(new Rectangle(1, y, image.getWidth() - 2, height));
-            }
-            return rectangles;
-        }
-
-        private Pair<Integer> getPadding(List<Pair<Integer>> pairs) {
-            if (pairs.size() == 0) {
-                return new Pair<Integer>(0, 0);
-            } else if (pairs.size() == 1) {
-                if (pairs.get(0).first == 1) {
-                    return new Pair<Integer>(pairs.get(0).second - pairs.get(0).first, 0);
-                } else {
-                    return new Pair<Integer>(0, pairs.get(0).second - pairs.get(0).first);                    
-                }
-            } else {
-                int index = pairs.size() - 1;
-                return new Pair<Integer>(pairs.get(0).second - pairs.get(0).first,
-                        pairs.get(index).second - pairs.get(index).first);
-            }
-        }
-
-        private List<Rectangle> getRectangles(List<Pair<Integer>> leftPairs,
-                List<Pair<Integer>> topPairs) {
-            List<Rectangle> rectangles = new ArrayList<Rectangle>();
-            for (Pair<Integer> left : leftPairs) {
-                int y = left.first;
-                int height = left.second - left.first;
-                for (Pair<Integer> top : topPairs) {
-                    int x = top.first;
-                    int width = top.second - top.first;
-
-                    rectangles.add(new Rectangle(x, y, width, height));
-                }
-            }
-            return rectangles;
-        }
-
-        private Pair<List<Pair<Integer>>> getPatches(int[] pixels, boolean[] startWithPatch) {
-            int lastIndex = 1;
-            int lastPixel = pixels[1];
-            boolean first = true;
-
-            List<Pair<Integer>> fixed = new ArrayList<Pair<Integer>>();
-            List<Pair<Integer>> patches = new ArrayList<Pair<Integer>>();
-
-            for (int i = 1; i < pixels.length - 1; i++) {
-                int pixel = pixels[i];
-                if (pixel != lastPixel) {
-                    if (lastPixel == BLACK_TICK) {
-                        if (first) startWithPatch[0] = true;
-                        patches.add(new Pair<Integer>(lastIndex, i));
-                    } else {
-                        fixed.add(new Pair<Integer>(lastIndex, i));
-                    }
-                    first = false;
-
-                    lastIndex = i;
-                    lastPixel = pixel;
-                }
-            }
-            if (lastPixel == BLACK_TICK) {
-                if (first) startWithPatch[0] = true;
-                patches.add(new Pair<Integer>(lastIndex, pixels.length - 1));
-            } else {
-                fixed.add(new Pair<Integer>(lastIndex, pixels.length - 1));
-            }
-
-            if (patches.size() == 0) {
-                patches.add(new Pair<Integer>(1, pixels.length - 1));
-                startWithPatch[0] = true;
-                fixed.clear();
-            }
-
-            return new Pair<List<Pair<Integer>>>(fixed, patches);
-        }
-
-        void setLockVisible(boolean visible) {
-            showLock = visible;
-            repaint();
-        }
-    }
-
-    static class Pair<E> {
-        E first;
-        E second;
-
-        Pair(E first, E second) {
-            this.first = first;
-            this.second = second;
-        }
-
-        @Override
-        public String toString() {
-            return "Pair[" + first + ", " + second + "]";
-        }
-    }
 }
diff --git a/draw9patch/src/main/java/com/android/draw9patch/ui/ImageViewer.java b/draw9patch/src/main/java/com/android/draw9patch/ui/ImageViewer.java
new file mode 100644
index 0000000..e36afc1
--- /dev/null
+++ b/draw9patch/src/main/java/com/android/draw9patch/ui/ImageViewer.java
@@ -0,0 +1,572 @@
+/*
+ *
+ *  Copyright (C) 2013 The Android Open Source Project
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package com.android.draw9patch.ui;
+
+import java.awt.AWTEvent;
+import java.awt.BasicStroke;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.TexturePaint;
+import java.awt.Toolkit;
+import java.awt.event.AWTEventListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.awt.geom.Area;
+import java.awt.geom.Line2D;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.BufferedImage;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.AncestorEvent;
+import javax.swing.event.AncestorListener;
+
+public class ImageViewer extends JComponent {
+    private final Color CORRUPTED_COLOR = new Color(1.0f, 0.0f, 0.0f, 0.7f);
+    private final Color LOCK_COLOR = new Color(0.0f, 0.0f, 0.0f, 0.7f);
+    private final Color STRIPES_COLOR = new Color(1.0f, 0.0f, 0.0f, 0.5f);
+    private final Color BACK_COLOR = new Color(0xc0c0c0);
+    private final Color HELP_COLOR = new Color(0xffffe1);
+    private final Color PATCH_COLOR = new Color(1.0f, 0.37f, 0.99f, 0.5f);
+    private final Color PATCH_ONEWAY_COLOR = new Color(0.37f, 1.0f, 0.37f, 0.5f);
+
+    private static final float STRIPES_WIDTH = 4.0f;
+    private static final double STRIPES_SPACING = 6.0;
+    private static final int STRIPES_ANGLE = 45;
+
+    /** Default zoom level for the 9patch image. */
+    public static final int DEFAULT_ZOOM = 8;
+
+    /** Minimum zoom level for the 9patch image. */
+    public static final int MIN_ZOOM = 1;
+
+    /** Maximum zoom level for the 9patch image. */
+    public static final int MAX_ZOOM = 16;
+
+    /** Current 9patch zoom level, {@link #MIN_ZOOM} <= zoom <= {@link #MAX_ZOOM} */
+    private int zoom = DEFAULT_ZOOM;
+    private boolean showPatches;
+    private boolean showLock = true;
+
+    private final TexturePaint texture;
+    private final Container container;
+    private final StatusBar statusBar;
+
+    private final Dimension size;
+
+    private boolean locked;
+
+    private int lastPositionX;
+    private int lastPositionY;
+    private int currentButton;
+    private boolean showCursor;
+
+    private JLabel helpLabel;
+    private boolean eraseMode;
+
+    private JButton checkButton;
+    private List<Rectangle> corruptedPatches;
+    private boolean showBadPatches;
+
+    private JPanel helpPanel;
+    private boolean drawingLine;
+    private int lineFromX;
+    private int lineFromY;
+    private int lineToX;
+    private int lineToY;
+    private boolean showDrawingLine;
+
+    private BufferedImage image;
+    private PatchInfo patchInfo;
+
+    ImageViewer(Container container, TexturePaint texture, BufferedImage image,
+                StatusBar statusBar) {
+        this.container = container;
+        this.texture = texture;
+        this.image = image;
+        this.statusBar = statusBar;
+
+        setLayout(new GridBagLayout());
+        helpPanel = new JPanel(new BorderLayout());
+        helpPanel.setBorder(new EmptyBorder(0, 6, 0, 6));
+        helpPanel.setBackground(HELP_COLOR);
+        helpLabel = new JLabel("Press Shift to erase pixels."
+                + " Press Control to draw layout bounds");
+        helpLabel.putClientProperty("JComponent.sizeVariant", "small");
+        helpPanel.add(helpLabel, BorderLayout.WEST);
+        checkButton = new JButton("Show bad patches");
+        checkButton.putClientProperty("JComponent.sizeVariant", "small");
+        checkButton.putClientProperty("JButton.buttonType", "roundRect");
+        helpPanel.add(checkButton, BorderLayout.EAST);
+
+        add(helpPanel, new GridBagConstraints(0, 0, 1, 1,
+                1.0f, 1.0f, GridBagConstraints.FIRST_LINE_START, GridBagConstraints.HORIZONTAL,
+                new Insets(0, 0, 0, 0), 0, 0));
+
+        setOpaque(true);
+
+        // Exact size will be set by setZoom() in AncestorListener#ancestorMoved.
+        size = new Dimension(0, 0);
+
+        addAncestorListener(new AncestorListener() {
+            @Override
+            public void ancestorRemoved(AncestorEvent event) {
+            }
+            @Override
+            public void ancestorMoved(AncestorEvent event) {
+                // Set exactly size.
+                setZoom(DEFAULT_ZOOM);
+                removeAncestorListener(this);
+            }
+            @Override
+            public void ancestorAdded(AncestorEvent event) {
+            }
+        });
+
+        updatePatchInfo();
+
+        addMouseListener(new MouseAdapter() {
+            @Override
+            public void mousePressed(MouseEvent event) {
+                // Store the button here instead of retrieving it again in MouseDragged
+                // below, because on linux, calling MouseEvent.getButton() for the drag
+                // event returns 0, which appears to be technically correct (no button
+                // changed state).
+                currentButton = event.isShiftDown() ? MouseEvent.BUTTON3 : event.getButton();
+                currentButton = event.isControlDown() ? MouseEvent.BUTTON2 : currentButton;
+                startDrawingLine(event.getX(), event.getY());
+            }
+
+            @Override
+            public void mouseReleased(MouseEvent event) {
+                endDrawingLine();
+            }
+        });
+        addMouseMotionListener(new MouseMotionAdapter() {
+            @Override
+            public void mouseDragged(MouseEvent event) {
+                if (!checkLockedRegion(event.getX(), event.getY())) {
+                    // use the stored button, see note above
+
+                    moveLine(event.getX(), event.getY());
+                }
+            }
+
+            @Override
+            public void mouseMoved(MouseEvent event) {
+                checkLockedRegion(event.getX(), event.getY());
+            }
+        });
+        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+            public void eventDispatched(AWTEvent event) {
+                enableEraseMode((KeyEvent) event);
+            }
+        }, AWTEvent.KEY_EVENT_MASK);
+
+        checkButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                if (!showBadPatches) {
+                    corruptedPatches = CorruptPatch.findBadPatches(ImageViewer.this.image,
+                            patchInfo);
+                    checkButton.setText("Hide bad patches");
+                } else {
+                    checkButton.setText("Show bad patches");
+                    corruptedPatches = null;
+                }
+                repaint();
+                showBadPatches = !showBadPatches;
+            }
+        });
+    }
+
+    private void updatePatchInfo() {
+        patchInfo = new PatchInfo(image);
+    }
+
+    private void enableEraseMode(KeyEvent event) {
+        boolean oldEraseMode = eraseMode;
+        eraseMode = event.isShiftDown();
+        if (eraseMode != oldEraseMode) {
+            if (eraseMode) {
+                helpLabel.setText("Release Shift to draw pixels");
+            } else {
+                helpLabel.setText("Press Shift to erase pixels."
+                        + " Press Control to draw layout bounds");
+            }
+        }
+    }
+
+    private void startDrawingLine(int x, int y) {
+        int left = (getWidth() - size.width) / 2;
+        int top = helpPanel.getHeight() + (getHeight() - size.height) / 2;
+
+        x = (x - left) / zoom;
+        y = (y - top) / zoom;
+
+        int width = image.getWidth();
+        int height = image.getHeight();
+        if (((x == 0 || x == width - 1) && (y > 0 && y < height - 1))
+                || ((x > 0 && x < width - 1) && (y == 0 || y == height - 1))) {
+            drawingLine = true;
+            lineFromX = x;
+            lineFromY = y;
+            lineToX = x;
+            lineToY = y;
+
+            showDrawingLine = true;
+
+            showCursor = false;
+
+            repaint();
+        }
+    }
+
+    private void moveLine(int x, int y) {
+        if (!drawingLine) {
+            return;
+        }
+
+        int left = (getWidth() - size.width) / 2;
+        int top = helpPanel.getHeight() + (getHeight() - size.height) / 2;
+
+        x = (x - left) / zoom;
+        y = (y - top) / zoom;
+
+        int width = image.getWidth();
+        int height = image.getHeight();
+
+        showDrawingLine = false;
+
+        if (((x == lineFromX) && (y > 0 && y < height - 1))
+                || ((x > 0 && x < width - 1) && (y == lineFromY))) {
+            lineToX = x;
+            lineToY = y;
+
+            showDrawingLine = true;
+        }
+
+        repaint();
+    }
+
+    private void endDrawingLine() {
+        if (!drawingLine) {
+            return;
+        }
+
+        drawingLine = false;
+
+        if (!showDrawingLine) {
+            return;
+        }
+
+        int color;
+        switch (currentButton) {
+            case MouseEvent.BUTTON1:
+                color = PatchInfo.BLACK_TICK;
+                break;
+            case MouseEvent.BUTTON2:
+                color = PatchInfo.RED_TICK;
+                break;
+            case MouseEvent.BUTTON3:
+                color = 0;
+                break;
+            default:
+                return;
+        }
+
+        int x = lineFromX;
+        int y = lineFromY;
+
+        int dx = 0;
+        int dy = 0;
+
+        if (lineToX != lineFromX)
+            dx = lineToX > lineFromX ? 1 : -1;
+        else if (lineToY != lineFromY)
+            dy = lineToY > lineFromY ? 1 : -1;
+
+        do {
+            image.setRGB(x, y, color);
+
+            if (x == lineToX && y == lineToY)
+                break;
+
+            x += dx;
+            y += dy;
+        } while (true);
+
+        updatePatchInfo();
+        notifyPatchesUpdated();
+        if (showBadPatches) {
+            corruptedPatches = CorruptPatch.findBadPatches(image, patchInfo);
+        }
+
+        repaint();
+    }
+
+    private boolean checkLockedRegion(int x, int y) {
+        int oldX = lastPositionX;
+        int oldY = lastPositionY;
+        lastPositionX = x;
+        lastPositionY = y;
+
+        int left = (getWidth() - size.width) / 2;
+        int top = helpPanel.getHeight() + (getHeight() - size.height) / 2;
+
+        x = (x - left) / zoom;
+        y = (y - top) / zoom;
+
+        int width = image.getWidth();
+        int height = image.getHeight();
+
+        statusBar.setPointerLocation(Math.max(0, Math.min(x, width - 1)),
+                Math.max(0, Math.min(y, height - 1)));
+
+        boolean previousLock = locked;
+        locked = x > 0 && x < width - 1 && y > 0 && y < height - 1;
+
+        boolean previousCursor = showCursor;
+        showCursor =
+                !drawingLine &&
+                        ( ((x == 0 || x == width - 1) && (y > 0 && y < height - 1)) ||
+                                ((x > 0 && x < width - 1) && (y == 0 || y == height - 1)) );
+
+        if (locked != previousLock) {
+            repaint();
+        } else if (showCursor || (showCursor != previousCursor)) {
+            Rectangle clip = new Rectangle(lastPositionX - 1 - zoom / 2,
+                    lastPositionY - 1 - zoom / 2, zoom + 2, zoom + 2);
+            clip = clip.union(new Rectangle(oldX - 1 - zoom / 2,
+                    oldY - 1 - zoom / 2, zoom + 2, zoom + 2));
+            repaint(clip);
+        }
+
+        return locked;
+    }
+
+    @Override
+    protected void paintComponent(Graphics g) {
+        int x = (getWidth() - size.width) / 2;
+        int y = helpPanel.getHeight() + (getHeight() - size.height) / 2;
+
+        Graphics2D g2 = (Graphics2D) g.create();
+        g2.setColor(BACK_COLOR);
+        g2.fillRect(0, 0, getWidth(), getHeight());
+
+        g2.translate(x, y);
+        g2.setPaint(texture);
+        g2.fillRect(0, 0, size.width, size.height);
+        g2.scale(zoom, zoom);
+        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
+        g2.drawImage(image, 0, 0, null);
+
+        if (showPatches) {
+            g2.setColor(PATCH_COLOR);
+            for (Rectangle patch : patchInfo.patches) {
+                g2.fillRect(patch.x, patch.y, patch.width, patch.height);
+            }
+            g2.setColor(PATCH_ONEWAY_COLOR);
+            for (Rectangle patch : patchInfo.horizontalPatches) {
+                g2.fillRect(patch.x, patch.y, patch.width, patch.height);
+            }
+            for (Rectangle patch : patchInfo.verticalPatches) {
+                g2.fillRect(patch.x, patch.y, patch.width, patch.height);
+            }
+        }
+
+        if (corruptedPatches != null) {
+            g2.setColor(CORRUPTED_COLOR);
+            g2.setStroke(new BasicStroke(3.0f / zoom));
+            for (Rectangle patch : corruptedPatches) {
+                g2.draw(new RoundRectangle2D.Float(patch.x - 2.0f / zoom, patch.y - 2.0f / zoom,
+                        patch.width + 2.0f / zoom, patch.height + 2.0f / zoom,
+                        6.0f / zoom, 6.0f / zoom));
+            }
+        }
+
+        if (showLock && locked) {
+            int width = image.getWidth();
+            int height = image.getHeight();
+
+            g2.setColor(LOCK_COLOR);
+            g2.fillRect(1, 1, width - 2, height - 2);
+
+            g2.setColor(STRIPES_COLOR);
+            g2.translate(1, 1);
+            paintStripes(g2, width - 2, height - 2);
+            g2.translate(-1, -1);
+        }
+
+        g2.dispose();
+
+        if (drawingLine && showDrawingLine) {
+            Graphics cursor = g.create();
+            cursor.setXORMode(Color.WHITE);
+            cursor.setColor(Color.BLACK);
+
+            x = Math.min(lineFromX, lineToX);
+            y = Math.min(lineFromY, lineToY);
+            int w = Math.abs(lineFromX - lineToX) + 1;
+            int h = Math.abs(lineFromY - lineToY) + 1;
+
+            x = x * zoom;
+            y = y * zoom;
+            w = w * zoom;
+            h = h * zoom;
+
+            int left = (getWidth() - size.width) / 2;
+            int top = helpPanel.getHeight() + (getHeight() - size.height)
+                    / 2;
+
+            x += left;
+            y += top;
+
+            cursor.drawRect(x, y, w, h);
+            cursor.dispose();
+        }
+
+        if (showCursor) {
+            Graphics cursor = g.create();
+            cursor.setXORMode(Color.WHITE);
+            cursor.setColor(Color.BLACK);
+            cursor.drawRect(lastPositionX - zoom / 2, lastPositionY - zoom / 2, zoom, zoom);
+            cursor.dispose();
+        }
+    }
+
+    private void paintStripes(Graphics2D g, int width, int height) {
+        //draws pinstripes at the angle specified in this class
+        //and at the given distance apart
+        Shape oldClip = g.getClip();
+        Area area = new Area(new Rectangle(0, 0, width, height));
+        if(oldClip != null) {
+            area = new Area(oldClip);
+        }
+        area.intersect(new Area(new Rectangle(0,0,width,height)));
+        g.setClip(area);
+
+        g.setStroke(new BasicStroke(STRIPES_WIDTH));
+
+        double hypLength = Math.sqrt((width * width) +
+                (height * height));
+
+        double radians = Math.toRadians(STRIPES_ANGLE);
+        g.rotate(radians);
+
+        double spacing = STRIPES_SPACING;
+        spacing += STRIPES_WIDTH;
+        int numLines = (int)(hypLength / spacing);
+
+        for (int i=0; i<numLines; i++) {
+            double x = i * spacing;
+            Line2D line = new Line2D.Double(x, -hypLength, x, hypLength);
+            g.draw(line);
+        }
+        g.setClip(oldClip);
+    }
+
+    @Override
+    public Dimension getPreferredSize() {
+        return size;
+    }
+
+    void setZoom(int value) {
+        int width = image.getWidth();
+        int height = image.getHeight();
+
+        zoom = value;
+        if (size.height == 0 || (getHeight() - size.height) == 0) {
+            size.setSize(width * zoom, height * zoom + helpPanel.getHeight());
+        } else {
+            size.setSize(width * zoom, height * zoom);
+        }
+
+        if (!size.equals(getSize())) {
+            setSize(size);
+            container.validate();
+            repaint();
+        }
+    }
+
+    void setPatchesVisible(boolean visible) {
+        showPatches = visible;
+        updatePatchInfo();
+        repaint();
+    }
+
+    void setLockVisible(boolean visible) {
+        showLock = visible;
+        repaint();
+    }
+
+    public void setImage(BufferedImage image) {
+        this.image = image;
+    }
+
+    public BufferedImage getImage() {
+        return image;
+    }
+
+    public PatchInfo getPatchInfo() {
+        return patchInfo;
+    }
+
+    public interface StatusBar {
+        void setPointerLocation(int x, int y);
+    }
+
+    public interface PatchUpdateListener {
+        void patchesUpdated();
+    }
+
+    private final Set<PatchUpdateListener> listeners = new HashSet<PatchUpdateListener>();
+
+    public void addPatchUpdateListener(PatchUpdateListener p) {
+        listeners.add(p);
+    }
+
+    private void notifyPatchesUpdated() {
+        for (PatchUpdateListener p: listeners) {
+            p.patchesUpdated();
+        }
+    }
+}
\ No newline at end of file
diff --git a/draw9patch/src/main/java/com/android/draw9patch/ui/Pair.java b/draw9patch/src/main/java/com/android/draw9patch/ui/Pair.java
new file mode 100644
index 0000000..bc38671
--- /dev/null
+++ b/draw9patch/src/main/java/com/android/draw9patch/ui/Pair.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.ui;
+
+public class Pair<E> {
+    E first;
+    E second;
+
+    Pair(E first, E second) {
+        this.first = first;
+        this.second = second;
+    }
+
+    @Override
+    public String toString() {
+        return "Pair[" + first + ", " + second + "]";
+    }
+}
diff --git a/draw9patch/src/main/java/com/android/draw9patch/ui/PatchInfo.java b/draw9patch/src/main/java/com/android/draw9patch/ui/PatchInfo.java
new file mode 100644
index 0000000..f68740b
--- /dev/null
+++ b/draw9patch/src/main/java/com/android/draw9patch/ui/PatchInfo.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.ui;
+
+import com.android.draw9patch.graphics.GraphicsUtilities;
+
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PatchInfo {
+    /** Color used to indicate stretch regions and padding. */
+    public static final int BLACK_TICK = 0xFF000000;
+
+    /** Color used to indicate layout bounds. */
+    public static final int RED_TICK = 0xFFFF0000;
+
+    /** Areas of the image that are stretchable in both directions. */
+    public final List<Rectangle> patches;
+
+    /** Areas of the image that are not stretchable in either direction. */
+    public final List<Rectangle> fixed;
+
+    /** Areas of image stretchable horizontally. */
+    public final List<Rectangle> horizontalPatches;
+
+    /** Areas of image stretchable vertically. */
+    public final List<Rectangle> verticalPatches;
+
+    public final boolean verticalStartWithPatch;
+    public final boolean horizontalStartWithPatch;
+
+    /** Beginning and end padding in the horizontal direction */
+    public final Pair<Integer> horizontalPadding;
+
+    /** Beginning and end padding in the vertical direction */
+    public final Pair<Integer> verticalPadding;
+
+    private BufferedImage image;
+
+    public PatchInfo(BufferedImage image) {
+        this.image = image;
+
+        int width = image.getWidth();
+        int height = image.getHeight();
+
+        int[] row = GraphicsUtilities.getPixels(image, 0, 0, width, 1, null);
+        int[] column = GraphicsUtilities.getPixels(image, 0, 0, 1, height, null);
+
+        P left = getPatches(column);
+        verticalStartWithPatch = left.startsWithPatch;
+
+        P top = getPatches(row);
+        horizontalStartWithPatch = top.startsWithPatch;
+
+        fixed = getRectangles(left.fixed, top.fixed);
+        patches = getRectangles(left.patches, top.patches);
+
+        if (fixed.size() > 0) {
+            horizontalPatches = getRectangles(left.fixed, top.patches);
+            verticalPatches = getRectangles(left.patches, top.fixed);
+        } else {
+            if (top.fixed.size() > 0) {
+                horizontalPatches = new ArrayList<Rectangle>(0);
+                verticalPatches = getVerticalRectangles(top.fixed);
+            } else if (left.fixed.size() > 0) {
+                horizontalPatches = getHorizontalRectangles(left.fixed);
+                verticalPatches = new ArrayList<Rectangle>(0);
+            } else {
+                horizontalPatches = verticalPatches = new ArrayList<Rectangle>(0);
+            }
+        }
+
+        row = GraphicsUtilities.getPixels(image, 0, height - 1, width, 1, row);
+        column = GraphicsUtilities.getPixels(image, width - 1, 0, 1, height, column);
+
+        top = PatchInfo.getPatches(row);
+        horizontalPadding = getPadding(top.fixed);
+
+        left = PatchInfo.getPatches(column);
+        verticalPadding = getPadding(left.fixed);
+    }
+
+    private List<Rectangle> getVerticalRectangles(List<Pair<Integer>> topPairs) {
+        List<Rectangle> rectangles = new ArrayList<Rectangle>();
+        for (Pair<Integer> top : topPairs) {
+            int x = top.first;
+            int width = top.second - top.first;
+
+            rectangles.add(new Rectangle(x, 1, width, image.getHeight() - 2));
+        }
+        return rectangles;
+    }
+
+    private List<Rectangle> getHorizontalRectangles(List<Pair<Integer>> leftPairs) {
+        List<Rectangle> rectangles = new ArrayList<Rectangle>();
+        for (Pair<Integer> left : leftPairs) {
+            int y = left.first;
+            int height = left.second - left.first;
+
+            rectangles.add(new Rectangle(1, y, image.getWidth() - 2, height));
+        }
+        return rectangles;
+    }
+
+    private Pair<Integer> getPadding(List<Pair<Integer>> pairs) {
+        if (pairs.size() == 0) {
+            return new Pair<Integer>(0, 0);
+        } else if (pairs.size() == 1) {
+            if (pairs.get(0).first == 1) {
+                return new Pair<Integer>(pairs.get(0).second - pairs.get(0).first, 0);
+            } else {
+                return new Pair<Integer>(0, pairs.get(0).second - pairs.get(0).first);
+            }
+        } else {
+            int index = pairs.size() - 1;
+            return new Pair<Integer>(pairs.get(0).second - pairs.get(0).first,
+                    pairs.get(index).second - pairs.get(index).first);
+        }
+    }
+
+    private List<Rectangle> getRectangles(List<Pair<Integer>> leftPairs,
+                                          List<Pair<Integer>> topPairs) {
+        List<Rectangle> rectangles = new ArrayList<Rectangle>();
+        for (Pair<Integer> left : leftPairs) {
+            int y = left.first;
+            int height = left.second - left.first;
+            for (Pair<Integer> top : topPairs) {
+                int x = top.first;
+                int width = top.second - top.first;
+
+                rectangles.add(new Rectangle(x, y, width, height));
+            }
+        }
+        return rectangles;
+    }
+
+    private static class P {
+        public final List<Pair<Integer>> fixed;
+        public final List<Pair<Integer>> patches;
+        public final boolean startsWithPatch;
+
+        private P(List<Pair<Integer>> f, List<Pair<Integer>> p, boolean s) {
+            fixed = f;
+            patches = p;
+            startsWithPatch = s;
+        }
+    }
+
+    private static P getPatches(int[] pixels) {
+        int lastIndex = 1;
+        int lastPixel = pixels[1];
+        boolean first = true;
+        boolean startWithPatch = false;
+
+        List<Pair<Integer>> fixed = new ArrayList<Pair<Integer>>();
+        List<Pair<Integer>> patches = new ArrayList<Pair<Integer>>();
+
+        for (int i = 1; i < pixels.length - 1; i++) {
+            int pixel = pixels[i];
+            if (pixel != lastPixel) {
+                if (lastPixel == BLACK_TICK) {
+                    if (first) startWithPatch = true;
+                    patches.add(new Pair<Integer>(lastIndex, i));
+                } else {
+                    fixed.add(new Pair<Integer>(lastIndex, i));
+                }
+                first = false;
+
+                lastIndex = i;
+                lastPixel = pixel;
+            }
+        }
+        if (lastPixel == BLACK_TICK) {
+            if (first) startWithPatch = true;
+            patches.add(new Pair<Integer>(lastIndex, pixels.length - 1));
+        } else {
+            fixed.add(new Pair<Integer>(lastIndex, pixels.length - 1));
+        }
+
+        if (patches.size() == 0) {
+            patches.add(new Pair<Integer>(1, pixels.length - 1));
+            startWithPatch = true;
+            fixed.clear();
+        }
+
+        return new P(fixed, patches, startWithPatch);
+    }
+}
diff --git a/draw9patch/src/main/java/com/android/draw9patch/ui/StretchesViewer.java b/draw9patch/src/main/java/com/android/draw9patch/ui/StretchesViewer.java
new file mode 100644
index 0000000..efe0055
--- /dev/null
+++ b/draw9patch/src/main/java/com/android/draw9patch/ui/StretchesViewer.java
@@ -0,0 +1,326 @@
+/*
+ *
+ *  Copyright (C) 2013 The Android Open Source Project
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package com.android.draw9patch.ui;
+
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.TexturePaint;
+import java.awt.image.BufferedImage;
+
+import javax.swing.BorderFactory;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+
+public class StretchesViewer extends JPanel {
+    public static final float DEFAULT_SCALE = 2.0f;
+    private static final int MARGIN = 24;
+
+    private final Container container;
+    private final ImageViewer viewer;
+    private final TexturePaint texture;
+
+    private BufferedImage image;
+    private PatchInfo patchInfo;
+
+    private StretchView horizontal;
+    private StretchView vertical;
+    private StretchView both;
+
+    private Dimension size;
+
+    private float horizontalPatchesSum;
+    private float verticalPatchesSum;
+
+    private boolean showPadding;
+
+    StretchesViewer(Container container, ImageViewer viewer, TexturePaint texture) {
+        this.container = container;
+        this.viewer = viewer;
+        this.texture = texture;
+
+        image = viewer.getImage();
+        patchInfo = viewer.getPatchInfo();
+
+        viewer.addPatchUpdateListener(new ImageViewer.PatchUpdateListener() {
+            @Override
+            public void patchesUpdated() {
+                computePatches();
+            }
+        });
+
+        setOpaque(false);
+        setLayout(new GridBagLayout());
+        setBorder(BorderFactory.createEmptyBorder(MARGIN, MARGIN, MARGIN, MARGIN));
+
+        horizontal = new StretchView();
+        vertical = new StretchView();
+        both = new StretchView();
+
+        setScale(DEFAULT_SCALE);
+
+        add(vertical, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
+                GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+        add(horizontal, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
+                GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+        add(both, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
+                GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+    }
+
+    @Override
+    protected void paintComponent(Graphics g) {
+        Graphics2D g2 = (Graphics2D) g.create();
+        g2.setPaint(texture);
+        g2.fillRect(0, 0, getWidth(), getHeight());
+        g2.dispose();
+    }
+
+    void setScale(float scale) {
+        int patchWidth = image.getWidth() - 2;
+        int patchHeight = image.getHeight() - 2;
+
+        int scaledWidth = (int) (patchWidth * scale);
+        int scaledHeight = (int) (patchHeight * scale);
+
+        horizontal.scaledWidth = scaledWidth;
+        vertical.scaledHeight = scaledHeight;
+        both.scaledWidth = scaledWidth;
+        both.scaledHeight = scaledHeight;
+
+        size = new Dimension(scaledWidth, scaledHeight);
+
+        computePatches();
+    }
+
+    void computePatches() {
+        image = viewer.getImage();
+        patchInfo = viewer.getPatchInfo();
+
+        boolean measuredWidth = false;
+        boolean endRow = true;
+
+        int remainderHorizontal = 0;
+        int remainderVertical = 0;
+
+        if (patchInfo.fixed.size() > 0) {
+            int start = patchInfo.fixed.get(0).y;
+            for (Rectangle rect : patchInfo.fixed) {
+                if (rect.y > start) {
+                    endRow = true;
+                    measuredWidth = true;
+                }
+                if (!measuredWidth) {
+                    remainderHorizontal += rect.width;
+                }
+                if (endRow) {
+                    remainderVertical += rect.height;
+                    endRow = false;
+                    start = rect.y;
+                }
+            }
+        }
+
+        horizontal.remainderHorizontal = horizontal.scaledWidth - remainderHorizontal;
+        vertical.remainderHorizontal = vertical.scaledWidth - remainderHorizontal;
+        both.remainderHorizontal = both.scaledWidth - remainderHorizontal;
+
+        horizontal.remainderVertical = horizontal.scaledHeight - remainderVertical;
+        vertical.remainderVertical = vertical.scaledHeight - remainderVertical;
+        both.remainderVertical = both.scaledHeight - remainderVertical;
+
+        horizontalPatchesSum = 0;
+        if (patchInfo.horizontalPatches.size() > 0) {
+            int start = -1;
+            for (Rectangle rect : patchInfo.horizontalPatches) {
+                if (rect.x > start) {
+                    horizontalPatchesSum += rect.width;
+                    start = rect.x;
+                }
+            }
+        } else {
+            int start = -1;
+            for (Rectangle rect : patchInfo.patches) {
+                if (rect.x > start) {
+                    horizontalPatchesSum += rect.width;
+                    start = rect.x;
+                }
+            }
+        }
+
+        verticalPatchesSum = 0;
+        if (patchInfo.verticalPatches.size() > 0) {
+            int start = -1;
+            for (Rectangle rect : patchInfo.verticalPatches) {
+                if (rect.y > start) {
+                    verticalPatchesSum += rect.height;
+                    start = rect.y;
+                }
+            }
+        } else {
+            int start = -1;
+            for (Rectangle rect : patchInfo.patches) {
+                if (rect.y > start) {
+                    verticalPatchesSum += rect.height;
+                    start = rect.y;
+                }
+            }
+        }
+
+        setSize(size);
+        container.validate();
+        repaint();
+    }
+
+    void setPaddingVisible(boolean visible) {
+        showPadding = visible;
+        repaint();
+    }
+
+    private class StretchView extends JComponent {
+        private final Color PADDING_COLOR = new Color(0.37f, 0.37f, 1.0f, 0.5f);
+
+        int scaledWidth;
+        int scaledHeight;
+
+        int remainderHorizontal;
+        int remainderVertical;
+
+        StretchView() {
+            scaledWidth = image.getWidth();
+            scaledHeight = image.getHeight();
+        }
+
+        @Override
+        protected void paintComponent(Graphics g) {
+            int x = (getWidth() - scaledWidth) / 2;
+            int y = (getHeight() - scaledHeight) / 2;
+
+            Graphics2D g2 = (Graphics2D) g.create();
+            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+            g.translate(x, y);
+
+            x = 0;
+            y = 0;
+
+            if (patchInfo.patches.size() == 0) {
+                g.drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
+                g2.dispose();
+                return;
+            }
+
+            int fixedIndex = 0;
+            int horizontalIndex = 0;
+            int verticalIndex = 0;
+            int patchIndex = 0;
+
+            boolean hStretch;
+            boolean vStretch;
+
+            float vWeightSum = 1.0f;
+            float vRemainder = remainderVertical;
+
+            vStretch = patchInfo.verticalStartWithPatch;
+            while (y < scaledHeight - 1) {
+                hStretch = patchInfo.horizontalStartWithPatch;
+
+                int height = 0;
+                float vExtra = 0.0f;
+
+                float hWeightSum = 1.0f;
+                float hRemainder = remainderHorizontal;
+
+                while (x < scaledWidth - 1) {
+                    Rectangle r;
+                    if (!vStretch) {
+                        if (hStretch) {
+                            r = patchInfo.horizontalPatches.get(horizontalIndex++);
+                            float extra = r.width / horizontalPatchesSum;
+                            int width = (int) (extra * hRemainder / hWeightSum);
+                            hWeightSum -= extra;
+                            hRemainder -= width;
+                            g.drawImage(image, x, y, x + width, y + r.height, r.x, r.y,
+                                    r.x + r.width, r.y + r.height, null);
+                            x += width;
+                        } else {
+                            r = patchInfo.fixed.get(fixedIndex++);
+                            g.drawImage(image, x, y, x + r.width, y + r.height, r.x, r.y,
+                                    r.x + r.width, r.y + r.height, null);
+                            x += r.width;
+                        }
+                        height = r.height;
+                    } else {
+                        if (hStretch) {
+                            r = patchInfo.patches.get(patchIndex++);
+                            vExtra = r.height / verticalPatchesSum;
+                            height = (int) (vExtra * vRemainder / vWeightSum);
+                            float extra = r.width / horizontalPatchesSum;
+                            int width = (int) (extra * hRemainder / hWeightSum);
+                            hWeightSum -= extra;
+                            hRemainder -= width;
+                            g.drawImage(image, x, y, x + width, y + height, r.x, r.y,
+                                    r.x + r.width, r.y + r.height, null);
+                            x += width;
+                        } else {
+                            r = patchInfo.verticalPatches.get(verticalIndex++);
+                            vExtra = r.height / verticalPatchesSum;
+                            height = (int) (vExtra * vRemainder / vWeightSum);
+                            g.drawImage(image, x, y, x + r.width, y + height, r.x, r.y,
+                                    r.x + r.width, r.y + r.height, null);
+                            x += r.width;
+                        }
+
+                    }
+                    hStretch = !hStretch;
+                }
+                x = 0;
+                y += height;
+                if (vStretch) {
+                    vWeightSum -= vExtra;
+                    vRemainder -= height;
+                }
+                vStretch = !vStretch;
+            }
+
+            if (showPadding) {
+                g.setColor(PADDING_COLOR);
+                g.fillRect(patchInfo.horizontalPadding.first,
+                        patchInfo.verticalPadding.first,
+                        scaledWidth - patchInfo.horizontalPadding.first
+                                - patchInfo.horizontalPadding.second,
+                        scaledHeight - patchInfo.verticalPadding.first
+                                - patchInfo.verticalPadding.second);
+            }
+
+            g2.dispose();
+        }
+
+        @Override
+        public Dimension getPreferredSize() {
+            return size;
+        }
+    }
+}
\ No newline at end of file
diff --git a/draw9patch/src/test/java/com/android/draw9patch/ui/PatchInfoTest.java b/draw9patch/src/test/java/com/android/draw9patch/ui/PatchInfoTest.java
new file mode 100644
index 0000000..7ca4fdd
--- /dev/null
+++ b/draw9patch/src/test/java/com/android/draw9patch/ui/PatchInfoTest.java
@@ -0,0 +1,104 @@
+/*
+ *
+ *  Copyright (C) 2013 The Android Open Source Project
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package com.android.draw9patch.ui;
+
+import junit.framework.TestCase;
+
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+
+public class PatchInfoTest extends TestCase {
+    private BufferedImage createImage(String[] data) {
+        int h = data.length;
+        int w = data[0].length();
+        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+
+        for (int row = 0; row < h; row++) {
+            for (int col = 0; col < w; col++) {
+                char c = data[row].charAt(col);
+                image.setRGB(col, row, c == '*' ? PatchInfo.BLACK_TICK : 0);
+            }
+        }
+        return image;
+    }
+
+    public void testPatchInfo() {
+        BufferedImage image = createImage(new String[] {
+                "0123**6789",
+                "1........*",
+                "*........*",
+                "3........*",
+                "412*****89",
+        });
+        PatchInfo pi = new PatchInfo(image);
+
+        // The left and top patch markers don't begin from the first pixel
+        assertFalse(pi.horizontalStartWithPatch);
+        assertFalse(pi.verticalStartWithPatch);
+
+        // There should be one patch in the middle where the left and top patch markers intersect
+        assertEquals(1, pi.patches.size());
+        assertEquals(new Rectangle(4, 2, 2, 1), pi.patches.get(0));
+
+        // There should be 2 horizontal stretchable areas - area below the top marker but excluding
+        // the main patch
+        assertEquals(2, pi.horizontalPatches.size());
+        assertEquals(new Rectangle(4, 1, 2, 1), pi.horizontalPatches.get(0));
+        assertEquals(new Rectangle(4, 3, 2, 1), pi.horizontalPatches.get(1));
+
+        // Similarly, there should be 2 vertical stretchable areas
+        assertEquals(2, pi.verticalPatches.size());
+        assertEquals(new Rectangle(1, 2, 3, 1), pi.verticalPatches.get(0));
+        assertEquals(new Rectangle(6, 2, 3, 1), pi.verticalPatches.get(1));
+
+        // The should be 4 fixed regions - the regions that don't fall under the patches
+        assertEquals(4, pi.fixed.size());
+
+        // The horizontal padding is described by the bottom bar.
+        // In this case, there is a 2 pixel (pixels 1 & 2) padding at start and 1 pixel (pixel 8)
+        // padding at end
+        assertEquals(2, pi.horizontalPadding.first.intValue());
+        assertEquals(1, pi.horizontalPadding.second.intValue());
+
+        // The vertical padding is described by the bar at the right.
+        // In this case, there is no padding as the content area matches the image area
+        assertEquals(0, pi.verticalPadding.first.intValue());
+        assertEquals(0, pi.verticalPadding.second.intValue());
+    }
+
+    public void testPadding() {
+        BufferedImage image = createImage(new String[] {
+                "0123**6789",
+                "1.........",
+                "2.........",
+                "3........*",
+                "4........*",
+                "5***456789",
+        });
+        PatchInfo pi = new PatchInfo(image);
+
+        // 0 pixel padding at start and 5 pixel padding at the end (pixels 4 through 8 inclusive)
+        assertEquals(0, pi.horizontalPadding.first.intValue());
+        assertEquals(5, pi.horizontalPadding.second.intValue());
+
+        // 2 pixel padding at the start and 0 at the end
+        assertEquals(2, pi.verticalPadding.first.intValue());
+        assertEquals(0, pi.verticalPadding.second.intValue());
+    }
+}
