1

我在用

iText 版本 5.3.3。Java jdk 1.6.0

我正在开发一个报告软件,用户希望在其中自定义具有 1 点黑色边框的 JTable 单元格,该边框出现在 JTable 上,如下所示:-

JTable 输出

PDF输出:

PDF 输出

在两个输出上,1 点边界单元的单元之间存在一些间隙。我们发现线不在网格线上。无论如何,这些边界线是否可能作为 1 点线出现在网格上。以下是使用 JTable 和 pdf 测试上述问题的示例代码。

表图像.java

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.LineBorder;
import javax.swing.table.JTableHeader;
import com.lowagie.text.Document;
import com.lowagie.text.PageSize;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfTemplate;
import com.lowagie.text.pdf.PdfWriter;

class TableImage {

    public static void main(String[] args) throws Exception {
        Object[][] data = {
            {"Hari", new Integer(23), new Double(78.23), (true)},
            {"James", new Integer(23), new Double(47.64), (false)},
            {"Sally", new Integer(22), new Double(84.81), (true)}
        };
        String[] columns = {"Name", "Age", "GPA", "Pass"};
        JTable table = new JTable(data, columns);
        JScrollPane scroll = new JScrollPane(table);
        JPanel p = new JPanel(new BorderLayout());
        p.add(scroll, BorderLayout.CENTER);
        JOptionPane.showMessageDialog(null, p);
        JTableHeader h = table.getTableHeader();
        int x = table.getWidth();
        int y = table.getHeight();
        table.setDefaultRenderer(Object.class,
                new ColumnAlignmentRenderer(
                table.getDefaultRenderer(Object.class)));
        BufferedImage bi = new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB);
        Graphics g = bi.createGraphics();
        Graphics2D g2 = (Graphics2D) g;
        table.paint(g2);
        JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));
        print(table);
    }

    private static void print(JTable table) {
        Document document = new Document(PageSize.A4.rotate());
        try {
            PdfWriter writer = PdfWriter.getInstance(document,
                    new FileOutputStream("F://jTable.pdf"));
            document.open();
            PdfContentByte cb = writer.getDirectContent();
            cb.saveState();
            PdfTemplate pdfTemplate = cb.createTemplate(
                    table.getWidth(), table.getHeight());
            Graphics2D g2 = pdfTemplate.createGraphics(
                    table.getWidth(), table.getHeight());
            table.print(g2);
            cb.addTemplate(pdfTemplate, 20, 100);
            g2.dispose();
            cb.restoreState();
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
        document.close();
    }

    private TableImage() {
    }
}

ColumnAlignmentRenderer.java

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;

public class ColumnAlignmentRenderer extends DefaultTableCellRenderer {

    private TableCellRenderer mWrappedRenderer;
    private HashMap objFormatCellMap;

    public ColumnAlignmentRenderer(TableCellRenderer pWrappedRenderer) {
        mWrappedRenderer = pWrappedRenderer;
    }

    public Component getTableCellRendererComponent(JTable pTable,
            Object pValue, boolean pIsSelected,
            boolean pHasFocus, int pRow, int pColumn) {
        int hAlignment = SwingConstants.LEFT;
        int vAlignment = SwingConstants.CENTER;
        String pattern = "##000.0";
        Font font = pTable.getFont();
        Border cellBorder = pTable.getBorder();
        // Border cellBorder = BorderFactory.createCompoundBorder();
        Color backgroundColor = Color.WHITE;
        Color foregroundColor = Color.BLACK;
        // Use the wrapped renderer 
        Component renderedComponent =
                mWrappedRenderer.getTableCellRendererComponent(
                pTable, pValue, pIsSelected, pHasFocus, pRow, pColumn);
        int iLeft = 1;
        int iRight = 1;
        int iTop = 1;
        int iBottom = 1;
        Map fontAttributes = font.getAttributes();
        cellBorder = BorderFactory.createCompoundBorder(cellBorder, 
                new ZoneBorder(iTop, iLeft, iBottom, iRight, Color.BLACK));
        ((JLabel) renderedComponent).setBorder(cellBorder);
        if (pIsSelected) {
            renderedComponent.setBackground(pTable.getSelectionBackground());
        }
        return renderedComponent;
    }

