Mini-Project 3: Text layout

Assigned
Wednesday, 7 February 2024
Summary
We practice with subtype polymorphism by further extending the text layout example from the text layout lab.
Collaboration
Students should work in pairs on this project. You may also consult other students in the class as you develop your solution. If you receive help from anyone, make sure to cite them in your responses.

In this mini-project, you will continue our text layout / text block example.

1. Implement Truncated.java, Centered.java, and RightJustified.java, as described in the subtype polymorphism lab.

  • You need not ensure that Truncated, Centered, or RightJustfied` have a sensible width parameter. If the user provides an inauspicious width parameter, do whatever you’d like.

2. Implement HorizontallyFlipped.java and VerticallyFlipped.java, which do what they say. (That is, rearrange the text blocks horizontally and vertically.)

  • For example, horizontally flipping "Hello" would give "olleH".

3. Design and implement at least one other new kind of text block.

4. There are (at least) three models of equality for TextBlock objects:

  • Two textblocks are equal if they contain the same lines.
  • Two textblocks are equal if they were built in the same way.
  • Two textblocks are equal if they occupy the same memory location.

Implement these as TBUtils.equal(TextBlock t1, TextBlock t2), TBUtils.eqv(TextBlock t1, TextBlock t2), and TBUtils.eq(TextBlock t1, TextBlock t2), respectively. If you find it useful to require and implement similar procedures in each of the kinds of TextBlocks (e.g., every TextBlock must include equal(TextBlock other) or eqv(TextBlock other)), you can add them to the interface.

5. Write appropriate tests for each of your procedures. Make sure to check edge cases.

Grading rubric

The rubric may evolve slightly during grading.

Redo or above

Submissions that fail to meet any of these requirements will get an I.

[ ] Includes the specified `.java` files, correctly named.  
[ ] Each class has an introductory Javadoc comment that indicates
    the author and purpose. 
[ ] Includes a `README.md` file that contains the appropriate information 
    (authors, purpose, acknowledgements if appropriate)
[ ] All files compile correctly.
[ ] Includes one more text block.
[ ] The `README.md` includes a link to the GitHub repo.
[ ] The GitHub repo has at least five commits.

Meets expectations or above

Submissions that fail to meet any of these requirements but meet all previous requirements will receive an R.

[ ] Appears to follow Google Java style guidelines for indentation and such.
[ ] Includes tests for each of the different kinds of textblocks as a
    top-level block.
[ ] `Truncated` works for widths at least 1 and less than or equal to 
    the width of the parameter block.
[ ] `Centered` works for widths greater than or equal to the width of 
    the parameter block.
[ ] `RightJustified` works for widths greater than or equal to the width
    of the parameter block.
[ ] `HorizontallyFlipped` works for nonempty blocks of two or more lines.
[ ] `VerticallyFlipped` works for nonempty blocks of two or more lines.
[ ] The GitHub repo has at least five meaningful commits.
[ ] Each commit has an appropriate commit message.

Exemplary / Exceeds expectations

Submissions that fail to meet any of these requirements but meet all previous requirements will receive an M.

[ ] All (or most) repeated code has been factored out into individual 
    methods.  
[ ] All or most variable names are appropriate.
[ ] Includes tests for each of the different kinds of text blocks as
    parameters to other text blocks (or themselves).
[ ] Tests include interesting edge cases, such as empty blocks.
[ ] `Truncated` works with a width of 0.
[ ] `Centered` works with a width greater than the width of the 
    parameter block.
[ ] `HorizontallyFlipped` works with empty blocks (`new TextLine("")`).
[ ] `VerticallyFlipped` works with empty blocks (`new TextLine("")`).

Q&A

What should a call to the Truncated constructor look like?
new Truncated(myblock, 5) truncates the block at 5 characters wide.
What happens when we truncate a BoxedBlock?
You probably lose the right side of the box.
What should a call to the Truncated constructor do if the width is greater than the width of the block?
Whatever you’d like.
Do you have hints for eqv?
Option one: It could check the types of the objects and make sure that they are the same and then recurse on any components.
Option two: You could require that all TextBlock objects provide an eqv(TextBlock other) method that does something similar.
You should be able to figure out which is better.
Do you have hints for eq?
I’d use ==.
What should we name the test file?
TextBlockTests.java
Should Centered and RightJustified truncate if necessary?
It’s up to you. If someone doesn’t give additional width, you can do whatever you think is appropriate.
What will my tests look like?
For example, if you create new BoxedBlock(new TextLine("Hello")), you know that the width should be 7, the height should be 3, lines 0 and 2 should be "+-----+" and line 1 should be "|Hello|".
To test equal, you can create a variety of equal boxed blocks in different ways. For example, new HorizontallyFlipped(new HorizontallyFlipped(new TextLine("Hello"))) should be equal to new TextLine("Hello") but not eq or eqv.
Can I just convert my text blocks to strings and compare those?
Sure. I’d recommend that you add a static toString(TextBlock block) method to TBUtils.