📄 layoutengine.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.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 + -