You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ye...@apache.org on 2010/05/10 18:11:51 UTC

svn commit: r942809 [1/3] - in /poi/trunk: ./ src/contrib/src/org/apache/poi/hssf/contrib/ src/documentation/content/xdocs/ src/examples/src/org/apache/poi/hssf/view/ src/examples/src/org/apache/poi/hssf/view/brush/ src/examples/src/org/apache/poi/ss/e...

Author: yegor
Date: Mon May 10 16:11:50 2010
New Revision: 942809

URL: http://svn.apache.org/viewvc?rev=942809&view=rev
Log:
Enhanced SViewer to support most border types, cell formats, and conditional formatting. Added ToHtml example that converts a spreadsheet into HTML, See Bugzilla #49066

Added:
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVBorder.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVFractionalFormat.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVRowHeader.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVSheetTable.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellEditor.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableModel.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableUtils.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/SViewer.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/SViewerPanel.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/BasicBrush.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/Brush.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/DoubleStroke.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/PendingPaintings.java
    poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/package.html
    poi/trunk/src/examples/src/org/apache/poi/ss/examples/html/
    poi/trunk/src/examples/src/org/apache/poi/ss/examples/html/HSSFHtmlHelper.java
    poi/trunk/src/examples/src/org/apache/poi/ss/examples/html/HtmlHelper.java
    poi/trunk/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java
    poi/trunk/src/examples/src/org/apache/poi/ss/examples/html/XSSFHtmlHelper.java
    poi/trunk/src/examples/src/org/apache/poi/ss/examples/html/excelStyle.css
    poi/trunk/src/examples/src/org/apache/poi/ss/examples/html/package.html
    poi/trunk/src/java/org/apache/poi/ss/format/
    poi/trunk/src/java/org/apache/poi/ss/format/CellDateFormatter.java
    poi/trunk/src/java/org/apache/poi/ss/format/CellElapsedFormatter.java
    poi/trunk/src/java/org/apache/poi/ss/format/CellFormat.java
    poi/trunk/src/java/org/apache/poi/ss/format/CellFormatCondition.java
    poi/trunk/src/java/org/apache/poi/ss/format/CellFormatPart.java
    poi/trunk/src/java/org/apache/poi/ss/format/CellFormatResult.java
    poi/trunk/src/java/org/apache/poi/ss/format/CellFormatType.java
    poi/trunk/src/java/org/apache/poi/ss/format/CellFormatter.java
    poi/trunk/src/java/org/apache/poi/ss/format/CellGeneralFormatter.java
    poi/trunk/src/java/org/apache/poi/ss/format/CellNumberFormatter.java
    poi/trunk/src/java/org/apache/poi/ss/format/CellTextFormatter.java
    poi/trunk/src/java/org/apache/poi/ss/format/package.html
    poi/trunk/src/ooxml/testcases/org/apache/poi/ss/format/
    poi/trunk/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java
    poi/trunk/src/testcases/org/apache/poi/ss/format/
    poi/trunk/src/testcases/org/apache/poi/ss/format/CellFormatTestBase.java
    poi/trunk/src/testcases/org/apache/poi/ss/format/TestCellFormat.java
    poi/trunk/src/testcases/org/apache/poi/ss/format/TestCellFormatCondition.java
    poi/trunk/test-data/spreadsheet/DateFormatTests.xlsx   (with props)
    poi/trunk/test-data/spreadsheet/ElapsedFormatTests.xlsx   (with props)
    poi/trunk/test-data/spreadsheet/FormatChoiceTests.xls   (with props)
    poi/trunk/test-data/spreadsheet/FormatChoiceTests.xlsx   (with props)
    poi/trunk/test-data/spreadsheet/FormatConditionTests.xlsx   (with props)
    poi/trunk/test-data/spreadsheet/GeneralFormatTests.xlsx   (with props)
    poi/trunk/test-data/spreadsheet/NumberFormatApproxTests.xlsx   (with props)
    poi/trunk/test-data/spreadsheet/NumberFormatTests.xlsx   (with props)
    poi/trunk/test-data/spreadsheet/TextFormatTests.xlsx   (with props)
Removed:
    poi/trunk/src/contrib/src/org/apache/poi/hssf/contrib/
Modified:
    poi/trunk/build.xml
    poi/trunk/src/documentation/content/xdocs/status.xml

Modified: poi/trunk/build.xml
URL: http://svn.apache.org/viewvc/poi/trunk/build.xml?rev=942809&r1=942808&r2=942809&view=diff
==============================================================================
--- poi/trunk/build.xml (original)
+++ poi/trunk/build.xml Mon May 10 16:11:50 2010
@@ -504,6 +504,11 @@ under the License.
                 <pathelement path="${ooxml.output.dir}"/>
             </classpath>
         </javac>
