]> source.dussan.org Git - poi.git/commitdiff
Patch to sucky viewer... which is slowly getting less sucky. ;-)
authorGlen Stampoultzis <glens@apache.org>
Sat, 20 Jul 2002 11:41:21 +0000 (11:41 +0000)
committerGlen Stampoultzis <glens@apache.org>
Sat, 20 Jul 2002 11:41:21 +0000 (11:41 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352787 13f79535-47bb-0310-9956-ffa450edef68

src/contrib/src/org/apache/poi/hssf/contrib/view/SVFractionalFormat.java [new file with mode: 0644]
src/contrib/src/org/apache/poi/hssf/contrib/view/SVRowHeader.java [new file with mode: 0644]
src/contrib/src/org/apache/poi/hssf/contrib/view/SVTableCellEditor.java [new file with mode: 0644]
src/contrib/src/org/apache/poi/hssf/contrib/view/SVTableCellRenderer.java
src/contrib/src/org/apache/poi/hssf/contrib/view/SVTableModel.java
src/contrib/src/org/apache/poi/hssf/contrib/view/SVTableUtils.java [new file with mode: 0644]
src/contrib/src/org/apache/poi/hssf/contrib/view/SViewer.java
src/contrib/src/org/apache/poi/hssf/contrib/view/SViewerPanel.java

diff --git a/src/contrib/src/org/apache/poi/hssf/contrib/view/SVFractionalFormat.java b/src/contrib/src/org/apache/poi/hssf/contrib/view/SVFractionalFormat.java
new file mode 100644 (file)
index 0000000..edf54ef
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ *  ====================================================================
+ *  The Apache Software License, Version 1.1
+ *
+ *  Copyright (c) 2002 The Apache Software Foundation.  All rights
+ *  reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in
+ *  the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *  3. The end-user documentation included with the redistribution,
+ *  if any, must include the following acknowledgment:
+ *  "This product includes software developed by the
+ *  Apache Software Foundation (http://www.apache.org/)."
+ *  Alternately, this acknowledgment may appear in the software itself,
+ *  if and wherever such third-party acknowledgments normally appear.
+ *
+ *  4. The names "Apache" and "Apache Software Foundation" and
+ *  "Apache POI" must not be used to endorse or promote products
+ *  derived from this software without prior written permission. For
+ *  written permission, please contact apache@apache.org.
+ *
+ *  5. Products derived from this software may not be called "Apache",
+ *  "Apache POI", nor may "Apache" appear in their name, without
+ *  prior written permission of the Apache Software Foundation.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ *  SUCH DAMAGE.
+ *  ====================================================================
+ *
+ *  This software consists of voluntary contributions made by many
+ *  individuals on behalf of the Apache Software Foundation.  For more
+ *  information on the Apache Software Foundation, please see
+ *  <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hssf.contrib.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
+ * @created    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.0001;
+    double AllowedError = 0.001;
+    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(Num).toString();
+  }
+
+  private String formatUnit(double f, int units) {
+    //JMH TBD
+    return null;
+  }
+
+  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;
+    }
+    else 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;
+  }
+
+
+}
diff --git a/src/contrib/src/org/apache/poi/hssf/contrib/view/SVRowHeader.java b/src/contrib/src/org/apache/poi/hssf/contrib/view/SVRowHeader.java
new file mode 100644 (file)
index 0000000..c5b0c2e
--- /dev/null
@@ -0,0 +1,126 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hssf.contrib.view;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.event.*;
+
+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.getPhysicalNumberOfRows(); }
+    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();
+      int rowHeight = (int)sheet.getRow(index).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));
+  }
+}
diff --git a/src/contrib/src/org/apache/poi/hssf/contrib/view/SVTableCellEditor.java b/src/contrib/src/org/apache/poi/hssf/contrib/view/SVTableCellEditor.java
new file mode 100644 (file)
index 0000000..8949d30
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ *  ====================================================================
+ *  The Apache Software License, Version 1.1
+ *
+ *  Copyright (c) 2002 The Apache Software Foundation.  All rights
+ *  reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in
+ *  the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *  3. The end-user documentation included with the redistribution,
+ *  if any, must include the following acknowledgment:
+ *  "This product includes software developed by the
+ *  Apache Software Foundation (http://www.apache.org/)."
+ *  Alternately, this acknowledgment may appear in the software itself,
+ *  if and wherever such third-party acknowledgments normally appear.
+ *
+ *  4. The names "Apache" and "Apache Software Foundation" and
+ *  "Apache POI" must not be used to endorse or promote products
+ *  derived from this software without prior written permission. For
+ *  written permission, please contact apache@apache.org.
+ *
+ *  5. Products derived from this software may not be called "Apache",
+ *  "Apache POI", nor may "Apache" appear in their name, without
+ *  prior written permission of the Apache Software Foundation.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ *  SUCH DAMAGE.
+ *  ====================================================================
+ *
+ *  This software consists of voluntary contributions made by many
+ *  individuals on behalf of the Apache Software Foundation.  For more
+ *  information on the Apache Software Foundation, please see
+ *  <http://www.apache.org/>.
+ */
+package org.apache.poi.hssf.contrib.view;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.text.*;
+import java.util.*;
+
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.table.*;
+
+import org.apache.poi.hssf.usermodel.*;
+import org.apache.poi.hssf.util.HSSFColor;
+
+/**
+ * Sucky Viewer Table Cell Editor -- not commented via javadoc as it
+ * nearly completely consists of overridden methods.
+ *
+ * @author     Jason Height
+ * @created    16 July 2002
+ */
+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;
+
+
+  /**
+   *Constructor for the SVTableCellEditor object
+   *
+   * @param  wb  Description of the Parameter
+   */
+  public SVTableCellEditor(HSSFWorkbook wb) {
+    this.wb = wb;
+    this.editor = new JTextField();
+  }
+
+
+  /**
+   *  Gets the cellEditable attribute of the SVTableCellEditor object
+   *
+   * @param  e  Description of the Parameter
+   * @return    The cellEditable value
+   */
+  public boolean isCellEditable(java.util.EventObject e) {
+    if (e instanceof MouseEvent) {
+      return ((MouseEvent) e).getClickCount() >= 2;
+    }
+    return false;
+  }
+
+
+  /**
+   *  Description of the Method
+   *
+   * @param  anEvent  Description of the Parameter
+   * @return          Description of the Return Value
+   */
+  public boolean shouldSelectCell(EventObject anEvent) {
+    return true;
+  }
+
+
+  /**
+   *  Description of the Method
+   *
+   * @param  anEvent  Description of the Parameter
+   * @return          Description of the Return Value
+   */
+  public boolean startCellEditing(EventObject anEvent) {
+    System.out.println("Start Cell Editing");
+    return true;
+  }
+
+
+  /**
+   *  Description of the Method
+   *
+   * @return    Description of the Return Value
+   */
+  public boolean stopCellEditing() {
+    System.out.println("Stop Cell Editing");
+    fireEditingStopped();
+    return true;
+  }
+
+
+  /**  Description of the Method */
+  public void cancelCellEditing() {
+    System.out.println("Cancel Cell Editing");
+    fireEditingCanceled();
+  }
+
+
+  /**
+   *  Description of the Method
+   *
+   * @param  e  Description of the Parameter
+   */
+  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
+   *
+   * @param  table       Description of the Parameter
+   * @param  value       Description of the Parameter
+   * @param  isSelected  Description of the Parameter
+   * @param  row         Description of the Parameter
+   * @param  column      Description of the Parameter
+   * @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.getStringCellValue());
+          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(new Integer(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]);
+    }
+
+}
index 91b03ea1b8f5fb52cf24008cf0001fbe43620dc1..ab09ba5c40392b78b1a64e020c2533b5ece57edf 100644 (file)
@@ -83,15 +83,11 @@ import org.apache.poi.hssf.util.HSSFColor;
 public class SVTableCellRenderer extends JLabel
     implements TableCellRenderer, Serializable
 {
-  private static final Color black = getAWTColor(new HSSFColor.BLACK());
-  private static final Color white = getAWTColor(new HSSFColor.WHITE());
-
     protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
     protected SVBorder cellBorder = new SVBorder();
 
 
     private HSSFWorkbook wb = null;
-    private Hashtable colors = HSSFColor.getIndexHash();
 
     /** This class holds the references to the predefined cell formats.
      */
@@ -114,8 +110,8 @@ public class SVTableCellRenderer extends JLabel
         textFormatter[0x09] = new DecimalFormat("0%");
         textFormatter[0x0A] = new DecimalFormat("0.00%");
         textFormatter[0x0B] = new DecimalFormat("0.00E0");
-//??        textFormatter[0x0C] = new DecimalFormat("# ?/?");
-//??        textFormatter[0x0D] = new DecimalFormat("# ??/??");
+        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");
@@ -160,7 +156,10 @@ public class SVTableCellRenderer extends JLabel
         if (textFormatter[index] instanceof DecimalFormat) {
           return ((DecimalFormat)textFormatter[index]).format(value);
         }
-        else throw new RuntimeException("Sorry. I cant handle a non decimal formatter for a decimal value :"+Integer.toHexString(index));
+        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) {
@@ -188,30 +187,18 @@ public class SVTableCellRenderer extends JLabel
         if (c != null) {
           HSSFCellStyle s = c.getCellStyle();
           HSSFFont f = wb.getFontAt(s.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);
-          setFont(font);
+          setFont(SVTableUtils.makeFont(f));
 
           if (s.getFillPattern() == HSSFCellStyle.SOLID_FOREGROUND) {
-            setBackground(getAWTColor(s.getFillForegroundColor(), white));
-          } else setBackground(white);
+            setBackground(SVTableUtils.getAWTColor(s.getFillForegroundColor(), SVTableUtils.white));
+          } else setBackground(SVTableUtils.white);
 
-          setForeground(getAWTColor(f.getColor(), black));
+          setForeground(SVTableUtils.getAWTColor(f.getColor(), SVTableUtils.black));
 
-          cellBorder.setBorder(getAWTColor(s.getTopBorderColor(), black),
-                               getAWTColor(s.getRightBorderColor(), black),
-                               getAWTColor(s.getBottomBorderColor(), black),
-                               getAWTColor(s.getLeftBorderColor(), 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);
@@ -230,7 +217,6 @@ public class SVTableCellRenderer extends JLabel
                   setValue("false");
                 }
               break;
-              case HSSFCell.CELL_TYPE_FORMULA:
               case HSSFCell.CELL_TYPE_NUMERIC:
                 short format = s.getDataFormat();
                 double numericValue = c.getNumericCellValue();
@@ -242,6 +228,7 @@ public class SVTableCellRenderer extends JLabel
               case HSSFCell.CELL_TYPE_STRING:
                 setValue(c.getStringCellValue());
               break;
+              case HSSFCell.CELL_TYPE_FORMULA:
               default:
                 setValue("?");
             }
