JTextPane 中的垂直和水平对齐

Vertical and Horizontal Allignment in JTextPane

我正在尝试在 JTable 中插入一个值。但是我遇到了一些问题(设计)。当我尝试正常添加一个值时 word/Line 换行不起作用,所以我尝试插入嵌入了 HTML 标签

的值
<html>Value</html>

但问题是顶部出现了一些额外的 space(第一行刚好在中间)。因此,我尝试使用渲染器将 JTextpane 添加到 JTable,但它只会使水平居中而不是垂直居中(Word/Line 包装工作正常)。

总之我的需求是

  1. 我需要在 JTable 中输入一个值。
  2. 如果超出列宽,我需要Word/Line换行。
  3. 我需要将值准确显示在单元格中间(水平和垂直居中)

    class TableCellLongTextRenderer extends JTextPane implements TableCellRenderer {    
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        this.setText((String) value);
        StyledDocument doc = this.getStyledDocument();
        SimpleAttributeSet center = new SimpleAttributeSet();
        StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
        StyleConstants.setSpaceAbove(center, StyleConstants.getSpaceBelow(center) / 2);
        StyleConstants.setSpaceBelow(center, StyleConstants.getSpaceAbove(center));
        doc.setParagraphAttributes(0, doc.getLength(), center, false);
        return this;
    }}
    

    我的代码有什么问题,有人可以帮我改正吗?提前致谢。

您可以只使用普通的 HTML 和默认的 TableCellRenderer,这是基于 JLabel 来实现这个基本原则的。

以下示例使用 html table,进一步将文本(断行)与标签的中心对齐。它使用 JLabelhorizontalAlignmentverticalAlignment 属性使内容在标签内对齐。

它还对行高做了一点小把戏 ;)

import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                String text
                                = "<html><div align=center>"
                                + "And Caesar's spirit, raging for revenge,<br>"
                                + "With Ate by his side come hot from hell,<br>"
                                + "Shall in these confines with a monarch's voice<br>"
                                + "Cry \"Havoc!\" and let slip the dogs of war,<br>"
                                + "That this foul deed shall smell above the earth<br>"
                                + "With carrion men, groaning for burial.";

                DefaultTableModel model = new DefaultTableModel(0, 1);
                model.addRow(new String[]{text});

                JTable table = new JTable(model) {
                    @Override
                    public int getRowHeight(int row) {
                        Component comp = prepareRenderer(getCellRenderer(row, 0), row, 0);
                        return comp.getPreferredSize().height;
                    }
                };
                ((JLabel)table.getDefaultRenderer(Object.class)).setHorizontalAlignment(JLabel.CENTER);
                ((JLabel)table.getDefaultRenderer(Object.class)).setVerticalAlignment(JLabel.CENTER);
                table.setRowHeight(100);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}

现在,我预先包装了文字并将其应用到模型中。您可以创建自定义 TableCellRenderer(使用 DefaultTableCellRenderer)和 post-wrap 文本,具体取决于您的需要