Patch to sucky viewer... which is slowly getting less sucky. ;-)

git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352787 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Glen Stampoultzis 2002-07-20 11:41:21 +00:00
parent f649d5bb21
commit b03909b0b6
8 changed files with 1037 additions and 87 deletions

View File

@ -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;
}
}

View File

@ -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));
}
}

View File

@ -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]);
}
}

View File

@ -83,15 +83,11 @@ import org.apache.poi.hssf.util.HSSFColor;
public class SVTableCellRenderer extends JLabel public class SVTableCellRenderer extends JLabel
implements TableCellRenderer, Serializable 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 static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
protected SVBorder cellBorder = new SVBorder(); protected SVBorder cellBorder = new SVBorder();
private HSSFWorkbook wb = null; private HSSFWorkbook wb = null;
private Hashtable colors = HSSFColor.getIndexHash();
/** This class holds the references to the predefined cell formats. /** 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[0x09] = new DecimalFormat("0%");
textFormatter[0x0A] = new DecimalFormat("0.00%"); textFormatter[0x0A] = new DecimalFormat("0.00%");
textFormatter[0x0B] = new DecimalFormat("0.00E0"); textFormatter[0x0B] = new DecimalFormat("0.00E0");
//?? textFormatter[0x0C] = new DecimalFormat("# ?/?"); textFormatter[0x0C] = new SVFractionalFormat("# ?/?");
//?? textFormatter[0x0D] = new DecimalFormat("# ??/??"); textFormatter[0x0D] = new SVFractionalFormat("# ??/??");
textFormatter[0x0E] = new SimpleDateFormat("M/d/yy"); textFormatter[0x0E] = new SimpleDateFormat("M/d/yy");
textFormatter[0x0F] = new SimpleDateFormat("d-MMM-yy"); textFormatter[0x0F] = new SimpleDateFormat("d-MMM-yy");
textFormatter[0x10] = new SimpleDateFormat("d-MMM"); textFormatter[0x10] = new SimpleDateFormat("d-MMM");
@ -160,7 +156,10 @@ public class SVTableCellRenderer extends JLabel
if (textFormatter[index] instanceof DecimalFormat) { if (textFormatter[index] instanceof DecimalFormat) {
return ((DecimalFormat)textFormatter[index]).format(value); 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) { public boolean useRedColor(short index, double value) {
@ -188,30 +187,18 @@ public class SVTableCellRenderer extends JLabel
if (c != null) { if (c != null) {
HSSFCellStyle s = c.getCellStyle(); HSSFCellStyle s = c.getCellStyle();
HSSFFont f = wb.getFontAt(s.getFontIndex()); HSSFFont f = wb.getFontAt(s.getFontIndex());
boolean isbold = f.getBoldweight() > HSSFFont.BOLDWEIGHT_NORMAL; setFont(SVTableUtils.makeFont(f));
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);
if (s.getFillPattern() == HSSFCellStyle.SOLID_FOREGROUND) { if (s.getFillPattern() == HSSFCellStyle.SOLID_FOREGROUND) {
setBackground(getAWTColor(s.getFillForegroundColor(), white)); setBackground(SVTableUtils.getAWTColor(s.getFillForegroundColor(), SVTableUtils.white));
} else setBackground(white); } else setBackground(SVTableUtils.white);
setForeground(getAWTColor(f.getColor(), black)); setForeground(SVTableUtils.getAWTColor(f.getColor(), SVTableUtils.black));
cellBorder.setBorder(getAWTColor(s.getTopBorderColor(), black), cellBorder.setBorder(SVTableUtils.getAWTColor(s.getTopBorderColor(), SVTableUtils.black),
getAWTColor(s.getRightBorderColor(), black), SVTableUtils.getAWTColor(s.getRightBorderColor(), SVTableUtils.black),
getAWTColor(s.getBottomBorderColor(), black), SVTableUtils.getAWTColor(s.getBottomBorderColor(), SVTableUtils.black),
getAWTColor(s.getLeftBorderColor(), black), SVTableUtils.getAWTColor(s.getLeftBorderColor(), SVTableUtils.black),
s.getBorderTop(), s.getBorderRight(), s.getBorderTop(), s.getBorderRight(),
s.getBorderBottom(), s.getBorderLeft(), s.getBorderBottom(), s.getBorderLeft(),
hasFocus); hasFocus);
@ -230,7 +217,6 @@ public class SVTableCellRenderer extends JLabel
setValue("false"); setValue("false");
} }
break; break;
case HSSFCell.CELL_TYPE_FORMULA:
case HSSFCell.CELL_TYPE_NUMERIC: case HSSFCell.CELL_TYPE_NUMERIC:
short format = s.getDataFormat(); short format = s.getDataFormat();
double numericValue = c.getNumericCellValue(); double numericValue = c.getNumericCellValue();
@ -242,6 +228,7 @@ public class SVTableCellRenderer extends JLabel
case HSSFCell.CELL_TYPE_STRING: case HSSFCell.CELL_TYPE_STRING:
setValue(c.getStringCellValue()); setValue(c.getStringCellValue());
break; break;
case HSSFCell.CELL_TYPE_FORMULA:
default: default:
setValue("?"); setValue("?");
} }
@ -266,16 +253,18 @@ public class SVTableCellRenderer extends JLabel
} }
} else { } else {
setValue(""); setValue("");
setBackground(white); setBackground(SVTableUtils.white);
} }
if (hasFocus) { if (hasFocus) {
if (!isBorderSet) { if (!isBorderSet) {
cellBorder.setBorder(black, //This is the border to paint when there is no border
black, //and the cell has focus
black, cellBorder.setBorder(SVTableUtils.black,
black, SVTableUtils.black,
SVTableUtils.black,
SVTableUtils.black,
HSSFCellStyle.BORDER_NONE, HSSFCellStyle.BORDER_NONE,
HSSFCellStyle.BORDER_NONE, HSSFCellStyle.BORDER_NONE,
HSSFCellStyle.BORDER_NONE, HSSFCellStyle.BORDER_NONE,
@ -323,20 +312,4 @@ public class SVTableCellRenderer extends JLabel
protected void setValue(Object value) { protected void setValue(Object value) {
setText((value == null) ? "" : value.toString()); 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]);
}
} }

View File

@ -109,5 +109,15 @@ public class SVTableModel extends AbstractTableModel {
return HSSFCell.class; 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");
}
} }

View File

@ -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]);
}
}

View File

@ -58,11 +58,9 @@ package org.apache.poi.hssf.contrib.view;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.net.URL; import java.net.*;
import java.net.URLConnection;
import java.applet.*; import java.applet.*;
import java.io.InputStream; import java.io.*;
import java.io.FileInputStream;
import javax.swing.*; import javax.swing.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@ -100,6 +98,7 @@ public class SViewer extends JApplet {
} }
catch(Exception e) { catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
System.exit(1);
} }
} }
@ -121,34 +120,24 @@ public class SViewer extends JApplet {
} else { } else {
wb = constructWorkbook(filename); wb = constructWorkbook(filename);
} }
panel = new SViewerPanel(wb); panel = new SViewerPanel(wb, false);
getContentPane().setLayout(new BorderLayout()); getContentPane().setLayout(new BorderLayout());
getContentPane().add(panel, BorderLayout.CENTER); getContentPane().add(panel, BorderLayout.CENTER);
} }
private HSSFWorkbook constructWorkbook(String filename) { private HSSFWorkbook constructWorkbook(String filename) throws FileNotFoundException, IOException {
HSSFWorkbook wb = null; HSSFWorkbook wb = null;
try {
FileInputStream in = new FileInputStream(filename); FileInputStream in = new FileInputStream(filename);
wb = new HSSFWorkbook(in); wb = new HSSFWorkbook(in);
in.close(); in.close();
} catch (Exception e) {
e.printStackTrace();
}
return wb; return wb;
} }
private HSSFWorkbook constructWorkbook(InputStream in) { private HSSFWorkbook constructWorkbook(InputStream in) throws IOException {
HSSFWorkbook wb = null; HSSFWorkbook wb = null;
try {
wb = new HSSFWorkbook(in); wb = new HSSFWorkbook(in);
in.close(); in.close();
} catch (Exception e) {
e.printStackTrace();
}
return wb; return wb;
} }
@ -174,14 +163,15 @@ public class SViewer extends JApplet {
* opens a url and returns an inputstream * opens a url and returns an inputstream
* *
*/ */
private InputStream getXLSFromURL(String urlstring) { private InputStream getXLSFromURL(String urlstring) throws MalformedURLException, IOException {
InputStream is = null;
try {
URL url = new URL(urlstring); URL url = new URL(urlstring);
is = url.openStream(); URLConnection uc = url.openConnection();
} catch (Exception e) { String field = uc.getHeaderField(0);
e.printStackTrace(); for (int i=0;field != null; i++) {
System.out.println(field);
field = uc.getHeaderField(i);
} }
BufferedInputStream is = new BufferedInputStream(uc.getInputStream());
return is; return is;
} }