@@ -266,16 +253,18 @@ public class SVTableCellRenderer extends JLabel
             }
         } else {
           setValue("");
-          setBackground(white);
+          setBackground(SVTableUtils.white);
         }
 
 
        if (hasFocus) {
             if (!isBorderSet) {
-              cellBorder.setBorder(black,
-                                   black,
-                                   black,
-                                   black,
+              //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,
@@ -323,20 +312,4 @@ public class SVTableCellRenderer extends JLabel
     protected void setValue(Object value) {
        setText((value == null) ? "" : value.toString());
     }
-
-    /** 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(new Integer(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]);
-    }
-
-
 }
index 8ea268bbd5671f628f343bc8e4c64c76f36c432d..4942cc4da2e79d105fdc3e61639f210839414b57 100644 (file)
@@ -109,5 +109,15 @@ public class SVTableModel extends AbstractTableModel {
        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");
+  }
+
 
 }
diff --git a/src/contrib/src/org/apache/poi/hssf/contrib/view/SVTableUtils.java b/src/contrib/src/org/apache/poi/hssf/contrib/view/SVTableUtils.java
new file mode 100644 (file)
index 0000000..1c76a26
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ *  ====================================================================
+ *  The Apache Software License, Version 1.1
+ *
+ *  Copyright (c) 2002 The Apache Software Foundation.  All rights
+ *  reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in
+ *  the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *  3. The end-user documentation included with the redistribution,
+ *  if any, must include the following acknowledgment:
+ *  "This product includes software developed by the
+ *  Apache Software Foundation (http://www.apache.org/)."
+ *  Alternately, this acknowledgment may appear in the software itself,
+ *  if and wherever such third-party acknowledgments normally appear.
+ *
+ *  4. The names "Apache" and "Apache Software Foundation" and
+ *  "Apache POI" must not be used to endorse or promote products
+ *  derived from this software without prior written permission. For
+ *  written permission, please contact apache@apache.org.
+ *
+ *  5. Products derived from this software may not be called "Apache",
+ *  "Apache POI", nor may "Apache" appear in their name, without
+ *  prior written permission of the Apache Software Foundation.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ *  SUCH DAMAGE.
+ *  ====================================================================
+ *
+ *  This software consists of voluntary contributions made by many
+ *  individuals on behalf of the Apache Software Foundation.  For more
+ *  information on the Apache Software Foundation, please see
+ *  <http://www.apache.org/>.
+ */
+package org.apache.poi.hssf.contrib.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
+ * @created    16 July 2002
+ */
+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
+   *
+   * @param  wb     Description of the Parameter
+   * @param  style  Description of the Parameter
+   * @return        Description of the Return Value
+   */
+  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(new Integer(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]);
+  }
+
+}
index b5c327608a3a414a472533a68e1b45f812380705..376e8eb2a6100aeb6bb8418c5d9f0171728b8d2c 100644 (file)
@@ -58,11 +58,9 @@ package org.apache.poi.hssf.contrib.view;
 
 import java.awt.*;
 import java.awt.event.*;
-import java.net.URL;
-import java.net.URLConnection;
+import java.net.*;
 import java.applet.*;
-import java.io.InputStream;
-import java.io.FileInputStream;
+import java.io.*;
 import javax.swing.*;
 
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@@ -100,6 +98,7 @@ public class SViewer extends JApplet {
     }
     catch(Exception e) {
       e.printStackTrace();
+      System.exit(1);
     }
   }
 
