6

Is there a method in Java to automatically ellipsize a string? Just in Java, not other libraries.

Thanks.

Milo Casagrande
  • 135
  • 1
  • 3
  • 11
  • 2
    Nvm... Btw how can I remove comments?... – Alderath Jul 20 '10 at 09:47
  • 3
    `Just in Java, not other libraries.` Sorry, I should start to read the questions :( Although it is good practice to reuse existing libraries like `StringUtils`. It's what they are here for... And it might save you some work. http://commons.apache.org/lang/api/org/apache/commons/lang/StringUtils.html – moxn Jul 20 '10 at 10:14
  • 1
    @moxn thanks for the link, I didn't know about that. Unfortunately I have to be careful with importing new external JARs, also for license problems (project I work on is closed source). This one seems to be Apache 2.0 so it shouldn't be a problem., right? – Milo Casagrande Jul 20 '10 at 12:34
  • `StringUtils` link above no longer active. Active link as of today: http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/StringUtils.html – aliteralmind Jun 16 '14 at 14:07

5 Answers5

9

Depending on your use case, it might be useful to put the ellipsis between letters (i.e. add letters at the end to provide some context):

/**
 * Puts ellipses in input strings that are longer than than maxCharacters. Shorter strings or
 * null is returned unchanged.
 * @param input the input string that may be subjected to shortening
 * @param maxCharacters the maximum characters that are acceptable for the unshortended string. Must be at least 3, otherwise a string with ellipses is too long already.
 * @param charactersAfterEllipsis the number of characters that should appear after the ellipsis (0 or larger) 
 * @return the truncated string with trailing ellipses
 */
public static String ellipsize(String input, int maxCharacters, int charactersAfterEllipsis) {
  if(maxCharacters < 3) {
    throw new IllegalArgumentException("maxCharacters must be at least 3 because the ellipsis already take up 3 characters");
  }
  if(maxCharacters - 3 > charactersAfterEllipsis) {
    throw new IllegalArgumentException("charactersAfterEllipsis must be less than maxCharacters");
  }
  if (input == null || input.length() < maxCharacters) {
    return input;
  }
  return input.substring(0, maxCharacters - 3 - charactersAfterEllipsis) + "..." + input.substring(input.length() - charactersAfterEllipsis);
}

There are also more sophisticated features you might want from you ellipsis algorithm: If you need to place the text into a graphical element and you are using a proportional font, then you must measure the length of the String.

For Swing/AWT that would be java.awt.Font.getStringBounds. In such a case, a simple algrithm would cut the string one letter at a time and add the ellipsis, until the string fits into the limit given. If used often, the bisection method elaborated in http://www.codeproject.com/KB/cs/AutoEllipsis.aspx?msg=3278640 (C#, but should be easy enough to translate to Java) may save some processor cycles.

appersiano
  • 2,670
  • 22
  • 42
nd.
  • 8,699
  • 2
  • 32
  • 42
  • I have implemented something along the lines of what you suggested. Thanks! I think I'll try to provide a general String-ellipsising class, for now I needed a quick hack inside a class, but it's worth trying to invest some time and develop a good API. – Milo Casagrande Jul 20 '10 at 12:37
  • 1
    I think you should use the ellipsis char, …, not three dots, that may be divided in the end of a line (appart from being only 1 length instead of 3) – Aitor Gómez Oct 17 '12 at 11:51
  • @Wakka you are right, if the ellipsis is available on the output, then it may be a good choice (e.g. when using Swing). For certain applications three dots should be acceptable as well: If the target does not support the ellipsis character (e.g. if the output uses ISO-8859-1) or for fixed-width fonts where ellipsis only takes one width instead of 3. – nd. Oct 17 '12 at 14:06
  • @nd.yeah, that's true. f*** encoding ;-) – Aitor Gómez Oct 17 '12 at 15:10
  • if(maxCharacters - 3 > charactersAfterEllipsis) { throw new IllegalArgumentException("charactersAfterEllipsis must be less than maxCharacters"); } you should invert with (!(...)) – Andrew Glukhoff Apr 22 '20 at 13:04
8

This method will return the ellipsized String:

String ellipsize(String input, int maxLength) {
    String ellip = "...";
    if (input == null || input.length() <= maxLength 
           || input.length() < ellip.length()) {
        return input;
    }
    return input.substring(0, maxLength - ellip.length()).concat(ellip);
}
cuh
  • 3,723
  • 4
  • 30
  • 47
4

There is not. But here's another crack at a simple method to do this.

String ellipsize(String input, int maxLength) {
  if (input == null || input.length() < maxLength) {
    return input;
  }
  return input.substring(0, maxLength) + "...";
}
Sean Owen
  • 66,182
  • 23
  • 141
  • 173
4

A oneliner which of course does not outperform the other offered solutions:

longString.replaceFirst("(.{5}).+(.{5})", "$1...$2")

Will leave only first and last 5 characters and put ... in the middle.

anydoby
  • 408
  • 4
  • 9
2

Sure, try this one:

public static String ellipsise (String input, int maxLen) {
    if (input == null)
        return null;
    if ((input.length() < maxLen) || (maxLen < 3))
        return input;
    return input.substring (0, maxLen - 3) + "...";
}

This has the advantage of fixing the bug where the King's English is not used properly :-)

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • The King's English - sorry?! – Buffalo Jun 21 '16 at 11:32
  • 1
    @Buffalo, you're stretching my memory a bit, this answer was posted six years ago. However, I suspect I meant that the King's English (rather than the quaint US variant) uses `ise` (not `ize`) at the ends of words like `ellipsise`. That'd be my best guess given the playful smiley and the fact I've spelt it differently. – paxdiablo Jun 21 '16 at 12:10