如何在打印时在JTable中添加背景图像?

时间:2011-08-10 06:04:11

标签: java swing jtable

我想打印带有背景图片或水印的JTable。我的代码是:

public void actionPerformed(ActionEvent ae)
{
    boolean status=false;

    MessageFormat header = null;
    header = new MessageFormat("Header");
    MessageFormat footer = null;
    footer = new MessageFormat("Page");

    boolean fitWidth = true;
    boolean showPrintDialog = true;
    boolean interactive = true;

    /* determine the print mode */
    JTable.PrintMode mode = fitWidth ? JTable.PrintMode.FIT_WIDTH
                                     : JTable.PrintMode.NORMAL;

    try
    {
        status = jt.print(mode, header, footer,showPrintDialog,null,interactive);

        if(status ==true)
        {
            frame.dispose();
        }
    }
    catch(Exception ee)
    {
        System.out.println(ee.getMessage());
    }
}

如何在此方法中传递或设置背景图像?

2 个答案:

答案 0 :(得分:3)

没有简单的方法可以为整个JTable设置BackGround的内容,但JViewPort中的JScrollPane可以轻松完成,但如果在JScrollPane内则无关紧要JTable或其他JComponents

例如

import java.awt.*;
import javax.swing.*;

class ImageAsTableBackround {

    private JScrollPane sp;
    private JTable table;
    private String[] head = {"One", "Two", "Three", "Four", "Five", "Six"};
    private String[][] data = new String[25][6];

    public void buildGUI() {
        sp = new JScrollPane();

// uncomment these codes lines for panting an image from package, 
// but then block code table = new TableBackroundPaint0(data, head);
        //sp.setViewport(new ImageViewport());
        //table = new JTable(data, head);
        //table.setOpaque(false);

// code for painting from generated code    
        table = new TableBackroundPaint0(data, head);

        table.setBackground(new Color(0, 0, 0, 0));
        table.setFillsViewportHeight(true);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        sp.setViewportView(table);
        JFrame frame = new JFrame();
        frame.getContentPane().add(sp);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    class ImageViewport extends JViewport {

        private static final long serialVersionUID = 1L;
        private Image img;

        public ImageViewport() {
            try {
                ImageIcon image = new ImageIcon(getClass().getResource("resources/PICT6090.jpg"));
                img = image.getImage();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (img != null) {
                g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
            } else {
                g.drawString("This space for rent", 50, 50);
            }
        }
    }

    class TableBackroundPaint0 extends JTable {

        private static final long serialVersionUID = 1L;

        TableBackroundPaint0(Object[][] data, Object[] head) {
            super(data, head);
            setOpaque(false);
            ((JComponent) getDefaultRenderer(Object.class)).setOpaque(false);
        }

        @Override
        public void paintComponent(Graphics g) {
            Color background = new Color(168, 210, 241);
            Color controlColor = new Color(230, 240, 230);
            int width = getWidth();
            int height = getHeight();
            Graphics2D g2 = (Graphics2D) g;
            Paint oldPaint = g2.getPaint();
            g2.setPaint(new GradientPaint(0, 0, background, width, 0, controlColor));
            g2.fillRect(0, 0, width, height);
            g2.setPaint(oldPaint);
            for (int row : getSelectedRows()) {
                Rectangle start = getCellRect(row, 0, true);
                Rectangle end = getCellRect(row, getColumnCount() - 1, true);
                g2.setPaint(new GradientPaint(start.x, 0, controlColor, (int) ((end.x + end.width - start.x) * 1.25), 0, Color.orange));
                g2.fillRect(start.x, start.y, end.x + end.width - start.x, start.height);
            }
            super.paintComponent(g);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ImageAsTableBackround().buildGUI();
            }
        });
    }
}

答案 1 :(得分:3)

问题分为两部分

  • 打印每页的图片
  • 确保图像“闪耀”表格

第二个是由@mKorbel解决的(虽然没有真正解决,因为没有很好的解决方案:-)

要解决第一个问题,我会选择一个自定义的Printable和子类JTable来返回它,比如

public class BackgroundPrintable implements Printable {

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

    public BackgroundPrintable(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 {
        printImage(graphics, pageFormat, pageIndex);
        int exists = tablePrintable.print(graphics, pageFormat, pageIndex);
        if (exists != PAGE_EXISTS) {
            return exists;
        }
        return PAGE_EXISTS;        
    }

    private void printImage(Graphics graphics, PageFormat pageFormat,
            int pageIndex) {
        // grab an untainted graphics
        Graphics2D g2d = (Graphics2D)graphics.create();
        // do the image painting 
        ....
        // cleanup  
        g2d.dispose();
    }

}

// use in JTable subclass
@Override
public Printable getPrintable(PrintMode printMode,
        MessageFormat headerFormat, MessageFormat footerFormat) {
    Printable printable = super.getPrintable(printMode, null, null);
    BackgroundPrintable custom = new BackgroundPrintable(headerFormat, footerFormat);
    custom.setTablePrintable(this, printable);
    return custom;
}

要实现第二个目标,JTable及其渲染器必须是透明的。棘手,因为:

  • 可能只有在打印时 - 否则它们应该具有通常的不透明度
  • 渲染器的所有必须是透明的,没有完全安全的方法来抓住它们

自定义JTable可以尝试通过在其prepareRenderer中强制渲染组件的不透明度来实现这一点:

  @Override
   public Component prepareRenderer(TableCellRenderer renderer,
            int row, int column) {
        JComponent comp = (JComponent) super.prepareRenderer(renderer, row, column);
        if (isPaintingForPrint()) {
            comp.setOpaque(false);
        } else {
            comp.setOpaque(true);
        }   
        return comp;
   }

实际上,这并不完全有效:对于自然透明的组件,else块中的代码可能是错误的事情。我担心没有真正可靠的解决方案。