CSCI 151 Lab 9: Creating a Text Editor


Overview

In this lab, we will implement both an array and linked-list version of a data structure to create a text editor.

Description

We have explored a few different representations of lists. In this lab, we will explore two different list implementations in the context of creating a text editor.

To make an editor, we will need to store a sequence of text characters. We will also need the concept of a cursor, to help us locate where we want to be editing the sequence of text. This cursor will be between characters, and can be moved using the arrow keys. The cursor allows us to insert new characters at the cursor, and delete characters before the cursor with the backspace or delete key.

The text that you enter can then be saved to a file.

Step 1: Setup

  1. Download the skeleton for this project.
  2. Unpack the code into a new Eclipse Java project.
  3. Add in the JUnit library to your project settings if necessary.
  4. Run the Editor.java file and verify that the GUI is displayed (it won't do anything yet).

Step 2: DoubleTextNode

The basic building block of our Linked Text View will be a DoubleTextNode. The skeleton of this class is provided for you in the editor.model.implementations package. Much of the manipulation of references will be implemented locally here in the DoubleTextNode class, simplifying the later implementation of the TextView.

Besides the get methods for each field, included in the skeleton is an equals method to determine if two DoubleTextNode objects have the same internal data.

Also included is a method called isConsistent, which will verify that when this node refers to another node with either its next or prev references, that node also refers back to this node.

Step 2.1: Implementation

Here are the methods you need to complete. Node (haha) that there is not a setNext or setPrev method included in this implementation. They are not strictly necessary, since you are allowed to access and modify private fields in other objects *of the same class*. That is, any method of DoubleTextNode can access private fields in other DoubleTextNode objects.

setNext, setPrev

I suggest making setNext and setPrev methods, which make sure things end up consistent. That is, for example, calling setNext should also make sure to set the prev of the next node back to the current node. It is not necessary to make such setNext and setPrev methods, but it may make some of the other methods easier to implement.

public void addAfter(DoubleTextNode other)

Given another node called other, inserts it immediately after this node in the chain of nodes that come next. You may assume that other != null.

public void addBefore(DoubleTextNode other)

Given another node called other, inserts it immediately before this node in the chain of nodes that come previous. Again, you may assume other != null.

public void removeAfter()

Removes the node that comes immediately after this node in the next chain. You may not assume that next != null.

public void removeBefore()

Removes the node that comes immediately before this node in the previous chain.

public DoubleTextNode copyBefore()

Returns a copy of the chain of nodes extending in the previous direction, including this node. This should be a deep copy of the nodes and their data, that is, the copy should consist of entirely new nodes, not just references to the old nodes.

public DoubleTextNode copyAfter()

Returns a copy of the chain of nodes extending in the next direction, including this node. This should be a deep copy of the nodes and their data.

public void mergeAfter(DoubleTextNode other)

Splices in the other node (and everything after it) into the chain after this node, dropping everything currently after this node.

public void mergeBefore(DoubleTextNode other)

Splices in the other node into chain before this node, dropping everything currently before this node.

Step 2.2: Testing

Run your code through the DoubleTextNodeTest suite to make sure your implementation has the correct behavior.

Step 3: DoubleTextNodeView

You can now use your DoubleTextNode to implement the DocumentView interface. You can track the cursor implicitly by recording the node before and the node after the cursor, which we think of as being in between two nodes. Keep in mind that the entire document should always be a valid doubly linked list, with before and after referencing consecutive nodes. (Though one or both of before or after may be null, if the cursor is at the beginning or end of the list.)

Step 3.1: Implementation

Here are the methods you need to complete. Feel free to add more helper methods if you feel they are necessary or helpful for completing your code.

public boolean isEmpty()

Returns true if there are no characters in the sequence.

public void insert(char c)

Adds a new character before the cursor.

public void removeBefore()

Removes the character immediately before the cursor.

public boolean atStart()

Returns true if there is no character before the cursor.

public boolean atEnd()

Returns true if there is no character after the cursor.

public void goRight()

Moves the cursor to the right.

public void goLeft()

Moves the cursor to the left.

public char peekAfter()

Returns the character after the cursor.

public char peekBefore()

Returns the character before the cursor.

public DoubleTextNodeView shallowCopy()

Returns a shallow copy of the DoubleTextNodeView object. No new DoubleTextNodes are created.

public DoubleTextNodeView deepCopy()

Returns a deep copy of the DoubleTextNodeView object. All internal DoubleTextNodes are copied.

public void removeAll()

Resets the sequence to have no characters.

Step 3.2: Testing

Run your code through the DoubleTextNodeViewTest suite to make sure your implementation has the correct behavior.

Once you have passed the tests, you should be able to edit text in the GUI window.

Step 4: ArrayView

The ArrayView class implements the same DocumentView interface, but using an ArrayList as the central data structure. You will need to also keep track of the index of the character after the cursor.

Step 4.1: Implementation

Proceed to implement the same methods as described in Step 3.1. Feel free to add more helper methods if you feel they are necessary to completing your code.

Step 4.2: Testing

Run your code through the ArrayViewTest suite to make sure your implementation has the correct behavior.

Once you have passed the tests, you should be able to edit text in the GUI window.

Step 5: Evaluation

Describe in your own words the strengths and weaknesses of your two implementations above. Be sure to mention big-O in your analysis.

What to Hand In

Submit your DoubleTextNode.java, DoubleTextNodeView.java, and ArrayView.java implementations, along with a document for your evaluation in Step 5.

Grading