📄 tableelement.java
字号:
/******************************************************************************
* The contents of this file are subject to the Compiere License Version 1.1
* ("License"); You may not use this file except in compliance with the License
* You may obtain a copy of the License at http://www.compiere.org/license.html
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Original Code is Compiere ERP & CRM Business Solution
* The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
* Portions created by Jorg Janke are Copyright (C) 1999-2002 Jorg Janke, parts
* created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
* Contributor(s): ______________________________________.
*****************************************************************************/
package org.compiere.print.layout;
import java.awt.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.awt.image.*;
import java.text.*;
import java.util.*;
import java.util.regex.*;
import org.compiere.print.*;
import org.compiere.model.*;
import org.compiere.util.*;
/**
* Table Print Element.
* Maintains a logical cross page table, which is "broken up" when printing
* <pre>
* The table is 3 pages wide, 2 pages high
* +-----+-----+-----+
* | 1.1 | 1.2 | 1.3 |
* +-----+-----+-----+
* | 2.1 | 2.2 | 2.3 |
* +-----+-----+-----+
* Printed
* +-----+-----+-----+
* | 1 | 2 | 3 |
* +-----+-----+-----+
* | 4 | 5 | 6 |
* +-----+-----+-----+
* </pre>
* @author Jorg Janke
* @version $Id: TableElement.java,v 1.22 2003/02/14 06:47:06 jjanke Exp $
*/
public class TableElement extends PrintElement
{
/**
* Constructor.
* Created in LayoutEngine.
* The rowCol.. maps are organized as follows - Point (row,col)
* row - data if 0..m - if -1 for the entire column
* column - data if 0..n - if -1 for the entire row
* i.e. Point (-1, -1) is the default for the table
*
* @param columnHeader array with column headers (Key=ColumnName)
* @param columnMaxWidth array with column max width - 0=no restrictions - negative=supress if null
* @param columnMaxHeight array with row max height for a column - 0=no restrictions; -1=one row only
* @param columnJustification field justification for column
*
* @param fixedWidth array with column fixed width
* @param lastLineFunction Last Line is a function line
* @param multiLineHeader if true, the header is not truncated at maxWidth
*
* @param data 2D array with data to be printed [row][col]
* @param pk array of primary keys
* @param pkColumnName primary key name
*
* @param pageNoStart page number of starting page
* @param firstPage bounds on first page
* @param nextPages bounds on following pages
* @param repeatedColumns repeat first x columns on - X Axis follow pages
* @param additionalLines map of old colum to below printed column
*
* @param rowColFont HashMap with Point as key with Font overwrite
* @param rowColColor HashMap with Point as key with foreground Color overwrite
* @param rowColBackground HashMap with Point as key with background Color overwrite
* @param tFormat table format
* @param pageBreak Arraylist of rows with page break
*/
public TableElement (ValueNamePair[] columnHeader,
int[] columnMaxWidth, int[] columnMaxHeight, String[] columnJustification,
boolean[] fixedWidth, boolean lastLineFunction, boolean multiLineHeader,
Object[][] data, KeyNamePair[] pk, String pkColumnName,
int pageNoStart, Rectangle firstPage, Rectangle nextPages, int repeatedColumns, HashMap additionalLines,
HashMap rowColFont, HashMap rowColColor, HashMap rowColBackground,
MPrintTableFormat tFormat, ArrayList pageBreak)
{
Log.trace(Log.l4_Data, "TableElement", "Cols=" + columnHeader.length + ", Rows=" + data.length);
m_columnHeader = columnHeader;
m_columnMaxWidth = columnMaxWidth;
m_columnMaxHeight = columnMaxHeight;
m_columnJustification = columnJustification;
m_lastLineFunction = lastLineFunction;
m_fixedWidth = fixedWidth;
//
m_multiLineHeader = multiLineHeader;
m_data = data;
m_pk = pk;
m_pkColumnName = pkColumnName;
//
m_pageNoStart = pageNoStart;
m_firstPage = firstPage;
m_nextPages = nextPages;
m_repeatedColumns = repeatedColumns;
m_additionalLines = additionalLines;
// Used Fonts,Colots
Point p = new Point (ALL, ALL);
m_rowColFont = rowColFont;
m_baseFont = (Font)m_rowColFont.get(p);
if (m_baseFont == null)
m_baseFont = new Font(null);
m_rowColColor = rowColColor;
m_baseColor = (Color)m_rowColColor.get(p);
if (m_baseColor == null)
m_baseColor = Color.black;
m_rowColBackground = rowColBackground;
m_baseBackground = (Color)m_rowColBackground.get(p);
if (m_baseBackground == null)
m_baseBackground = Color.white;
m_tFormat = tFormat;
// Page Break - not two after each other
m_pageBreak = pageBreak;
for (int i = 0; i < m_pageBreak.size(); i++)
{
Integer row = (Integer)m_pageBreak.get(i);
while ((i + 1) < m_pageBreak.size())
{
Integer nextRow = (Integer)m_pageBreak.get(i+1);
if ((row.intValue()+1) == nextRow.intValue())
{
Log.trace(8, "Removing PageBreak row=" + row);
m_pageBreak.remove(i);
row = nextRow;
}
else
break;
}
} // for all page breaks
// Load Image
waitForLoad(LayoutEngine.IMAGE_TRUE);
waitForLoad(LayoutEngine.IMAGE_FALSE);
} // TableElement
/** Column Headers */
private ValueNamePair[] m_columnHeader;
/** Max column widths */
private int[] m_columnMaxWidth;
/** Max row height per column */
private int[] m_columnMaxHeight;
/** Field Justification for Column */
private String[] m_columnJustification;
/** True if column fixed length */
private boolean[] m_fixedWidth;
/** Create multiple header lines if required */
private boolean m_multiLineHeader;
/** Last Line is a function line */
private boolean m_lastLineFunction;
/** The Data */
private Object[][] m_data;
/** Primary Keys */
private KeyNamePair[] m_pk;
/** Primary Key Column Name */
private String m_pkColumnName;
/** Starting page Number */
private int m_pageNoStart;
/** Bounds of first Page */
private Rectangle m_firstPage;
/** Bounds of next Pages */
private Rectangle m_nextPages;
/** repeat first x columns on - X Axis follow pages */
private int m_repeatedColumns;
/** base font for table */
private Font m_baseFont;
/** HashMap with Point as key with Font overwrite */
private HashMap m_rowColFont;
/** base foreground color for table */
private Color m_baseColor;
/** HashMap with Point as key with foreground Color overwrite */
private HashMap m_rowColColor;
/** base color for table */
private Color m_baseBackground;
/** HashMap with Point as key with background Color overwrite */
private HashMap m_rowColBackground;
/** Format of Table */
private MPrintTableFormat m_tFormat;
/** Page Break Rows */
private ArrayList m_pageBreak;
/** width of columns (float) */
private ArrayList m_columnWidths = new ArrayList();
/** height of rows (float) */
private ArrayList m_rowHeights = new ArrayList();
/** height of header */
private int m_headerHeight = 0;
/** first data row number per page */
private ArrayList m_firstRowOnPage = new ArrayList();
/** first column number per -> page */
private ArrayList m_firstColumnOnPage = new ArrayList();
/** Height of page */
private ArrayList m_pageHeight = new ArrayList();
/** Key: Point(row,col) - Value: NamePair */
private HashMap m_rowColDrillDown = new HashMap();
/** Key: Integer (original Column) - Value: Integer (below column) */
private HashMap m_additionalLines = new HashMap();
/** Key: Point(row,col) - Value: ArrayList of data */
private HashMap m_additionalLineData = new HashMap();
/*************************************************************************/
/** Header Row Indicator */
public static final int HEADER_ROW = -2;
/** Header Row Indicator */
public static final int ALL = -1;
/** Horizontal - GAP between text & line */
private static final int H_GAP = 2;
/** Vertical | GAP between text & line */
private static final int V_GAP = 2;
/** Verical Line | width */
private static final int V_LINE = 1;
/** Horizontal Line - width */
private static final int H_LINE = 1;
/*************************************************************************/
/**
* Layout and Calculate Size.
* Set p_width & p_height
* @return true if calculated
*/
protected boolean calculateSize()
{
if (p_sizeCalculated)
return true;
Log.trace(Log.l5_DData, "TableElement.calculateSize");
p_width = 0;
m_additionalLineData = new HashMap(); // reset
// Max Column Width = 50% of available width (used if maxWidth not set)
float dynMxColumnWidth = m_firstPage.width / 2;
// Width caolculation
int rows = m_data.length;
int cols = m_columnHeader.length;
// Data Sizes and Header Sizes
Dimension2DImpl[][] dataSizes = new Dimension2DImpl[rows][cols];
Dimension2DImpl[] headerSizes = new Dimension2DImpl[cols];
FontRenderContext frc = new FontRenderContext(null, true, true);
// data rows
for (int dataCol = 0; dataCol < cols; dataCol++)
{
int col = dataCol;
// Print below existing column
if (m_additionalLines.containsKey(new Integer(dataCol)))
{
col = ((Integer)m_additionalLines.get(new Integer(dataCol))).intValue();
Log.trace(9, "DataColumn=" + dataCol + ", BelowColumn=" + col);
}
float colWidth = 0;
for (int row = 0; row < rows; row++)
{
Object dataItem = m_data[row][dataCol];
if (dataItem == null)
{
dataSizes[row][dataCol] = new Dimension2DImpl();
continue;
}
String string = dataItem.toString();
if (string.length() == 0)
{
dataSizes[row][dataCol] = new Dimension2DImpl();
continue;
}
Font font = getFont(row, dataCol);
// Print below existing column
if (col != dataCol)
{
addAdditionalLines(row, col, dataItem);
dataSizes[row][dataCol] = new Dimension2DImpl(); // don't print
}
else
dataSizes[row][dataCol] = new Dimension2DImpl();
if (dataItem instanceof Boolean)
{
dataSizes[row][col].addBelow(LayoutEngine.IMAGE_SIZE);
continue;
}
// No Width Limitations
if (m_columnMaxWidth[col] == 0 || m_columnMaxWidth[col] == -1)
{
TextLayout layout = new TextLayout (string, font, frc);
float width = layout.getAdvance() + 2; // buffer
float height = layout.getAscent() + layout.getDescent() + layout.getLeading();
if (width > dynMxColumnWidth)
m_columnMaxWidth[col] = (int)Math.ceil(dynMxColumnWidth);
else if (colWidth < width)
colWidth = width;
dataSizes[row][col].addBelow(width, height);
}
// Width limitations
if (m_columnMaxWidth[col] != 0 && m_columnMaxWidth[col] != -1)
{
float height = 0;
if (m_fixedWidth[col])
colWidth = Math.abs(m_columnMaxWidth[col]);
//
String[] lines = Pattern.compile("$", Pattern.MULTILINE).split(string);
for (int lineNo = 0; lineNo < lines.length; lineNo++)
{
AttributedString aString = new AttributedString(lines[lineNo]);
aString.addAttribute(TextAttribute.FONT, font);
AttributedCharacterIterator iter = aString.getIterator();
LineBreakMeasurer measurer = new LineBreakMeasurer(iter, frc);
while (measurer.getPosition() < iter.getEndIndex())
{
TextLayout layout = measurer.nextLayout(Math.abs(m_columnMaxWidth[col]));
float width = layout.getAdvance();
if (colWidth < width)
colWidth = width;
float lineHeight = layout.getAscent() + layout.getDescent() + layout.getLeading();
if (m_columnMaxHeight[col] == -1) // one line only
{
height = lineHeight;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -