MessageFormat header / footerFormat как изменить шрифт для печати JTable - PullRequest
5 голосов
/ 27 мая 2011

по отношению к этой теме У меня есть вопрос, если кто-то узнает, можно ли переопределить / изменить шрифт большего размера (тип шрифта, размер, цвет) для MessageFormat headerFormat JTable.PrintMode или я должен нарисовать g2.drawString («мой верхний / нижний колонтитул») и JTable # print () по отдельности

1 Ответ

9 голосов
/ 14 июня 2011

Как все уже упоминали (пока я отдыхал в отпуске :-) - TablePrintable тесно связан для секретности, нет возможности создавать подклассы, нет способа настроить печать верхнего / нижнего колонтитула. Единственный вариант перехвата - обернуть таблицу для печати по умолчанию, позволить ей выполнять свою работу без верхнего / нижнего колонтитула и взять на себя печать верхнего / нижнего колонтитула самостоятельно.

Проблема с фрагментами, показанными до сих пор, состоит в том, что они не очень хорошо работают с многостраничными страницами - как это известно и упоминалось всеми авторами, конечно, - потому что печатная форма по умолчанию считает, что нет верхних и нижних колонтитулов и свободно использует требуемое пространство ими. Не удивительно: -)

Так что вопрос: есть ли способ сделать так, чтобы по умолчанию не печатать в области верхнего / нижнего колонтитула? И да, это так: ответ двойного обхвата (эээ… обертка) - заставьте печатную машину по умолчанию считать, что у нее меньше места для печати, оборачивая данный pageFormat в тот, который возвращает скорректированный getImageableHeight / Y. Что-то вроде:

public class CustomPageFormat extends PageFormat {

    private PageFormat delegate;
    private double headerHeight;
    private double footerHeight;

    public CustomPageFormat(PageFormat format, double headerHeight, double footerHeight) {
        this.delegate = format;
        this.headerHeight = headerHeight;
        this.footerHeight = footerHeight;
    }
    /** 
     * @inherited <p>
     */
    @Override
    public double getImageableY() {
        return delegate.getImageableY() + headerHeight;
    }

    /** 
     * @inherited <p>
     */
    @Override
    public double getImageableHeight() {
        return delegate.getImageableHeight() - headerHeight - footerHeight;
    }

    // all other methods simply delegate

Затем используйте в оболочке для печати (нижний колонтитул должен быть выполнен аналогично):

public class CustomTablePrintable implements Printable {

    Printable tablePrintable;
    JTable table;
    MessageFormat header; 
    MessageFormat footer;

    public CustomTablePrintable(MessageFormat header, MessageFormat footer) {
        this.header = header;
        this.footer = footer;
    }

    public void setTablePrintable(JTable table, Printable printable) {
        tablePrintable = printable;        
        this.table = table;
    }

    @Override
    public int print(Graphics graphics, PageFormat pageFormat, 
            int pageIndex) throws PrinterException {
        // grab an untainted graphics
        Graphics2D g2d = (Graphics2D)graphics.create();
        // calculate the offsets and wrap the pageFormat
        double headerOffset = calculateHeaderHeight(g2d, pageIndex);
        CustomPageFormat wrappingPageFormat = new CustomPageFormat(pageFormat, headerOffset, 0);
        // feed the wrapped pageFormat into the default printable
        int exists = tablePrintable.print(graphics, wrappingPageFormat, pageIndex);
        if (exists != PAGE_EXISTS) {
            g2d.dispose();
            return exists;
        }
        // translate the graphics to the start of the original pageFormat and draw header
        g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
        printHeader(g2d, pageIndex, (int) pageFormat.getImageableWidth());
        g2d.dispose();

        return PAGE_EXISTS;        
    }


    protected double calculateHeaderHeight(Graphics2D g, int pageIndex) {
        if (header == null) return 0;
        Object[] pageNumber = new Object[]{new Integer(pageIndex + 1)};
        String text = header.format(pageNumber);
        Font headerFont = table.getFont().deriveFont(Font.BOLD, 18f);
        g.setFont(headerFont);
        Rectangle2D rect = g.getFontMetrics().getStringBounds(text, g);
        return rect.getHeight();
    }

    protected void printHeader(Graphics2D g, int pageIndex, int imgWidth) {
        Object[] pageNumber = new Object[]{new Integer(pageIndex + 1)};
        String text = header.format(pageNumber);
        Font headerFont = table.getFont().deriveFont(Font.BOLD, 18f);
        g.setFont(headerFont);
        Rectangle2D rect = g.getFontMetrics().getStringBounds(text, g);
        // following is c&p from TablePrintable printText
        int tx;

        // if the text is small enough to fit, center it
        if (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()));
        g.setColor(Color.BLACK);
        g.drawString(text, tx, ty);

    }
}

И в конце вернуть это из таблицы getPrintable, например:

    final JTable table = new JTable(myModel){

        /** 
         * @inherited <p>
         */
        @Override
        public Printable getPrintable(PrintMode printMode,
                MessageFormat headerFormat, MessageFormat footerFormat) {
            Printable printable = super.getPrintable(printMode, null, null);
            CustomTablePrintable custom = new CustomTablePrintable(headerFormat, footerFormat);
            custom.setTablePrintable(this, printable);
            return custom;
        }

    };

printHeader / Footer может быть реализован, чтобы делать все, что требуется.

В конце дня: ответ на вопрос «нужно ли мне вызывать g.drawString (...)» по-прежнему «Да». Но, по крайней мере, это безопасно за пределами самой таблицы: -)

...