| |
| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==================================================================== */ |
| |
| package org.apache.poi.hssf.view; |
| |
| import java.awt.*; |
| |
| import javax.swing.border.AbstractBorder; |
| |
| import org.apache.poi.ss.usermodel.BorderStyle; |
| |
| /** |
| * 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 |
| * appear in the generated stuff. |
| * |
| * @author Andrew C. Oliver (acoliver at apache dot org) |
| * @author Jason Height |
| */ |
| public class SVBorder extends AbstractBorder { |
| private Color northColor = null; |
| private Color eastColor = null; |
| private Color southColor = null; |
| private Color westColor = null; |
| private BorderStyle northBorderType = BorderStyle.NONE; |
| private BorderStyle eastBorderType = BorderStyle.NONE; |
| private BorderStyle southBorderType = BorderStyle.NONE; |
| private BorderStyle westBorderType = BorderStyle.NONE; |
| private boolean northBorder=false; |
| private boolean eastBorder=false; |
| private boolean southBorder=false; |
| private boolean westBorder=false; |
| private boolean selected = false; |
| |
| public void setBorder(Color northColor, Color eastColor, |
| Color southColor, Color westColor, |
| BorderStyle northBorderType, BorderStyle eastBorderType, |
| BorderStyle southBorderType, BorderStyle westBorderType, |
| boolean selected) { |
| this.eastColor = eastColor; |
| this.southColor = southColor; |
| this.westColor = westColor; |
| this.northBorderType = northBorderType; |
| this.eastBorderType = eastBorderType; |
| this.southBorderType = southBorderType; |
| this.westBorderType = westBorderType; |
| this.northBorder=northBorderType != BorderStyle.NONE; |
| this.eastBorder=eastBorderType != BorderStyle.NONE; |
| this.southBorder=southBorderType != BorderStyle.NONE; |
| this.westBorder=westBorderType != BorderStyle.NONE; |
| this.selected = selected; |
| } |
| |
| @Override |
| public void paintBorder(Component c, Graphics g, int x, int y, int width, |
| int height) { |
| Color oldColor = g.getColor(); |
| |
| |
| paintSelectedBorder(g, x, y, width, height); |
| paintNormalBorders(g, x, y, width, height); |
| paintDottedBorders(g, x, y, width, height); |
| paintDashedBorders(g, x, y, width, height); |
| paintDoubleBorders(g, x, y, width, height); |
| paintDashDotDotBorders(g, x, y, width, height); |
| |
| |
| g.setColor(oldColor); |
| } |
| |
| /** |
| * Called by paintBorder to paint the border of a selected cell. |
| * The paramaters are the Graphics object, location and dimensions of the |
| * cell. |
| */ |
| private void paintSelectedBorder(Graphics g, int x, int y, int width, |
| int height) { |
| if (selected) { |
| //Need to setup thickness of 2 |
| g.setColor(Color.black); |
| //paint the border |
| g.drawRect(x,y,width-1,height-1); |
| |
| //paint the filled rectangle at the bottom left hand position |
| 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); |
| |
| g.setColor(eastColor); |
| |
| for (int k=0; k < thickness; k++) { |
| g.drawLine(width-k,y,width-k,height); |
| } |
| } |
| |
| if (southBorder && |
| ((southBorderType == BorderStyle.THIN) || |
| (southBorderType == BorderStyle.MEDIUM) || |
| (southBorderType == BorderStyle.THICK) |
| ) |
| ) { |
| |
| int thickness = getThickness(southBorderType); |
| |
| g.setColor(southColor); |
| for (int k=0; k < thickness; k++) { |
| g.drawLine(x,height - k,width,height - k); |
| } |
| } |
| |
| if (westBorder && |
| ((westBorderType == BorderStyle.THIN) || |
| (westBorderType == BorderStyle.MEDIUM) || |
| (westBorderType == BorderStyle.THICK) |
| ) |
| ) { |
| |
| int thickness = getThickness(westBorderType); |
| |
| g.setColor(westColor); |
| |
| for (int k=0; k < thickness; k++) { |
| g.drawLine(x+k,y,x+k,height); |
| } |
| } |
| } |
| |
| /** |
| * 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); |
| |
| g.setColor(northColor); |
| |
| for (int k=0; k < thickness; k++) { |
| for (int xc = x; xc < width; xc=xc+2) { |
| g.drawLine(xc,y+k,xc,y+k); |
| } |
| } |
| } |
| |
| if (eastBorder && |
| eastBorderType == BorderStyle.DOTTED |
| ) { |
| |
| int thickness = getThickness(eastBorderType); |
| thickness++; //need for dotted borders to show up east |
| |
| g.setColor(eastColor); |
| |
| 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 (southBorder && |
| southBorderType == BorderStyle.DOTTED |
| ) { |
| |
| 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++; |
| |
| g.setColor(westColor); |
| |
| for (int k=0; k < thickness; k++) { |
| for (int yc=y;yc < height; yc=yc+2) { |
| g.drawLine(x+k,yc,x+k,yc); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Called by paintBorder to paint the various versions of dotted line |
| * borders for a cell. |
| */ |
| private void paintDashedBorders(Graphics g, int x, int y, int width, |
| int height) { |
| if (northBorder && |
| ((northBorderType == BorderStyle.DASHED) || |
| (northBorderType == BorderStyle.HAIR)) |
| ) { |
| int thickness = getThickness(northBorderType); |
| |
| int dashlength = 1; |
| |
| if (northBorderType == BorderStyle.DASHED) |
| dashlength = 2; |
| |
| g.setColor(northColor); |
| |
| for (int k=0; k < thickness; k++) { |
| for (int xc = x; xc < width; xc=xc+5) { |
| g.drawLine(xc,y+k,xc+dashlength,y+k); |
| } |
| } |
| } |
| |
| if (eastBorder && |
| ((eastBorderType == BorderStyle.DASHED) || |
| (eastBorderType == BorderStyle.HAIR)) |
| ) { |
| |
| int thickness = getThickness(eastBorderType); |
| thickness++; //need for dotted borders to show up east |
| |
| |
| int dashlength = 1; |
| |
| if (eastBorderType == BorderStyle.DASHED) |
| dashlength = 2; |
| |
| g.setColor(eastColor); |
| |
| for (int k=0; k < thickness; k++) { |
| for (int yc=y;yc < height; yc=yc+5) { |
| g.drawLine(width-k,yc,width-k,yc+dashlength); |
| } |
| } |
| } |
| |
| if (southBorder && |
| ((southBorderType == BorderStyle.DASHED) || |
| (southBorderType == BorderStyle.HAIR)) |
| ) { |
| |
| int thickness = getThickness(southBorderType); |
| thickness++; |
| |
| int dashlength = 1; |
| |
| if (southBorderType == BorderStyle.DASHED) |
| dashlength = 2; |
| |
| g.setColor(southColor); |
| for (int k=0; k < thickness; k++) { |
| for (int xc = x; xc < width; xc=xc+5) { |
| g.drawLine(xc,height-k,xc+dashlength,height-k); |
| } |
| } |
| } |
| |
| if (westBorder && |
| ((westBorderType == BorderStyle.DASHED) || |
| (westBorderType == BorderStyle.HAIR)) |
| ) { |
| |
| int thickness = getThickness(westBorderType); |
| // thickness++; |
| |
| int dashlength = 1; |
| |
| if (westBorderType == BorderStyle.DASHED) |
| dashlength = 2; |
| |
| g.setColor(westColor); |
| |
| for (int k=0; k < thickness; k++) { |
| for (int yc=y;yc < height; yc=yc+5) { |
| g.drawLine(x+k,yc,x+k,yc+dashlength); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Called by paintBorder to paint the double line |
| * borders for a cell. |
| */ |
| private void paintDoubleBorders(Graphics g, int x, int y, int width, |
| int height) { |
| if (northBorder && |
| northBorderType == BorderStyle.DOUBLE) { |
| |
| g.setColor(northColor); |
| |
| int leftx=x; |
| int rightx=width; |
| |
| // if there are borders on the west or east then |
| // the second line shouldn't cross them |
| if (westBorder) |
| leftx = x+3; |
| |
| if (eastBorder) |
| rightx = width-3; |
| |
| g.drawLine(x,y,width,y); |
| g.drawLine(leftx,y+2,rightx,y+2); |
| } |
| |
| if (eastBorder && |
| 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); |
| } |
| |
| 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++; |
| |
| g.setColor(westColor); |
| |
| int topy=y; |
| int bottomy=height-3; |
| |
| if (northBorder) |
| topy=y+2; |
| |
| if (southBorder) |
| bottomy=height-3; |
| |
| g.drawLine(x,y,x,height); |
| g.drawLine(x+2,topy,x+2,bottomy); |
| } |
| } |
| |
| /** |
| * Called by paintBorder to paint the various versions of dash dot dot line |
| * borders for a cell. |
| */ |
| private void paintDashDotDotBorders(Graphics g, int x, int y, int width, |
| int height) { |
| if (northBorder && |
| ((northBorderType == BorderStyle.DASH_DOT_DOT) || |
| (northBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT)) |
| ) { |
| int thickness = getThickness(northBorderType); |
| |
| 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)) |
| ) { |
| |
| int thickness = getThickness(eastBorderType); |
| |
| g.setColor(eastColor); |
| |
| for (int l=y;l < height;) { |
| //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); |
| } |
| |
| } |
| } |
| |
| /** |
| * 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 right/bottom 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. |
| * @returns 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; |
| } |
| |
| /** |
| * @returns 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; |
| } |
| } |
| |
| |
| } |