在基于jtextpane的jtable单元格渲染器中裁剪文本行

时间:2010-01-26 14:07:18

标签: java swing jtable renderer

我在表格中使用JTextPane作为单元格渲染器(因此我可以轻松控制颜色,字体,大小和链接)。 问题是,当单元格太小而无法包含全文时,行会被包裹。

我事先知道预期文本行的数量(或者我可以计算),所以我相应地设置了行的高度。

如何在细胞末端(视觉上,即在字母中间)进行裁剪?

谢谢,asaf :-)

更多信息:我尝试过在网上找到的两种解决方案。涉及setting my own EditroKit的一个 。另一个列在下面,并涉及覆盖setSize() 唉,没有人工作......

这是我的渲染器(为弄乱的缩进道歉......):

package textTable;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Insets;

import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextPane;
import javax.swing.table.TableCellRenderer;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

public class LogRenderer extends JPanel implements TableCellRenderer {
    static class NoWrapTextPane extends JTextPane {
        public NoWrapTextPane () {
            super();
        }
        @Override
        public boolean getScrollableTracksViewportWidth() {
            return false;
        }
        @Override
        public void setSize(Dimension d) {
            if(d.width < getParent().getSize().width) {
                d.width = getParent().getSize().width;
            }
            super.setSize(d);
        }
    }

    private JTextPane textPane = new NoWrapTextPane();//JTextPane();
    private StyledDocument doc = textPane.getStyledDocument();
    private SimpleAttributeSet attr = new SimpleAttributeSet();
    private FontMetrics fontMetrics;

    public LogRenderer() {
    textPane.setMargin(new Insets(0,0,0,0));

        fontMetrics = textPane.getFontMetrics(getFont());

        StyleConstants.setFontFamily(attr, "monospaced");//"Courier"

    setLayout(new BorderLayout());
    add(textPane,BorderLayout.CENTER);
}

public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus, int row,
        int column) {
        String[] text;
        if (value != null && value instanceof String[]) {
            text = (String[]) value;
        } else {
            text = null;
        }
        try {
            doc.remove(0, doc.getLength());
            if (text != null) {
                int offset = 0;
                for (String line : text) {
                    doc.insertString(offset, line+"\n", attr);
                    offset += (line == null ? 0 : line.length()) +1;
                }
                int preferredHeight = fontMetrics.getHeight() *     text.length;
                if (preferredHeight != table.getRowHeight(row)) {
                    System.out.println("preferredHeight     "+preferredHeight+" = fontMetrics.getHeight() "+fontMetrics.getHeight()+" + text.length     "+text.length);
                    table.setRowHeight(row, preferredHeight);
                } 
            }
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
//      textPane.setToolTipText("hi");
        return this;
    }   
}

1 个答案:

答案 0 :(得分:3)

使用自定义renderer。扩展JLabel应该为您提供省略号符号以指示截断,但您可以使用JPanelthis approach来剪切结果。

附录:你引用的WrapEditorKit效果很好,似乎做你想做的事。在LogRenderer中,我认为您可以扩展JEditorPane并在构造函数中设置编辑器。例如:

private static class LogRenderer
    extends JEditorPane implements TableCellRenderer {

    public LogRenderer() {
        this.setEditorKit(new WrapEditorKit());
    }

    public Component getListCellRendererComponent(
        JList list, Object value, int index,
        boolean isSelected, boolean cellHasFocus) {
        this.setText((String) value);
        return this;
    }

    @Override
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected,
        boolean hasFocus, int row, int column) {
        this.setText((String) value);
        return this;
    }
}