@@ -121,34 +120,24 @@ public class SViewer extends JApplet {
     } else {
       wb = constructWorkbook(filename);
     }
-    panel = new SViewerPanel(wb);
+    panel = new SViewerPanel(wb, false);
     getContentPane().setLayout(new BorderLayout());
     getContentPane().add(panel, BorderLayout.CENTER);
   }
 
-  private HSSFWorkbook constructWorkbook(String filename) {
+  private HSSFWorkbook constructWorkbook(String filename) throws FileNotFoundException, IOException {
     HSSFWorkbook wb = null;
-
-    try {
       FileInputStream in = new FileInputStream(filename);
       wb = new HSSFWorkbook(in);
       in.close();
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
     return wb;
   }
 
-  private HSSFWorkbook constructWorkbook(InputStream in) {
+  private HSSFWorkbook constructWorkbook(InputStream in) throws IOException {
     HSSFWorkbook wb = null;
 
-    try {
       wb = new HSSFWorkbook(in);
       in.close();
-
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
     return wb;
   }
 
@@ -174,14 +163,15 @@ public class SViewer extends JApplet {
    * opens a url and returns an inputstream
    *
    */
-  private InputStream getXLSFromURL(String urlstring) {
-  InputStream is = null;
-  try {
+  private InputStream getXLSFromURL(String urlstring) throws MalformedURLException, IOException {
     URL url = new URL(urlstring);
-    is = url.openStream();
-  } catch (Exception e) {
-    e.printStackTrace();
+    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;
   }
 
index 548ad689b97d31fcf8409f2f1792f20e96dc2ae8..85704c33c4b4c296a3fe61c2547652322212b021 100644 (file)
@@ -60,10 +60,10 @@ import java.awt.*;
 import java.awt.event.*;
 import java.io.*;
 import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.event.*;
 
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.hssf.usermodel.HSSFSheet;
-import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.*;
 
 /**
  * This class presents the sheets to the user.
@@ -73,38 +73,227 @@ import org.apache.poi.hssf.usermodel.HSSFCell;
  * @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 woorkbook that is being displayed*/
   private HSSFWorkbook wb;
-  private JTable sheets[];
+  /** Reference to the tabs component*/
+  private 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) {
+  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
-    JTabbedPane sheetPane = new JTabbedPane(JTabbedPane.BOTTOM);
+    sheetPane = new JTabbedPane(JTabbedPane.BOTTOM);
+
+    if (allowEdits)
+      sheetPane.addMouseListener(createTabListener());
     int sheetCount = wb.getNumberOfSheets();
-    sheets = new JTable[sheetCount];
-    SVTableCellRenderer rnd = new SVTableCellRenderer(wb);
     for (int i=0; i<sheetCount;i++) {
       String sheetName = wb.getSheetName(i);
-      //Construct the view of the sheet
-      SVTableModel tm = new SVTableModel(wb.getSheetAt(i));
-      sheets[i] = new JTable(tm);
-      sheets[i].setDefaultRenderer(HSSFCell.class, rnd);
       //Add the new sheet to the tabbed pane
-      sheetPane.addTab(sheetName, new JScrollPane(sheets[i]));
+      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);
+      short width = sheet.getColumnWidth((short)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 = (String)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) {
     try {
@@ -112,7 +301,7 @@ public class SViewerPanel extends JPanel {
       HSSFWorkbook wb = new HSSFWorkbook(in);
       in.close();
 
-      SViewerPanel p = new SViewerPanel(wb);
+      SViewerPanel p = new SViewerPanel(wb, true);
       JFrame frame;
       frame = new JFrame() {
         protected void processWindowEvent(WindowEvent e) {
@@ -128,7 +317,7 @@ public class SViewerPanel extends JPanel {
       };
       frame.setTitle("Viewer Frame");
       frame.getContentPane().add(p, BorderLayout.CENTER);
-      frame.setSize(400,320);
+      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);