Skip to content
Snippets Groups Projects
Commit efe596d7 authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

Replacing one method for each alignment option with parameterized method

Preparing for center alignment options, we don't want to have a method
overloading explosion. Right now, this is replacing four methods with
one. Later, it will prevent the need to write five more.
parent a23d0205
No related branches found
No related tags found
No related merge requests found
...@@ -23,6 +23,16 @@ package edu.unl.cse.bohn; ...@@ -23,6 +23,16 @@ package edu.unl.cse.bohn;
* <p>Note that StringBox is <i>not</i> robust to hidden characters, such as VT100 escape sequences.</p> * <p>Note that StringBox is <i>not</i> robust to hidden characters, such as VT100 escape sequences.</p>
*/ */
public class StringBox { public class StringBox {
/**
* Horizontal alignment directives
*/
public enum Horizontal {LEFT, RIGHT}
/**
* Vertical alignment directives
*/
public enum Vertical {TOP, BOTTOM}
private int maximumWidth; private int maximumWidth;
private int maximumHeight; private int maximumHeight;
private int logicalHeight; private int logicalHeight;
...@@ -89,32 +99,74 @@ public class StringBox { ...@@ -89,32 +99,74 @@ public class StringBox {
* @see #placeStringAlignTopLeft(String, int, int) * @see #placeStringAlignTopLeft(String, int, int)
*/ */
public StringBox placeString(String string, int topRow, int leftColumn) { public StringBox placeString(String string, int topRow, int leftColumn) {
return placeStringAlignTopLeft(string, topRow, leftColumn); return placeString(string, Vertical.TOP, topRow, Horizontal.LEFT, leftColumn);
} }
/** /**
* Places a string in the StringBox with its upper-left corner in the specified location. If the string * <p>Places a string in the StringBox. If <code>verticalAlignment</code> is <code>TOP</code> then the string's
* contains multiple lines, each line after the first will be placed in the row subsequent to the previous line, * first line will be in the <code>verticalPosition</code>'th row, and each subsequent line will be in each
* and the lines will be left-justified. Any portions of the string that would be placed outside the StringBox's * subsequent row. If <code>verticalAlignment</code> is <code>BOTTOM</code> then the string's last line will be in
* defined boundaries will be silently truncated. * 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
* <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>
* *
* @param string the string to be placed in the StringBox * @param string the string to be placed in the StringBox
* @param topRow the row on which the first line of the string should be placed * @param verticalAlignment vertical alignment directive (top/bottom)
* @param leftColumn the column in which the first character of each row should be placed * @param verticalPosition the row on which the string should be top/bottom aligned
* @param horizontalAlignment horizontal alignment directive (left/right)
* @param horizontalPosition the column on which the string should be top/bottom aligned
* @return the current StringBox object, suitable for chained calls * @return the current StringBox object, suitable for chained calls
*/ */
public StringBox placeStringAlignTopLeft(String string, int topRow, int leftColumn) { public StringBox placeString(String string, Vertical verticalAlignment, int verticalPosition,
String[] strings = string.split("\n"); Horizontal horizontalAlignment, int horizontalPosition) {
String[] strings = string.split(System.lineSeparator());
// This would benefit from the switch expression in JDK 12/13
int topRow = verticalAlignment == Vertical.TOP ? verticalPosition :
verticalAlignment == Vertical.BOTTOM ? verticalPosition - strings.length + 1 :
0;
int firstRow = Math.max(topRow, 0); int firstRow = Math.max(topRow, 0);
int lastRow = Math.min(topRow + strings.length, maximumHeight); int lastRow = Math.min(topRow + strings.length, maximumHeight);
int offset = -topRow; int offset = -topRow;
for (int i = firstRow; i < lastRow; i++) { for (int i = firstRow; i < lastRow; i++) {
rows[i].placeSubstringAlignLeft(strings[i + offset], leftColumn); switch (horizontalAlignment) {
case LEFT:
rows[i].placeSubstringAlignLeft(strings[i + offset], horizontalPosition);
break;
case RIGHT:
rows[i].placeSubstringAlignRight(strings[i + offset], horizontalPosition);
break;
default:
System.err.println("Unreachable code was reached in StringBox.placeString()!");
System.err.println("\thorizontalAlignment == " + horizontalAlignment);
Horizontal recoveryAlignment = Horizontal.LEFT;
System.err.println("\tAttempting to recover with horizontalAlignment = " + recoveryAlignment);
rows[i].placeSubstringAlignLeft(strings[i + offset], horizontalPosition);
}
} }
logicalHeight = Math.max(logicalHeight, lastRow); logicalHeight = Math.max(logicalHeight, lastRow);
return this; return this;
} }
/* ******************
* LEGACY METHODS *
********************/
/**
* Places a string in the StringBox with its upper-left corner in the specified location. If the string
* contains multiple lines, each line after the first will be placed in the row subsequent to the previous line,
* and the lines will be left-justified. Any portions of the string that would be placed outside the StringBox's
* defined boundaries will be silently truncated.
*
* @param string the string to be placed in the StringBox
* @param topRow the row on which the first line of the string should be placed
* @param leftColumn the column in which the first character of each row should be placed
* @return the current StringBox object, suitable for chained calls
*/
public StringBox placeStringAlignTopLeft(String string, int topRow, int leftColumn) {
return placeString(string, Vertical.TOP, topRow, Horizontal.LEFT, leftColumn);
}
/** /**
* Places a string in the StringBox with its lower-left corner in the specified location. If the string * Places a string in the StringBox with its lower-left corner in the specified location. If the string
* contains multiple lines, each line before the last will be placed in the row previous to the subsequent line, * contains multiple lines, each line before the last will be placed in the row previous to the subsequent line,
...@@ -127,8 +179,7 @@ public class StringBox { ...@@ -127,8 +179,7 @@ public class StringBox {
* @return the current StringBox object, suitable for chained calls * @return the current StringBox object, suitable for chained calls
*/ */
public StringBox placeStringAlignBottomLeft(String string, int bottomRow, int leftColumn) { public StringBox placeStringAlignBottomLeft(String string, int bottomRow, int leftColumn) {
String[] strings = string.split("\n"); return placeString(string, Vertical.BOTTOM, bottomRow, Horizontal.LEFT, leftColumn);
return placeStringAlignTopLeft(string, bottomRow - strings.length + 1, leftColumn);
} }
/** /**
...@@ -143,15 +194,7 @@ public class StringBox { ...@@ -143,15 +194,7 @@ public class StringBox {
* @return the current StringBox object, suitable for chained calls * @return the current StringBox object, suitable for chained calls
*/ */
public StringBox placeStringAlignTopRight(String string, int topRow, int rightColumn) { public StringBox placeStringAlignTopRight(String string, int topRow, int rightColumn) {
String[] strings = string.split("\n"); return placeString(string, Vertical.TOP, topRow, Horizontal.RIGHT, rightColumn);
int firstRow = Math.max(topRow, 0);
int lastRow = Math.min(topRow + strings.length, maximumHeight);
int offset = -topRow;
for (int i = firstRow; i < lastRow; i++) {
rows[i].placeSubstringAlignRight(strings[i + offset], rightColumn);
}
logicalHeight = Math.max(logicalHeight, lastRow);
return this;
} }
/** /**
...@@ -166,10 +209,13 @@ public class StringBox { ...@@ -166,10 +209,13 @@ public class StringBox {
* @return the current StringBox object, suitable for chained calls * @return the current StringBox object, suitable for chained calls
*/ */
public StringBox placeStringAlignBottomRight(String string, int bottomRow, int rightColumn) { public StringBox placeStringAlignBottomRight(String string, int bottomRow, int rightColumn) {
String[] strings = string.split("\n"); return placeString(string, Vertical.BOTTOM, bottomRow, Horizontal.RIGHT, rightColumn);
return placeStringAlignTopRight(string, bottomRow - strings.length + 1, rightColumn);
} }
/* *************************
* END OF LEGACY METHODS *
***************************/
/** /**
* <p>Generates the string that the client code produced by calling {@link #placeString(String, int, int)} and * <p>Generates the string that the client code produced by calling {@link #placeString(String, int, int)} and
* its related methods. Any unused lines between the last line of text and the bottom of the StringBox will be * its related methods. Any unused lines between the last line of text and the bottom of the StringBox will be
...@@ -201,11 +247,11 @@ public class StringBox { ...@@ -201,11 +247,11 @@ public class StringBox {
returnString.append(rows[0].toString()); returnString.append(rows[0].toString());
} }
for (int i = 1; i < logicalHeight; i++) { for (int i = 1; i < logicalHeight; i++) {
returnString.append("\n").append(rows[i].toString()); returnString.append(System.lineSeparator()).append(rows[i].toString());
} }
if (padToHeight) { if (padToHeight) {
for (int i = logicalHeight; i < maximumHeight; i++) { for (int i = logicalHeight; i < maximumHeight; i++) {
returnString.append("\n").append(rows[i].toString()); returnString.append(System.lineSeparator()).append(rows[i].toString());
} }
} }
return returnString.toString(); return returnString.toString();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment