同步操作将从 Stefan/Java8Source 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/** Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************/package javax.swing;import javax.swing.table.*;import java.awt.*;import java.awt.print.*;import java.awt.geom.*;import java.text.MessageFormat;/*** An implementation of <code>Printable</code> for printing* <code>JTable</code>s.* <p>* This implementation spreads table rows naturally in sequence* across multiple pages, fitting as many rows as possible per page.* The distribution of columns, on the other hand, is controlled by a* printing mode parameter passed to the constructor. When* <code>JTable.PrintMode.NORMAL</code> is used, the implementation* handles columns in a similar manner to how it handles rows, spreading them* across multiple pages (in an order consistent with the table's* <code>ComponentOrientation</code>).* When <code>JTable.PrintMode.FIT_WIDTH</code> is given, the implementation* scales the output smaller if necessary, to ensure that all columns fit on* the page. (Note that width and height are scaled equally, ensuring that the* aspect ratio remains the same).* <p>* The portion of table printed on each page is headed by the* appropriate section of the table's <code>JTableHeader</code>.* <p>* Header and footer text can be added to the output by providing* <code>MessageFormat</code> instances to the constructor. The* printing code requests Strings from the formats by calling* their <code>format</code> method with a single parameter:* an <code>Object</code> array containing a single element of type* <code>Integer</code>, representing the current page number.* <p>* There are certain circumstances where this <code>Printable</code>* cannot fit items appropriately, resulting in clipped output.* These are:* <ul>* <li>In any mode, when the header or footer text is too wide to* fit completely in the printable area. The implementation* prints as much of the text as possible starting from the beginning,* as determined by the table's <code>ComponentOrientation</code>.* <li>In any mode, when a row is too tall to fit in the* printable area. The upper most portion of the row* is printed and no lower border is shown.* <li>In <code>JTable.PrintMode.NORMAL</code> when a column* is too wide to fit in the printable area. The center of the* column is printed and no left and right borders are shown.* </ul>* <p>* It is entirely valid for a developer to wrap this <code>Printable</code>* inside another in order to create complex reports and documents. They may* even request that different pages be rendered into different sized* printable areas. The implementation was designed to handle this by* performing most of its calculations on the fly. However, providing different* sizes works best when <code>JTable.PrintMode.FIT_WIDTH</code> is used, or* when only the printable width is changed between pages. This is because when* it is printing a set of rows in <code>JTable.PrintMode.NORMAL</code> and the* implementation determines a need to distribute columns across pages,* it assumes that all of those rows will fit on each subsequent page needed* to fit the columns.* <p>* It is the responsibility of the developer to ensure that the table is not* modified in any way after this <code>Printable</code> is created (invalid* modifications include changes in: size, renderers, or underlying data).* The behavior of this <code>Printable</code> is undefined if the table is* changed at any time after creation.** @author Shannon Hickey*/class TablePrintable implements Printable {/** The table to print. */private JTable table;/** For quick reference to the table's header. */private JTableHeader header;/** For quick reference to the table's column model. */private TableColumnModel colModel;/** To save multiple calculations of total column width. */private int totalColWidth;/** The printing mode of this printable. */private JTable.PrintMode printMode;/** Provides the header text for the table. */private MessageFormat headerFormat;/** Provides the footer text for the table. */private MessageFormat footerFormat;/** The most recent page index asked to print. */private int last = -1;/** The next row to print. */private int row = 0;/** The next column to print. */private int col = 0;/** Used to store an area of the table to be printed. */private final Rectangle clip = new Rectangle(0, 0, 0, 0);/** Used to store an area of the table's header to be printed. */private final Rectangle hclip = new Rectangle(0, 0, 0, 0);/** Saves the creation of multiple rectangles. */private final Rectangle tempRect = new Rectangle(0, 0, 0, 0);/** Vertical space to leave between table and header/footer text. */private static final int H_F_SPACE = 8;/** Font size for the header text. */private static final float HEADER_FONT_SIZE = 18.0f;/** Font size for the footer text. */private static final float FOOTER_FONT_SIZE = 12.0f;/** The font to use in rendering header text. */private Font headerFont;/** The font to use in rendering footer text. */private Font footerFont;/*** Create a new <code>TablePrintable</code> for the given* <code>JTable</code>. Header and footer text can be specified using the* two <code>MessageFormat</code> parameters. When called upon to provide* a String, each format is given the current page number.** @param table the table to print* @param printMode the printing mode for this printable* @param headerFormat a <code>MessageFormat</code> specifying the text to* be used in printing a header, or null for none* @param footerFormat a <code>MessageFormat</code> specifying the text to* be used in printing a footer, or null for none* @throws IllegalArgumentException if passed an invalid print mode*/public TablePrintable(JTable table,JTable.PrintMode printMode,MessageFormat headerFormat,MessageFormat footerFormat) {this.table = table;header = table.getTableHeader();colModel = table.getColumnModel();totalColWidth = colModel.getTotalColumnWidth();if (header != null) {// the header clip height can be set once since it's unchanginghclip.height = header.getHeight();}this.printMode = printMode;this.headerFormat = headerFormat;this.footerFormat = footerFormat;// derive the header and footer font from the table's fontheaderFont = table.getFont().deriveFont(Font.BOLD,HEADER_FONT_SIZE);footerFont = table.getFont().deriveFont(Font.PLAIN,FOOTER_FONT_SIZE);}/*** Prints the specified page of the table into the given {@link Graphics}* context, in the specified format.** @param graphics the context into which the page is drawn* @param pageFormat the size and orientation of the page being drawn* @param pageIndex the zero based index of the page to be drawn* @return PAGE_EXISTS if the page is rendered successfully, or* NO_SUCH_PAGE if a non-existent page index is specified* @throws PrinterException if an error causes printing to be aborted*/public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)throws PrinterException {// for easy access to these valuesfinal int imgWidth = (int)pageFormat.getImageableWidth();final int imgHeight = (int)pageFormat.getImageableHeight();if (imgWidth <= 0) {throw new PrinterException("Width of printable area is too small.");}// to pass the page number when formatting the header and footer textObject[] pageNumber = new Object[]{Integer.valueOf(pageIndex + 1)};// fetch the formatted header text, if anyString headerText = null;if (headerFormat != null) {headerText = headerFormat.format(pageNumber);}// fetch the formatted footer text, if anyString footerText = null;if (footerFormat != null) {footerText = footerFormat.format(pageNumber);}// to store the bounds of the header and footer textRectangle2D hRect = null;Rectangle2D fRect = null;// the amount of vertical space needed for the header and footer textint headerTextSpace = 0;int footerTextSpace = 0;// the amount of vertical space available for printing the tableint availableSpace = imgHeight;// if there's header text, find out how much space is needed for it// and subtract that from the available spaceif (headerText != null) {graphics.setFont(headerFont);hRect = graphics.getFontMetrics().getStringBounds(headerText,graphics);headerTextSpace = (int)Math.ceil(hRect.getHeight());availableSpace -= headerTextSpace + H_F_SPACE;}// if there's footer text, find out how much space is needed for it// and subtract that from the available spaceif (footerText != null) {graphics.setFont(footerFont);fRect = graphics.getFontMetrics().getStringBounds(footerText,graphics);footerTextSpace = (int)Math.ceil(fRect.getHeight());availableSpace -= footerTextSpace + H_F_SPACE;}if (availableSpace <= 0) {throw new PrinterException("Height of printable area is too small.");}// depending on the print mode, we may need a scale factor to// fit the table's entire width on the pagedouble sf = 1.0D;if (printMode == JTable.PrintMode.FIT_WIDTH &&totalColWidth > imgWidth) {// if not, we would have thrown an acception previouslyassert imgWidth > 0;// it must be, according to the if-condition, since imgWidth > 0assert totalColWidth > 1;sf = (double)imgWidth / (double)totalColWidth;}// dictated by the previous two assertionsassert sf > 0;// This is in a loop for two reasons:// First, it allows us to catch up in case we're called starting// with a non-zero pageIndex. Second, we know that we can be called// for the same page multiple times. The condition of this while// loop acts as a check, ensuring that we don't attempt to do the// calculations again when we are called subsequent times for the// same page.while (last < pageIndex) {// if we are finished all columns in all rowsif (row >= table.getRowCount() && col == 0) {return NO_SUCH_PAGE;}// rather than multiplying every row and column by the scale factor// in findNextClip, just pass a width and height that have already// been divided by itint scaledWidth = (int)(imgWidth / sf);int scaledHeight = (int)((availableSpace - hclip.height) / sf);// calculate the area of the table to be printed for this pagefindNextClip(scaledWidth, scaledHeight);last++;}// create a copy of the graphics so we don't affect the one given to usGraphics2D g2d = (Graphics2D)graphics.create();// translate into the co-ordinate system of the pageFormatg2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());// to save and store the transformAffineTransform oldTrans;// if there's footer text, print it at the bottom of the imageable areaif (footerText != null) {oldTrans = g2d.getTransform();g2d.translate(0, imgHeight - footerTextSpace);printText(g2d, footerText, fRect, footerFont, imgWidth);g2d.setTransform(oldTrans);}// if there's header text, print it at the top of the imageable area// and then translate downwardsif (headerText != null) {printText(g2d, headerText, hRect, headerFont, imgWidth);g2d.translate(0, headerTextSpace + H_F_SPACE);}// constrain the table output to the available spacetempRect.x = 0;tempRect.y = 0;tempRect.width = imgWidth;tempRect.height = availableSpace;g2d.clip(tempRect);// if we have a scale factor, scale the graphics object to fit// the entire widthif (sf != 1.0D) {g2d.scale(sf, sf);// otherwise, ensure that the current portion of the table is// centered horizontally} else {int diff = (imgWidth - clip.width) / 2;g2d.translate(diff, 0);}// store the old transform and clip for later restorationoldTrans = g2d.getTransform();Shape oldClip = g2d.getClip();// if there's a table header, print the current section and// then translate downwardsif (header != null) {hclip.x = clip.x;hclip.width = clip.width;g2d.translate(-hclip.x, 0);g2d.clip(hclip);header.print(g2d);// restore the original transform and clipg2d.setTransform(oldTrans);g2d.setClip(oldClip);// translate downwardsg2d.translate(0, hclip.height);}// print the current section of the tableg2d.translate(-clip.x, -clip.y);g2d.clip(clip);table.print(g2d);// restore the original transform and clipg2d.setTransform(oldTrans);g2d.setClip(oldClip);// draw a box around the tableg2d.setColor(Color.BLACK);g2d.drawRect(0, 0, clip.width, hclip.height + clip.height);// dispose the graphics copyg2d.dispose();return PAGE_EXISTS;}/*** A helper method that encapsulates common code for rendering the* header and footer text.** @param g2d the graphics to draw into* @param text the text to draw, non null* @param rect the bounding rectangle for this text,* as calculated at the given font, non null* @param font the font to draw the text in, non null* @param imgWidth the width of the area to draw into*/private void printText(Graphics2D g2d,String text,Rectangle2D rect,Font font,int imgWidth) {int tx;// if the text is small enough to fit, center itif (rect.getWidth() < imgWidth) {tx = (int)((imgWidth - rect.getWidth()) / 2);// otherwise, if the table is LTR, ensure the left side of// the text shows; the right can be clipped} else if (table.getComponentOrientation().isLeftToRight()) {tx = 0;// otherwise, ensure the right side of the text shows} else {tx = -(int)(Math.ceil(rect.getWidth()) - imgWidth);}int ty = (int)Math.ceil(Math.abs(rect.getY()));g2d.setColor(Color.BLACK);g2d.setFont(font);g2d.drawString(text, tx, ty);}/*** Calculate the area of the table to be printed for* the next page. This should only be called if there* are rows and columns left to print.** To avoid an infinite loop in printing, this will* always put at least one cell on each page.** @param pw the width of the area to print in* @param ph the height of the area to print in*/private void findNextClip(int pw, int ph) {final boolean ltr = table.getComponentOrientation().isLeftToRight();// if we're ready to start a new set of rowsif (col == 0) {if (ltr) {// adjust clip to the left of the first columnclip.x = 0;} else {// adjust clip to the right of the first columnclip.x = totalColWidth;}// adjust clip to the top of the next set of rowsclip.y += clip.height;// adjust clip width and height to be zeroclip.width = 0;clip.height = 0;// fit as many rows as possible, and at least oneint rowCount = table.getRowCount();int rowHeight = table.getRowHeight(row);do {clip.height += rowHeight;if (++row >= rowCount) {break;}rowHeight = table.getRowHeight(row);} while (clip.height + rowHeight <= ph);}// we can short-circuit for JTable.PrintMode.FIT_WIDTH since// we'll always fit all columns on the pageif (printMode == JTable.PrintMode.FIT_WIDTH) {clip.x = 0;clip.width = totalColWidth;return;}if (ltr) {// adjust clip to the left of the next set of columnsclip.x += clip.width;}// adjust clip width to be zeroclip.width = 0;// fit as many columns as possible, and at least oneint colCount = table.getColumnCount();int colWidth = colModel.getColumn(col).getWidth();do {clip.width += colWidth;if (!ltr) {clip.x -= colWidth;}if (++col >= colCount) {// reset col to 0 to indicate we're finished all columnscol = 0;break;}colWidth = colModel.getColumn(col).getWidth();} while (clip.width + colWidth <= pw);}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。