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

📄 layoutengine.java

📁 Java写的ERP系统
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
 * 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.print.*;
import java.awt.geom.*;
import java.util.*;
import java.sql.*;
import java.net.*;

import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;

import org.apache.log4j.Logger;

import org.compiere.model.*;
import org.compiere.print.*;
import org.compiere.util.DisplayType;
import org.compiere.util.NamePair;
import org.compiere.util.KeyNamePair;
import org.compiere.util.ValueNamePair;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Log;

/**
 *	Print Engine Abstract Class.
 *	All coordinates are relative to the Page.
 *  The Language setting is maintained in the format
 *
 * 	@author 	Jorg Janke
 * 	@version 	$Id: LayoutEngine.java,v 1.40 2003/04/24 06:15:09 jjanke Exp $
 */
public class LayoutEngine
{
	/**
	 *	Detail Constructor
	 *  @param format Print Format
	 *  @param data Print Data
	 *  @param query query for parameter info
	 */
	public LayoutEngine (MPrintFormat format, PrintData data, MQuery query)
	{
		log.info(format + " - " + data + " - " + query);
		setPrintFormat(format, false);
		setPrintData(data, query, false);
		layout();
	}	//	LayoutEngine


	/*************************************************************************/

	/**	Logger						*/
	private Logger				log = Logger.getLogger (getClass());
	/** Existing Layout				*/
	private boolean				m_hasLayout = false;
	/**	The Format					*/
	private MPrintFormat 		m_format;
	/**	Print Context				*/
	private Properties			m_printCtx;
	/** The Data					*/
	private PrintData 			m_data;
	/** The Query (parameter		*/
	private MQuery				m_query;
	/**	Default Color				*/
	private MPrintColor 		m_printColor;
	/**	Default Font				*/
	private MPrintFont			m_printFont;
	/**	Printed Column Count		*/
	private int					m_columnCount = -1;


	/**	Paper - default: standard portrait		*/
	private CPaper				m_paper;
	/**	Header Area Height (1/4")				*/
	private int		m_headerHeight = 18;		//	1/4" => 72/4
	/** Footer Area Height (1/4")				*/
	private int		m_footerHeight = 18;


	/**	Current Page Number			*/
	private int					m_pageNo = 0;
	/** Current Page				*/
	private Page				m_currPage;
	/** Pages						*/
	private ArrayList			m_pages = new ArrayList();
	/**	Header&Footer for all pages	*/
	private HeaderFooter		m_headerFooter;


	/**	Header Coordinates			*/
	private Rectangle			m_header = new Rectangle ();
	/** Content Coordinates			*/
	private Rectangle			m_content = new Rectangle();
	/** Footer Coordinates			*/
	private Rectangle			m_footer = new Rectangle();
	/** Temporary NL Position		*/
	private int					m_tempNLPositon = 0;

	/** Header Area					*/
	public static final int 	AREA_HEADER = 0;
	/** Content Area				*/
	public static final int 	AREA_CONTENT = 1;
	/** Footer Area					*/
	public static final int 	AREA_FOOTER = 2;
	/** Area Pointer				*/
	private int					m_area = AREA_CONTENT;

	/** Current Position in 1/72 inch	*/
	private Point2D.Double[]	m_position = new Point2D.Double[] {new Point2D.Double(0,0), new Point2D.Double(0,0), new Point2D.Double(0,0)};
	/** Max Height Since New Line		*/
	private float				m_maxHeightSinceNewLine[] = new float[] {0f, 0f, 0f};
	/** Current Font					*/
	private Font				m_font;
	/** Current Paint					*/
	private Paint				m_paint;
	/** Current Stroke					*/
	private Stroke				m_stroke;

	/**	Primary Table Element for Page XY Info	*/
	private TableElement		m_tableElement = null;

	/*************************************************************************/

	public static Image			IMAGE_TRUE = null;
	public static Image			IMAGE_FALSE = null;
	public static Dimension		IMAGE_SIZE = new Dimension(10,10);

	static {
		Toolkit tk = Toolkit.getDefaultToolkit();
		URL url = LayoutEngine.class.getResource("true10.gif");
		if (url != null)
			IMAGE_TRUE = tk.getImage(url);
		url = LayoutEngine.class.getResource("false10.gif");
		if (url != null)
			IMAGE_FALSE = tk.getImage(url);
	}	//	static init

	/*************************************************************************/

