Reindent to 4 spaces - optimize imports

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1870977 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2019-12-07 11:53:48 +00:00
parent b2a33515e9
commit de2467e9ae
8 changed files with 1393 additions and 1338 deletions

View File

@ -15,10 +15,12 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
package org.apache.poi.hssf.view; package org.apache.poi.hssf.view;
import java.awt.*; import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import javax.swing.border.AbstractBorder; import javax.swing.border.AbstractBorder;
@ -26,532 +28,532 @@ import org.apache.poi.ss.usermodel.BorderStyle;
/** /**
* This is an attempt to implement Excel style borders for the SheetViewer. * This is an attempt to implement Excel style borders for the SheetViewer.
* Mostly just overrides stuff so the javadoc won't appear here but will * Mostly just overrides stuff so the javadoc won't appear here but will
* appear in the generated stuff. * appear in the generated stuff.
* *
* @author Andrew C. Oliver (acoliver at apache dot org) * @author Andrew C. Oliver (acoliver at apache dot org)
* @author Jason Height * @author Jason Height
*/ */
public class SVBorder extends AbstractBorder { public class SVBorder extends AbstractBorder {
private Color northColor; private Color northColor;
private Color eastColor; private Color eastColor;
private Color southColor; private Color southColor;
private Color westColor; private Color westColor;
private BorderStyle northBorderType = BorderStyle.NONE; private BorderStyle northBorderType = BorderStyle.NONE;
private BorderStyle eastBorderType = BorderStyle.NONE; private BorderStyle eastBorderType = BorderStyle.NONE;
private BorderStyle southBorderType = BorderStyle.NONE; private BorderStyle southBorderType = BorderStyle.NONE;
private BorderStyle westBorderType = BorderStyle.NONE; private BorderStyle westBorderType = BorderStyle.NONE;
private boolean northBorder; private boolean northBorder;
private boolean eastBorder; private boolean eastBorder;
private boolean southBorder; private boolean southBorder;
private boolean westBorder; private boolean westBorder;
private boolean selected; private boolean selected;
public void setBorder(Color northColor, Color eastColor, public void setBorder(Color northColor, Color eastColor,
Color southColor, Color westColor, Color southColor, Color westColor,
BorderStyle northBorderType, BorderStyle eastBorderType, BorderStyle northBorderType, BorderStyle eastBorderType,
BorderStyle southBorderType, BorderStyle westBorderType, BorderStyle southBorderType, BorderStyle westBorderType,
boolean selected) { boolean selected) {
this.eastColor = eastColor; this.eastColor = eastColor;
this.southColor = southColor; this.southColor = southColor;
this.westColor = westColor; this.westColor = westColor;
this.northBorderType = northBorderType; this.northBorderType = northBorderType;
this.eastBorderType = eastBorderType; this.eastBorderType = eastBorderType;
this.southBorderType = southBorderType; this.southBorderType = southBorderType;
this.westBorderType = westBorderType; this.westBorderType = westBorderType;
this.northBorder=northBorderType != BorderStyle.NONE; this.northBorder = northBorderType != BorderStyle.NONE;
this.eastBorder=eastBorderType != BorderStyle.NONE; this.eastBorder = eastBorderType != BorderStyle.NONE;
this.southBorder=southBorderType != BorderStyle.NONE; this.southBorder = southBorderType != BorderStyle.NONE;
this.westBorder=westBorderType != BorderStyle.NONE; this.westBorder = westBorderType != BorderStyle.NONE;
this.selected = selected; this.selected = selected;
} }
@Override @Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height) { int height) {
Color oldColor = g.getColor(); Color oldColor = g.getColor();
paintSelectedBorder(g, x, y, width, height); paintSelectedBorder(g, x, y, width, height);
paintNormalBorders(g, x, y, width, height); paintNormalBorders(g, x, y, width, height);
paintDottedBorders(g, x, y, width, height); paintDottedBorders(g, x, y, width, height);
paintDashedBorders(g, x, y, width, height); paintDashedBorders(g, x, y, width, height);
paintDoubleBorders(g, x, y, width, height); paintDoubleBorders(g, x, y, width, height);
paintDashDotDotBorders(g, x, y, width, height); paintDashDotDotBorders(g, x, y, width, height);
g.setColor(oldColor); g.setColor(oldColor);
} }
/** /**
* Called by paintBorder to paint the border of a selected cell. * Called by paintBorder to paint the border of a selected cell.
* The paramaters are the Graphics object, location and dimensions of the * The paramaters are the Graphics object, location and dimensions of the
* cell. * cell.
*/ */
private void paintSelectedBorder(Graphics g, int x, int y, int width, private void paintSelectedBorder(Graphics g, int x, int y, int width,
int height) { int height) {
if (selected) { if (selected) {
//Need to setup thickness of 2 //Need to setup thickness of 2
g.setColor(Color.black); g.setColor(Color.black);
//paint the border //paint the border
g.drawRect(x,y,width-1,height-1); g.drawRect(x, y, width - 1, height - 1);
//paint the filled rectangle at the bottom left hand position //paint the filled rectangle at the bottom left hand position
g.fillRect(x+width-5, y+height-5, 5, 5); g.fillRect(x + width - 5, y + height - 5, 5, 5);
}
}
/**
* Called by paintBorder to paint the various versions of normal line
* borders for a cell.
*/
private void paintNormalBorders(Graphics g, int x, int y, int width,
int height) {
if (northBorder &&
((northBorderType == BorderStyle.THIN) ||
(northBorderType == BorderStyle.MEDIUM) ||
(northBorderType == BorderStyle.THICK)
)
) {
int thickness = getThickness(northBorderType);
g.setColor(northColor);
for (int k=0; k < thickness; k++) {
g.drawLine(x,y+k,width,y+k);
} }
} }
if (eastBorder &&
((eastBorderType == BorderStyle.THIN) ||
(eastBorderType == BorderStyle.MEDIUM) ||
(eastBorderType == BorderStyle.THICK)
)
) {
int thickness = getThickness(eastBorderType); /**
* Called by paintBorder to paint the various versions of normal line
* borders for a cell.
*/
private void paintNormalBorders(Graphics g, int x, int y, int width,
int height) {
g.setColor(eastColor); if (northBorder &&
((northBorderType == BorderStyle.THIN) ||
(northBorderType == BorderStyle.MEDIUM) ||
(northBorderType == BorderStyle.THICK)
)
) {
for (int k=0; k < thickness; k++) { int thickness = getThickness(northBorderType);
g.drawLine(width-k,y,width-k,height);
g.setColor(northColor);
for (int k = 0; k < thickness; k++) {
g.drawLine(x, y + k, width, y + k);
}
} }
}
if (southBorder && if (eastBorder &&
((southBorderType == BorderStyle.THIN) || ((eastBorderType == BorderStyle.THIN) ||
(southBorderType == BorderStyle.MEDIUM) || (eastBorderType == BorderStyle.MEDIUM) ||
(southBorderType == BorderStyle.THICK) (eastBorderType == BorderStyle.THICK)
) )
) { ) {
int thickness = getThickness(southBorderType); int thickness = getThickness(eastBorderType);
g.setColor(southColor); g.setColor(eastColor);
for (int k=0; k < thickness; k++) {
g.drawLine(x,height - k,width,height - k); for (int k = 0; k < thickness; k++) {
g.drawLine(width - k, y, width - k, height);
}
} }
}
if (westBorder && if (southBorder &&
((westBorderType == BorderStyle.THIN) || ((southBorderType == BorderStyle.THIN) ||
(westBorderType == BorderStyle.MEDIUM) || (southBorderType == BorderStyle.MEDIUM) ||
(westBorderType == BorderStyle.THICK) (southBorderType == BorderStyle.THICK)
) )
) { ) {
int thickness = getThickness(westBorderType); int thickness = getThickness(southBorderType);
g.setColor(westColor); g.setColor(southColor);
for (int k = 0; k < thickness; k++) {
for (int k=0; k < thickness; k++) { g.drawLine(x, height - k, width, height - k);
g.drawLine(x+k,y,x+k,height); }
} }
}
}
/** if (westBorder &&
* Called by paintBorder to paint the dotted line ((westBorderType == BorderStyle.THIN) ||
* borders for a cell. (westBorderType == BorderStyle.MEDIUM) ||
*/ (westBorderType == BorderStyle.THICK)
private void paintDottedBorders(Graphics g, int x, int y, int width, )
int height) { ) {
if (northBorder &&
northBorderType == BorderStyle.DOTTED) {
int thickness = getThickness(northBorderType);
g.setColor(northColor); int thickness = getThickness(westBorderType);
for (int k=0; k < thickness; k++) { g.setColor(westColor);
for (int xc = x; xc < width; xc=xc+2) {
g.drawLine(xc,y+k,xc,y+k); for (int k = 0; k < thickness; k++) {
} g.drawLine(x + k, y, x + k, height);
}
} }
} }
if (eastBorder && /**
eastBorderType == BorderStyle.DOTTED * Called by paintBorder to paint the dotted line
) { * borders for a cell.
*/
private void paintDottedBorders(Graphics g, int x, int y, int width,
int height) {
if (northBorder &&
northBorderType == BorderStyle.DOTTED) {
int thickness = getThickness(northBorderType);
int thickness = getThickness(eastBorderType); g.setColor(northColor);
thickness++; //need for dotted borders to show up east
g.setColor(eastColor); for (int k = 0; k < thickness; k++) {
for (int xc = x; xc < width; xc = xc + 2) {
for (int k=0; k < thickness; k++) { g.drawLine(xc, y + k, xc, y + k);
for (int yc=y;yc < height; yc=yc+2) { }
g.drawLine(width-k,yc,width-k,yc); }
}
} }
}
if (southBorder && if (eastBorder &&
southBorderType == BorderStyle.DOTTED eastBorderType == BorderStyle.DOTTED
) { ) {
int thickness = getThickness(southBorderType); int thickness = getThickness(eastBorderType);
thickness++; thickness++; //need for dotted borders to show up east
g.setColor(southColor);
for (int k=0; k < thickness; k++) { g.setColor(eastColor);
for (int xc = x; xc < width; xc=xc+2) {
g.drawLine(xc,height-k,xc,height-k); for (int k = 0; k < thickness; k++) {
} for (int yc = y; yc < height; yc = yc + 2) {
g.drawLine(width - k, yc, width - k, yc);
}
}
} }
}
if (westBorder && if (southBorder &&
westBorderType == BorderStyle.DOTTED southBorderType == BorderStyle.DOTTED
) { ) {
int thickness = getThickness(westBorderType); int thickness = getThickness(southBorderType);
thickness++;
g.setColor(southColor);
for (int k = 0; k < thickness; k++) {
for (int xc = x; xc < width; xc = xc + 2) {
g.drawLine(xc, height - k, xc, height - k);
}
}
}
if (westBorder &&
westBorderType == BorderStyle.DOTTED
) {
int thickness = getThickness(westBorderType);
// thickness++; // thickness++;
g.setColor(westColor); g.setColor(westColor);
for (int k=0; k < thickness; k++) { for (int k = 0; k < thickness; k++) {
for (int yc=y;yc < height; yc=yc+2) { for (int yc = y; yc < height; yc = yc + 2) {
g.drawLine(x+k,yc,x+k,yc); g.drawLine(x + k, yc, x + k, yc);
} }
}
} }
} }
}
/** /**
* Called by paintBorder to paint the various versions of dotted line * Called by paintBorder to paint the various versions of dotted line
* borders for a cell. * borders for a cell.
*/ */
private void paintDashedBorders(Graphics g, int x, int y, int width, private void paintDashedBorders(Graphics g, int x, int y, int width,
int height) { int height) {
if (northBorder && if (northBorder &&
((northBorderType == BorderStyle.DASHED) || ((northBorderType == BorderStyle.DASHED) ||
(northBorderType == BorderStyle.HAIR)) (northBorderType == BorderStyle.HAIR))
) { ) {
int thickness = getThickness(northBorderType); int thickness = getThickness(northBorderType);
int dashlength = 1; int dashlength = 1;
if (northBorderType == BorderStyle.DASHED) if (northBorderType == BorderStyle.DASHED)
dashlength = 2; dashlength = 2;
g.setColor(northColor); g.setColor(northColor);
for (int k=0; k < thickness; k++) { for (int k = 0; k < thickness; k++) {
for (int xc = x; xc < width; xc=xc+5) { for (int xc = x; xc < width; xc = xc + 5) {
g.drawLine(xc,y+k,xc+dashlength,y+k); g.drawLine(xc, y + k, xc + dashlength, y + k);
} }
}
} }
}
if (eastBorder && if (eastBorder &&
((eastBorderType == BorderStyle.DASHED) || ((eastBorderType == BorderStyle.DASHED) ||
(eastBorderType == BorderStyle.HAIR)) (eastBorderType == BorderStyle.HAIR))
) { ) {
int thickness = getThickness(eastBorderType); int thickness = getThickness(eastBorderType);
thickness++; //need for dotted borders to show up east thickness++; //need for dotted borders to show up east
int dashlength = 1; int dashlength = 1;
if (eastBorderType == BorderStyle.DASHED) if (eastBorderType == BorderStyle.DASHED)
dashlength = 2; dashlength = 2;
g.setColor(eastColor); g.setColor(eastColor);
for (int k=0; k < thickness; k++) { for (int k = 0; k < thickness; k++) {
for (int yc=y;yc < height; yc=yc+5) { for (int yc = y; yc < height; yc = yc + 5) {
g.drawLine(width-k,yc,width-k,yc+dashlength); g.drawLine(width - k, yc, width - k, yc + dashlength);
} }
}
} }
}
if (southBorder && if (southBorder &&
((southBorderType == BorderStyle.DASHED) || ((southBorderType == BorderStyle.DASHED) ||
(southBorderType == BorderStyle.HAIR)) (southBorderType == BorderStyle.HAIR))
) { ) {
int thickness = getThickness(southBorderType); int thickness = getThickness(southBorderType);
thickness++; thickness++;
int dashlength = 1; int dashlength = 1;
if (southBorderType == BorderStyle.DASHED) if (southBorderType == BorderStyle.DASHED)
dashlength = 2; dashlength = 2;
g.setColor(southColor); g.setColor(southColor);
for (int k=0; k < thickness; k++) { for (int k = 0; k < thickness; k++) {
for (int xc = x; xc < width; xc=xc+5) { for (int xc = x; xc < width; xc = xc + 5) {
g.drawLine(xc,height-k,xc+dashlength,height-k); g.drawLine(xc, height - k, xc + dashlength, height - k);
} }
}
} }
}
if (westBorder && if (westBorder &&
((westBorderType == BorderStyle.DASHED) || ((westBorderType == BorderStyle.DASHED) ||
(westBorderType == BorderStyle.HAIR)) (westBorderType == BorderStyle.HAIR))
) { ) {
int thickness = getThickness(westBorderType); int thickness = getThickness(westBorderType);
// thickness++; // thickness++;
int dashlength = 1; int dashlength = 1;
if (westBorderType == BorderStyle.DASHED) if (westBorderType == BorderStyle.DASHED)
dashlength = 2; dashlength = 2;
g.setColor(westColor); g.setColor(westColor);
for (int k=0; k < thickness; k++) { for (int k = 0; k < thickness; k++) {
for (int yc=y;yc < height; yc=yc+5) { for (int yc = y; yc < height; yc = yc + 5) {
g.drawLine(x+k,yc,x+k,yc+dashlength); g.drawLine(x + k, yc, x + k, yc + dashlength);
} }
}
} }
} }
}
/** /**
* Called by paintBorder to paint the double line * Called by paintBorder to paint the double line
* borders for a cell. * borders for a cell.
*/ */
private void paintDoubleBorders(Graphics g, int x, int y, int width, private void paintDoubleBorders(Graphics g, int x, int y, int width,
int height) { int height) {
if (northBorder && if (northBorder &&
northBorderType == BorderStyle.DOUBLE) { northBorderType == BorderStyle.DOUBLE) {
g.setColor(northColor); g.setColor(northColor);
int leftx=x; int leftx = x;
int rightx=width; int rightx = width;
// if there are borders on the west or east then // if there are borders on the west or east then
// the second line shouldn't cross them // the second line shouldn't cross them
if (westBorder) { if (westBorder) {
leftx = x + 3; leftx = x + 3;
}
if (eastBorder) {
rightx = width - 3;
}
g.drawLine(x, y, width, y);
g.drawLine(leftx, y + 2, rightx, y + 2);
} }
if (eastBorder) { if (eastBorder &&
rightx = width - 3; eastBorderType == BorderStyle.DOUBLE
) {
int thickness = getThickness(eastBorderType);
thickness++; //need for dotted borders to show up east
g.setColor(eastColor);
int topy = y;
int bottomy = height;
if (northBorder) {
topy = y + 3;
}
if (southBorder) {
bottomy = height - 3;
}
g.drawLine(width - 1, y, width - 1, height);
g.drawLine(width - 3, topy, width - 3, bottomy);
} }
g.drawLine(x,y,width,y); if (southBorder &&
g.drawLine(leftx,y+2,rightx,y+2); southBorderType == BorderStyle.DOUBLE
} ) {
if (eastBorder && g.setColor(southColor);
eastBorderType == BorderStyle.DOUBLE
) {
int thickness = getThickness(eastBorderType); int leftx = y;
thickness++; //need for dotted borders to show up east int rightx = width;
g.setColor(eastColor); if (westBorder)
leftx = x + 3;
int topy=y; if (eastBorder)
int bottomy=height; rightx = width - 3;
if (northBorder) {
topy = y + 3; g.drawLine(x, height - 1, width, height - 1);
g.drawLine(leftx, height - 3, rightx, height - 3);
} }
if (southBorder) { if (westBorder &&
bottomy = height - 3; westBorderType == BorderStyle.DOUBLE
} ) {
g.drawLine(width-1,y,width-1,height); int thickness = getThickness(westBorderType);
g.drawLine(width-3,topy,width-3,bottomy);
}
if (southBorder &&
southBorderType == BorderStyle.DOUBLE
) {
g.setColor(southColor);
int leftx=y;
int rightx=width;
if (westBorder)
leftx=x+3;
if (eastBorder)
rightx=width-3;
g.drawLine(x,height - 1,width,height - 1);
g.drawLine(leftx,height - 3,rightx,height - 3);
}
if (westBorder &&
westBorderType == BorderStyle.DOUBLE
) {
int thickness = getThickness(westBorderType);
// thickness++; // thickness++;
g.setColor(westColor); g.setColor(westColor);
int topy=y; int topy = y;
int bottomy=height-3; int bottomy = height - 3;
if (northBorder) if (northBorder)
topy=y+2; topy = y + 2;
if (southBorder) if (southBorder)
bottomy=height-3; bottomy = height - 3;
g.drawLine(x,y,x,height); g.drawLine(x, y, x, height);
g.drawLine(x+2,topy,x+2,bottomy); g.drawLine(x + 2, topy, x + 2, bottomy);
} }
} }
/** /**
* Called by paintBorder to paint the various versions of dash dot dot line * Called by paintBorder to paint the various versions of dash dot dot line
* borders for a cell. * borders for a cell.
*/ */
private void paintDashDotDotBorders(Graphics g, int x, int y, int width, private void paintDashDotDotBorders(Graphics g, int x, int y, int width,
int height) { int height) {
if (northBorder && if (northBorder &&
((northBorderType == BorderStyle.DASH_DOT_DOT) || ((northBorderType == BorderStyle.DASH_DOT_DOT) ||
(northBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT)) (northBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT))
) { ) {
int thickness = getThickness(northBorderType); int thickness = getThickness(northBorderType);
g.setColor(northColor);
for (int l = x; l < width; ) {
l = l + drawDashDotDot(g, l, y, thickness, true, true);
}
g.setColor(northColor);
for (int l=x; l < width;) {
l=l+drawDashDotDot(g, l, y, thickness, true, true);
} }
} if (eastBorder &&
((eastBorderType == BorderStyle.DASH_DOT_DOT) ||
(eastBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT))
) {
if (eastBorder && int thickness = getThickness(eastBorderType);
((eastBorderType == BorderStyle.DASH_DOT_DOT) ||
(eastBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT))
) {
int thickness = getThickness(eastBorderType); g.setColor(eastColor);
g.setColor(eastColor); for (int l = y; l < height; ) {
//System.err.println("drawing east");
for (int l=y;l < height;) { l = l + drawDashDotDot(g, width - 1, l, thickness, false, false);
//System.err.println("drawing east"); }
l=l+drawDashDotDot(g,width-1,l,thickness,false,false);
}
}
if (southBorder &&
((southBorderType == BorderStyle.DASH_DOT_DOT) ||
(southBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT))
) {
int thickness = getThickness(southBorderType);
g.setColor(southColor);
for (int l=x; l < width;) {
//System.err.println("drawing south");
l=l+drawDashDotDot(g, l, height-1, thickness, true, false);
}
}
if (westBorder &&
((westBorderType == BorderStyle.DASH_DOT_DOT) ||
(westBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT))
) {
int thickness = getThickness(westBorderType);
g.setColor(westColor);
for (int l=y;l < height;) {
//System.err.println("drawing west");
l=l+drawDashDotDot(g,x,l,thickness,false,true);
} }
} if (southBorder &&
} ((southBorderType == BorderStyle.DASH_DOT_DOT) ||
(southBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT))
) {
/** int thickness = getThickness(southBorderType);
* Draws one dash dot dot horizontally or vertically with thickness drawn
* incrementally to either the right or left.
*
* @param g graphics object for drawing with
* @param x the x origin of the line
* @param y the y origin of the line
* @param thickness the thickness of the line
* @param horizontal or vertical (true for horizontal)
* @param rightBottom or left/top thickness (true for right or top),
* if true then the x or y origin will be incremented to provide
* thickness, if false, they'll be decremented. For vertical
* borders, x is incremented or decremented, for horizontal its y.
* Just set to true for north and west, and false for east and
* south.
* @return length - returns the length of the line.
*/
private int drawDashDotDot(Graphics g,int x, int y, int thickness,
boolean horizontal,
boolean rightBottom) {
for (int t=0; t < thickness; t++) { g.setColor(southColor);
if (!rightBottom) {
t = 0 - t; //add negative thickness so we go the other way
//then we'll decrement instead of increment.
}
if (horizontal) {
g.drawLine(x,y+t,x+5,y+t);
g.drawLine(x+8,y+t,x+10,y+t);
g.drawLine(x+13,y+t,x+15,y+t);
} else {
g.drawLine(x+t,y,x+t,y+5);
g.drawLine(x+t,y+8,x+t,y+10);
g.drawLine(x+t,y+13,x+t,y+15);
}
}
return 18;
}
/** for (int l = x; l < width; ) {
* @return the line thickness for a border based on border type //System.err.println("drawing south");
*/ l = l + drawDashDotDot(g, l, height - 1, thickness, true, false);
private int getThickness(BorderStyle thickness) { }
switch (thickness) { }
case DASH_DOT_DOT:
case DASHED: if (westBorder &&
case HAIR: ((westBorderType == BorderStyle.DASH_DOT_DOT) ||
return 1; (westBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT))
case THIN: ) {
return 2;
case MEDIUM: int thickness = getThickness(westBorderType);
case MEDIUM_DASH_DOT_DOT:
return 3; g.setColor(westColor);
case THICK:
return 4; for (int l = y; l < height; ) {
default: //System.err.println("drawing west");
return 1; l = l + drawDashDotDot(g, x, l, thickness, false, true);
} }
}
}
}
/**
* Draws one dash dot dot horizontally or vertically with thickness drawn
* incrementally to either the right or left.
*
* @param g graphics object for drawing with
* @param x the x origin of the line
* @param y the y origin of the line
* @param thickness the thickness of the line
* @param horizontal or vertical (true for horizontal)
* @param rightBottom or left/top thickness (true for right or top),
* if true then the x or y origin will be incremented to provide
* thickness, if false, they'll be decremented. For vertical
* borders, x is incremented or decremented, for horizontal its y.
* Just set to true for north and west, and false for east and
* south.
* @return length - returns the length of the line.
*/
private int drawDashDotDot(Graphics g, int x, int y, int thickness,
boolean horizontal,
boolean rightBottom) {
for (int t = 0; t < thickness; t++) {
if (!rightBottom) {
t = 0 - t; //add negative thickness so we go the other way
//then we'll decrement instead of increment.
}
if (horizontal) {
g.drawLine(x, y + t, x + 5, y + t);
g.drawLine(x + 8, y + t, x + 10, y + t);
g.drawLine(x + 13, y + t, x + 15, y + t);
} else {
g.drawLine(x + t, y, x + t, y + 5);
g.drawLine(x + t, y + 8, x + t, y + 10);
g.drawLine(x + t, y + 13, x + t, y + 15);
}
}
return 18;
}
/**
* @return the line thickness for a border based on border type
*/
private int getThickness(BorderStyle thickness) {
switch (thickness) {
case DASH_DOT_DOT:
case DASHED:
case HAIR:
return 1;
case THIN:
return 2;
case MEDIUM:
case MEDIUM_DASH_DOT_DOT:
return 3;
case THICK:
return 4;
default:
return 1;
}
}
} }

