--- /dev/null
+/*
+ * ====================================================================
+ * 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;
+ }
+
+
+}
--- /dev/null
+/* ====================================================================
+ * 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));
+ }
+}
--- /dev/null
+/*
+ * ====================================================================
+ * 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]);
+ }
+
+}
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.
*/
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");
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) {
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);
setValue("false");
}
break;
- case HSSFCell.CELL_TYPE_FORMULA:
case HSSFCell.CELL_TYPE_NUMERIC:
short format = s.getDataFormat();
double numericValue = c.getNumericCellValue();
case HSSFCell.CELL_TYPE_STRING:
setValue(c.getStringCellValue());
break;
+ case HSSFCell.CELL_TYPE_FORMULA:
default:
setValue("?");
}
}
} 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,
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]);
- }
-
-
}
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");
+ }
+
}
--- /dev/null
+/*
+ * ====================================================================
+ * 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]);
+ }
+
+}
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;
}
catch(Exception e) {
e.printStackTrace();
+ System.exit(1);
}
}
} 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;
}
* 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;
}
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.
* @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 {
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) {
};
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);