Question

i'm using a JTextPane as a cell renderer in my table (so i can control color, font, size and links easily). the problem is that lines get wrapped when the cell's get too small to contain the full text.

i know the number of expected text lines in advance (or i can just count), so i set the row's height accordingly.

how do i get the lines to crop (visually! i.e. in the middle of a letter) at the cell end?

thanks, asaf :-)

more info: i've tried two solutions i found on the net. one that involves setting my own EditroKit . the other is listed below, and involves overriding of setSize().
alas, none worked...

here is my renderer (apologies for messed up indentation...):

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;
    }   
}
Was it helpful?

Solution

Use a custom renderer. Extending JLabel should give you ellipsis symbols to indicate truncation, but you can use JPanel and this approach to let clipping chop the result.

Addendum: The WrapEditorKit that you cited works well and seems to do what you want. In your LogRenderer, I think you can extend JEditorPane and set the editor in the constructor. For example:

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;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top