View File

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

View File

@ -15,85 +15,95 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
package org.apache.poi.hssf.view; package org.apache.poi.hssf.view;
import java.awt.*; import java.awt.Component;
import javax.swing.*; import java.awt.Dimension;
import javax.swing.table.*;
import org.apache.poi.hssf.usermodel.*; import javax.swing.AbstractListModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.UIManager;
import javax.swing.table.JTableHeader;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
/** /**
* This class presents the row header to the table. * This class presents the row header to the table.
* *
*
* @author Jason Height * @author Jason Height
*/ */
public class SVRowHeader extends JList<Object> { public class SVRowHeader extends JList<Object> {
/** This model simply returns an integer number up to the number of rows /**
* that are present in the sheet. * This model simply returns an integer number up to the number of rows
* * that are present in the sheet.
*/ */
private class SVRowHeaderModel extends AbstractListModel<Object> { private class SVRowHeaderModel extends AbstractListModel<Object> {
private HSSFSheet sheet; private HSSFSheet sheet;
public SVRowHeaderModel(HSSFSheet sheet) { public SVRowHeaderModel(HSSFSheet sheet) {
this.sheet = sheet; this.sheet = sheet;
}
@Override
public int getSize() {
return sheet.getLastRowNum() + 1;
}
@Override
public Object getElementAt(int index) {
return Integer.toString(index + 1);
}
} }
@Override /**
public int getSize() { * Renderes the row number
return sheet.getLastRowNum() + 1; */
} private class RowHeaderRenderer extends JLabel implements ListCellRenderer<Object> {
@Override private HSSFSheet sheet;
public Object getElementAt(int index) { private int extraHeight;
return Integer.toString(index+1);
}
}
/** Renderes the row number*/ RowHeaderRenderer(HSSFSheet sheet, JTable table, int extraHeight) {
private class RowHeaderRenderer extends JLabel implements ListCellRenderer<Object> { this.sheet = sheet;
private HSSFSheet sheet; this.extraHeight = extraHeight;
private int extraHeight; JTableHeader header = table.getTableHeader();
setOpaque(true);
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
setHorizontalAlignment(CENTER);
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
RowHeaderRenderer(HSSFSheet sheet, JTable table, int extraHeight) { @Override
this.sheet = sheet; public Component getListCellRendererComponent(JList list,
this.extraHeight = extraHeight; Object value, int index, boolean isSelected, boolean cellHasFocus) {
JTableHeader header = table.getTableHeader(); Dimension d = getPreferredSize();
setOpaque(true); HSSFRow row = sheet.getRow(index);
setBorder(UIManager.getBorder("TableHeader.cellBorder")); int rowHeight;
setHorizontalAlignment(CENTER); if (row == null) {
setForeground(header.getForeground()); rowHeight = (int) sheet.getDefaultRowHeightInPoints();
setBackground(header.getBackground()); } else {
setFont(header.getFont()); rowHeight = (int) row.getHeightInPoints();
}
d.height = rowHeight + extraHeight;
setPreferredSize(d);
setText((value == null) ? "" : value.toString());
return this;
}
} }
@Override public SVRowHeader(HSSFSheet sheet, JTable table, int extraHeight) {
public Component getListCellRendererComponent( JList list, ListModel<Object> lm = new SVRowHeaderModel(sheet);
Object value, int index, boolean isSelected, boolean cellHasFocus) { this.setModel(lm);
Dimension d = getPreferredSize();
HSSFRow row = sheet.getRow(index); setFixedCellWidth(50);
int rowHeight; setCellRenderer(new RowHeaderRenderer(sheet, table, extraHeight));
if(row == null) {
rowHeight = (int)sheet.getDefaultRowHeightInPoints();
} else {
rowHeight = (int)row.getHeightInPoints();
}
d.height = rowHeight+extraHeight;
setPreferredSize(d);
setText((value == null) ? "" : value.toString());
return this;
} }
}
public SVRowHeader(HSSFSheet sheet, JTable table, int extraHeight) {
ListModel<Object> lm = new SVRowHeaderModel(sheet);
this.setModel(lm);
setFixedCellWidth(50);
setCellRenderer(new RowHeaderRenderer(sheet, table, extraHeight));
}
} }