	/**
	 * 	Set Print Format
	 *  Optionally re-calculate layout
	 *  @param doLayout if layout exists, redo it
	 * 	@param format print Format
	 */
	public void setPrintFormat (MPrintFormat format, boolean doLayout)
	{
		m_format = format;
		//	Initial & Default Settings
		m_printCtx = new Properties(format.getCtx());

		//	Set Paper
		boolean tempHasLayout = m_hasLayout;
		m_hasLayout = false;	//	do not start re-calculation
		MPrintPaper mPaper = MPrintPaper.get(format.getAD_PrintPaper_ID());
		if (m_format.isStandardHeaderFooter())
			setPaper(mPaper.getCPaper());
		else
			setPaper(mPaper.getCPaper(),
				m_format.getHeaderMargin(), m_format.getFooterMargin());
		m_hasLayout = tempHasLayout;
		//
		m_printColor = MPrintColor.get(format.getAD_PrintColor_ID());
		setPaint(m_printColor.getColor());
		m_printFont = MPrintFont.get (format.getAD_PrintFont_ID());
		setFont(m_printFont.getFont());
		m_stroke = new BasicStroke (1.0f);

		//	Print Context
		Env.setContext(m_printCtx, Page.CONTEXT_REPORTNAME, m_format.getName());
		Env.setContext(m_printCtx, Page.CONTEXT_HEADER, Env.getHeader(m_printCtx, 0));
		Env.setContext(m_printCtx, Env.LANG, m_format.getLanguage().getAD_Language());

		if (m_hasLayout && doLayout)
			layout();			//	re-calculate
	}	//	setPrintFormat

	/**
	 * 	Set PrintData.
	 *  Optionally re-calculate layout
	 * 	@param data data
	 *  @param doLayout if layout exists, redo it
	 *  @param query query for parameter
	 */
	public void setPrintData (PrintData data, MQuery query, boolean doLayout)
	{
		m_data = data;
		m_query = query;
		if (m_hasLayout && doLayout)
			layout();			//	re-calculate
	}	//	setPrintData

	/*************************************************************************/

	/**
	 * 	Set Paper
	 * 	@param paper Paper
	 */
	public void setPaper (CPaper paper)
	{
		setPaper(paper, m_headerHeight, m_footerHeight);
	}	//	setPaper

	/**
	 * 	Set Paper
	 *  Optionally re-calculate layout
	 * 	@param paper Paper
	 *  @param headerHeight header height
	 *  @param footerHeight footer height
	 */
	public void setPaper (CPaper paper, int headerHeight, int footerHeight)
	{
		if (paper == null)
			return;
		//
		boolean paperChange = headerHeight != m_headerHeight || footerHeight != m_footerHeight;
		if (!paperChange)
			paperChange = !paper.equals(m_paper);
		//
		log.debug("setPaper " + paper + " - Header=" + headerHeight + ", Footer=" + footerHeight);
		m_paper = paper;
		m_headerHeight = headerHeight;
		m_footerHeight = footerHeight;
		calculatePageSize();
		//
		if (m_hasLayout && paperChange)
			layout();			//	re-calculate
	}	//	setPaper

	/**
	 * 	Show Dialog and Set Paper
	 *  Optionally re-calculate layout
	 *  @param job printer job
	 */
	public void pageSetupDialog (PrinterJob job)
	{
		log.info("pageSetupDialog");
		if (m_paper.pageSetupDialog(job))
		{
			setPaper(m_paper);
			layout();
		}
	}	//	pageSetupDialog

	/**
	 * 	Set Paper from Page Format.
	 *  PageFormat is derived from CPaper
	 * 	@param pf Optional PageFormat - if null standard paper Portrait
	 */
	protected void setPageFormat (PageFormat pf)
	{
		if (pf != null)
			setPaper(new CPaper(pf));
		else
			setPaper(null);
	}	//	setPageFormat

	/**
	 * 	Get Page Format
	 * 	@return page format
	 */
	public PageFormat getPageFormat ()
	{
		return m_paper.getPageFormat();
	}	//	getPageFormat

	/**
	 * 	Calculate Page size based on Paper and header/footerHeight.
	 *  <pre>
	 *  Paper: 8.5x11.0" Portrait x=32.0,y=32.0 w=548.0,h=728.0
	 *  +------------------------ Paper   612x792
	 *  |    non-imageable space          32x32
	 *  |  +--------------------- Header = printable area start
	 *  |  | headerHeight=32      =>  [x=32,y=32,width=548,height=32]
	 *  |  +--------------------- Content
	 *  |  |                      =>  [x=32,y=64,width=548,height=664]
	 *  |  |
	 *  |  |
	 *  |  |
	 *  |  +--------------------- Footer
	 *  |  | footerHeight=32      =>  [x=32,y=728,width=548,height=32]
	 *  |  +--------------------- Footer end = printable area end
	 *  |   non-imageable space
	 *  +------------------------
	 *  </pre>
	 */
	private void calculatePageSize()
	{
		int x = (int)m_paper.getImageableX (true);
		int w = (int)m_paper.getImageableWidth (true);
		//
		int y = (int)m_paper.getImageableY (true);
		int h = (int)m_paper.getImageableHeight (true);

		int height = m_headerHeight;
		m_header.setBounds (x, y, w, height);
		//
		y += height;
		height = h-m_headerHeight-m_footerHeight;
		m_content.setBounds (x, y, w, height);
		//
		y += height;
		height = m_footerHeight;
		m_footer.setBounds (x, y, w, height);

		log.debug ("calulatePaperSize - Paper=" + m_paper + ",HeaderHeight=" + m_headerHeight + ",FooterHeight=" + m_footerHeight
			+ " => Header=" + m_header + ",Contents=" + m_content + ",Footer=" + m_footer);
	}	//	calculatePageSize

