当前位置: 首页 > 知识库问答 >
问题:

JTable 1点边框不出现在网格线上

谭晓博
2023-03-14

我正在使用

iText版本5.3.3。Java jdk 1.6.0

我正在开发一个报表软件,用户可以定制带有1点黑色边框的JTable单元格,显示在JTable上,如下所示:-

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
    table.setIntercellSpacing(new Dimension(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)}
    };

请对此提出一些建议。

    null

**

我观察到,如果我们看到的pdf在75%zoomin JTable看起来是准确的。但是当这个JTable以100%的速度显示时,它显示的边框和单元格外的颜色不同。在打印成pdf(即100%)之前,我们是否有任何可以将JTable打印(即table.print(g)从75%缩放到25%。如果有任何JTable缩放的想法,这将是很大的帮助!谢谢!

共有1个答案

逑翰翮
2023-03-14

我建议使用

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);

侧栏:如果你想要更多的帮助,在评论中给这个人的答案加上标签会比不接受他们的答案更有可能提供帮助...

 类似资料:
  • 问题内容: 给定当前的CSS网格示例,如何折叠边框以避免出现双边框? 这是使用Html表实现的如此简单的事情。如何使用? 问题答案: 您可能会这样: 另一个想法是依靠渐变来填补空白,如下所示: 您还可以调整初始解决方案以使其更加灵活,并且可以在一行中处理任意数量的项目。 在整个页面上运行以下代码并调整窗口大小:

  • 问题内容: 范例GUI大家好,我有 问题。如果有人可以帮助,那就太好了。我正在使用border和 gridlayout,并且试图拆分GUI,但是这没有发生,因为我希望 按钮占整体的一小部分,可以说是1/5,但目前 超过了GUI的一半。我也尝试将按钮放在尺寸上, 但是我不确定这是否是一个好习惯。我有两个类,一个是 RunFurniture,它是框架的主要方法,另一个是 GUI的PanelFurnit

  • 问题内容: 即使单元格为空,我应该使用哪种CSS来显示单元格的边框? 专门针对IE 7。 问题答案: 如果我还记得的话,除非在某些IE中存在该单元格,否则它不存在… 如果您可以放置​​一个(不间断的空格)来填补空白,那通常会起作用。还是您需要纯CSS解决方案? 显然,IE8默认显示单元格,您必须使用隐藏它,但是它在IE7中根本不起作用(默认情况下是隐藏的)。

  • 我有一个超过40年的过去Storm的大数据集(约20000),其中有一个3小时间隔的中心点列表。我试图覆盖一个网格网格到一个大的区域,我想从其中计数的次数每次Storm已经通过任何给定的网格单元,但是我目前的实现只跟踪在这三个小时的时间间隔的位置,导致一些情况当轨道也应该被计算时,它会跳过网格空间。 我尝试使用geopandas来解决这个问题,为每个Storm轨迹创建一个线系列,然后对网格网格执行

  • border(int $borderStyle): \Vtiful\Kernel\Format 示例 $config = [ 'path' => './tests' ]; ​ $fileObject = new \Vtiful\Kernel\Excel($config); ​ $fileObject = $fileObject->fileName('tutorial.xlsx'); $f

  • 在CSS1中,就支持为元素添加边框,并可以设置边框的样式、颜色、及粗细。不过,当时的边框太过单一,只支持简单的线条边框。 在CSS3中,为了实现丰富的边框效果,对边框属性进行了扩展,除了线条边框外,也可以把图像作为边框,同时还可以创建圆角边框,也可以使用盒阴影来为元素添加一个或多个边框阴影。 线条边框使用 border属性定义,图像边框使用 border-image 属性来定义,圆角边框使用 bo