+        <copy todir="${examples.output.dir}">
+          <fileset dir="${examples.src}">
+            <include name="**/*.css"/>
+          </fileset>
+        </copy>
     </target>
 
     <target name="compile-ooxml" depends="compile-main,compile-scratchpad">

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=942809&r1=942808&r2=942809&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Mon May 10 16:11:50 2010
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.7-SNAPSHOT" date="2010-??-??">
+           <action dev="POI-DEVELOPERS" type="add">49066 - Worksheet/cell formatting, with view and HTML converter</action>
            <action dev="POI-DEVELOPERS" type="fix">49020 - Workaround Excel outputting invalid XML in button definitions by not closing BR tags</action>
            <action dev="POI-DEVELOPERS" type="fix">49050 - Improve performance of AbstractEscherHolderRecord when there are lots of Continue Records</action>
            <action dev="POI-DEVELOPERS" type="fix">49194 - Correct text size limit for OOXML .xlsx files</action>

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVBorder.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVBorder.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVBorder.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVBorder.java Mon May 10 16:11:50 2010
@@ -0,0 +1,564 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hssf.view;
+
+import java.awt.*;
+
+import javax.swing.border.AbstractBorder;
+
+import org.apache.poi.hssf.usermodel.HSSFCellStyle;
+
+/**
+ * This is an attempt to implement Excel style borders for the SheetViewer.
+ * Mostly just overrides stuff so the javadoc won't appear here but will 
+ * appear in the generated stuff.
+ * 
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height
+ */
+public class SVBorder extends AbstractBorder {
+  private Color northColor = null;
+  private Color eastColor = null;
+  private Color southColor = null;
+  private Color westColor = null;
+  private int northBorderType = HSSFCellStyle.BORDER_NONE;
+  private int eastBorderType =HSSFCellStyle.BORDER_NONE;
+  private int southBorderType = HSSFCellStyle.BORDER_NONE;
+  private int westBorderType = HSSFCellStyle.BORDER_NONE;
+  private boolean northBorder=false;
+  private boolean eastBorder=false;
+  private boolean southBorder=false;
+  private boolean westBorder=false;
+  private boolean selected = false;
+
+   public void setBorder(Color northColor, Color eastColor,
+                         Color southColor, Color westColor,
+                         int northBorderType, int eastBorderType,
+                         int southBorderType, int westBorderType,
+                         boolean selected) {
+     this.eastColor = eastColor;
+     this.southColor = southColor;
+     this.westColor = westColor;
+     this.northBorderType = northBorderType;
+     this.eastBorderType = eastBorderType;
+     this.southBorderType = southBorderType;
+     this.westBorderType = westBorderType;
+     this.northBorder=northBorderType != HSSFCellStyle.BORDER_NONE;
+     this.eastBorder=eastBorderType != HSSFCellStyle.BORDER_NONE;
+     this.southBorder=southBorderType != HSSFCellStyle.BORDER_NONE;
+     this.westBorder=westBorderType != HSSFCellStyle.BORDER_NONE;
+     this.selected = selected;
+   }
+
+   public void paintBorder(Component c, Graphics g, int x, int y, int width,
+                           int height) {
+      Color oldColor = g.getColor();
+
+
+     paintSelectedBorder(g, x, y, width, height);
+     paintNormalBorders(g, x, y, width, height);
+     paintDottedBorders(g, x, y, width, height);
+     paintDashedBorders(g, x, y, width, height);
+     paintDoubleBorders(g, x, y, width, height);
+     paintDashDotDotBorders(g, x, y, width, height);
+
+
+     g.setColor(oldColor);
+   }
+
+   /**
+    * Called by paintBorder to paint the border of a selected cell.
+    * The paramaters are the Graphics object, location and dimensions of the 
+    * cell.
+    */
+   private void paintSelectedBorder(Graphics g, int x, int y, int width,
+                                  int height) {
+     if (selected) {
+       //Need to setup thickness of 2
+       g.setColor(Color.black);
+       //paint the border
+       g.drawRect(x,y,width-1,height-1);
+
+       //paint the filled rectangle at the bottom left hand position
+       g.fillRect(x+width-5, y+height-5, 5, 5);
+     }
+   }
+
+
+   /**
+    * Called by paintBorder to paint the various versions of normal line
+    * borders for a cell.  
+    */
+   private void paintNormalBorders(Graphics g, int x, int y, int width,
+                                  int height) {
+
+      if (northBorder &&
+             ((northBorderType == HSSFCellStyle.BORDER_THIN) ||
+              (northBorderType == HSSFCellStyle.BORDER_MEDIUM) ||
+              (northBorderType == HSSFCellStyle.BORDER_THICK)
+             )
+         ) {
+
+        int thickness = getThickness(northBorderType);
+
+      	g.setColor(northColor);
+
+        for (int k=0; k < thickness; k++) {
+           g.drawLine(x,y+k,width,y+k);
+        }
+      }
+
+      if (eastBorder &&
+             ((eastBorderType == HSSFCellStyle.BORDER_THIN) ||
+              (eastBorderType == HSSFCellStyle.BORDER_MEDIUM) ||
+              (eastBorderType == HSSFCellStyle.BORDER_THICK)
+             )
+         ) {
+
+        int thickness = getThickness(eastBorderType);
+
+      	g.setColor(eastColor);
+
+        for (int k=0; k < thickness; k++) {
+           g.drawLine(width-k,y,width-k,height);
+        }
+      }
+
+      if (southBorder &&
+              ((southBorderType == HSSFCellStyle.BORDER_THIN) ||
+               (southBorderType == HSSFCellStyle.BORDER_MEDIUM) ||
+               (southBorderType == HSSFCellStyle.BORDER_THICK)
+              )
+         ) {
+
+        int thickness = getThickness(southBorderType);
+
+      	g.setColor(southColor);
+        for (int k=0; k < thickness; k++) {
+           g.drawLine(x,height - k,width,height - k);
+        }
+      }
+
+      if (westBorder &&
+             ((westBorderType == HSSFCellStyle.BORDER_THIN) ||
+              (westBorderType == HSSFCellStyle.BORDER_MEDIUM) ||
+              (westBorderType == HSSFCellStyle.BORDER_THICK)
+             )
+         ) {
+
+        int thickness = getThickness(westBorderType);
+
+      	g.setColor(westColor);
+
+        for (int k=0; k < thickness; k++) {
+           g.drawLine(x+k,y,x+k,height);
+        }
+      }
+   }
+
+   /**
+    * Called by paintBorder to paint the dotted line
+    * borders for a cell.  
+    */
+   private void paintDottedBorders(Graphics g, int x, int y, int width,
+                                  int height) {
+      if (northBorder &&
+             northBorderType == HSSFCellStyle.BORDER_DOTTED) {
+        int thickness = getThickness(northBorderType);
+
+      	g.setColor(northColor);
+
+        for (int k=0; k < thickness; k++) {
+           for (int xc = x; xc < width; xc=xc+2) {
+             g.drawLine(xc,y+k,xc,y+k);
+           }
+        }
+      }
+
+      if (eastBorder &&
+              eastBorderType == HSSFCellStyle.BORDER_DOTTED
+         ) {
+
+        int thickness = getThickness(eastBorderType);
+        thickness++; //need for dotted borders to show up east
+
+      	g.setColor(eastColor);
+
+        for (int k=0; k < thickness; k++) {
+           for (int yc=y;yc < height; yc=yc+2) {
+                g.drawLine(width-k,yc,width-k,yc);
+           }
+        }
+      }
+
+      if (southBorder &&
+              southBorderType == HSSFCellStyle.BORDER_DOTTED
+         ) {
+
+        int thickness = getThickness(southBorderType);
+        thickness++;
+      	g.setColor(southColor);
+        for (int k=0; k < thickness; k++) {
+           for (int xc = x; xc < width; xc=xc+2) {
+             g.drawLine(xc,height-k,xc,height-k);
+           }
+        }
+      }
+
+      if (westBorder &&
+            westBorderType == HSSFCellStyle.BORDER_DOTTED
+         ) {
+
+        int thickness = getThickness(westBorderType);
+//        thickness++;
+
+      	g.setColor(westColor);
+
+        for (int k=0; k < thickness; k++) {
+           for (int yc=y;yc < height; yc=yc+2) {
+                g.drawLine(x+k,yc,x+k,yc);
+           }
+        }
+      }
+   }
+
+   /**
+    * Called by paintBorder to paint the various versions of dotted line
+    * borders for a cell.  
+    */
+   private void paintDashedBorders(Graphics g, int x, int y, int width,
+                                  int height) {
+      if (northBorder &&
+             ((northBorderType == HSSFCellStyle.BORDER_DASHED) ||
+              (northBorderType == HSSFCellStyle.BORDER_HAIR))
+         ) {
+        int thickness = getThickness(northBorderType);
+
+        int dashlength = 1;
+
+        if (northBorderType == HSSFCellStyle.BORDER_DASHED)
+           dashlength = 2;
+
+      	g.setColor(northColor);
+
+        for (int k=0; k < thickness; k++) {
+           for (int xc = x; xc < width; xc=xc+5) {
+             g.drawLine(xc,y+k,xc+dashlength,y+k);
+           }
+        }
+      }
+
+      if (eastBorder &&
+              ((eastBorderType == HSSFCellStyle.BORDER_DASHED) ||
+               (eastBorderType == HSSFCellStyle.BORDER_HAIR))
+         ) {
+
+        int thickness = getThickness(eastBorderType);
+        thickness++; //need for dotted borders to show up east
+
+
+        int dashlength = 1;
+
+        if (eastBorderType == HSSFCellStyle.BORDER_DASHED)
+           dashlength = 2;
+
+      	g.setColor(eastColor);
+
+        for (int k=0; k < thickness; k++) {
+           for (int yc=y;yc < height; yc=yc+5) {
+                g.drawLine(width-k,yc,width-k,yc+dashlength);
+           }
+        }
+      }
+
+      if (southBorder &&
+              ((southBorderType == HSSFCellStyle.BORDER_DASHED) ||
+               (southBorderType == HSSFCellStyle.BORDER_HAIR))
+         ) {
+
+        int thickness = getThickness(southBorderType);
+        thickness++;
+
+        int dashlength = 1;
+
+        if (southBorderType == HSSFCellStyle.BORDER_DASHED)
+           dashlength = 2;
+
+      	g.setColor(southColor);
+        for (int k=0; k < thickness; k++) {
+           for (int xc = x; xc < width; xc=xc+5) {
+             g.drawLine(xc,height-k,xc+dashlength,height-k);
+           }
+        }
+      }
+
+      if (westBorder &&
+            ((westBorderType == HSSFCellStyle.BORDER_DASHED) ||
+             (westBorderType == HSSFCellStyle.BORDER_HAIR))
+         ) {
+
+        int thickness = getThickness(westBorderType);
+//        thickness++;
+
+        int dashlength = 1;
+
+        if (westBorderType == HSSFCellStyle.BORDER_DASHED)
+           dashlength = 2;
+
+      	g.setColor(westColor);
+
+        for (int k=0; k < thickness; k++) {
+           for (int yc=y;yc < height; yc=yc+5) {
+                g.drawLine(x+k,yc,x+k,yc+dashlength);
+           }
+        }
+      }
+   }
+
+   /**
+    * Called by paintBorder to paint the double line
+    * borders for a cell.  
+    */
+   private void paintDoubleBorders(Graphics g, int x, int y, int width,
+                                  int height) {
+      if (northBorder &&
+             northBorderType == HSSFCellStyle.BORDER_DOUBLE) {
+
+      	g.setColor(northColor);
+
+        int leftx=x;
+        int rightx=width;
+
+                // if there are borders on the west or east then
+                // the second line shouldn't cross them
+        if (westBorder)
+           leftx = x+3;
+
+        if (eastBorder)
+           rightx = width-3;
+
+           g.drawLine(x,y,width,y);
+           g.drawLine(leftx,y+2,rightx,y+2);
+      }
+
+      if (eastBorder &&
+              eastBorderType == HSSFCellStyle.BORDER_DOUBLE
+         ) {
+
+        int thickness = getThickness(eastBorderType);
+        thickness++; //need for dotted borders to show up east
+
+      	g.setColor(eastColor);
+
+        int topy=y;
+        int bottomy=height;
+
+        if (northBorder)
+          topy=y+3;
+
+        if (southBorder)
+            bottomy=height-3;
+
+        g.drawLine(width-1,y,width-1,height);
+        g.drawLine(width-3,topy,width-3,bottomy);
+      }
+
+      if (southBorder &&
+              southBorderType == HSSFCellStyle.BORDER_DOUBLE
+         ) {
+
+      	g.setColor(southColor);
+
+        int leftx=y;
+        int rightx=width;
+
+        if (westBorder)
+           leftx=x+3;
+
+        if (eastBorder)
+           rightx=width-3;
+
+
+        g.drawLine(x,height - 1,width,height - 1);
+        g.drawLine(leftx,height - 3,rightx,height - 3);
+      }
+
+      if (westBorder &&
+            westBorderType == HSSFCellStyle.BORDER_DOUBLE
+         ) {
+
+        int thickness = getThickness(westBorderType);
+//        thickness++;
+
+      	g.setColor(westColor);
+
+        int topy=y;
+        int bottomy=height-3;
+
+        if (northBorder)
+           topy=y+2;
+
+        if (southBorder)
+           bottomy=height-3;
+
+        g.drawLine(x,y,x,height);
+        g.drawLine(x+2,topy,x+2,bottomy);
+      }
+   }
+
+   /**
+    * Called by paintBorder to paint the various versions of dash dot dot line
+    * borders for a cell.  
+    */
+   private void paintDashDotDotBorders(Graphics g, int x, int y, int width,
+                                  int height) {
+      if (northBorder &&
+             ((northBorderType == HSSFCellStyle.BORDER_DASH_DOT_DOT) ||
+              (northBorderType == HSSFCellStyle.BORDER_MEDIUM_DASH_DOT_DOT))
+         ) {
+        int thickness = getThickness(northBorderType);
+
+      	g.setColor(northColor);
+        for (int l=x; l < width;) {
+          l=l+drawDashDotDot(g, l, y, thickness, true, true);
+        }
+
+      }
+
+      if (eastBorder &&
+              ((eastBorderType == HSSFCellStyle.BORDER_DASH_DOT_DOT) ||
+               (eastBorderType == HSSFCellStyle.BORDER_MEDIUM_DASH_DOT_DOT))
+         ) {
+
+        int thickness = getThickness(eastBorderType);
+
+      	g.setColor(eastColor);
+
+        for (int l=y;l < height;) {
+          //System.err.println("drawing east");
+          l=l+drawDashDotDot(g,width-1,l,thickness,false,false);
+        }
+      }
+
+      if (southBorder &&
+              ((southBorderType == HSSFCellStyle.BORDER_DASH_DOT_DOT) ||
+               (southBorderType == HSSFCellStyle.BORDER_MEDIUM_DASH_DOT_DOT))
+         ) {
+
+        int thickness = getThickness(southBorderType);
+
+      	g.setColor(southColor);
+
+        for (int l=x; l < width;) {
+          //System.err.println("drawing south");
+          l=l+drawDashDotDot(g, l, height-1, thickness, true, false);
+        }
+      }
+
+      if (westBorder &&
+            ((westBorderType == HSSFCellStyle.BORDER_DASH_DOT_DOT) ||
+             (westBorderType == HSSFCellStyle.BORDER_MEDIUM_DASH_DOT_DOT))
+         ) {
+
+        int thickness = getThickness(westBorderType);
+
+      	g.setColor(westColor);
+
+        for (int l=y;l < height;) {
+          //System.err.println("drawing west");
+          l=l+drawDashDotDot(g,x,l,thickness,false,true);
+        }
+
+      }
+   }
+
+   /**
+    *  Draws one dash dot dot horizontally or vertically with thickness drawn
+    *  incrementally to either the right or left.
+    *
+    *  @param g graphics object for drawing with
+    *  @param x the x origin of the line
+    *  @param y the y origin of the line
+    *  @param thickness the thickness of the line
+    *  @param horizontal or vertical (true for horizontal)
+    *  @param right/bottom or left/top thickness (true for right or top),
+    *         if true then the x or y origin will be incremented to provide
+    *         thickness, if false, they'll be decremented.  For vertical
+    *         borders, x is incremented or decremented, for horizontal its y.
+    *         Just set to true for north and west, and false for east and
+    *         south.
+    *  @returns length - returns the length of the line.
+    */
+   private int drawDashDotDot(Graphics g,int x, int y, int thickness,
+                              boolean horizontal,
+                              boolean rightBottom) {
+
+      for (int t=0; t < thickness; t++) {
+         if (!rightBottom) {
+            t = 0 - t; //add negative thickness so we go the other way
+                       //then we'll decrement instead of increment.
+         }
+         if (horizontal) {
+            g.drawLine(x,y+t,x+5,y+t);
+            g.drawLine(x+8,y+t,x+10,y+t);
+            g.drawLine(x+13,y+t,x+15,y+t);
+         } else {
+            g.drawLine(x+t,y,x+t,y+5);
+            g.drawLine(x+t,y+8,x+t,y+10);
+            g.drawLine(x+t,y+13,x+t,y+15);
+         }
+      }
+      return 18;
+   }
+
+   /**
+    * @returns the line thickness for a border based on border type
+    */
+   private int getThickness(int thickness) {
+       int retval=1;
+       switch (thickness) {
+           case HSSFCellStyle.BORDER_THIN:
+             retval=2;
+             break;
+           case HSSFCellStyle.BORDER_MEDIUM:
+             retval=3;
+             break;
+           case HSSFCellStyle.BORDER_THICK:
+             retval=4;
+             break;
+           case HSSFCellStyle.BORDER_DASHED:
+             retval=1;
+             break;
+           case HSSFCellStyle.BORDER_DASH_DOT_DOT:
+             retval=1;
+             break;
+           case HSSFCellStyle.BORDER_MEDIUM_DASH_DOT_DOT:
+             retval=3;
+             break;
+           case HSSFCellStyle.BORDER_HAIR:
+             retval=1;
+             break;
+           default:
+             retval=1;
+       }
+       return retval;
+   }
+
+
+}

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVFractionalFormat.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVFractionalFormat.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVFractionalFormat.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVFractionalFormat.java Mon May 10 16:11:50 2010
@@ -0,0 +1,220 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hssf.view;
+
+import java.text.*;
+
+/**
+ * This class is used to format cells into their fractional format.
+ *
+ * I cant be 100% sure that the same fractional value will be displayed as in
+ * excel but then again it is a lossy formating mode anyway
+ *
+ * @author     Jason Height
+ * @since      15 July 2002
+ */
+public class SVFractionalFormat extends Format {
+  private short ONE_DIGIT = 1;
+  private short TWO_DIGIT = 2;
+  private short THREE_DIGIT = 3;
+  private short UNITS = 4;
+  private int units = 1;
+  private short mode = -1;
+
+  /** Constructs a new FractionalFormatter
+   *
+   *  The formatStr defines how the number will be formatted
+   *  # ?/? Up to one digit
+   *  # ??/?? Up to two digits
+   *  # ???/??? Up to three digits
+   *  # ?/2 In halves
+   *  # ?/4 In quarters
+   *  # ?/8 In eighths
+   *  # ?/16 In sixteenths
+   *  # ?/10 In tenths
+   *  # ?/100 In hundredths
+   */
+  public SVFractionalFormat(String formatStr) {
+    if ("# ?/?".equals(formatStr))
+      mode = ONE_DIGIT;
+    else if ("# ??/??".equals(formatStr))
+      mode = TWO_DIGIT;
+    else if ("# ???/???".equals(formatStr))
+      mode = THREE_DIGIT;
+    else if ("# ?/2".equals(formatStr)) {
+      mode = UNITS;
+      units = 2;
+    } else if ("# ?/4".equals(formatStr)) {
+      mode = UNITS;
+      units = 4;
+    } else if ("# ?/8".equals(formatStr)) {
+      mode = UNITS;
+      units = 8;
+    } else if ("# ?/16".equals(formatStr)) {
+      mode = UNITS;
+      units = 16;
+    } else if ("# ?/10".equals(formatStr)) {
+      mode = UNITS;
+      units = 10;
+    } else if ("# ?/100".equals(formatStr)) {
+      mode = UNITS;
+      units = 100;
+    }
+  }
+
+  /**
+   *  Returns a fractional string representation of a double to a maximum denominator size
+   *
+   * This code has been translated to java from the following web page.
+   * http://www.codeproject.com/cpp/fraction.asp
+   * Originally coded in c++ By Dean Wyant  dwyant@mindspring.com
+   * The code on the web page is freely available.
+   *
+   * @param  f       Description of the Parameter
+   * @param  MaxDen  Description of the Parameter
+   * @return         Description of the Return Value
+   */
+  private String format(final double f, final int MaxDen) {
+    long Whole = (long)f;
+    int sign = 1;
+    if (f < 0) {
+      sign = -1;
+    }
+    double Precision = 0.00001;
+    double AllowedError = Precision;
+    double d = Math.abs(f);
+    d -= Whole;
+    double Frac = d;
+    double Diff = Frac;
+    long Num = 1;
+    long Den = 0;
+    long A = 0;
+    long B = 0;
+    long i = 0;
+    if (Frac > Precision) {
+      while (true) {
+        d = 1.0 / d;
+        i = (long) (d + Precision);
+        d -= i;
+        if (A > 0) {
+          Num = i * Num + B;
+        }
+        Den = (long) (Num / Frac + 0.5);
+        Diff = Math.abs((double) Num / Den - Frac);
+        if (Den > MaxDen) {
+          if (A > 0) {
+            Num = A;
+            Den = (long) (Num / Frac + 0.5);
+            Diff = Math.abs((double) Num / Den - Frac);
+          } else {
+            Den = MaxDen;
+            Num = 1;
+            Diff = Math.abs((double) Num / Den - Frac);
+            if (Diff > Frac) {
+              Num = 0;
+              Den = 1;
+              // Keeps final check below from adding 1 and keeps Den from being 0
+              Diff = Frac;
+            }
+          }
+          break;
+        }
+        if ((Diff <= AllowedError) || (d < Precision)) {
+          break;
+        }
+        Precision = AllowedError / Diff;
+        // This calcualtion of Precision does not always provide results within
+        // Allowed Error. It compensates for loss of significant digits that occurs.
+        // It helps to round the inprecise reciprocal values to i.
+        B = A;
+        A = Num;
+      }
+    }
+    if (Num == Den) {
+      Whole++;
+      Num = 0;
+      Den = 0;
+    } else if (Den == 0) {
+      Num = 0;
+    }
+    if (sign < 0) {
+      if (Whole == 0) {
+        Num = -Num;
+      } else {
+        Whole = -Whole;
+      }
+    }
+    return new StringBuffer().append(Whole).append(" ").append(Num).append("/").append(Den).toString();
+  }
+
+  /** This method formats the double in the units specified.
+   *  The usints could be any number but in this current implementation it is
+   *  halves (2), quaters (4), eigths (8) etc
+   */
+  private String formatUnit(double f, int units) {
+    long Whole = (long)f;
+    f -= Whole;
+    long Num = Math.round(f * units);
+
+    return new StringBuffer().append(Whole).append(" ").append(Num).append("/").append(units).toString();
+  }
+
+  public final String format(double val) {
+    if (mode == ONE_DIGIT) {
+      return format(val, 9);
+    } else if (mode == TWO_DIGIT) {
+      return format(val, 99);
+    } else if (mode == THREE_DIGIT) {
+      return format(val, 999);
+    } else if (mode == UNITS) {
+      return formatUnit(val , units);
+    }
+    throw new RuntimeException("Unexpected Case");
+  }
+
+  public StringBuffer format(Object obj,
+                                      StringBuffer toAppendTo,
+                                      FieldPosition pos) {
+    if (obj instanceof Number) {
+      toAppendTo.append(format(((Number)obj).doubleValue()));
+      return toAppendTo;
+    }
+    throw new IllegalArgumentException("Can only handle Numbers");
+  }
+
+  public Object parseObject(String source,
+                                   ParsePosition status) {
+    //JMH TBD
+    return null;
+  }
+
+  public Object parseObject(String source)
+                   throws ParseException {
+    //JMH TBD
+    return null;
+  }
+
+  public Object clone() {
+    //JMH TBD
+    return null;
+  }
+
+
+}

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVRowHeader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVRowHeader.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVRowHeader.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVRowHeader.java Mon May 10 16:11:50 2010
@@ -0,0 +1,96 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hssf.view;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.table.*;
+
+import org.apache.poi.hssf.usermodel.*;
+
+/**
+ * This class presents the row header to the table.
+ *
+ *
+ * @author Jason Height
+ */
+public class SVRowHeader extends JList {
+  /** This model simply returns an integer number up to the number of rows
+   *  that are present in the sheet.
+   *
+   */
+  private class SVRowHeaderModel extends AbstractListModel {
+    private HSSFSheet sheet;
+
+    public SVRowHeaderModel(HSSFSheet sheet) {
+      this.sheet = sheet;
+    }
+
+    public int getSize() {
+    	return sheet.getLastRowNum() + 1;
+    }
+    public Object getElementAt(int index) {
+      return Integer.toString(index+1);
+    }
+  }
+
+  /** Renderes the row number*/
+  private class RowHeaderRenderer extends JLabel implements ListCellRenderer {
+    private HSSFSheet sheet;
+    private int extraHeight;
+
+    RowHeaderRenderer(HSSFSheet sheet, JTable table, int extraHeight) {
+      this.sheet = sheet;
+      this.extraHeight = extraHeight;
+      JTableHeader header = table.getTableHeader();
+      setOpaque(true);
+      setBorder(UIManager.getBorder("TableHeader.cellBorder"));
+      setHorizontalAlignment(CENTER);
+      setForeground(header.getForeground());
+      setBackground(header.getBackground());
+      setFont(header.getFont());
+    }
+
+    public Component getListCellRendererComponent( JList list,
+           Object value, int index, boolean isSelected, boolean cellHasFocus) {
+      Dimension d = getPreferredSize();
+      HSSFRow row = sheet.getRow(index);
+      int rowHeight;
+      if(row == null) {
+    	  rowHeight = (int)sheet.getDefaultRowHeightInPoints();
+      } else {
+    	  rowHeight = (int)row.getHeightInPoints();
+      }
+      d.height = rowHeight+extraHeight;
+      setPreferredSize(d);
+      setText((value == null) ? "" : value.toString());
+      return this;
+    }
+  }
+
+  public SVRowHeader(HSSFSheet sheet, JTable table, int extraHeight) {
+    ListModel lm = new SVRowHeaderModel(sheet);
+    this.setModel(lm);
+
+    setFixedCellWidth(50);
+    setCellRenderer(new RowHeaderRenderer(sheet, table, extraHeight));
+  }
+}

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVSheetTable.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVSheetTable.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVSheetTable.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVSheetTable.java Mon May 10 16:11:50 2010
@@ -0,0 +1,241 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hssf.view;
+
+import org.apache.poi.hssf.view.brush.PendingPaintings;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.*;
+import javax.swing.text.JTextComponent;
+import java.awt.*;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
+
+/**
+ * This class is a table that represents the values in a single worksheet.
+ *
+ * @author Ken Arnold, Industrious Media LLC
+ */
+public class SVSheetTable extends JTable {
+  private final HSSFSheet sheet;
+  private final PendingPaintings pendingPaintings;
+  private FormulaDisplayListener formulaListener;
+  private JScrollPane scroll;
+
+  private static final Color HEADER_BACKGROUND = new Color(235, 235, 235);
+
+  /**
+   * This field is the magic number to convert from a Character width to a java
+   * pixel width.
+   * <p/>
+   * When the "normal" font size in a workbook changes, this effects all of the
+   * heights and widths. Unfortunately there is no way to retrieve this
+   * information, hence the MAGIC number.
+   * <p/>
+   * This number may only work for the normal style font size of Arial size 10.
+   */
+  private static final int magicCharFactor = 7;
+
+  private class HeaderCell extends JLabel {
+    private final int row;
+
+    public HeaderCell(Object value, int row) {
+      super(value.toString(), CENTER);
+      this.row = row;
+      setBackground(HEADER_BACKGROUND);
+      setOpaque(true);
+      setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
+      setRowSelectionAllowed(false);
+    }
+
+    @Override
+    public Dimension getPreferredSize() {
+      Dimension d = super.getPreferredSize();
+      if (row >= 0) {
+        d.height = getRowHeight(row);
+      }
+      return d;
+    }
+
+    @Override
+    public Dimension getMaximumSize() {
+      Dimension d = super.getMaximumSize();
+      if (row >= 0) {
+        d.height = getRowHeight(row);
+      }
+      return d;
+    }
+
+    @Override
+    public Dimension getMinimumSize() {
+      Dimension d = super.getMinimumSize();
+      if (row >= 0) {
+        d.height = getRowHeight(row);
+      }
+      return d;
+    }
+  }
+
+  private class HeaderCellRenderer implements TableCellRenderer {
+    public Component getTableCellRendererComponent(JTable table, Object value,
+        boolean isSelected, boolean hasFocus, int row, int column) {
+
+      return new HeaderCell(value, row);
+    }
+  }
+
+  private class FormulaDisplayListener implements ListSelectionListener {
+    private final JTextComponent formulaDisplay;
+
+    public FormulaDisplayListener(JTextComponent formulaDisplay) {
+      this.formulaDisplay = formulaDisplay;
+    }
+
+    public void valueChanged(ListSelectionEvent e) {
+      int row = getSelectedRow();
+      int col = getSelectedColumn();
+      if (row < 0 || col < 0) {
+        return;
+      }
+
+      if (e.getValueIsAdjusting()) {
+        return;
+      }
+
+      HSSFCell cell = (HSSFCell) getValueAt(row, col);
+      String formula = "";
+      if (cell != null) {
+        if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
+          formula = cell.getCellFormula();
+        } else {
+          formula = cell.toString();
+        }
+        if (formula == null)
+          formula = "";
+      }
+      formulaDisplay.setText(formula);
+    }
+  }
+
+  public SVSheetTable(HSSFSheet sheet) {
+    super(new SVTableModel(sheet));
+    this.sheet = sheet;
+
+    setIntercellSpacing(new Dimension(0, 0));
+    setAutoResizeMode(AUTO_RESIZE_OFF);
+    JTableHeader header = getTableHeader();
+    header.setDefaultRenderer(new HeaderCellRenderer());
+    pendingPaintings = new PendingPaintings(this);
+
+    //Set the columns the correct size
+    TableColumnModel columns = getColumnModel();
+    for (int i = 0; i < columns.getColumnCount(); i++) {
+      TableColumn column = columns.getColumn(i);
+      int width = sheet.getColumnWidth(i);
+      //256 is because the width is in 256ths of a character
+      column.setPreferredWidth(width / 256 * magicCharFactor);
+    }
+
+    Toolkit t = getToolkit();
+    int res = t.getScreenResolution();
+    TableModel model = getModel();
+    for (int i = 0; i < model.getRowCount(); i++) {
+      Row row = sheet.getRow(i - sheet.getFirstRowNum());
+      if (row != null) {
+        short h = row.getHeight();
+        int height = Math.round(Math.max(1, h / (res / 70 * 20) + 3));
+        System.out.printf("%d: %d (%d @ %d)%n", i, height, h, res);
+        setRowHeight(i, height);
+      }
+    }
+
+    addHierarchyListener(new HierarchyListener() {
+      public void hierarchyChanged(HierarchyEvent e) {
+        if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0) {
+          Container changedParent = e.getChangedParent();
+          if (changedParent instanceof JViewport) {
+            Container grandparent = changedParent.getParent();
+            if (grandparent instanceof JScrollPane) {
+              JScrollPane jScrollPane = (JScrollPane) grandparent;
+              setupScroll(jScrollPane);
+            }
+          }
+        }
+      }
+    });
+  }
+
+  public void setupScroll(JScrollPane scroll) {
+    if (scroll == this.scroll)
+      return;
+
+    this.scroll = scroll;
+    if (scroll == null)
+      return;
+
+    SVRowHeader rowHeader = new SVRowHeader(sheet, this, 0);
+    scroll.setRowHeaderView(rowHeader);
+    scroll.setCorner(JScrollPane.UPPER_LEADING_CORNER, headerCell("?"));
+  }
+
+  public void setFormulaDisplay(JTextComponent formulaDisplay) {
+    ListSelectionModel rowSelMod = getSelectionModel();
+    ListSelectionModel colSelMod = getColumnModel().getSelectionModel();
+
+    if (formulaDisplay == null) {
+      rowSelMod.removeListSelectionListener(formulaListener);
+      colSelMod.removeListSelectionListener(formulaListener);
+      formulaListener = null;
+    }
+
+    if (formulaDisplay != null) {
+      formulaListener = new FormulaDisplayListener(formulaDisplay);
+      rowSelMod.addListSelectionListener(formulaListener);
+      colSelMod.addListSelectionListener(formulaListener);
+    }
+  }
+
+  public JTextComponent getFormulaDisplay() {
+    if (formulaListener == null)
+      return null;
+    else
+      return formulaListener.formulaDisplay;
+  }
+
+  public Component headerCell(String text) {
+    return new HeaderCell(text, -1);
+  }
+
+  @Override
+  public void paintComponent(Graphics g1) {
+    Graphics2D g = (Graphics2D) g1;
+
+    pendingPaintings.clear();
+
+    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+        RenderingHints.VALUE_ANTIALIAS_ON);
+    super.paintComponent(g);
+
+    pendingPaintings.paint(g);
+  }
+}
\ No newline at end of file

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellEditor.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellEditor.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellEditor.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellEditor.java Mon May 10 16:11:50 2010
@@ -0,0 +1,203 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hssf.view;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import javax.swing.*;
+import javax.swing.table.*;
+
+import org.apache.poi.hssf.usermodel.*;
+import org.apache.poi.hssf.util.HSSFColor;
+
+/**
+ * Sheet Viewer Table Cell Editor -- not commented via javadoc as it
+ * nearly completely consists of overridden methods.
+ *
+ * @author     Jason Height
+ */
+public class SVTableCellEditor extends AbstractCellEditor implements TableCellEditor, ActionListener {
+  private static final Color black = getAWTColor(new HSSFColor.BLACK());
+  private static final Color white = getAWTColor(new HSSFColor.WHITE());
+  private Hashtable colors = HSSFColor.getIndexHash();
+
+
+  private HSSFWorkbook wb;
+  private JTextField editor;
+
+  private HSSFCell editorValue;
+
+
+  public SVTableCellEditor(HSSFWorkbook wb) {
+    this.wb = wb;
+    this.editor = new JTextField();
+  }
+
+
+  /**
+   *  Gets the cellEditable attribute of the SVTableCellEditor object
+   *
+   * @return    The cellEditable value
+   */
+  public boolean isCellEditable(java.util.EventObject e) {
+    if (e instanceof MouseEvent) {
+      return ((MouseEvent) e).getClickCount() >= 2;
+    }
+    return false;
+  }
+
+
+  public boolean shouldSelectCell(EventObject anEvent) {
+    return true;
+  }
+
+
+  public boolean startCellEditing(EventObject anEvent) {
+    System.out.println("Start Cell Editing");
+    return true;
+  }
+
+
+  public boolean stopCellEditing() {
+    System.out.println("Stop Cell Editing");
+    fireEditingStopped();
+    return true;
+  }
+
+
+  public void cancelCellEditing() {
+    System.out.println("Cancel Cell Editing");
+    fireEditingCanceled();
+  }
+
+
+  public void actionPerformed(ActionEvent e) {
+    System.out.println("Action performed");
+    stopCellEditing();
+  }
+
+
+  /**
+   *  Gets the cellEditorValue attribute of the SVTableCellEditor object
+   *
+   * @return    The cellEditorValue value
+   */
+  public Object getCellEditorValue() {
+    System.out.println("GetCellEditorValue");
+    //JMH Look at when this method is called. Should it return a HSSFCell?
+    return editor.getText();
+  }
+
+
+  /**
+   *  Gets the tableCellEditorComponent attribute of the SVTableCellEditor object
+   *
+   * @return             The tableCellEditorComponent value
+   */
+  public Component getTableCellEditorComponent(JTable table, Object value,
+      boolean isSelected,
+      int row,
+      int column) {
+    System.out.println("GetTableCellEditorComponent");
+    HSSFCell cell = (HSSFCell) value;
+    if (cell != null) {
+          HSSFCellStyle style = cell.getCellStyle();
+          HSSFFont f = wb.getFontAt(style.getFontIndex());
+          boolean isbold = f.getBoldweight() > HSSFFont.BOLDWEIGHT_NORMAL;
+          boolean isitalics = f.getItalic();
+
+          int fontstyle = Font.PLAIN;
+
+          if (isbold) fontstyle = Font.BOLD;
+          if (isitalics) fontstyle = fontstyle | Font.ITALIC;
+
+          int fontheight = f.getFontHeightInPoints();
+          if (fontheight == 9) fontheight = 10; //fix for stupid ol Windows
+
+          Font font = new Font(f.getFontName(),fontstyle,fontheight);
+          editor.setFont(font);
+
+          if (style.getFillPattern() == HSSFCellStyle.SOLID_FOREGROUND) {
+            editor.setBackground(getAWTColor(style.getFillForegroundColor(), white));
+          } else editor.setBackground(white);
+
+          editor.setForeground(getAWTColor(f.getColor(), black));
+
+
+      //Set the value that is rendered for the cell
+      switch (cell.getCellType()) {
+        case HSSFCell.CELL_TYPE_BLANK:
+          editor.setText("");
+          break;
+        case HSSFCell.CELL_TYPE_BOOLEAN:
+          if (cell.getBooleanCellValue()) {
+            editor.setText("true");
+          } else {
+            editor.setText("false");
+          }
+          break;
+        case HSSFCell.CELL_TYPE_NUMERIC:
+          editor.setText(Double.toString(cell.getNumericCellValue()));
+          break;
+        case HSSFCell.CELL_TYPE_STRING:
+          editor.setText(cell.getRichStringCellValue().getString());
+          break;
+        case HSSFCell.CELL_TYPE_FORMULA:
+        default:
+          editor.setText("?");
+      }
+      switch (style.getAlignment()) {
+        case HSSFCellStyle.ALIGN_LEFT:
+        case HSSFCellStyle.ALIGN_JUSTIFY:
+        case HSSFCellStyle.ALIGN_FILL:
+          editor.setHorizontalAlignment(SwingConstants.LEFT);
+          break;
+        case HSSFCellStyle.ALIGN_CENTER:
+        case HSSFCellStyle.ALIGN_CENTER_SELECTION:
+          editor.setHorizontalAlignment(SwingConstants.CENTER);
+          break;
+        case HSSFCellStyle.ALIGN_GENERAL:
+        case HSSFCellStyle.ALIGN_RIGHT:
+          editor.setHorizontalAlignment(SwingConstants.RIGHT);
+          break;
+        default:
+          editor.setHorizontalAlignment(SwingConstants.LEFT);
+          break;
+      }
+
+    }
+    return editor;
+  }
+
+    /** This method retrieves the AWT Color representation from the colour hash table
+     *
+     */
+    private final Color getAWTColor(int index, Color deflt) {
+      HSSFColor clr = (HSSFColor)colors.get(Integer.valueOf(index));
+      if (clr == null) return deflt;
+      return getAWTColor(clr);
+    }
+
+    private static final Color getAWTColor(HSSFColor clr) {
+      short[] rgb = clr.getTriplet();
+      return new Color(rgb[0],rgb[1],rgb[2]);
+    }
+}

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java Mon May 10 16:11:50 2010
@@ -0,0 +1,274 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hssf.view;
+
+import javax.swing.*;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.border.*;
+
+import java.awt.Component;
+import java.awt.Color;
+import java.awt.Rectangle;
+
+import java.io.Serializable;
+import java.text.*;
+
+import org.apache.poi.hssf.usermodel.*;
+
+
+/**
+ * Sheet Viewer Table Cell Render -- not commented via javadoc as it
+ * nearly completely consists of overridden methods.
+ *
+ * @author Andrew C. Oliver
+ */
+public class SVTableCellRenderer extends JLabel
+    implements TableCellRenderer, Serializable
+{
+    protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
+    protected SVBorder cellBorder = new SVBorder();
+
+
+    private HSSFWorkbook wb = null;
+
+    /** This class holds the references to the predefined cell formats.
+     */
+    private class CellFormatter {
+      private Format[] textFormatter;
+
+      private DecimalFormat generalNumberFormat = new DecimalFormat("0");
+
+      public CellFormatter() {
+        textFormatter = new Format[0x31];
+
+        textFormatter[0x01] = new DecimalFormat("0");
+        textFormatter[0x02] = new DecimalFormat("0.00");
+        textFormatter[0x03] = new DecimalFormat("#,##0");
+        textFormatter[0x04] = new DecimalFormat("#,##0.00");
+        textFormatter[0x05] = new DecimalFormat("$#,##0;$#,##0");
+        textFormatter[0x06] = new DecimalFormat("$#,##0;$#,##0");
+        textFormatter[0x07] = new DecimalFormat("$#,##0.00;$#,##0.00");
+        textFormatter[0x08] = new DecimalFormat("$#,##0.00;$#,##0.00");
+        textFormatter[0x09] = new DecimalFormat("0%");
+        textFormatter[0x0A] = new DecimalFormat("0.00%");
+        textFormatter[0x0B] = new DecimalFormat("0.00E0");
+        textFormatter[0x0C] = new SVFractionalFormat("# ?/?");
+        textFormatter[0x0D] = new SVFractionalFormat("# ??/??");
+        textFormatter[0x0E] = new SimpleDateFormat("M/d/yy");
+        textFormatter[0x0F] = new SimpleDateFormat("d-MMM-yy");
+        textFormatter[0x10] = new SimpleDateFormat("d-MMM");
+        textFormatter[0x11] = new SimpleDateFormat("MMM-yy");
+        textFormatter[0x12] = new SimpleDateFormat("h:mm a");
+        textFormatter[0x13] = new SimpleDateFormat("h:mm:ss a");
+        textFormatter[0x14] = new SimpleDateFormat("h:mm");
+        textFormatter[0x15] = new SimpleDateFormat("h:mm:ss");
+        textFormatter[0x16] = new SimpleDateFormat("M/d/yy h:mm");
+        // 0x17 - 0x24 reserved for international and undocumented 0x25, "(#,##0_);(#,##0)"
+        //start at 0x26
+        //jmh need to do colour
+        //"(#,##0_);[Red](#,##0)"
+        textFormatter[0x26] = new DecimalFormat("#,##0;#,##0");
+        //jmh need to do colour
+        //(#,##0.00_);(#,##0.00)
+        textFormatter[0x27] = new DecimalFormat("#,##0.00;#,##0.00");
+        textFormatter[0x28] = new DecimalFormat("#,##0.00;#,##0.00");
+//??        textFormatter[0x29] = new DecimalFormat("_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)");
+//??        textFormatter[0x2A] = new DecimalFormat("_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)");
+//??        textFormatter[0x2B] = new DecimalFormat("_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)");
+//??        textFormatter[0x2C] = new DecimalFormat("_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)");
+        textFormatter[0x2D] = new SimpleDateFormat("mm:ss");
+//??        textFormatter[0x2E] = new SimpleDateFormat("[h]:mm:ss");
+        textFormatter[0x2F] = new SimpleDateFormat("mm:ss.0");
+        textFormatter[0x30] = new DecimalFormat("##0.0E0");
+      }
+
+      public String format(short index, Object value) {
+        if (index == 0)
+          return value.toString();
+        if (textFormatter[index] == null)
+          throw new RuntimeException("Sorry. I cant handle the format code :"+Integer.toHexString(index));
+        return textFormatter[index].format(value);
+      }
+
+      public String format(short index, double value) {
+        if ( index <= 0 )
+          return generalNumberFormat.format(value);
+        if (textFormatter[index] == null)
+          throw new RuntimeException("Sorry. I cant handle the format code :"+Integer.toHexString(index));
+        if (textFormatter[index] instanceof DecimalFormat) {
+          return ((DecimalFormat)textFormatter[index]).format(value);
+        }
+        if (textFormatter[index] instanceof SVFractionalFormat) {
+          return ((SVFractionalFormat)textFormatter[index]).format(value);
+        }
+        throw new RuntimeException("Sorry. I cant handle a non decimal formatter for a decimal value :"+Integer.toHexString(index));
+      }
+
+      public boolean useRedColor(short index, double value) {
+        return (((index == 0x06)||(index == 0x08)||(index == 0x26) || (index == 0x27)) && (value < 0));
+      }
+    }
+
+    private final CellFormatter cellFormatter = new CellFormatter();
+
+    public SVTableCellRenderer(HSSFWorkbook wb) {
+	super();
+	setOpaque(true);
+        setBorder(noFocusBorder);
+        this.wb = wb;
+    }
+
+    public Component getTableCellRendererComponent(JTable table, Object value,
+                          boolean isSelected, boolean hasFocus, int row, int column) {
+	boolean isBorderSet = false;
+
+        //If the JTables default cell renderer has been setup correctly the
+        //value will be the HSSFCell that we are trying to render
+        HSSFCell c = (HSSFCell)value;
+
+        if (c != null) {
+          HSSFCellStyle s = c.getCellStyle();
+          HSSFFont f = wb.getFontAt(s.getFontIndex());
+          setFont(SVTableUtils.makeFont(f));
+
+          if (s.getFillPattern() == HSSFCellStyle.SOLID_FOREGROUND) {
+            setBackground(SVTableUtils.getAWTColor(s.getFillForegroundColor(), SVTableUtils.white));
+          } else setBackground(SVTableUtils.white);
+
+          setForeground(SVTableUtils.getAWTColor(f.getColor(), SVTableUtils.black));
+
+          cellBorder.setBorder(SVTableUtils.getAWTColor(s.getTopBorderColor(), SVTableUtils.black),
+                               SVTableUtils.getAWTColor(s.getRightBorderColor(), SVTableUtils.black),
+                               SVTableUtils.getAWTColor(s.getBottomBorderColor(), SVTableUtils.black),
+                               SVTableUtils.getAWTColor(s.getLeftBorderColor(), SVTableUtils.black),
+                               s.getBorderTop(), s.getBorderRight(),
+                               s.getBorderBottom(), s.getBorderLeft(),
+                               hasFocus);
+            setBorder(cellBorder);
+            isBorderSet=true;
+
+            //Set the value that is rendered for the cell
+            switch (c.getCellType()) {
+              case HSSFCell.CELL_TYPE_BLANK:
+                setValue("");
+              break;
+              case HSSFCell.CELL_TYPE_BOOLEAN:
+                if (c.getBooleanCellValue()) {
+                  setValue("true");
+                } else {
+                  setValue("false");
+                }
+              break;
+              case HSSFCell.CELL_TYPE_NUMERIC:
+                short format = s.getDataFormat();
+                double numericValue = c.getNumericCellValue();
+                if (cellFormatter.useRedColor(format, numericValue))
+                  setForeground(Color.red);
+                else setForeground(null);
+                setValue(cellFormatter.format(format, c.getNumericCellValue()));
+              break;
+              case HSSFCell.CELL_TYPE_STRING:
+                setValue(c.getRichStringCellValue().getString());
+              break;
+              case HSSFCell.CELL_TYPE_FORMULA:
+              default:
+                setValue("?");
+            }
+            //Set the text alignment of the cell
+            switch (s.getAlignment()) {
+              case HSSFCellStyle.ALIGN_LEFT:
+              case HSSFCellStyle.ALIGN_JUSTIFY:
+              case HSSFCellStyle.ALIGN_FILL:
+                setHorizontalAlignment(SwingConstants.LEFT);
+                break;
+              case HSSFCellStyle.ALIGN_CENTER:
+              case HSSFCellStyle.ALIGN_CENTER_SELECTION:
+                setHorizontalAlignment(SwingConstants.CENTER);
+                break;
+              case HSSFCellStyle.ALIGN_GENERAL:
+              case HSSFCellStyle.ALIGN_RIGHT:
+                setHorizontalAlignment(SwingConstants.RIGHT);
+                break;
+              default:
+                setHorizontalAlignment(SwingConstants.LEFT);
+                break;
+            }
+        } else {
+          setValue("");
+          setBackground(SVTableUtils.white);
+        }
+
+
+	if (hasFocus) {
+            if (!isBorderSet) {
+              //This is the border to paint when there is no border
+              //and the cell has focus
+              cellBorder.setBorder(SVTableUtils.black,
+                                   SVTableUtils.black,
+                                   SVTableUtils.black,
+                                   SVTableUtils.black,
+                                   HSSFCellStyle.BORDER_NONE,
+                                   HSSFCellStyle.BORDER_NONE,
+                                   HSSFCellStyle.BORDER_NONE,
+                                   HSSFCellStyle.BORDER_NONE,
+                                   isSelected);
+              setBorder(cellBorder);
+            }
+	    if (table.isCellEditable(row, column)) {
+	        setForeground( UIManager.getColor("Table.focusCellForeground") );
+	        setBackground( UIManager.getColor("Table.focusCellBackground") );
+	    }
+	} else if (!isBorderSet) {
+	    setBorder(noFocusBorder);
+	}
+
+	// ---- begin optimization to avoid painting background ----
+	Color back = getBackground();
+	boolean colorMatch = (back != null) && ( back.equals(table.getBackground()) ) && table.isOpaque();
+        setOpaque(!colorMatch);
+	// ---- end optimization to aviod painting background ----
+	return this;
+    }
+
+    public void validate() {}
+
+    public void revalidate() {}
+
+    public void repaint(long tm, int x, int y, int width, int height) {}
+
+    public void repaint(Rectangle r) { }
+
+    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
+	// Strings get interned...
+	if (propertyName=="text") {
+	    super.firePropertyChange(propertyName, oldValue, newValue);
+	}
+    }
+
+    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }
+
+    /**
+     * Sets the string to either the value or "" if the value is null.
+     *
+     */
+    protected void setValue(Object value) {
+	setText((value == null) ? "" : value.toString());
+    }
+}

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableModel.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableModel.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableModel.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableModel.java Mon May 10 16:11:50 2010
@@ -0,0 +1,87 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hssf.view;
+
+import java.util.Iterator;
+import javax.swing.table.*;
+
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+
+/**
+ * Sheet Viewer Table Model - The model for the Sheet Viewer just overrides things.
+ * @author Andrew C. Oliver
+ */
+
+public class SVTableModel extends AbstractTableModel {
+  private HSSFSheet st = null;
+  int maxcol = 0;
+
+  public SVTableModel(HSSFSheet st, int maxcol) {
+    this.st = st;
+    this.maxcol=maxcol;
+  }
+
+  public SVTableModel(HSSFSheet st) {
+    this.st = st;
+    Iterator i = st.rowIterator();
+
+    while (i.hasNext()) {
+      HSSFRow row = (HSSFRow)i.next();
+      if (maxcol < (row.getLastCellNum()+1)) {
+         this.maxcol = row.getLastCellNum();
+      }
+    }
+  }
+
+
+  public int getColumnCount() {
+    return this.maxcol+1;
+  }
+  public Object getValueAt(int row, int col) {
+    HSSFRow r = st.getRow(row);
+    HSSFCell c = null;
+    if (r != null) {
+      c = r.getCell(col);
+    }
+    return c;
+  }
+  public int getRowCount() {
+    return st.getLastRowNum() + 1;
+  }
+
+  public Class getColumnClass(int c) {
+	return HSSFCell.class;
+  }
+
+  public boolean isCellEditable(int rowIndex, int columnIndex) {
+    return true;
+  }
+
+  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+    if (aValue != null)
+      System.out.println("SVTableModel.setValueAt. value type = "+aValue.getClass().getName());
+    else System.out.println("SVTableModel.setValueAt. value type = null");
+  }
+
+
+}

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableUtils.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableUtils.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableUtils.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableUtils.java Mon May 10 16:11:50 2010
@@ -0,0 +1,93 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hssf.view;
+
+import java.util.*;
+import java.awt.*;
+import javax.swing.border.*;
+
+import org.apache.poi.hssf.usermodel.*;
+import org.apache.poi.hssf.util.*;
+
+/**
+ * SVTableCell Editor and Renderer helper functions.
+ *
+ * @author     Jason Height
+ */
+public class SVTableUtils {
+  private final static Hashtable colors = HSSFColor.getIndexHash();
+  /**  Description of the Field */
+  public final static Color black = getAWTColor(new HSSFColor.BLACK());
+  /**  Description of the Field */
+  public final static Color white = getAWTColor(new HSSFColor.WHITE());
+  /**  Description of the Field */
+  public static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
+
+
+  /**
+   *  Creates a new font for a specific cell style
+   */
+  public static Font makeFont(HSSFFont font) {
+    boolean isbold = font.getBoldweight() > HSSFFont.BOLDWEIGHT_NORMAL;
+    boolean isitalics = font.getItalic();
+    int fontstyle = Font.PLAIN;
+    if (isbold) {
+      fontstyle = Font.BOLD;
+    }
+    if (isitalics) {
+      fontstyle = fontstyle | Font.ITALIC;
+    }
+
+    int fontheight = font.getFontHeightInPoints();
+    if (fontheight == 9) {
+      //fix for stupid ol Windows
+      fontheight = 10;
+    }
+
+    return new Font(font.getFontName(), fontstyle, fontheight);
+  }
+
+
+  /**
+   * This method retrieves the AWT Color representation from the colour hash table
+   *
+   * @param  index  Description of the Parameter
+   * @param  deflt  Description of the Parameter
+   * @return        The aWTColor value
+   */
+  public final static Color getAWTColor(int index, Color deflt) {
+    HSSFColor clr = (HSSFColor) colors.get(Integer.valueOf(index));
+    if (clr == null) {
+      return deflt;
+    }
+    return getAWTColor(clr);
+  }
+
+
+  /**
+   *  Gets the aWTColor attribute of the SVTableUtils class
+   *
+   * @param  clr  Description of the Parameter
+   * @return      The aWTColor value
+   */
+  public final static Color getAWTColor(HSSFColor clr) {
+    short[] rgb = clr.getTriplet();
+    return new Color(rgb[0], rgb[1], rgb[2]);
+  }
+}

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/SViewer.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/SViewer.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/SViewer.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/SViewer.java Mon May 10 16:11:50 2010
@@ -0,0 +1,172 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hssf.view;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.net.*;
+import java.io.*;
+import javax.swing.*;
+
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+
+/**
+ * Sheet Viewer - Views XLS files via HSSF.  Can be used as an applet with
+ * filename="" or as a applications (pass the filename as the first parameter).
+ * Or you can pass it a URL in a "url" parameter when run as an applet or just
+ * that first parameter must start with http:// and it will guess its a url. I
+ * only tested it as an applet though, so it probably won't work...you fix it.
+ *
+ * @author Andrew C. Oliver
+ * @author Jason Height
+ */
+public class SViewer extends JApplet {
+  private SViewerPanel panel;
+  boolean isStandalone = false;
+  String filename = null;
+
+  /**Get a parameter value*/
+  public String getParameter(String key, String def) {
+    return isStandalone ? System.getProperty(key, def) :
+      (getParameter(key) != null ? getParameter(key) : def);
+  }
+
+  /**Construct the applet*/
+  public SViewer() {
+  }
+
+  /**Initialize the applet*/
+  public void init() {
+    try {
+      jbInit();
+    }
+    catch(Exception e) {
+      e.printStackTrace();
+      System.exit(1);
+    }
+  }
+
+  /**Component initialization*/
+  private void jbInit() throws Exception {
+    InputStream i = null;
+    boolean isurl = false;
+    if (filename == null) filename = getParameter("filename");
+
+    if (filename == null || filename.substring(0,7).equals("http://")) {
+      isurl = true;
+      if (filename == null) filename = getParameter("url");
+      i = getXLSFromURL(filename);
+    }
+
+    HSSFWorkbook wb = null;
+    if (isurl) {
+      wb = constructWorkbook(i);
+    } else {
+      wb = constructWorkbook(filename);
+    }
+    panel = new SViewerPanel(wb, false);
+    getContentPane().setLayout(new BorderLayout());
+    getContentPane().add(panel, BorderLayout.CENTER);
+  }
+
+  private HSSFWorkbook constructWorkbook(String filename) throws FileNotFoundException, IOException {
+    HSSFWorkbook wb = null;
+      FileInputStream in = new FileInputStream(filename);
+      wb = new HSSFWorkbook(in);
+      in.close();
+    return wb;
+  }
+
+  private HSSFWorkbook constructWorkbook(InputStream in) throws IOException {
+    HSSFWorkbook wb = null;
+
+      wb = new HSSFWorkbook(in);
+      in.close();
+    return wb;
+  }
+
+  /**Start the applet*/
+  public void start() {
+  }
+  /**Stop the applet*/
+  public void stop() {
+  }
+  /**Destroy the applet*/
+  public void destroy() {
+  }
+  /**Get Applet information*/
+  public String getAppletInfo() {
+    return "Applet Information";
+  }
+  /**Get parameter info*/
+  public String[][] getParameterInfo() {
+    return null;
+  }
+
+  /**
+   * opens a url and returns an inputstream
+   *
+   */
+  private InputStream getXLSFromURL(String urlstring) throws MalformedURLException, IOException {
+    URL url = new URL(urlstring);
+    URLConnection uc = url.openConnection();
+    String field = uc.getHeaderField(0);
+    for (int i=0;field != null; i++) {
+      System.out.println(field);
+      field = uc.getHeaderField(i);
+  }
+    BufferedInputStream is = new BufferedInputStream(uc.getInputStream());
+    return is;
+  }
+
+
+  /**Main method*/
+  public static void main(String[] args) {
+    if(args.length < 1) {
+      throw new IllegalArgumentException("A filename to view must be supplied as the first argument, but none was given");
+    }
+
+    SViewer applet = new SViewer();
+    applet.isStandalone = true;
+    applet.filename = args[0];
+    Frame frame;
+    frame = new Frame() {
+      protected void processWindowEvent(WindowEvent e) {
+        super.processWindowEvent(e);
+        if (e.getID() == WindowEvent.WINDOW_CLOSING) {
+          System.exit(0);
+        }
+      }
+      public synchronized void setTitle(String title) {
+        super.setTitle(title);
+        enableEvents(AWTEvent.WINDOW_EVENT_MASK);
+      }
+    };
+    frame.setTitle("Applet Frame");
+    frame.add(applet, BorderLayout.CENTER);
+    applet.init();
+    applet.start();
+    frame.setSize(400,320);
+    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
+    frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2);
+    frame.setVisible(true);
+  }
+}

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/SViewerPanel.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/SViewerPanel.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/SViewerPanel.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/SViewerPanel.java Mon May 10 16:11:50 2010
@@ -0,0 +1,292 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hssf.view;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.table.*;
+
+import org.apache.poi.hssf.usermodel.*;
+
+/**
+ * This class presents the sheets to the user.
+ *
+ *
+ * @author Andrew C. Oliver
+ * @author Jason Height
+ */
+public class SViewerPanel extends JPanel {
+  /** This field is the magic number to convert from a Character width to a
+   *  java pixel width.
+   *
+   * When the "normal" font size in a workbook changes, this effects all
+   * of the heights and widths. Unfortunately there is no way to retrieve this
+   * information, hence the MAGIC number.
+   *
+   * This number may only work for the normal style font size of Arial size 10.
+   *
+   */
+  private static final int magicCharFactor = 7;
+  /** Reference to the wookbook that is being displayed*/
+  /* package */ HSSFWorkbook wb;
+  /** Reference to the tabs component*/
+  /* package */ JTabbedPane sheetPane;
+  /** Reference to the cell renderer that is used to render all cells*/
+  private SVTableCellRenderer cellRenderer;
+  /** Reference to the cell editor that is used to edit all cells.
+   *  Only constructed if editing is allowed
+   */
+  private SVTableCellEditor cellEditor;
+  /** Flag indicating if editing is allowed. Otherwise the viewer is in
+   *  view only mode.
+   */
+  private boolean allowEdits;
+
+  /**Construct the representation of the workbook*/
+  public SViewerPanel(HSSFWorkbook wb, boolean allowEdits) {
+    this.wb = wb;
+    this.allowEdits = allowEdits;
+
+    initialiseGui();
+  }
+
+  private void initialiseGui() {
+    cellRenderer = new SVTableCellRenderer(this.wb);
+    if (allowEdits)
+      cellEditor = new SVTableCellEditor(this.wb);
+
+    //Initialise the Panel
+    sheetPane = new JTabbedPane(JTabbedPane.BOTTOM);
+
+    if (allowEdits)
+      sheetPane.addMouseListener(createTabListener());
+    int sheetCount = wb.getNumberOfSheets();
+    for (int i=0; i<sheetCount;i++) {
+      String sheetName = wb.getSheetName(i);
+      //Add the new sheet to the tabbed pane
+      sheetPane.addTab(sheetName, makeSheetView(wb.getSheetAt(i)));
+    }
+    setLayout(new BorderLayout());
+    add(sheetPane, BorderLayout.CENTER);
+  }
+
+  protected JComponent makeSheetView(HSSFSheet sheet) {
+    JTable sheetView = new JTable(new SVTableModel(sheet));
+    sheetView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+    sheetView.setDefaultRenderer(HSSFCell.class, cellRenderer);
+    if (allowEdits)
+      sheetView.setDefaultEditor(HSSFCell.class, cellEditor);
+    JTableHeader header = sheetView.getTableHeader();
+    //Dont allow column reordering
+    header.setReorderingAllowed(false);
+    //Only allow column resizing if editing is allowed
+    header.setResizingAllowed(allowEdits);
+
+    //Set the columns the correct size
+    TableColumnModel columns = sheetView.getColumnModel();
+    for (int i=0; i< columns.getColumnCount(); i++) {
+      TableColumn column = columns.getColumn(i);
+      int width = sheet.getColumnWidth(i);
+      //256 is because the width is in 256ths of a character
+      column.setPreferredWidth(width/256*magicCharFactor);
+    }
+
+    //Set the rows to the correct size
+    int rows = sheet.getPhysicalNumberOfRows();
+    Insets insets = cellRenderer.getInsets();
+    //Need to include the insets in the calculation of the row height to use.
+    int extraHeight = insets.bottom+insets.top;
+    for (int i=0; i< rows; i++) {
+      HSSFRow row = sheet.getRow(i);
+      if (row == null) {
+        sheetView.setRowHeight(i, (int)sheet.getDefaultRowHeightInPoints()+extraHeight);
+      } else {
+        sheetView.setRowHeight(i, (int)row.getHeightInPoints()+extraHeight);
+      }
+    }
+
+    //Add the row header to the sheet
+    SVRowHeader rowHeader = new SVRowHeader(sheet, sheetView, extraHeight);
+    JScrollPane scroll = new JScrollPane( sheetView );
+    scroll.setRowHeaderView(rowHeader);
+    return scroll;
+  }
+
+  public void paint(Graphics g) {
+    //JMH I am only overriding this to get a picture of the time taken to paint
+    long start = System.currentTimeMillis();
+    super.paint(g);
+    long elapsed = System.currentTimeMillis()-start;
+    System.out.println("Paint time = "+elapsed);
+  }
+
+  protected MouseListener createTabListener() {
+    return new TabListener();
+  }
+
+  /** This class defines the default MouseListener that listens to
+   *  mouse events in the tabbed pane
+   *
+   *  The default is to popup a menu when the event occurs over a tab
+   */
+  private class TabListener implements MouseListener {
+    public JPopupMenu popup;
+    public TabListener() {
+      popup = new JPopupMenu("Sheet");
+      popup.add(createInsertSheetAction());
+      popup.add(createDeleteSheetAction());
+      popup.add(createRenameSheetAction());
+    }
+
+    protected Action createInsertSheetAction() {
+      return new InsertSheetAction();
+    }
+
+    protected Action createDeleteSheetAction() {
+      return new DeleteSheetAction();
+    }
+
+    protected Action createRenameSheetAction() {
+      return new RenameSheetAction();
+    }
+
+
+    /** This method will display the popup if the mouseevent is a popup event
+     *  and the event occurred over a tab
+     */
+    protected void checkPopup(MouseEvent e) {
+      if (e.isPopupTrigger()) {
+        int tab = sheetPane.getUI().tabForCoordinate(sheetPane, e.getX(), e.getY());
+        if (tab != -1) {
+          popup.show(sheetPane, e.getX(), e.getY());
+        }
+      }
+    }
+
+    public void mouseClicked(MouseEvent e) {
+      checkPopup(e);
+    }
+
+    public void mousePressed(MouseEvent e) {
+      checkPopup(e);
+    }
+
+    public void mouseReleased(MouseEvent e) {
+      checkPopup(e);
+    }
+
+    public void mouseEntered(MouseEvent e) {}
+    public void mouseExited(MouseEvent e) {}
+  }
+
+  /** This class defines the action that is performed when the sheet is renamed*/
+  private class RenameSheetAction extends AbstractAction {
+    public RenameSheetAction() {
+      super("Rename");
+    }
+
+    public void actionPerformed(ActionEvent e) {
+      int tabIndex = sheetPane.getSelectedIndex();
+      if (tabIndex != -1) {
+        String newSheetName = JOptionPane.showInputDialog(sheetPane, "Enter a new Sheetname", "Rename Sheet", JOptionPane.QUESTION_MESSAGE);
+        if (newSheetName != null) {
+          wb.setSheetName(tabIndex, newSheetName);
+          sheetPane.setTitleAt(tabIndex, newSheetName);
+        }
+      }
+    }
+  }
+
+  /** This class defines the action that is performed when a sheet is inserted*/
+  private class InsertSheetAction extends AbstractAction {
+    public InsertSheetAction() {
+      super("Insert");
+    }
+
+    public void actionPerformed(ActionEvent e) {
+      //Create a new sheet then search for the sheet and make sure that the
+      //sheetPane shows it.
+      HSSFSheet newSheet = wb.createSheet();
+      for (int i=0; i<wb.getNumberOfSheets();i++) {
+        HSSFSheet sheet = wb.getSheetAt(i);
+        if (newSheet == sheet) {
+          sheetPane.insertTab(wb.getSheetName(i), null, makeSheetView(sheet), null, i);
+        }
+      }
+    }
+  }
+
+  /** This class defines the action that is performed when the sheet is deleted*/
+  private class DeleteSheetAction extends AbstractAction {
+    public DeleteSheetAction() {
+      super("Delete");
+    }
+
+    public void actionPerformed(ActionEvent e) {
+      int tabIndex = sheetPane.getSelectedIndex();
+      if (tabIndex != -1) {
+        if (JOptionPane.showConfirmDialog(sheetPane, "Are you sure that you want to delete the selected sheet", "Delete Sheet?", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
+          wb.removeSheetAt(tabIndex);
+          sheetPane.remove(tabIndex);
+        }
+      }
+    }
+  }
+
+  public boolean isEditable() {
+    return allowEdits;
+  }
+
+  /**Main method*/
+  public static void main(String[] args) {
+    if(args.length < 1) {
+      throw new IllegalArgumentException("A filename to view must be supplied as the first argument, but none was given");
+    }
+    try {
+      FileInputStream in = new FileInputStream(args[0]);
+      HSSFWorkbook wb = new HSSFWorkbook(in);
+      in.close();
+
+      SViewerPanel p = new SViewerPanel(wb, true);
+      JFrame frame;
+      frame = new JFrame() {
+        protected void processWindowEvent(WindowEvent e) {
+          super.processWindowEvent(e);
+          if (e.getID() == WindowEvent.WINDOW_CLOSING) {
+            System.exit(0);
+          }
+        }
+        public synchronized void setTitle(String title) {
+          super.setTitle(title);
+          enableEvents(AWTEvent.WINDOW_EVENT_MASK);
+        }
+      };
+      frame.setTitle("Viewer Frame");
+      frame.getContentPane().add(p, BorderLayout.CENTER);
+      frame.setSize(800,640);
+      Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
+      frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2);
+      frame.setVisible(true);
+    } catch (IOException ex) {
+      ex.printStackTrace();
+      System.exit(1);
+    }
+  }
+}

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/BasicBrush.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/BasicBrush.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/BasicBrush.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/BasicBrush.java Mon May 10 16:11:50 2010
@@ -0,0 +1,72 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hssf.view.brush;
+
+import java.awt.*;
+
+/**
+ * This is a basic brush that just draws the line with the given parameters.
+ * This is a {@link BasicStroke} object that can be used as a {@link Brush}.
+ *
+ * @author Ken Arnold, Industrious Media LLC
+ * @see BasicStroke
+ */
+public class BasicBrush extends BasicStroke implements Brush {
+    /**
+     * Creates a new basic brush with the given width. Invokes {@link
+     * BasicStroke#BasicStroke(float)}
+     *
+     * @param width The brush width.
+     *
+     * @see BasicStroke#BasicStroke(float)
+     */
+    public BasicBrush(float width) {
+        super(width);
+    }
+
+    /**
+     * Creates a new basic brush with the given width, cap, and join.  Invokes
+     * {@link BasicStroke#BasicStroke(float,int,int)}
+     *
+     * @param width The brush width.
+     * @param cap   The capping style.
+     * @param join  The join style.
+     *
+     * @see BasicStroke#BasicStroke(float, int, int)
+     */
+    public BasicBrush(float width, int cap, int join) {
+        super(width, cap, join);
+    }
+
+    /**
+     * Creates a new basic brush with the given parameters.  Invokes {@link
+     * BasicStroke#BasicStroke(float,int,int,float,float[],float)} with a miter
+     * limit of 11 (the normal default value).
+     *
+     * @param width   The brush width.
+     * @param cap     The capping style.
+     * @param join    The join style.
+     * @param dashes  The dash intervals.
+     * @param dashPos The intial dash position in the dash intervals.
+     *
+     * @see BasicStroke#BasicStroke(float, int, int, float, float[], float)
+     */
+    public BasicBrush(float width, int cap, int join, float[] dashes,
+            int dashPos) {
+        super(width, cap, join, 11.0f, dashes, dashPos);
+    }
+}
\ No newline at end of file

Added: poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/Brush.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/Brush.java?rev=942809&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/Brush.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/view/brush/Brush.java Mon May 10 16:11:50 2010
@@ -0,0 +1,14 @@
+package org.apache.poi.hssf.view.brush;
+
+import java.awt.*;
+
+/**
+ * This is the type you must implement to create a brush that will be used for a
+ * spreadsheet border.
+ *
+ * @author Ken Arnold, Industrious Media LLC
+ */
+public interface Brush extends Stroke {
+    /** Returns the width of the brush. */
+    float getLineWidth();
+}
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org