mirror of https://github.com/apache/poi.git
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:
parent
b2a33515e9
commit
de2467e9ae
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue