25
public class Divers {
  public static void main(String args[]){

     String format = "|%1$-10s|%2$-10s|%3$-20s|\n";
     System.out.format(format, "FirstName", "Init.", "LastName");
     System.out.format(format, "Real", "", "Gagnon");
     System.out.format(format, "John", "D", "Doe");

     String ex[] = { "John", "F.", "Kennedy" };

     System.out.format(String.format(format, (Object[])ex));
  }
}

output:

|FirstName |Init.     |LastName            |
|Real      |          |Gagnon              |
|John      |D         |Doe                 |
|John      |F.        |Kennedy             |

I want the output to be centered. If I do not use '-' flag the output will be aligned to the right.

I did not find a flag to center text in the API.

This article has some information about format, but nothing on centre justify.

6

9 Answers 9

26

I quickly hacked this up. You can now use StringUtils.center(String s, int size) in String.format.

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;

import org.junit.Test;

public class TestCenter {
    @Test
    public void centersString() {
        assertThat(StringUtils.center(null, 0), equalTo(null));
        assertThat(StringUtils.center("foo", 3), is("foo"));
        assertThat(StringUtils.center("foo", -1), is("foo"));
        assertThat(StringUtils.center("moon", 10), is("   moon   "));
        assertThat(StringUtils.center("phone", 14, '*'), is("****phone*****"));
        assertThat(StringUtils.center("India", 6, '-'), is("India-"));
        assertThat(StringUtils.center("Eclipse IDE", 21, '*'), is("*****Eclipse IDE*****"));
    }

    @Test
    public void worksWithFormat() {
        String format = "|%1$-10s|%2$-10s|%3$-20s|\n";
        assertThat(String.format(format, StringUtils.center("FirstName", 10), StringUtils.center("Init.", 10), StringUtils.center("LastName", 20)),
                is("|FirstName |  Init.   |      LastName      |\n"));
    }
}

class StringUtils {

    public static String center(String s, int size) {
        return center(s, size, ' ');
    }

    public static String center(String s, int size, char pad) {
        if (s == null || size <= s.length())
            return s;

        StringBuilder sb = new StringBuilder(size);
        for (int i = 0; i < (size - s.length()) / 2; i++) {
            sb.append(pad);
        }
        sb.append(s);
        while (sb.length() < size) {
            sb.append(pad);
        }
        return sb.toString();
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

I will stick to StringUtils from apache commons lang since it is easy to integrate that using maven
The pad argument is String, but if it is longer than 1 character, the method will not work correctly. This test will fail assertEquals("01foo01", StringUtils.center("foo", 6, "0123"));. It should be char. I'll fix that.
18
public static String center(String text, int len){
    String out = String.format("%"+len+"s%s%"+len+"s", "",text,"");
    float mid = (out.length()/2);
    float start = mid - (len/2);
    float end = start + len; 
    return out.substring((int)start, (int)end);
}

public static void main(String[] args) throws Exception{
    // Test
    String s = "abcdefghijklmnopqrstuvwxyz";
    for (int i = 1; i < 200;i++){
        for (int j = 1; j < s.length();j++){
            //center(s.substring(0, j),i);
            System.out.println(center(s.substring(0, j),i));
        }
    }
}

1 Comment

Great answer! Might want to consider making your method names lowercase, the capitalization makes it seem like it is a class rather then a method.
16

Converted the code found at https://www.leveluplunch.com/java/examples/center-justify-string/ into a handy, small one-line function:

public static String centerString (int width, String s) {
    return String.format("%-" + width  + "s", String.format("%" + (s.length() + (width - s.length()) / 2) + "s", s));
}

Usage:

public static void main(String[] args){
    String out = centerString(10, "afgb");
    System.out.println(out); //Prints "   afgb   "
}

I think it's a very neat solution that's worth mentioning.

1 Comment

Great solution! Could you explain how it works in more detail?
10

Here's the answer using apache commons lang StringUtils.

Please note that you have to add the jar file to the build path. If you are using maven make sure to add commons lang in the dependencies.

import org.apache.commons.lang.StringUtils;
public class Divers {
  public static void main(String args[]){

    String format = "|%1$-10s|%2$-10s|%3$-20s|\n";
    System.out.format(format, "FirstName", "Init.", "LastName");
    System.out.format(format,StringUtils.center("Real",10),StringUtils.center("",10),StringUtils.center("Gagnon",20);

    System.out.format(String.format(format, (Object[])ex));
  }
}

2 Comments

This answer it's more suitable, because uses a well-known Library for this purpose
agreed @PauloOliveira
7
int spaceSize = n - s.length();
int prefixSize = spaceSize / 2;
int suffixSize = (spaceSize + 1) / 2

"one-liner" since Java 11

return n > s.length()
     ? " ".repeat(prefixSize) + s + " ".repeat(suffixSize)
     : s;

Inlining the above vars into one return we can get:

return n > s.length() ? " ".repeat((n - s.length()) / 2) + s + " ".repeat((n - s.length() + 1) / 2**)** : s;


since Java 8

Java 8 has no " ".repeat(10) method. So

  • just replace the " ".repeat(10) with Java 8 analog. See https://stackoverflow.com/a/57514604/601844, and

  • use the same (as Java 11 ☝️) alg:

      int spaceSize = n - s.length();
      int prefixSize = spaceSize / 2;
      int suffixSize = (spaceSize + 1) / 2
      return n > s.length()
           ? space(prefixSize) + s + space(suffixSize)
           : s;
    
    
    private String space(int spaceSize) {
      return generate(() -> " ").limit(spaceSize).collect(joining());
    }
    

Comments

3

I was playing around with Mertuarez's elegant answer above and decided to post my version.

public class CenterString {

    public static String center(String text, int len){
        if (len <= text.length())
            return text.substring(0, len);
        int before = (len - text.length())/2;
        if (before == 0)
            return String.format("%-" + len + "s", text);
        int rest = len - before;
        return String.format("%" + before + "s%-" + rest + "s", "", text);  
    }

    // Test
    public static void main(String[] args) {
        String s = "abcde";
        for (int i = 1; i < 10; i++){
            int max = Math.min(i,  s.length());
            for (int j = 1; j <= max; j++){
                System.out.println(center(s.substring(0, j), i) + "|");
            }
        }
    }
}

Output:

a|
a |
ab|
 a |
ab |
abc|
 a  |
 ab |
abc |
abcd|
  a  |
 ab  |
 abc |
abcd |
abcde|
  a   |
  ab  |
 abc  |
 abcd |
abcde |
   a   |
  ab   |
  abc  |
 abcd  |
 abcde |
   a    |
   ab   |
  abc   |
  abcd  |
 abcde  |
    a    |
   ab    |
   abc   |
  abcd   |
  abcde  | 

Practical differences from Mertuarez's code:

  1. Mine does the math up-front and makes the final centered string in one shot instead of making a too-long string and then taking a substring from it. I assume this is slightly more performant, but I did not test it.
  2. In the case of text that can't be perfectly centered, mine consistently puts it half a character to the left rather than putting it half a character to the right half of the time.
  3. In the case of text that's longer than the specified length, mine consistently returns a substring of the specified length that's rooted at the beginning of the original text.

Comments

2

This is another way to place a string in center.

public static void center(String s, int length, CharSequence ch) {
    /* It works as follows
     * String centerString = String.format("|%" + (length - s.length()) + "s", s);
     * centerString = String.format("%" + -length + "s|", centerString);
     * System.out.println(centerString);
     */

    String centerString = String.format("%-" + length + "s|", String.format("|%" + (length - s.length()) + "s", s));
    System.out.println(centerString);
}

Comments

1

Here's an example of how I've handled centering column headers in Java:

public class Test {
    public static void main(String[] args) {
        String[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September",
                "October", "November", "December" };

        // Find length of longest months value.
        int maxLengthMonth = 0;
        boolean firstValue = true;
        for (String month : months) {
            maxLengthMonth = (firstValue) ? month.length() : Math.max(maxLengthMonth, month.length());
            firstValue = false;
        }

        // Display months in column header row
        for (String month : months) {
            StringBuilder columnHeader = new StringBuilder(month);
            // Add space to front or back of columnHeader
            boolean addAtEnd = true;
            while (columnHeader.length() < maxLengthMonth) {
                if (addAtEnd) {
                    columnHeader.append(" ");
                    addAtEnd = false;
                } else {
                    columnHeader.insert(0, " ");
                    addAtEnd = true;
                }
            }
            // Display column header with two extra leading spaces for each
            // column
            String format = "  %" + Integer.toString(maxLengthMonth) + "s";
            System.out.printf(format, columnHeader);
        }
        System.out.println();

        // Display 10 rows of random numbers
        for (int i = 0; i < 10; i++) {
            for (String month : months) {
                double randomValue = Math.random() * 999999;
                String format = "  %" + Integer.toString(maxLengthMonth) + ".2f";
                System.out.printf(format, randomValue);
            }
            System.out.println();
        }
    }
}

Comments

1

Here's another example. Allows you to choose how you want to treat the center when there is a different number of padding characters added to the beginning and end of the string.

Uses Java 11 String::repeat.

public class Strings {

    public enum Lean {
        START,
        END
    }

    public static String center(String value, int targetLength, Lean lean) {
        return center(value, targetLength, lean, ' ');
    }

    private static String center(String value, int targetLength, Lean lean, char pad) {

        if (targetLength < 1) {
            throw new IllegalArgumentException("Cannot center something into less than one space.");
        }

        int sourceLength = value.length();

        if (sourceLength == targetLength) {
            return value;
        }

        int paddingToAdd = targetLength - sourceLength;
        int half = paddingToAdd / 2;
        String spad = Character.toString(pad);
        String padding = spad.repeat(half);
        String startExtra = "";
        String endExtra = "";

        if (paddingToAdd % 2 == 1) {
            if (lean == Lean.START) {
                endExtra = spad;
            } else {
                startExtra = spad;
            }
        }

        return padding + startExtra + value + endExtra + padding;
    }
}



public class StringsTest {

    @Test
    public void centerAbcIn9LeanStart() {
        doTest(
                "abc",
                9,
                Strings.Lean.START,
                "   abc   "
        );
    }

    @Test
    public void centerAbcIn9LeanEnd() {
        doTest(
                "abc",
                9,
                Strings.Lean.END,
                "   abc   "
        );
    }

    @Test
    public void centerAbcIn10LeanStart() {
        doTest(
                "abc",
                10,
                Strings.Lean.START,
                "   abc    "
        );
    }

    @Test
    public void centerAbcIn10LeanEnd() {
        doTest(
                "abc",
                10,
                Strings.Lean.END,
                "    abc   "
        );
    }

    @Test
    public void centerAbcdIn9LeanStart() {
        doTest(
                "abcd",
                9,
                Strings.Lean.START,
                "  abcd   "
        );
    }

    @Test
    public void centerAbcdIn9LeanEnd() {
        doTest(
                "abcd",
                9,
                Strings.Lean.END,
                "   abcd  "
        );
    }

    @Test
    public void centerAbcdIn10LeanStart() {
        doTest(
                "abcd",
                10,
                Strings.Lean.START,
                "   abcd   "
        );
    }

    @Test
    public void centerAbcdIn10LeanEnd() {
        doTest(
                "abcd",
                10,
                Strings.Lean.START,
                "   abcd   "
        );
    }

    @Test
    public void centerAIn1LeanStart() {
        doTest(
                "a",
                1,
                Strings.Lean.START,
                "a"
        );
    }

    @Test
    public void centerAIn1LeanEnd() {
        doTest(
                "a",
                1,
                Strings.Lean.END,
                "a"
        );
    }

    @Test
    public void centerAIn2LeanStart() {
        doTest(
                "a",
                2,
                Strings.Lean.START,
                "a "
        );
    }

    @Test
    public void centerAIn2LeanEnd() {
        doTest(
                "a",
                2,
                Strings.Lean.END,
                " a"
        );
    }

    @Test
    public void centerAIn3LeanStart() {
        doTest(
                "a",
                3,
                Strings.Lean.START,
                " a "
        );
    }

    @Test
    public void centerAIn3LeanEnd() {
        doTest(
                "a",
                3,
                Strings.Lean.END,
                " a "
        );
    }

    @Test
    public void centerAbIn3LeanStart() {
        doTest(
                "ab",
                3,
                Strings.Lean.START,
                "ab "
        );
    }

    @Test
    public void centerAbIn3LeanEnd() {
        doTest(
                "ab",
                3,
                Strings.Lean.END,
                " ab"
        );
    }

    public void doTest(String value, int targetLength, Strings.Lean lean, String expected) {

        assertThat(
                "Test setup error: targetLength != expected.length()",
                targetLength,
                equalTo(expected.length()));

        assertThat(
                "Test setup error: value != expected.trim()",
                value,
                equalTo(expected.trim()));

        String actual = Strings.center(value, targetLength, lean);
        assertThat(actual, equalTo(expected));
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.