View File

@ -54,208 +54,208 @@ import org.apache.poi.ss.usermodel.Row;
* @author Ken Arnold, Industrious Media LLC * @author Ken Arnold, Industrious Media LLC
*/ */
public class SVSheetTable extends JTable { public class SVSheetTable extends JTable {
private final HSSFSheet sheet; private final HSSFSheet sheet;
private final PendingPaintings pendingPaintings; private final PendingPaintings pendingPaintings;
private FormulaDisplayListener formulaListener; private FormulaDisplayListener formulaListener;
private JScrollPane scroll; private JScrollPane scroll;
private static final Color HEADER_BACKGROUND = new Color(235, 235, 235); private static final Color HEADER_BACKGROUND = new Color(235, 235, 235);
/** /**
* This field is the magic number to convert from a Character width to a java * This field is the magic number to convert from a Character width to a java
* pixel width. * pixel width.
* <p> * <p>
* When the "normal" font size in a workbook changes, this effects all of the * 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 * heights and widths. Unfortunately there is no way to retrieve this
* information, hence the MAGIC number. * information, hence the MAGIC number.
* <p> * <p>
* This number may only work for the normal style font size of Arial size 10. * This number may only work for the normal style font size of Arial size 10.
*/ */
private static final int magicCharFactor = 7; private static final int magicCharFactor = 7;
private class HeaderCell extends JLabel { private class HeaderCell extends JLabel {
private final int row; private final int row;
public HeaderCell(Object value, int row) { public HeaderCell(Object value, int row) {
super(value.toString(), CENTER); super(value.toString(), CENTER);
this.row = row; this.row = row;
setBackground(HEADER_BACKGROUND); setBackground(HEADER_BACKGROUND);
setOpaque(true); setOpaque(true);
setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
setRowSelectionAllowed(false); setRowSelectionAllowed(false);
}
@Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
if (row >= 0) {
d.height = getRowHeight(row);
}
return d;
}
@Override
public Dimension getMaximumSize() {
Dimension d = super.getMaximumSize();
if (row >= 0) {
d.height = getRowHeight(row);
}
return d;
}
@Override
public Dimension getMinimumSize() {
Dimension d = super.getMinimumSize();
if (row >= 0) {
d.height = getRowHeight(row);
}
return d;
}
}
private class HeaderCellRenderer implements TableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
return new HeaderCell(value, row);
}
}
private class FormulaDisplayListener implements ListSelectionListener {
private final JTextComponent formulaDisplay;
public FormulaDisplayListener(JTextComponent formulaDisplay) {
this.formulaDisplay = formulaDisplay;
}
@Override
public void valueChanged(ListSelectionEvent e) {
int row = getSelectedRow();
int col = getSelectedColumn();
if (row < 0 || col < 0) {
return;
}
if (e.getValueIsAdjusting()) {
return;
}
HSSFCell cell = (HSSFCell) getValueAt(row, col);
String formula = "";
if (cell != null) {
if (cell.getCellType() == CellType.FORMULA) {
formula = cell.getCellFormula();
} else {
formula = cell.toString();
} }
if (formula == null)
formula = "";
}
formulaDisplay.setText(formula);
}
}
public SVSheetTable(HSSFSheet sheet) { @Override
super(new SVTableModel(sheet)); public Dimension getPreferredSize() {
this.sheet = sheet; Dimension d = super.getPreferredSize();
if (row >= 0) {
setIntercellSpacing(new Dimension(0, 0)); d.height = getRowHeight(row);
setAutoResizeMode(AUTO_RESIZE_OFF);
JTableHeader header = getTableHeader();
header.setDefaultRenderer(new HeaderCellRenderer());
pendingPaintings = new PendingPaintings(this);
//Set the columns the correct size
TableColumnModel columns = getColumnModel();
for (int i = 0; i < columns.getColumnCount(); i++) {
TableColumn column = columns.getColumn(i);
int width = sheet.getColumnWidth(i);
//256 is because the width is in 256ths of a character
column.setPreferredWidth(width / 256 * magicCharFactor);
}
Toolkit t = getToolkit();
int res = t.getScreenResolution();
TableModel model = getModel();
for (int i = 0; i < model.getRowCount(); i++) {
Row row = sheet.getRow(i - sheet.getFirstRowNum());
if (row != null) {
short h = row.getHeight();
int height = Math.toIntExact(Math.round(Math.max(1., h / (res / 70. * 20.) + 3.)));
System.out.printf("%d: %d (%d @ %d)%n", i, height, h, res);
setRowHeight(i, height);
}
}
addHierarchyListener(new HierarchyListener() {
@Override
public void hierarchyChanged(HierarchyEvent e) {
if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0) {
Container changedParent = e.getChangedParent();
if (changedParent instanceof JViewport) {
Container grandparent = changedParent.getParent();
if (grandparent instanceof JScrollPane) {
JScrollPane jScrollPane = (JScrollPane) grandparent;
setupScroll(jScrollPane);
} }
} return d;
} }
}
});
}
public void setupScroll(JScrollPane scroll) { @Override
if (scroll == this.scroll) public Dimension getMaximumSize() {
return; Dimension d = super.getMaximumSize();
if (row >= 0) {
d.height = getRowHeight(row);
}
return d;
}
this.scroll = scroll; @Override
if (scroll == null) public Dimension getMinimumSize() {
return; Dimension d = super.getMinimumSize();
if (row >= 0) {
SVRowHeader rowHeader = new SVRowHeader(sheet, this, 0); d.height = getRowHeight(row);
scroll.setRowHeaderView(rowHeader); }
scroll.setCorner(JScrollPane.UPPER_LEADING_CORNER, headerCell("?")); return d;
} }
public void setFormulaDisplay(JTextComponent formulaDisplay) {
ListSelectionModel rowSelMod = getSelectionModel();
ListSelectionModel colSelMod = getColumnModel().getSelectionModel();
if (formulaDisplay == null) {
rowSelMod.removeListSelectionListener(formulaListener);
colSelMod.removeListSelectionListener(formulaListener);
formulaListener = null;
} }
if (formulaDisplay != null) { private class HeaderCellRenderer implements TableCellRenderer {
formulaListener = new FormulaDisplayListener(formulaDisplay); @Override
rowSelMod.addListSelectionListener(formulaListener); public Component getTableCellRendererComponent(JTable table, Object value,
colSelMod.addListSelectionListener(formulaListener); boolean isSelected, boolean hasFocus, int row, int column) {
return new HeaderCell(value, row);
}
} }
}
public JTextComponent getFormulaDisplay() { private class FormulaDisplayListener implements ListSelectionListener {
if (formulaListener == null) private final JTextComponent formulaDisplay;
return null;
else
return formulaListener.formulaDisplay;
}
public Component headerCell(String text) { public FormulaDisplayListener(JTextComponent formulaDisplay) {
return new HeaderCell(text, -1); this.formulaDisplay = formulaDisplay;
} }
@Override @Override
public void paintComponent(Graphics g1) { public void valueChanged(ListSelectionEvent e) {
Graphics2D g = (Graphics2D) g1; int row = getSelectedRow();
int col = getSelectedColumn();
if (row < 0 || col < 0) {
return;
}
pendingPaintings.clear(); if (e.getValueIsAdjusting()) {
return;
}
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, HSSFCell cell = (HSSFCell) getValueAt(row, col);
RenderingHints.VALUE_ANTIALIAS_ON); String formula = "";
super.paintComponent(g); if (cell != null) {
if (cell.getCellType() == CellType.FORMULA) {
formula = cell.getCellFormula();
} else {
formula = cell.toString();
}
if (formula == null)
formula = "";
}
formulaDisplay.setText(formula);
}
}
pendingPaintings.paint(g); public SVSheetTable(HSSFSheet sheet) {
} super(new SVTableModel(sheet));
this.sheet = sheet;
setIntercellSpacing(new Dimension(0, 0));
setAutoResizeMode(AUTO_RESIZE_OFF);
JTableHeader header = getTableHeader();
header.setDefaultRenderer(new HeaderCellRenderer());
pendingPaintings = new PendingPaintings(this);
//Set the columns the correct size
TableColumnModel columns = getColumnModel();
for (int i = 0; i < columns.getColumnCount(); i++) {
TableColumn column = columns.getColumn(i);
int width = sheet.getColumnWidth(i);
//256 is because the width is in 256ths of a character
column.setPreferredWidth(width / 256 * magicCharFactor);
}
Toolkit t = getToolkit();
int res = t.getScreenResolution();
TableModel model = getModel();
for (int i = 0; i < model.getRowCount(); i++) {
Row row = sheet.getRow(i - sheet.getFirstRowNum());
if (row != null) {
short h = row.getHeight();
int height = Math.toIntExact(Math.round(Math.max(1., h / (res / 70. * 20.) + 3.)));
System.out.printf("%d: %d (%d @ %d)%n", i, height, h, res);
setRowHeight(i, height);
}
}
addHierarchyListener(new HierarchyListener() {
@Override
public void hierarchyChanged(HierarchyEvent e) {
if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0) {
Container changedParent = e.getChangedParent();
if (changedParent instanceof JViewport) {
Container grandparent = changedParent.getParent();
if (grandparent instanceof JScrollPane) {
JScrollPane jScrollPane = (JScrollPane) grandparent;
setupScroll(jScrollPane);
}
}
}
}
});
}
public void setupScroll(JScrollPane scroll) {
if (scroll == this.scroll)
return;
this.scroll = scroll;
if (scroll == null)
return;
SVRowHeader rowHeader = new SVRowHeader(sheet, this, 0);
scroll.setRowHeaderView(rowHeader);
scroll.setCorner(JScrollPane.UPPER_LEADING_CORNER, headerCell("?"));
}
public void setFormulaDisplay(JTextComponent formulaDisplay) {
ListSelectionModel rowSelMod = getSelectionModel();
ListSelectionModel colSelMod = getColumnModel().getSelectionModel();
if (formulaDisplay == null) {
rowSelMod.removeListSelectionListener(formulaListener);
colSelMod.removeListSelectionListener(formulaListener);
formulaListener = null;
}
if (formulaDisplay != null) {
formulaListener = new FormulaDisplayListener(formulaDisplay);
rowSelMod.addListSelectionListener(formulaListener);
colSelMod.addListSelectionListener(formulaListener);
}
}
public JTextComponent getFormulaDisplay() {
if (formulaListener == null)
return null;
else
return formulaListener.formulaDisplay;
}
public Component headerCell(String text) {
return new HeaderCell(text, -1);
}
@Override
public void paintComponent(Graphics g1) {
Graphics2D g = (Graphics2D) g1;
pendingPaintings.clear();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
super.paintComponent(g);
pendingPaintings.paint(g);
}
} }

