1

私は使っている

iText バージョン 5.3.3。Java JDK 1.6.0

私は、ユーザーが以下のように JTable に表示される 1 ポイントの黒い境界線で JTable セルをカスタマイズしたいレポート ソフトウェアに取り組んでいます:-

JTable 出力

PDF出力:

PDF出力

両方の出力で、1 ポイント境界セルのセル間にギャップがあります。線がグリッド線上にないことがわかりました。これらの境界線がグリッド上に 1 つのポイント ラインとして表示される可能性はありますか。以下は、JTable と pdf を使用して上記の問題をテストするためのサンプル コードです。

TableImage.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

テーブルセルのセル間隔を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

**

pdf を 75% zoomin で表示すると、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 に答える