cropping text lines in a jtextpane-based jtable cell renderer
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 开发者_如何学GotextPane = 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;
}
}
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;
}
}
精彩评论