    public void setHashFormatCellData(HashMap hashFormatCellData) {
        this.objFormatCellMap = hashFormatCellData;
    }
}

ZoneBorder.java

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

public class ZoneBorder implements Border {

    private static final int WIDTH = 1;
    private Color color;
    private int iTop = 0, iRight = 0, iBottom = 0, iLeft = 0;

    public ZoneBorder(int T, int R, int B, int L, Color color) {
        this.iTop = T;
        this.iRight = R;
        this.iBottom = B;
        this.iLeft = L;
        this.color = color;
    }

    public boolean isBorderOpaque() {
        return false;
    }

    public Insets getBorderInsets(Component c) {
        return new Insets(iTop, iRight, iBottom, iLeft);
    }

    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        Color oldColor = g.getColor();
        g.setColor(color);
        for (int i = 0; i < iTop; i++) {
            g.drawLine(x, y + i, x + width - 1, y + i);
        }
        //g.setColor(southColor);
        for (int i = 0; i < iBottom; i++) {
            g.drawLine(x, y + height - i - 1, x + width - 1, y + height - i - 1);
        }
        //g.setColor(eastColor);
        for (int i = 0; i < iLeft; i++) {
            g.drawLine(x + i, y, x + i, y + height - 1);
        }
        //g.setColor(westColor);
        for (int i = 0; i < iRight; i++) {
            g.drawLine(x + width - i - 1, y, x + width - i - 1, y + height - 1);
        }
        g.setColor(oldColor);
    }
}
  • 更新 1

我更改了代码以将表格单元格的 intercellspacing 减少为 0

    table.setIntercellSpacing(new Dimension(0,0));

以及还将行边距更改为 0

    table.setRowMargin(0);

但是当行更多时,它会在某些地方的行之间显示空白行,如下所示:-

行间距图像

为此,我使用以下代码将数据增加到 9 行:-

 Object[][] data = {
        {"Hari", new Integer(23), new Double(78.23), (true)},
        {"James", new Integer(23), new Double(47.64), (false)},
        {"Sally", new Integer(22), new Double(84.81), (true)},
        {"Sally", new Integer(22), new Double(84.81), (true)},
        {"Sally", new Integer(22), new Double(84.81), (true)},
        {"Hari", new Integer(23), new Double(78.23), (true)},
        {"James", new Integer(23), new Double(47.64), (false)},
        {"Hari", new Integer(23), new Double(78.23), (true)},
        {"James", new Integer(23), new Double(47.64), (false)}
    };

请就此提出一些建议。

**

  • 更新 2

**

我观察到如果我们在 75% zoomin 中看到 pdf,JTable 看起来很准确。但是当这个 JTable 以 100% 显示时,单元格外的边框和颜色会有所不同。我们是否有任何东西可以让我们将 JTable 打印(即 table.print(g))从 75% 缩放到 25%,然后再将其打印为 pdf,即 100%。如果有任何 JTable 缩放的想法会很有帮助!谢谢!

4

1 回答 1

2

我建议使用

table.setGridColor(Color.black);

否则,如果您想使用自定义渲染器

table.setIntercellSpacing(new Dimension(0,0));

(并确保您的渲染器正确设置边框)。

编辑

就个人而言,您的更新闻起来像一个新问题(很高兴看到您的新更新代码 - 但它可能不利于原始问题/答案)。

我怀疑您的问题可能出在某个地方(这似乎有点可疑):

Border cellBorder = pTable.getBorder();
...
cellBorder = BorderFactory.createCompoundBorder(cellBorder, 
            new ZoneBorder(iTop, iLeft, iBottom, iRight, Color.BLACK));
((JLabel) renderedComponent).setBorder(cellBorder);

你能解释一下为什么要抓住表格的边框,将它与另一个边框复合,然后将结果添加到每个单元格中吗?

侧边栏:如果您需要更多帮助,请在评论中标记此人的答案,使他们更有可能提供帮助,而不是不接受他们的答案...

于 2012-10-16T18:50:15.100 回答