简体   繁体   English

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

[英]Print centered String inside hollow rectangle Java

I am working on a java program in which I am trying to utilize a header made of asterisks. 我正在尝试使用星号制成的标头的Java程序。

I would like to output a message in the center of the header but am not completely sure how to go about doing this. 我想在标题的中心输出一条消息,但不确定如何执行此操作。

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();
    }   
}

So this header will print an asterisk, hollow rectangle 60 wide and 3 tall. 因此,此标头将打印一个星号,空心矩形,宽60高3高。 I would like to format this as a custom method so I can reference this easily throughout the program. 我想将其格式化为自定义方法,以便在整个程序中轻松引用它。 As you can see I have formatted the frame, so the issue is getting the string in there and centering it inside the frame. 如您所见,我已经格式化了框架,因此问题在于将字符串放入其中并将其居中放置在框架中。 I sort of have an idea that I need to use msg.length() and possibly a printf() to do this but I'm not sure how to go about this. 我有点想法,我需要使用msg.length()和可能的printf()来执行此操作,但是我不确定如何执行此操作。

Something like this should work: 这样的事情应该起作用:

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);
}

Testing: 测试:

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);

Output: 输出:

********************************************************************************************
*                 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*
********************************************************************************************

Instead of printing the box first, you might want to print the top, the text and the bottom. 您可能要打印顶部,文本和底部,而不是先打印该框。 To print the text (the center rows) you can use this 要打印文本(中间行),您可以使用此

    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, "*");

Using what you've provided, you can construct your header by considering the amount of padding you will need in order to center your text. 使用您提供的内容,可以通过考虑将文本居中所需的填充量来构造标题。 When you've reached this amount you will be at approximately the center of the header, then you can start printing characters from your message 达到此数量后,您将位于标题的中心附近,然后可以开始从消息中打印字符


This solution will only print on the middle row, based on your comment: 根据您的评论,此解决方案将仅打印在中间行:

"No, the only thing I "know" is which line the text will be on (row 2)" “不,我唯一知道的是文本将位于哪一行(第2行)”

But hopefully the below changes can help you arrive at a final solution 但是希望下面的更改可以帮助您找到最终的解决方案

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();
        }
    }


Example output: 输出示例:

 ************************************************************ * Test Message * ************************************************************ ********************************************************************************************************************************** * This message has more than sixty characters causing the header to grow * ********************************************************************************************************************************** 

Note that the second example is greater than your initial 60, but the width of the header will grow to ensure spaces will be included 请注意,第二个示例大于您的初始60个示例,但是标头的宽度将增加以确保包含空格

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM