Question

I created a custom ListCellRenderer that extends Jidesoft's StyledLabel. The JList my renderer is used in is a fixed width, so in my renderer I attempt to shorten text based on this width. I call setText in getListCellRendererComponent, which sometimes works. When I select a cell, the text acts as if I had never shortened it at all. There is no branching related to the setText and text-shortening.

I attempted to use the solutions in this somewhat-related answer discussing custom rendering and cell heights, but it didn't work consistently on select either.

edit: some code

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

Solution

In your implementation of ListCellRenderer you're relying on the getGraphics() of the label. Sometimes, getGraphics() is null which is OK, but you're not entering the if(this.getGraphics() != null) condition and simply returning the unmodified string. That is why you get inconsistent results. Commenting out this condition solved the problem in the posted code. You should not rely on getGraphics() its value is out of your control.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top