在空心矩形Java中打印居中的字符串

时间:2016-06-07 16:55:24

标签: java

我正在研究一个java程序,我正在尝试使用由星号组成的标题。

我想在标题的中心输出一条消息,但我不完全确定如何进行此操作。

static void header(String msg) {
    int h = 3;
    int w = 60;  

    for(int j = 1; j <= h; j++)
    {  
        for(int i = 1; i <= w; i++)
        {
            if(j == 1 || j == h || i == 1 || i == w)  
            {
                System.out.print("*");
            }
            else
            {
                System.out.print(" ");
            }
        }
        System.out.println();
    }   
}

所以这个标题会打印一个星号,空心矩形60宽3高。我想将其格式化为自定义方法,以便我可以在整个程序中轻松引用它。正如您所看到的,我已经格式化了框架,因此问题是将字符串放在那里并将其居中放在框架内。我有一个想法,我需要使用msg.length()和可能的printf()来做这个,但我不知道如何去做。

3 个答案:

答案 0 :(得分:0)

这样的事情应该有效:

private void printMessage(final String message) {

    String[] lines = message.split("\\r?\\n");

    int maxWidth = Arrays.stream(lines).mapToInt(String::length).max().getAsInt();

    System.out.println(repeatString("*", maxWidth + 2));

    for(final String line : lines) {
        int lengthDiff = maxWidth - line.length();
        System.out.print("*" + repeatString(" ", (lengthDiff / 2)) + line + repeatString(" ", (lengthDiff / 2)) + "*\n");
    }

    System.out.println(repeatString("*", maxWidth + 2));
}

private String repeatString(final String string, final int repetitions) {
    return new String(new char[repetitions]).replace("\0", string);
}

测试:

String message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n" +
                 "Suspendisse volutpat lobortis sem at gravida. Aenean aliquet erat justo,\n" +
                 "id ultricies mi ullamcorper eu. Mauris scelerisque accumsan metus vitae congue. Vestibulum\n";

printMessage(message);

输出:

********************************************************************************************
*                 Lorem ipsum dolor sit amet, consectetur adipiscing elit.                 *
*         Suspendisse volutpat lobortis sem at gravida. Aenean aliquet erat justo,         *
*id ultricies mi ullamcorper eu. Mauris scelerisque accumsan metus vitae congue. Vestibulum*
********************************************************************************************

答案 1 :(得分:0)

您可能需要先打印顶部,文本和底部,而不是先打印此框。要打印文本(中间行),您可以使用此

    if (msg.length() > (w-2)) {
        msg = msg.substring(1, w-2);
    }
    int space=(w-2-msg.length())/2;
    System.out.printf("%s%" + (space + msg.length()) + "s%" + (w - (space + msg.length())) + "s", "*", msg, "*");

答案 2 :(得分:0)

使用您提供的内容,您可以考虑为了使文本居中所需的填充量来构建标题。当您达到此金额后,您将大致位于标题的中心,然后您就可以开始在邮件中打印字符

此解决方案仅根据您的评论打印在中间行:

  

&#34;不,我唯一知道&#34;是文本将在哪一行(行   2)&#34;

但希望以下更改可以帮助您找到最终解决方案

or

<小时/> 示例输出:

public static void main(String[] args){
        header("Test Message");
        header("This message has more than sixty characters causing the header to grow");
    }

    static void header(String msg) {
        int headerHeight = 3;
        int headerWidth = msg.length() > 60 ? msg.length() + 60 : 60;
        int paddingRequired = (headerWidth - msg.length() - 2) / 2;
        paddingRequired++; //To account for the boundary asterisk

        for(int rowIndex = 1; rowIndex <= headerHeight; rowIndex++) {
            for(int columnIndex = 1; columnIndex <= headerWidth; columnIndex++) {
                //Is this one of the asterisks at the edges of the middle row
                boolean isBoundaryAsterisk = (columnIndex == 1 || columnIndex == headerWidth);
                if((rowIndex == headerHeight) || (rowIndex == 1) || isBoundaryAsterisk) {
                    System.out.print("*");
                }
                else if((columnIndex > paddingRequired) && ((columnIndex - paddingRequired - 1) < msg.length())) {
                    System.out.print(msg.charAt(columnIndex-paddingRequired - 1));
                }
                else {
                    System.out.print(" ");
                }
            }
            System.out.println();
        }
    }

请注意,第二个示例大于您的初始60,但标题的宽度将增加以确保包含空格