View File

@ -15,7 +15,7 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
package org.apache.poi.hssf.view; package org.apache.poi.hssf.view;
@ -50,234 +50,237 @@ import org.apache.poi.ss.usermodel.FillPatternType;
* @author Andrew C. Oliver * @author Andrew C. Oliver
*/ */
public class SVTableCellRenderer extends JLabel public class SVTableCellRenderer extends JLabel
implements TableCellRenderer, Serializable implements TableCellRenderer, Serializable {
{
protected static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); protected static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
protected SVBorder cellBorder = new SVBorder(); protected SVBorder cellBorder = new SVBorder();
private HSSFWorkbook wb; private HSSFWorkbook wb;
/** This class holds the references to the predefined cell formats. /**
* This class holds the references to the predefined cell formats.
*/ */
private class CellFormatter { private class CellFormatter {
private Format[] textFormatter; private Format[] textFormatter;
private DecimalFormat generalNumberFormat = new DecimalFormat("0"); private DecimalFormat generalNumberFormat = new DecimalFormat("0");
public CellFormatter() { public CellFormatter() {
textFormatter = new Format[0x31]; textFormatter = new Format[0x31];
textFormatter[0x01] = new DecimalFormat("0"); textFormatter[0x01] = new DecimalFormat("0");
textFormatter[0x02] = new DecimalFormat("0.00"); textFormatter[0x02] = new DecimalFormat("0.00");
textFormatter[0x03] = new DecimalFormat("#,##0"); textFormatter[0x03] = new DecimalFormat("#,##0");
textFormatter[0x04] = new DecimalFormat("#,##0.00"); textFormatter[0x04] = new DecimalFormat("#,##0.00");
textFormatter[0x05] = new DecimalFormat("$#,##0;$#,##0"); textFormatter[0x05] = new DecimalFormat("$#,##0;$#,##0");
textFormatter[0x06] = new DecimalFormat("$#,##0;$#,##0"); textFormatter[0x06] = new DecimalFormat("$#,##0;$#,##0");
textFormatter[0x07] = new DecimalFormat("$#,##0.00;$#,##0.00"); textFormatter[0x07] = new DecimalFormat("$#,##0.00;$#,##0.00");
textFormatter[0x08] = new DecimalFormat("$#,##0.00;$#,##0.00"); textFormatter[0x08] = new DecimalFormat("$#,##0.00;$#,##0.00");
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 SVFractionalFormat("# ?/?"); textFormatter[0x0C] = new SVFractionalFormat("# ?/?");
textFormatter[0x0D] = new SVFractionalFormat("# ??/??"); 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");
textFormatter[0x11] = new SimpleDateFormat("MMM-yy"); textFormatter[0x11] = new SimpleDateFormat("MMM-yy");
textFormatter[0x12] = new SimpleDateFormat("h:mm a"); textFormatter[0x12] = new SimpleDateFormat("h:mm a");
textFormatter[0x13] = new SimpleDateFormat("h:mm:ss a"); textFormatter[0x13] = new SimpleDateFormat("h:mm:ss a");
textFormatter[0x14] = new SimpleDateFormat("h:mm"); textFormatter[0x14] = new SimpleDateFormat("h:mm");
textFormatter[0x15] = new SimpleDateFormat("h:mm:ss"); textFormatter[0x15] = new SimpleDateFormat("h:mm:ss");
textFormatter[0x16] = new SimpleDateFormat("M/d/yy h:mm"); textFormatter[0x16] = new SimpleDateFormat("M/d/yy h:mm");
// 0x17 - 0x24 reserved for international and undocumented 0x25, "(#,##0_);(#,##0)" // 0x17 - 0x24 reserved for international and undocumented 0x25, "(#,##0_);(#,##0)"
//start at 0x26 //start at 0x26
//jmh need to do colour //jmh need to do colour
//"(#,##0_);[Red](#,##0)" //"(#,##0_);[Red](#,##0)"
textFormatter[0x26] = new DecimalFormat("#,##0;#,##0"); textFormatter[0x26] = new DecimalFormat("#,##0;#,##0");
//jmh need to do colour //jmh need to do colour
//(#,##0.00_);(#,##0.00) //(#,##0.00_);(#,##0.00)
textFormatter[0x27] = new DecimalFormat("#,##0.00;#,##0.00"); textFormatter[0x27] = new DecimalFormat("#,##0.00;#,##0.00");
textFormatter[0x28] = new DecimalFormat("#,##0.00;#,##0.00"); textFormatter[0x28] = new DecimalFormat("#,##0.00;#,##0.00");
//?? textFormatter[0x29] = new DecimalFormat("_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)"); //?? textFormatter[0x29] = new DecimalFormat("_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)");
//?? textFormatter[0x2A] = new DecimalFormat("_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)"); //?? textFormatter[0x2A] = new DecimalFormat("_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)");
//?? textFormatter[0x2B] = new DecimalFormat("_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)"); //?? textFormatter[0x2B] = new DecimalFormat("_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)");
//?? textFormatter[0x2C] = new DecimalFormat("_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)"); //?? textFormatter[0x2C] = new DecimalFormat("_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)");
textFormatter[0x2D] = new SimpleDateFormat("mm:ss"); textFormatter[0x2D] = new SimpleDateFormat("mm:ss");
//?? textFormatter[0x2E] = new SimpleDateFormat("[h]:mm:ss"); //?? textFormatter[0x2E] = new SimpleDateFormat("[h]:mm:ss");
textFormatter[0x2F] = new SimpleDateFormat("mm:ss.0"); textFormatter[0x2F] = new SimpleDateFormat("mm:ss.0");
textFormatter[0x30] = new DecimalFormat("##0.0E0"); textFormatter[0x30] = new DecimalFormat("##0.0E0");
}
public String format(short index, double value) {
if ( index <= 0 )
return generalNumberFormat.format(value);
if (textFormatter[index] == null)
throw new RuntimeException("Sorry. I cant handle the format code :"+Integer.toHexString(index));
if (textFormatter[index] instanceof DecimalFormat) {
return ((DecimalFormat)textFormatter[index]).format(value);
} }
if (textFormatter[index] instanceof SVFractionalFormat) {
return ((SVFractionalFormat)textFormatter[index]).format(value);
}
throw new RuntimeException("Sorry. I cant handle a non decimal formatter for a decimal value :"+Integer.toHexString(index));
}
public boolean useRedColor(short index, double value) { public String format(short index, double value) {
return (((index == 0x06)||(index == 0x08)||(index == 0x26) || (index == 0x27)) && (value < 0)); if (index <= 0)
} return generalNumberFormat.format(value);
if (textFormatter[index] == null)
throw new RuntimeException("Sorry. I cant handle the format code :" + Integer.toHexString(index));
if (textFormatter[index] instanceof DecimalFormat) {
return ((DecimalFormat) textFormatter[index]).format(value);
}
if (textFormatter[index] instanceof SVFractionalFormat) {
return ((SVFractionalFormat) textFormatter[index]).format(value);
}
throw new RuntimeException("Sorry. I cant handle a non decimal formatter for a decimal value :" + Integer.toHexString(index));
}
public boolean useRedColor(short index, double value) {
return (((index == 0x06) || (index == 0x08) || (index == 0x26) || (index == 0x27)) && (value < 0));
}
} }
private final CellFormatter cellFormatter = new CellFormatter(); private final CellFormatter cellFormatter = new CellFormatter();
public SVTableCellRenderer(HSSFWorkbook wb) { public SVTableCellRenderer(HSSFWorkbook wb) {
super(); super();
setOpaque(true); setOpaque(true);
setBorder(noFocusBorder); setBorder(noFocusBorder);
this.wb = wb; this.wb = wb;
} }
@Override @Override
public Component getTableCellRendererComponent(JTable table, Object value, public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) { boolean isSelected, boolean hasFocus, int row, int column) {
boolean isBorderSet = false; boolean isBorderSet = false;
//If the JTables default cell renderer has been setup correctly the //If the JTables default cell renderer has been setup correctly the
//value will be the HSSFCell that we are trying to render //value will be the HSSFCell that we are trying to render
HSSFCell c = (HSSFCell)value; HSSFCell c = (HSSFCell) value;
if (c != null) { if (c != null) {
HSSFCellStyle s = c.getCellStyle(); HSSFCellStyle s = c.getCellStyle();
HSSFFont f = wb.getFontAt(s.getFontIndexAsInt()); HSSFFont f = wb.getFontAt(s.getFontIndexAsInt());
setFont(SVTableUtils.makeFont(f)); setFont(SVTableUtils.makeFont(f));
if (s.getFillPattern() == FillPatternType.SOLID_FOREGROUND) { if (s.getFillPattern() == FillPatternType.SOLID_FOREGROUND) {
setBackground(SVTableUtils.getAWTColor(s.getFillForegroundColor(), SVTableUtils.white)); setBackground(SVTableUtils.getAWTColor(s.getFillForegroundColor(), SVTableUtils.white));
} else setBackground(SVTableUtils.white); } else setBackground(SVTableUtils.white);
setForeground(SVTableUtils.getAWTColor(f.getColor(), SVTableUtils.black)); setForeground(SVTableUtils.getAWTColor(f.getColor(), SVTableUtils.black));
cellBorder.setBorder(SVTableUtils.getAWTColor(s.getTopBorderColor(), SVTableUtils.black), cellBorder.setBorder(SVTableUtils.getAWTColor(s.getTopBorderColor(), SVTableUtils.black),
SVTableUtils.getAWTColor(s.getRightBorderColor(), SVTableUtils.black), SVTableUtils.getAWTColor(s.getRightBorderColor(), SVTableUtils.black),
SVTableUtils.getAWTColor(s.getBottomBorderColor(), SVTableUtils.black), SVTableUtils.getAWTColor(s.getBottomBorderColor(), SVTableUtils.black),
SVTableUtils.getAWTColor(s.getLeftBorderColor(), SVTableUtils.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);
setBorder(cellBorder); setBorder(cellBorder);
isBorderSet=true; isBorderSet = true;
//Set the value that is rendered for the cell //Set the value that is rendered for the cell
switch (c.getCellType()) { switch (c.getCellType()) {
case BLANK: case BLANK:
setValue(""); setValue("");
break; break;
case BOOLEAN: case BOOLEAN:
if (c.getBooleanCellValue()) { if (c.getBooleanCellValue()) {
setValue("true"); setValue("true");
} else { } else {
setValue("false"); setValue("false");
} }
break; break;
case NUMERIC: case NUMERIC:
short format = s.getDataFormat(); short format = s.getDataFormat();
double numericValue = c.getNumericCellValue(); double numericValue = c.getNumericCellValue();
if (cellFormatter.useRedColor(format, numericValue)) if (cellFormatter.useRedColor(format, numericValue))
setForeground(Color.red); setForeground(Color.red);
else setForeground(null); else setForeground(null);
setValue(cellFormatter.format(format, c.getNumericCellValue())); setValue(cellFormatter.format(format, c.getNumericCellValue()));
break; break;
case STRING: case STRING:
setValue(c.getRichStringCellValue().getString()); setValue(c.getRichStringCellValue().getString());
break; break;
case FORMULA: case FORMULA:
default: default:
setValue("?"); setValue("?");
} }
//Set the text alignment of the cell //Set the text alignment of the cell
switch (s.getAlignment()) { switch (s.getAlignment()) {
case LEFT: case LEFT:
case JUSTIFY: case JUSTIFY:
case FILL: case FILL:
setHorizontalAlignment(SwingConstants.LEFT); setHorizontalAlignment(SwingConstants.LEFT);
break; break;
case CENTER: case CENTER:
case CENTER_SELECTION: case CENTER_SELECTION:
setHorizontalAlignment(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.CENTER);
break; break;
case GENERAL: case GENERAL:
case RIGHT: case RIGHT:
setHorizontalAlignment(SwingConstants.RIGHT); setHorizontalAlignment(SwingConstants.RIGHT);
break; break;
default: default:
setHorizontalAlignment(SwingConstants.LEFT); setHorizontalAlignment(SwingConstants.LEFT);
break; break;
} }
} else { } else {
setValue(""); setValue("");
setBackground(SVTableUtils.white); setBackground(SVTableUtils.white);
} }
if (hasFocus) { if (hasFocus) {
if (!isBorderSet) { if (!isBorderSet) {
//This is the border to paint when there is no border //This is the border to paint when there is no border
//and the cell has focus //and the cell has focus
cellBorder.setBorder(SVTableUtils.black, cellBorder.setBorder(SVTableUtils.black,
SVTableUtils.black, SVTableUtils.black,
SVTableUtils.black, SVTableUtils.black,
SVTableUtils.black, SVTableUtils.black,
BorderStyle.NONE, BorderStyle.NONE,
BorderStyle.NONE, BorderStyle.NONE,
BorderStyle.NONE, BorderStyle.NONE,
BorderStyle.NONE, BorderStyle.NONE,
isSelected); isSelected);
setBorder(cellBorder); setBorder(cellBorder);
} }
if (table.isCellEditable(row, column)) { if (table.isCellEditable(row, column)) {
setForeground( UIManager.getColor("Table.focusCellForeground") ); setForeground(UIManager.getColor("Table.focusCellForeground"));
setBackground( UIManager.getColor("Table.focusCellBackground") ); setBackground(UIManager.getColor("Table.focusCellBackground"));
} }
} else if (!isBorderSet) { } else if (!isBorderSet) {
setBorder(noFocusBorder); setBorder(noFocusBorder);
} }
// ---- begin optimization to avoid painting background ---- // ---- begin optimization to avoid painting background ----
Color back = getBackground(); Color back = getBackground();
boolean colorMatch = (back != null) && ( back.equals(table.getBackground()) ) && table.isOpaque(); boolean colorMatch = (back != null) && (back.equals(table.getBackground())) && table.isOpaque();
setOpaque(!colorMatch); setOpaque(!colorMatch);
// ---- end optimization to aviod painting background ---- // ---- end optimization to aviod painting background ----
return this; return this;
} }
@Override @Override
public void validate() {} public void validate() {
}
@Override @Override
public void revalidate() {} public void revalidate() {
}
@Override @Override
public void repaint(long tm, int x, int y, int width, int height) {} public void repaint(long tm, int x, int y, int width, int height) {
}
@Override @Override
public void repaint(Rectangle r) { } public void repaint(Rectangle r) {
}
@Override @Override
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
// Strings get interned... // Strings get interned...
if (propertyName=="text") { if (propertyName == "text") {
super.firePropertyChange(propertyName, oldValue, newValue); super.firePropertyChange(propertyName, oldValue, newValue);
} }
} }
@Override @Override
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { } public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
}
/** /**
* Sets the string to either the value or "" if the value is null. * Sets the string to either the value or "" if the value is null.
*
*/ */
protected void setValue(Object value) { protected void setValue(Object value) {
setText((value == null) ? "" : value.toString()); setText((value == null) ? "" : value.toString());
} }
} }