View File

@ -60,10 +60,10 @@ import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.io.*; import java.io.*;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFCell;
/** /**
* This class presents the sheets to the user. * This class presents the sheets to the user.
@ -73,38 +73,227 @@ import org.apache.poi.hssf.usermodel.HSSFCell;
* @author Jason Height * @author Jason Height
*/ */
public class SViewerPanel extends JPanel { 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 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*/ /**Construct the representation of the workbook*/
public SViewerPanel(HSSFWorkbook wb) { public SViewerPanel(HSSFWorkbook wb, boolean allowEdits) {
this.wb = wb; 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 //Initialise the Panel
JTabbedPane sheetPane = new JTabbedPane(JTabbedPane.BOTTOM); sheetPane = new JTabbedPane(JTabbedPane.BOTTOM);
if (allowEdits)
sheetPane.addMouseListener(createTabListener());
int sheetCount = wb.getNumberOfSheets(); int sheetCount = wb.getNumberOfSheets();
sheets = new JTable[sheetCount];
SVTableCellRenderer rnd = new SVTableCellRenderer(wb);
for (int i=0; i<sheetCount;i++) { for (int i=0; i<sheetCount;i++) {
String sheetName = wb.getSheetName(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 //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()); setLayout(new BorderLayout());
add(sheetPane, BorderLayout.CENTER); 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) { 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(); long start = System.currentTimeMillis();
super.paint(g); super.paint(g);
long elapsed = System.currentTimeMillis()-start; long elapsed = System.currentTimeMillis()-start;
System.out.println("Paint time = "+elapsed); 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*/ /**Main method*/
public static void main(String[] args) { public static void main(String[] args) {
try { try {
@ -112,7 +301,7 @@ public class SViewerPanel extends JPanel {
HSSFWorkbook wb = new HSSFWorkbook(in); HSSFWorkbook wb = new HSSFWorkbook(in);
in.close(); in.close();
SViewerPanel p = new SViewerPanel(wb); SViewerPanel p = new SViewerPanel(wb, true);
JFrame frame; JFrame frame;
frame = new JFrame() { frame = new JFrame() {
protected void processWindowEvent(WindowEvent e) { protected void processWindowEvent(WindowEvent e) {
@ -128,7 +317,7 @@ public class SViewerPanel extends JPanel {
}; };
frame.setTitle("Viewer Frame"); frame.setTitle("Viewer Frame");
frame.getContentPane().add(p, BorderLayout.CENTER); frame.getContentPane().add(p, BorderLayout.CENTER);
frame.setSize(400,320); frame.setSize(800,640);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2); frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2);
frame.setVisible(true); frame.setVisible(true);