我创建了一个自定义ListCellRenderer,它扩展了Jidesoft的StyledLabel。我的渲染器使用的JList是固定宽度的,所以在我的渲染程序中,我试图根据这个宽度缩短文本。我在getListCellRendererComponent中调用setText,它有时会起作用。当我选择一个单元格时,文本就好像我从未缩短过它一样。没有与setText和文本缩短相关的分支。
我试图使用这个有点相关的答案中的解决方案来讨论自定义渲染和单元高度,但在选择时也不一致。
编辑:一些代码
public class CustomListCellRenderer extends StyledLabel implements ListCellRenderer {
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
setText(shortenName(value.toString(), 150));
return this;
}
private String shortenName(String name, int width) {
if(this.getGraphics() != null) {
final FontMetrics fontMetrics = this.getFontMetrics(this.getFont());
String end = name.substring(name.length()/2);
String beginning = name.substring( 0, name.length()/2);
int stringWidth = SwingUtilities.computeStringWidth(fontMetrics, name);
if(stringWidth < width)
return name;
do {
end = end.substring(1);
beginning = beginning.substring(0, beginning.length() - 1);
stringWidth = SwingUtilities.computeStringWidth(fontMetrics, beginning + "..." + end);
} while (stringWidth > width);
return beginning + "..." + end;
}
return name;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
JList list = new JList(new String[] {
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"});
list.setCellRenderer(new CustomListCellRenderer());
frame.getContentPane().add(list);
frame.setVisible(true);
}
}
在ListCellRenderer
的实现中,您依赖于标签的getGraphics()
。有时,getGraphics()
就是null
,这是可以的,但您没有输入if(this.getGraphics() != null)
条件,只是返回未修改的字符串。这就是为什么你会得到不一致的结果。注释掉这个条件解决了发布代码中的问题。您不应该依赖getGraphics()
,它的值超出了您的控制范围。