	/**
	 * 	Set Paper
	 * 	@return Paper
	 */
	public CPaper getPaper()
	{
		return m_paper;
	}	//	getPaper

	/*************************************************************************/

	/**
	 * 	Create Layout
	 */
	private void layout()
	{
		log.debug("layout");

		//	Header/Footer
		m_headerFooter = new HeaderFooter(m_printCtx);
		if (!m_format.isForm() && m_format.isStandardHeaderFooter())
			createStandardHeaderFooter();
		//
		m_pageNo = 0;
		m_pages.clear();
		m_tableElement = null;
		newPage();
		//
		if (m_format.isForm())
			layoutForm();
		else
		{
			//	Parameter
			PrintElement element = layoutParameter();
			if (element != null)
			{
				m_currPage.addElement (element);
				element.setLocation(m_position[AREA_CONTENT]);
				m_position[AREA_CONTENT].y += element.getHeight() + 5;	//	GAP
			}
			//	Table
			element = layoutTable(m_format, m_data, 0);
			element.setLocation(m_content.getLocation());
			for (int p = 1; p <= element.getPageCount(); p++)
			{
				if (p != 1)
					newPage();
				m_currPage.addElement (element);
			}
		}
		//
		String pageInfo = String.valueOf(m_pages.size()) + getPageInfo(m_pages.size());
		Env.setContext(m_printCtx, Page.CONTEXT_PAGECOUNT, pageInfo);
		Timestamp now = new Timestamp(System.currentTimeMillis());
		Env.setContext(m_printCtx, Page.CONTEXT_DATE,
			DisplayType.getDateFormat(DisplayType.Date).format(now));
		Env.setContext(m_printCtx, Page.CONTEXT_TIME,
			DisplayType.getDateFormat(DisplayType.DateTime).format(now));
		//	Update Page Info
		int pages = m_pages.size();
		for (int i = 0; i < pages; i++)
		{
			Page page = (Page)m_pages.get(i);
			int pageNo = page.getPageNo();
			pageInfo = String.valueOf(pageNo) + getPageInfo(pageNo);
			page.setPageInfo(pageInfo);
			page.setPageCount(pages);
		}


		m_hasLayout = true;
	}	//	layout

	/*************************************************************************/

	/**
	 * 	Get PrintLayout (Report) Context
	 * 	@return context
	 */
	public Properties getCtx()
	{
		return m_printCtx;
	}	//	getCtx

	/**
	 * 	Get the number of printed Columns
	 * 	@return np of printed columns
	 */
	public int getColumnCount()
	{
		return m_columnCount;
	}	//	getColumnCount

	/**
	 *	Set the current Print Area
	 *  @param area see HEADER_.. constants
	 */
	protected void setArea (int area)
	{
		if (m_area == area)
			return;
		if (area < 0 || area > 2)
			throw new ArrayIndexOutOfBoundsException (area);
		m_area = area;
	}	//	setArea

	/**
	 *	Get the current Print Area
	 *  @return area see HEADER_.. constants
	 */
	public int getArea ()
	{
		return m_area;
	}	//	getArea

	/**
	 * 	Return bounds of current Area
	 * 	@return rectangle with bounds
	 */
	public Rectangle getAreaBounds()
	{
		Rectangle part = m_content;
		if (m_area == AREA_HEADER)
			part = m_header;
		else if (m_area == AREA_FOOTER)
			part = m_footer;
		//
		return part;
	}	//	getAreaBounds

	/*************************************************************************/

	/**
	 * 	Create New Page, set position to top content
	 * 	@return new page no
	 */
	protected int newPage()
	{
		m_pageNo++;
		m_currPage = new Page (m_printCtx, m_pageNo);
		m_pages.add(m_currPage);
		//
		m_position[AREA_HEADER].setLocation(m_header.x, m_header.y);
		m_position[AREA_CONTENT].setLocation(m_content.x, m_content.y);
		m_position[AREA_FOOTER].setLocation(m_footer.x, m_footer.y);
		m_maxHeightSinceNewLine = new float[] {0f, 0f, 0f};;
		log.debug("newPage - Page=" + m_pageNo);
		return m_pageNo;
	}	//	newPage

	/**
	 * 	Move to New Line (may cause new page)
	 */
	protected void newLine ()
	{
		Rectangle part = m_content;
		if (m_area == AREA_HEADER)
			part = m_header;
		else if (m_area == AREA_FOOTER)
			part = m_footer;

		//	Temporary NL Position
		int xPos = part.x;
		if (m_tempNLPositon != 0)
			xPos = m_tempNLPositon;

		if (isYspaceFor(m_maxHeightSinceNewLine[m_area]))
		{
			m_position[m_area].setLocation(xPos, m_position[m_area].y + m_maxHeightSinceNewLine[m_area]);
			if (Log.isTraceLevel(10))
				log.debug("newLine - Page=" + m_pageNo + " [" + m_area + "] " + m_position[m_area].x + "/" + m_position[m_area].y);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -