-
Notifications
You must be signed in to change notification settings - Fork 0
HW02
Jim edited this page Oct 7, 2024
·
59 revisions
In this challenging homework, we will learn how to use arrays and for loops by implementing a text input field.
A text input field allows a user to type a message inside of a computer program. You've used these things your whole life, but probably haven't given them much thought.
Let's change that. 🙂👍
- Try playing around with one of the search bars on this web page.
- What happens when you...
- press the
B
key on your keyboard? - press
SHIFT + B
? - press the
LEFT_ARROW_KEY
? - press the
RIGHT_ARROW_KEY
? - press
BACKSPACE
? - press
COMMAND + A
(orCONTROL + A
on Windows)? - press the left mouse button?
- hold the mouse and drag?
- press
B
while some text is highlighted? - press
BACKSPACE
while some text is highlighted? - double-click?
- press the
- What happens when you...
We need to store a sequence of characters that we'll be changing a lot.
We will use an array, specifically an array of characters (char[]
).
-
char[] buffer = new char[8];
is an array of 8char
's calledbuffer
-
buffer.length
will be8
-
-
for (int i = 0; i < array.length; ++i) { ... }
iterates overarray
forwards -
for (int i = array.length - 1; i >= 0; --i) { ... }
iterates overarray
backwards
- I highly recommend drawing simple little pictures of your array for this assignment
- This will be very useful to work out carefully by hand what should happen to your array, rather than just guessing
-
char[] buffer;
stores the user's message as an array of characters-
buffer
can store a message of length at mostbuffer.length
-
-
int length;
is the length of the current message stored in buffer- if
(length == 0)
then message is empty - if
(length == buffer.length)
then the message completely fills the buffer
- if
-
int cursor;
is the current cursor position-
0
means all the way to the left -
1
means in betweenbuffer[0]
andbuffer[1]
-
- the left side of the canvas is
$x = 0.0$ - the right side of the canvas is
$x = \texttt{buffer.length}$ - we are using a monospaced font; this means each character is the same width;
- for simplicity, we have each character be
$1.0$ unit wide -
buffer[0]
is drawn from$x = 0.0$ to$x = 1.0$ -
cursor
should be drawn at$x = \texttt{cursor}$
- for simplicity, we have each character be
-
example
- here is the message
COW
written in a monospaced font, with the cursor all the way to the left-
buffer.length
is4
-
length
is3
-
cursor
is0
-
| ##### ##### # # | # # # # # | # # # # # # | ##### ##### # # 0 1 2 3 4 -> x
- here is the message
- the bottom of the canvas is
$y = -1.0$ and the top is$y = 2.0$ (NOTE: you don't need this fact except for the A++, at which point you'll probably want to write your own text drawing function(s) anyway)
- All features must match the behavior of a typical text input field
- For example, pressing
BACKSPACE
should turnCO|W
(length 3) intoC|W
(length 2); NOTE: the|
is the cursor - You are responsible for discovering what the correct behavior of all commands is by experimenting with a real-world text input field
- For example, pressing
YouTube Link: https://www.youtube.com/watch?v=HTEWeeOiI3s
- You may NOT use any fancy Java standard library functions
- Use for loops, if statements, and the functions inside Cow.java
- You may NOT use the Java
String
class anywhere. - You may NOT create any new arrays (just modify the contents of
buffer
) - You may NOT use excessive repetition (for example, don't use separate
if
statements forc == 'A'
,c == 'B'
,c == 'C'
, ...) - You may NOT have any out of bounds errors
-
A-
- Update Cow
- User can press
A-Z
(any of the keysA
,B
, ...) - Draw the cursor bar (location of
cursor
as a vertical line) - User can press
0-9
- User can press
SHIFT + A
,SHIFT + B
... - User can press the space bar
- HINT: this is the character
' '
- HINT: this is the character
- User can press
LEFT_ARROW
- User can press
RIGHT_ARROW
- User can press
BACKSPACE
-
A
- Make the cursor bar blink
- HINT: You will want to introduce a
frame
ortime
variable to keep track of the current frame / time - NOTE: Making the cursor bar not blink for a bit after
keyAnyPressed
is an optional good idea
- HINT: You will want to introduce a
- Click the mouse to move
cursor
to the closestint
- If the user presses
ENTER
while the buffer containsPassw0rd
, replace the contents of the buffer withaccepted
- HINT: some repetition here is OK
- Make the cursor bar blink
-
A+
- Click and drag the mouse to select/highlight a sequence of characters
- HINT:
int select = 0;
can be the "selection cursor"; if(cursor == select)
is true, then nothing is selected (and the cursor should be blink as usual); it it is false, then the characters in between the two numbers are selected-
MIN(...)
andMAX(...)
may be useful
-
- NOTE: pressing
BACKSPACE
while characters are selected must do the right thing - NOTE: pressing
A
,B
, ... should also do the right thing
- HINT:
- Press
COMMAND + A
orCONTROL + A
to select all characters- NOTE: we want our app to be "cross platform" (work on both Mac and Windows)
- (Optional, but put in free response if you did it) Double-click the mouse to select all characters
- HINT: Be careful about the built-in
mouseHeld
(NOTE:mouseHeld
is true for the first framemousePressed
is true--and likely for a few frames after that as well)
- HINT: Be careful about the built-in
- Improve the animations of the cursor; Inspo: https://diskvoyager.com; Additional very important inspo: https://www.youtube.com/watch?v=emjuqqyq_qc
- Click and drag the mouse to select/highlight a sequence of characters
-
A++ (105)
- Build a full raw text editor like TextEdit/Notepad
- Copy and paste from system clipboard
- Multiple lines
- Build a full raw text editor like TextEdit/Notepad
class HW02 extends Cow {
public static void main(String[] arguments) {
char[] buffer = new char[8];
int length = 0;
int cursor = 0;
canvasConfig(0.0, -1.0, buffer.length, 2.0, WHITE, 512);
while (beginFrame()) {
// TODO
// NOTE: This function draws the first length-many characters of the buffer
HW02_drawText(buffer, length, BLACK);
}
}
}
Iterate over the characters A-Z
for (char c = 'A'; c <= 'Z'; ++c) { ... }
Convert char
from uppercase to lowercase
(char)('a' + (c - 'A'))
-
Example:
('D' - 'A') -> 3
and(char) ('a' + 3) -> 'd'
How can I make my code for typing letters, numbers and spaces less repetitive?
If you're finding your code looks like this...
for (char c = 'A'; c <= 'Z'; ++c) {
if (keyPressed(c)) {
... // Complicated logic for inserting a character
}
}
for (char c = '1'; c <= '9'; ++c) {
if (keyPressed(c)) {
... // Complicated logic for inserting a character
}
}
if (keyPressed(' ')) {
... // Complicated logic for inserting a character
}
Maybe instead consider something like this!
char newCharacter = 0; // initialize to the null (0) character
for (char c = 'A'; c <= 'Z'; ++c) {
... // Simple logic to setting newCharacter
// NOTE: this one also has to handle shift
}
for (char c = '0'; c <= '9'; ++c) {
... // Simple logic for setting newCharacter
}
if (keyPressed(' ')) {
... // Simple logic for setting newCharacter
}
if (newCharacter != 0) {
... // Complicated logic for inserting a character
}
👀
class HW02A extends Cow {
public static void main(String[] arguments) {
final char[] buffer = new char[8];
int length = 0;
int cursor = 0;
// NOTE: each character is 1 unit wide
canvasConfig(0.0, -1.0, buffer.length, 2.0, WHITE, 512);
int blinkCounter = 0;
while (beginFrame()) {
boolean insertCharacterValid = (length != buffer.length);
boolean backspaceValid = ((length != 0) && (cursor != 0));
boolean leftArrowKeyValid = (cursor != 0);
boolean rightArrowKeyValid = (cursor != length);
if (keyAnyPressed) {
blinkCounter = 0;
}
if (insertCharacterValid) {
char newCharacter; {
newCharacter = 0;
for (char c = 'A'; c <= 'Z'; ++c) {
if (keyPressed(c)) {
if (!keyHeld(SHIFT)) {
newCharacter = (char)('a' + (c - 'A'));
} else {
newCharacter = c;
}
}
}
for (char c = '0'; c <= '9'; ++c) {
if (keyPressed(c)) newCharacter = c;
}
if (keyPressed(' ')) newCharacter = ' ';
}
if (newCharacter != 0) {
for (int i = length; i > cursor; --i) buffer[i] = buffer[i - 1];
buffer[cursor] = newCharacter;
++cursor;
++length;
}
}
if (backspaceValid && keyPressed(BACKSPACE)) {
for (int i = cursor; i < length; ++i) buffer[i - 1] = buffer[i];
--cursor;
--length;
}
if (leftArrowKeyValid && keyPressed(LEFT_ARROW)) {
--cursor;
}
if (rightArrowKeyValid && keyPressed(RIGHT_ARROW)) {
++cursor;
}
if (mousePressed) {
cursor = length;
for (int i = 0; i < length; ++i) {
if (mouseX < i + 0.5) {
cursor = i;
blinkCounter = 0;
break;
}
}
}
if (keyPressed(ENTER)) {
if (true
&& (buffer[0] == 'P')
&& (buffer[1] == 'a')
&& (buffer[2] == 's')
&& (buffer[3] == 's')
&& (buffer[4] == 'w')
&& (buffer[5] == '0')
&& (buffer[6] == 'r')
&& (buffer[7] == 'd')) {
buffer[0] = 'a';
buffer[1] = 'c';
buffer[2] = 'c';
buffer[3] = 'e';
buffer[4] = 'p';
buffer[5] = 't';
buffer[6] = 'e';
buffer[7] = 'd';
}
}
{ // draw
if ((blinkCounter++ % 14) < 7) drawLine(cursor, -0.5, cursor, 1.5, PURPLE, 5.0);
HW02_drawText(buffer, length, BLACK);
}
}
}
}