View File

@ -15,80 +15,83 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
package org.apache.poi.hssf.view; package org.apache.poi.hssf.view;
import java.util.Iterator; import java.util.Iterator;
import javax.swing.table.*;
import javax.swing.table.AbstractTableModel;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.hssf.usermodel.HSSFCell;
/** /**
* Sheet Viewer Table Model - The model for the Sheet Viewer just overrides things. * Sheet Viewer Table Model - The model for the Sheet Viewer just overrides things.
*
* @author Andrew C. Oliver * @author Andrew C. Oliver
*/ */
public class SVTableModel extends AbstractTableModel { public class SVTableModel extends AbstractTableModel {
private HSSFSheet st; private HSSFSheet st;
int maxcol; int maxcol;
public SVTableModel(HSSFSheet st, int maxcol) { public SVTableModel(HSSFSheet st, int maxcol) {
this.st = st; this.st = st;
this.maxcol=maxcol; this.maxcol = maxcol;
}
public SVTableModel(HSSFSheet st) {
this.st = st;
Iterator<Row> i = st.rowIterator();
while (i.hasNext()) {
HSSFRow row = (HSSFRow)i.next();
if (maxcol < (row.getLastCellNum()+1)) {
this.maxcol = row.getLastCellNum();
}
} }
}
public SVTableModel(HSSFSheet st) {
this.st = st;
Iterator<Row> i = st.rowIterator();
@Override while (i.hasNext()) {
public int getColumnCount() { HSSFRow row = (HSSFRow) i.next();
return this.maxcol+1; if (maxcol < (row.getLastCellNum() + 1)) {
} this.maxcol = row.getLastCellNum();
@Override }
public Object getValueAt(int row, int col) { }
HSSFRow r = st.getRow(row);
HSSFCell c = null;
if (r != null) {
c = r.getCell(col);
} }
return c;
}
@Override
public int getRowCount() {
return st.getLastRowNum() + 1;
}
@Override
public Class<?> getColumnClass(int c) {
return HSSFCell.class;
}
@Override @Override
public boolean isCellEditable(int rowIndex, int columnIndex) { public int getColumnCount() {
return true; return this.maxcol + 1;
} }
@Override @Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) { public Object getValueAt(int row, int col) {
if (aValue != null) HSSFRow r = st.getRow(row);
System.out.println("SVTableModel.setValueAt. value type = "+aValue.getClass().getName()); HSSFCell c = null;
else System.out.println("SVTableModel.setValueAt. value type = null"); if (r != null) {
} c = r.getCell(col);
}
return c;
}
@Override
public int getRowCount() {
return st.getLastRowNum() + 1;
}
@Override
public Class<?> getColumnClass(int c) {
return HSSFCell.class;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
@Override
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

@ -32,55 +32,63 @@ import org.apache.poi.hssf.util.HSSFColor.HSSFColorPredefined;
/** /**
* SVTableCell Editor and Renderer helper functions. * SVTableCell Editor and Renderer helper functions.
* *
* @author Jason Height * @author Jason Height
*/ */
public class SVTableUtils { public class SVTableUtils {
private final static Map<Integer,HSSFColor> colors = HSSFColor.getIndexHash(); private final static Map<Integer, HSSFColor> colors = HSSFColor.getIndexHash();
/** Description of the Field */ /**
public final static Color black = getAWTColor(HSSFColorPredefined.BLACK); * Description of the Field
/** Description of the Field */ */
public final static Color white = getAWTColor(HSSFColorPredefined.WHITE); public final static Color black = getAWTColor(HSSFColorPredefined.BLACK);
/** Description of the Field */ /**
public static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); * Description of the Field
*/
public final static Color white = getAWTColor(HSSFColorPredefined.WHITE);
/**
* Description of the Field
*/
public static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
/** /**
* Creates a new font for a specific cell style * Creates a new font for a specific cell style
*/ */
public static Font makeFont(HSSFFont font) { public static Font makeFont(HSSFFont font) {
boolean isbold = font.getBold(); boolean isbold = font.getBold();
boolean isitalics = font.getItalic(); boolean isitalics = font.getItalic();
int fontstyle = Font.PLAIN; int fontstyle = Font.PLAIN;
if (isbold) { if (isbold) {
fontstyle = Font.BOLD; fontstyle = Font.BOLD;
} }
if (isitalics) { if (isitalics) {
fontstyle = fontstyle | Font.ITALIC; 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);
} }
int fontheight = font.getFontHeightInPoints(); /**
if (fontheight == 9) { * This method retrieves the AWT Color representation from the colour hash table
//fix for stupid ol Windows */
fontheight = 10; /* package */
static Color getAWTColor(int index, Color deflt) {
HSSFColor clr = colors.get(index);
if (clr == null) {
return deflt;
}
short[] rgb = clr.getTriplet();
return new Color(rgb[0], rgb[1], rgb[2]);
} }
return new Font(font.getFontName(), fontstyle, fontheight); /* package */
} static Color getAWTColor(HSSFColorPredefined clr) {
short[] rgb = clr.getTriplet();
/** This method retrieves the AWT Color representation from the colour hash table return new Color(rgb[0], rgb[1], rgb[2]);
*
*/
/* package */ static Color getAWTColor(int index, Color deflt) {
HSSFColor clr = colors.get(index);
if (clr == null) {
return deflt;
} }
short[] rgb = clr.getTriplet();
return new Color(rgb[0],rgb[1],rgb[2]);
}
/* package */ static Color getAWTColor(HSSFColorPredefined clr) {
short[] rgb = clr.getTriplet();
return new Color(rgb[0],rgb[1],rgb[2]);
}
} }

View File

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