⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tableelement.java

📁 Java写的ERP系统
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************
 * 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 + -