From 2bb4bff13764071f9775fd21151d19d9bcc339f4 Mon Sep 17 00:00:00 2001 From: Christopher Bohn <bohn@unl.edu> Date: Thu, 14 May 2020 18:28:46 -0500 Subject: [PATCH] Added vertical & horizontal center alignment --- README.md | 23 +++++-- src/main/java/edu/unl/cse/bohn/StringBox.java | 30 ++++++--- .../java/edu/unl/cse/bohn/StringBoxTest.java | 65 +++++++++++++++++-- 3 files changed, 98 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index f5df01b..7773298 100644 --- a/README.md +++ b/README.md @@ -206,9 +206,9 @@ stringBox.placeString("foo\nbar baz",-1,-1); If two inserted strings overlap, the string inserted last will overwrite a portion of the string written first: ``` stringBox.placeString("foo\nbar", Vertical.TOP, 2, Horizontal.LEFT, 10) - .placeString("larry\ncurly\nmoe", Vertical.BOTTOM, 5, Horizontal.LEFT, 6) + .placeString("larry\ncurly\nmoe", Vertical.BOTTOM, 6, Horizontal.LEFT, 6) .placeString("quux\nxyzzy", Vertical.TOP, 3, Horizontal.RIGHT, 20) - .placeString("one\ntwo\nthree", Vertical.BOTTOM, 10, Horizontal.RIGHT, 15); + .placeString("one\ntwo\nthree", Vertical.BOTTOM, 11, Horizontal.RIGHT, 15); ``` @@ -302,11 +302,20 @@ Equivalent to `placeString(string, Vertical.TOP, topRow, Horizontal.LEFT, leftCo #### `public StringBox placeString(String string, Vertical verticalAlignment, int verticalPosition, Horizontal horizontalAlignment, int horizontalPosition)` -Places a string in the StringBox. If `verticalAlignment` is `TOP` then the string's first line will be in the -`verticalPosition`'th row, and each subsequent line will be in each subsequent row. If `verticalAlignment` is `BOTTOM` -then the string's last line will be in the `verticalPosition`'th row, and each preceding line will be in each preceding -row. If `horizontalAlignment` is `LEFT` then each line will be left-justified to the `horizontalPosition`'th column. If -`horizontalAlignment` is `RIGHT` then each line will be right-justified to the `horizontalPosition`'th column. +Places a string in the StringBox. + +If `verticalAlignment` is `TOP` then the string's first line will be in the `verticalPosition`'th row, and each +subsequent line will be in each subsequent row. If `verticalAlignment` is `BOTTOM` then the string's last line will be +in the row immediately preceding the `verticalPosition`'th row, and each preceding line will be in each preceding row. + +If `horizontalAlignment` is `LEFT` then each line will be left-justified to the `horizontalPosition`'th column. If +`horizontalAlignment` is `RIGHT` then each line will be right-justified to the `horizontalPosition`'th column; that is, +the rightmost character will be immediately to the left of the `horizontalPosition`'th column. + +In cases of `CENTER` alignment: if there are an odd number of lines then the center line will be on the +`verticalPosition`'th row. Similarly, if there are an odd number of characters in a line then the center character will +be in the `horizontalPosition`'th column. If there are an even number of rows (or characters) then the row (character) +immediately below (to the right of) the midpoint will be in the designated row (column). * **Parameters:** * `string` — the string to be placed in the StringBox diff --git a/src/main/java/edu/unl/cse/bohn/StringBox.java b/src/main/java/edu/unl/cse/bohn/StringBox.java index bf6696f..9a01717 100644 --- a/src/main/java/edu/unl/cse/bohn/StringBox.java +++ b/src/main/java/edu/unl/cse/bohn/StringBox.java @@ -29,12 +29,12 @@ public class StringBox { /** * Horizontal alignment directives */ - public enum Horizontal {LEFT, RIGHT} + public enum Horizontal {LEFT, CENTER, RIGHT} /** * Vertical alignment directives */ - public enum Vertical {TOP, BOTTOM} + public enum Vertical {TOP, CENTER, BOTTOM} private int maximumWidth; private int maximumHeight; @@ -106,13 +106,23 @@ public class StringBox { } /** - * <p>Places a string in the StringBox. If <code>verticalAlignment</code> is <code>TOP</code> then the string's - * first line will be in the <code>verticalPosition</code>'th row, and each subsequent line will be in each - * subsequent row. If <code>verticalAlignment</code> is <code>BOTTOM</code> then the string's last line will be in - * the <code>verticalPosition</code>'th row, and each preceding line will be in each preceding row. If - * <code>horizontalAlignment</code> is <code>LEFT</code> then each line will be left-justified to the + * <p>Places a string in the StringBox.</p> + * + * <p>If <code>verticalAlignment</code> is <code>TOP</code> then the string's first line will be in the + * <code>verticalPosition</code>'th row, and each subsequent line will be in each subsequent row. If + * <code>verticalAlignment</code> is <code>BOTTOM</code> then the string's last line will be in the row immediately + * preceding the <code>verticalPosition</code>'th row, and each preceding line will be in each preceding row.</p> + * + * <p>If <code>horizontalAlignment</code> is <code>LEFT</code> then each line will be left-justified to the * <code>horizontalPosition</code>'th column. If <code>horizontalAlignment</code> is <code>RIGHT</code> then each - * line will be right-justified to the <code>horizontalPosition</code>'th column.</p> + * line will be right-justified to the <code>horizontalPosition</code>'th column; that is, the rightmost character + * will be immediately to the left of the <code>horizontalPosition</code>'th column.</p> + * + * <p>In cases of <code>CENTER</code> alignment: if there are an odd number of lines then the center line will be on + * the <code>verticalPosition</code>'th row. Similarly, if there are an odd number of characters in a line then the + * center character will be in the <code>horizontalPosition</code>'th column. If there are an even number of rows + * (or characters) then the row (character) immediately below (to the right of) the midpoint will be in the + * designated row (column).</p> * * @param string the string to be placed in the StringBox * @param verticalAlignment vertical alignment directive (top/bottom) @@ -127,7 +137,8 @@ public class StringBox { String[] strings = string != null ? string.split(System.lineSeparator()) : nullishString; // This would benefit from the switch expression in JDK 12/13 int topRow = verticalAlignment == Vertical.TOP ? verticalPosition : - verticalAlignment == Vertical.BOTTOM ? verticalPosition - strings.length + 1 : + verticalAlignment == Vertical.BOTTOM ? verticalPosition - strings.length : + verticalAlignment == Vertical.CENTER ? verticalPosition - strings.length / 2 : 0; int firstRow = Math.max(topRow, 0); int lastRow = Math.min(topRow + strings.length, maximumHeight); @@ -280,6 +291,7 @@ public class StringBox { .replace("\n", "\\"); int leftColumn = horizontalAlignment == Horizontal.LEFT ? horizontalPosition : horizontalAlignment == Horizontal.RIGHT ? horizontalPosition - modifiedString.length() : + horizontalAlignment == Horizontal.CENTER ? horizontalPosition - modifiedString.length() / 2 : 0; if (leftColumn > rightEdge) { int paddingSize = leftColumn - rightEdge; diff --git a/src/test/java/edu/unl/cse/bohn/StringBoxTest.java b/src/test/java/edu/unl/cse/bohn/StringBoxTest.java index 8a3f3b7..a24618f 100644 --- a/src/test/java/edu/unl/cse/bohn/StringBoxTest.java +++ b/src/test/java/edu/unl/cse/bohn/StringBoxTest.java @@ -23,8 +23,10 @@ public class StringBoxTest { stringRow = new StringBox.StringRow(10); } + @SuppressWarnings("EmptyMethod") @After public void tearDown() { + // intentionally empty } /* Tests for one row */ @@ -142,7 +144,8 @@ public class StringBoxTest { int position1 = 3; String input2 = "bar"; int position2 = 5; - @SuppressWarnings("SpellCheckingInspection") String expectedOutput = " fooar"; + //noinspection SpellCheckingInspection + String expectedOutput = " fooar"; // Act String actualOutput = stringRow.placeSubstringAlignLeft(input2, position2).placeSubstringAlignLeft(input1, position1).toString(); @@ -157,7 +160,8 @@ public class StringBoxTest { int position1 = 7; String input2 = "bar"; int position2 = 5; - @SuppressWarnings("SpellCheckingInspection") String expectedOutput = " bafoo"; + //noinspection SpellCheckingInspection + String expectedOutput = " bafoo"; // Act String actualOutput = stringRow.placeSubstringAlignLeft(input2, position2).placeSubstringAlignLeft(input1, position1).toString(); @@ -189,6 +193,30 @@ public class StringBoxTest { assertEquals(expectedOutput, actualOutput); } + @Test + public void testCenterOddNumberOfCharacters() { + // Arrange + String input = "foo"; + int position = 5; + String expectedOutput = " foo"; + // Act + String actualOutput = stringRow.placeSubstring(input, StringBox.Horizontal.CENTER, position).toString(); + // Assert + assertEquals(expectedOutput, actualOutput); + } + + @Test + public void testCenterEvenNumberOfCharacter() { + // Arrange + String input = "foobar"; + int position = 5; + String expectedOutput = " foobar"; + // Act + String actualOutput = stringRow.placeSubstring(input, StringBox.Horizontal.CENTER, position).toString(); + // Assert + assertEquals(expectedOutput, actualOutput); + } + /* Tests for multiple rows */ @Test @@ -207,13 +235,14 @@ public class StringBoxTest { @Test public void testNormalCases() { // Arrange - @SuppressWarnings("SpellCheckingInspection") String[] inputs = { + //noinspection SpellCheckingInspection + String[] inputs = { String.format("foo%nbar"), String.format("larry%ncurly%nmoe"), String.format("quux%nxyzzy"), String.format("one%ntwo%nthree") }; - int[] rows = {2, 5, 3, 10}; + int[] rows = {2, 6, 3, 11}; int[] columns = {10, 5, 20, 15}; //noinspection SpellCheckingInspection String expectedOutput = String.format( @@ -298,4 +327,32 @@ public class StringBoxTest { "Dimensions 0×3 are too small.", exception.getMessage()); } } + + @Test + public void testCenterOddNumberOfLines() { + // Arrange + String input = String.format("f%no%no"); + int row = 5; + int column = 0; + String expectedOutput = String.format("%n%n%n%nf%no%no"); + // Act + String actualOutput = stringBox.placeString(input, StringBox.Vertical.CENTER, row, + StringBox.Horizontal.CENTER, column).toString(false); + // Assert + assertEquals(expectedOutput, actualOutput); + } + + @Test + public void testCenterEvenNumberOfLines() { + // Arrange + String input = String.format("f%no%no%nb%na%nr"); + int row = 5; + int column = 0; + String expectedOutput = String.format("%n%nf%no%no%nb%na%nr"); + // Act + String actualOutput = stringBox.placeString(input, StringBox.Vertical.CENTER, row, + StringBox.Horizontal.CENTER, column).toString(false); + // Assert + assertEquals(expectedOutput, actualOutput); + } } \ No newline at end of file -- GitLab