代码之家  ›  专栏  ›  技术社区  ›  user1631306

转换为JScrollPane中JTable的图像

  •  1
  • user1631306  · 技术社区  · 8 年前

    我有一个 JTable a内部 JScrollPane JPanel . 我需要将表格导出为图像。如果表格足够小,可以在 滚动面板 ,没有滚动条。但如果表格太大,需要滚动条左右或上下移动,则在导出的图像中只能看到表格的一部分。 我正在使用以下代码

    public BufferedImage componentToImage( Component component, boolean visible)
    {
        if (visible)
        {
            BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TRANSLUCENT);
            Graphics2D g2d = (Graphics2D) img.getGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            component.paintAll(g2d);
            try
            {
                File outputfile = new File("C:\\Users\\SciOme Admin\\Desktop\\a.png");
                ImageIO.write(img, "png", outputfile);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return img;
        }
    }
    

    我经过的地方 滚动面板 作为组件。 我得到附加的部分图像,滚动条。但我需要完整的 JTable表格 .

    enter image description here

    JTable表格 滚动面板 . 一个表仅用于显示行标题并使其始终可见,即使在向右滚动时也是如此。

    1 回复  |  直到 8 年前
        1
  •  2
  •   MadProgrammer    8 年前

    基于你的形象,我建议你利用 JScrollPane rowHeader 支持渲染a JTable 即使在最好的情况下,这也不是一项容易的任务,通常您只需要利用表的内置打印支持,但这并没有考虑到 s 行标题 ,一个足够大的表可能需要打印到多个页面,这会变得很混乱。

    在你的情况下,你必须拆卸 并渲染 行标题 , columnHeader 和main view 你自己

    在“非常”基本的级别上,这将调用计算渲染所有组件所需的总体大小,计算每个组件的偏移位置并绘制它们,类似这样的。。。

    Component columnHeader = scrollPane.getColumnHeader().getView();
    Component rowHeader = scrollPane.getRowHeader().getView();
    Component view = scrollPane.getViewport().getView();
    
    int width = rowHeader.getPreferredSize().width + view.getPreferredSize().width;
    int height = columnHeader.getPreferredSize().height + view.getPreferredSize().height;
    
    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = img.createGraphics();
    g2d.setColor(Color.WHITE);
    g2d.fillRect(0, 0, width, height);
    int xOffset = rowHeader.getPreferredSize().width;
    int yOffset = columnHeader.getPreferredSize().height;
    
    Graphics2D rowHeaderG = (Graphics2D) g2d.create();
    rowHeaderG.translate(0, yOffset);
    rowHeader.printAll(rowHeaderG);
    rowHeaderG.dispose();
    
    Graphics2D colHeaderG = (Graphics2D) g2d.create();
    colHeaderG.translate(xOffset, 0);
    columnHeader.printAll(colHeaderG);
    colHeaderG.dispose();
    
    Graphics2D viewG = (Graphics2D) g2d.create();
    viewG.translate(xOffset, yOffset);
    view.printAll(viewG);
    viewG.dispose();
    g2d.dispose();
    

    我从一个旧的示例中借用了一些代码,并作为示例实现了基本思想。因为我没有你的代码,你还有其他问题,你必须自己解决(很难用水晶球调试),但这应该能帮助你开始

    从窗口。。。

    From the frame

    到图像。。。

    to the image

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Container;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JViewport;
    import javax.swing.SwingUtilities;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    import javax.swing.event.TableColumnModelEvent;
    import javax.swing.event.TableColumnModelListener;
    import javax.swing.table.JTableHeader;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumn;
    import javax.swing.table.TableColumnModel;
    
    public class TableRowHeaderTest {
    
        public static void main(String[] args) {
            new TableRowHeaderTest();
        }
    
        public TableRowHeaderTest() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    Object rowData1[][]
                            = {
                                {"", "", "", ""},
                                {"", "", "", ""},
                                {"", "", "", ""},
                                {"", "", "", ""}
                            };
    
                    Object columnNames1[] = {"HEADER 1", "HEADER 2", "HEADER 3", "HEADER 4"};
    
                    JTable table1 = new TableWithRowHeader(rowData1, columnNames1);
    
                    table1.getColumnModel().getColumn(0).setPreferredWidth(120);
    
                    JScrollPane scrollPane1 = new JScrollPane(table1);
    //                scrollPane1.setColumnHeaderView(null);
    
                    JButton print = new JButton("Save");
                    print.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            print(scrollPane1);
                        }
                    });
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(scrollPane1);
                    frame.add(print, BorderLayout.SOUTH);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        protected void print(JScrollPane scrollPane) {
            Component columnHeader = scrollPane.getColumnHeader().getView();
            Component rowHeader = scrollPane.getRowHeader().getView();
            Component view = scrollPane.getViewport().getView();
    
            int width = rowHeader.getPreferredSize().width + view.getPreferredSize().width;
            int height = columnHeader.getPreferredSize().height + view.getPreferredSize().height;
    
            BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = img.createGraphics();
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, width, height);
            int xOffset = rowHeader.getPreferredSize().width;
            int yOffset = columnHeader.getPreferredSize().height;
    
            Graphics2D rowHeaderG = (Graphics2D) g2d.create();
            rowHeaderG.translate(0, yOffset);
            rowHeader.printAll(rowHeaderG);
            rowHeaderG.dispose();
    
            Graphics2D colHeaderG = (Graphics2D) g2d.create();
            colHeaderG.translate(xOffset, 0);
            columnHeader.printAll(colHeaderG);
            colHeaderG.dispose();
    
            Graphics2D viewG = (Graphics2D) g2d.create();
            viewG.translate(xOffset, yOffset);
            view.printAll(viewG);
            viewG.dispose();
            g2d.dispose();
    
            try {
                ImageIO.write(img, "png", new File("Test.png"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
    
        }
    
        public class TableWithRowHeader extends JTable {
    
            private TableRowHeader rowHeader;
    
            public TableWithRowHeader(final Object[][] rowData, final Object[] columnNames) {
                super(rowData, columnNames);
                rowHeader = new TableRowHeader(this);
                setGridColor(Color.LIGHT_GRAY);
            }
    
            @Override
            protected void configureEnclosingScrollPane() {
                // This is required as it calls a private method...
                super.configureEnclosingScrollPane();
    
                Container parent = SwingUtilities.getUnwrappedParent(this);
                if (parent instanceof JViewport) {
    
                    JViewport port = (JViewport) parent;
                    Container gp = port.getParent();
                    if (gp instanceof JScrollPane) {
    
                        JScrollPane scrollPane = (JScrollPane) gp;
                        JViewport viewport = scrollPane.getViewport();
                        if (viewport == null || SwingUtilities.getUnwrappedView(viewport) != this) {
                            return;
                        }
    //                    scrollPane.setColumnHeaderView(null);
                        scrollPane.setRowHeaderView(rowHeader);
                    }
                }
            }
    
        }
    
        public class TableRowHeader extends JTableHeader {
    
            private JTable table;
    
            public TableRowHeader(JTable table) {
                super(table.getColumnModel());
                this.table = table;
    
                table.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
    
                    @Override
                    public void columnAdded(TableColumnModelEvent e) {
                        repaint();
                    }
    
                    @Override
                    public void columnRemoved(TableColumnModelEvent e) {
                        repaint();
                    }
    
                    @Override
                    public void columnMoved(TableColumnModelEvent e) {
                        repaint();
                    }
    
                    @Override
                    public void columnMarginChanged(ChangeEvent e) {
                        repaint();
                    }
    
                    @Override
                    public void columnSelectionChanged(ListSelectionEvent e) {
                        // Don't care about this, want to highlight the row...
                    }
                });
                table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
                    @Override
                    public void valueChanged(ListSelectionEvent e) {
                        repaint();
                    }
                });
            }
    
            public JTable getTable() {
                return table;
            }
    
            @Override
            public Dimension getPreferredSize() {
                Dimension size = new Dimension();
                JTable table = getTable();
                if (table != null) {
                    TableColumnModel model = table.getColumnModel();
                    if (model != null) {
    
                        for (int index = 0; index < model.getColumnCount(); index++) {
    
                            TableColumn column = model.getColumn(index);
                            TableCellRenderer renderer = column.getHeaderRenderer();
                            if (renderer == null) {
    
                                renderer = getDefaultRenderer();
    
                            }
                            Component comp = renderer.getTableCellRendererComponent(table, column.getHeaderValue(), false, false, -1, index);
                            size.width = Math.max(comp.getPreferredSize().width, size.width);
                            size.height += table.getRowHeight(index);
    
                        }
    
                    }
                }
                return size;
    
            }
    
            /**
             * Overridden to avoid propagating a invalidate up the tree when the
             * cell renderer child is configured.
             */
            @Override
            public void invalidate() {
            }
    
            /**
             * If the specified component is already a child of this then we don't
             * bother doing anything - stacking order doesn't matter for cell
             * renderer components (CellRendererPane doesn't paint anyway).
             */
            @Override
            protected void addImpl(Component x, Object constraints, int index) {
                if (x.getParent() == this) {
                    return;
                } else {
                    super.addImpl(x, constraints, index);
                }
            }
    
            @Override
            protected void paintComponent(Graphics g) {
    
    //            super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
    
                g2d.setColor(getBackground());
                g2d.fillRect(0, 0, getWidth(), getHeight());
    
                JTable table = getTable();
                if (table != null) {
    
                    int width = getWidth();
    
                    TableColumnModel model = table.getColumnModel();
                    if (model != null) {
    
                        for (int index = 0; index < model.getColumnCount(); index++) {
    
                            TableColumn column = model.getColumn(index);
                            TableCellRenderer renderer = column.getHeaderRenderer();
                            if (renderer == null) {
    
                                renderer = getDefaultRenderer();
    
                            }
    
                            boolean selected = table.getSelectedRow() == index;
    
                            Component comp = renderer.getTableCellRendererComponent(table, column.getHeaderValue(), selected, false, 0, index);
    
                            add(comp);
                            comp.validate();
    
                            int height = table.getRowHeight(index) - 1;
                            comp.setBounds(0, 0, width, height);
                            comp.paint(g2d);
                            comp.setBounds(-width, -height, 0, 0);
    
                            g2d.setColor(table.getGridColor());
                            g2d.drawLine(0, height, width, height);
    
                            g2d.translate(0, height + 1);
    
                        }
    
                    }
                }
                g2d.dispose();
                removeAll();
            }
    
        }
    
    }