# CS594--Homework 3

This homework is meant to give you practice with event-handling in Java.

1. Modify your temperature application from homework 2 so that the user can interactively change the temperature using the mouse. Specifically add the following two behaviors to your application:

1. If the user mouses down in the thermometer stem within 10 pixels of the top of the stem, then have the temperature gauge track the mouse. If the mouse goes above the maximum value or below the minimum value, then peg the temperature to the minimum or maximum value. The user does not have to keep the mouse within the stem while moving the gauge.
2. If the user mouses down in the filled arrow polyline in the gauge view, then have the arrowline follow the mouse. If the mouse moves below the horizontal line, then peg the arrowline to the minimum or maximum value, whichever is most appropriate. Use the mouse coordinates returned by the MouseEvent object to determine the appropriate angle for the arrow line, and then determine the temperature from that angle. The user does not have to keep the mouse within the gauge while moving the arrow.
The pie-arc will remain read-only. You may incorporate your controllers with the respective views. You may also use my solution code from the homework 2 solutions if you wish.

CS594 Students Only: Make the gauge be an oval arc with a height that is 1/2 the width of the arc (e.g., drawArc(0, 0, 100, 50)). Visually the height of the arc will only appear to be 1/4 the width because only the top half of the arc will be visible. Make the arrowline always terminate exactly on the arc's chord. You can get the point where a ray starting at the center of the arc intersects the arc's elliptical boundary using the following polar coordinate equation for an ellipse:

```x = center_x + (width/2) * cos(angle)
y = center_y - (height/2) * sin(angle)
```

2. In this problem you are going to extend your solution to the string problem in hw2 by finding the character at a given mouse coordinate and place a cursor before that character. You will then be able to move the cursor using keyboard commands. Your program should meet the following specifications:

1. It should be placed in a package named textselection and the file containing main should be named selectText.java. You should have additional files for the model and the view/controller.
2. It should take a point size and a series of strings as command line arguments. You can create a multiple word string by putting quotes around it. For example:
```    java selectText 20 "Vander Zanden" "Hooty And The Blowfish" "Boo Hoo"
```
3. Your application will display each string on a separate line, in a SERIF font, putting 10 pixels between each line.
4. The window that displays the text strings should be just large enough to accommodate all the text strings with a 10 pixel border of whitespace around the entire window.
5. Once the text strings are drawn, your code should allow the user to mousedown anywhere in the window and if one of the strings contains the (x,y) point, then draw a line between that character and the previous character.

• If the (x,y) coordinate is within five pixels of the rightmost character in any line, then the cursor line should be drawn after the last character in the line.
• If the (x,y) coordinate is between lines, above any of the lines, below any of the lines, to the left of any of the lines, or more than 5 pixels to the right of any of the lines, then no line should be drawn.
6. The user should be able to click as many times as the user likes and the cursor should move each time to the new mouse position. If the mouse position is outside the text or between lines, then the cursor should disappear.
7. Once the cursor has been positioned, the following key strokes should move the cursor in the specified ways:
• Left Arrow: Move the cursor one position to the left. Do nothing if the cursor is already in front of the left-most character in the string.
• Right Arrow: Move the cursor one position to the right. Do nothing if the cursor is already behind the right-most character in the string.
• Ctrl-a: Place the cursor before the leftmost character in the string.
• Ctrl-e: Place the cursor after the rightmost character in the string.
• h: same action as left arrow. (CS460 students only-CS594 students will insert this character into the string per the instructions below)
• l: same action as right arrow.(CS460 students only-CS594 students will insert this character into the string per the instructions below)

CS594 Students Only: Implement the following additional keyboard actions:

1. Del/Backspace: Delete the previous character if you are not at the beginning on the line and move the remaining character string to the left
2. Any printable character: Add the character to the string before the caret and move the remaining portion of the string to the right.
3. Carriage Return: A carriage return is a commit operation, not an "add a new line" operation. When the user presses the carriage return button you should make the cursor invisible and you should resize the window if the editted string has caused the width of the window to change. To do this, first call revalidate on the JComponent/JPanel on which you're writing characters, then call pack on the JFrame. You only need to resize the window when the user hits a carriage return. You do not need to resize the window each time a new character is entered or deleted.

# Hints

1. In order to make the window just big enough to accommodate the strings and the borders, you will need to have your getPreferredSize method compute the maximum width of any of the strings and then add 20 to it. Similarly you will need to compute the height of the strings, and add 20 pixels for the vertical borders and an appropriate sum for the vertical space between the lines.

2. In order to make the window have a border of 10 pixels of whitespace, you can do one of 2 things:

1. Learn about Java borders and create an empty 10 pixel border to go around the entire window.
2. Start the strings at location (10,10).

3. Do not call any of your methods either getWidth() or getHeight. These methods are defined by a JComponent and it determines the width and height of your component. If you accidentally override these methods, as I did in my initial program, you will cause your component to be sized incorrectly and you will see some of your text cut off.
4. Look at the documentation for the KeyEvent class if you want information about key events.
5. Control keys, like the arrow keys, DEL, and carriage return, should be handled by the keyPressed method. Printable characters should be handled by the keyTyped method.
6. Look at InputEvent to see how to test for the Control key, Shift key, Alt key, etc. As an example, you can test for the control key using the isControlDown method. You will have to ensure that the other modifier keys are not pressed. For example, Ctrl-Alt-a should not move the cursor.
7. Java returns a ^A key character when you type Ctrl-A. Unfortunately, Java does not make it easy to encode the ^A key character as a literal. For example, the character literal '^A' will produce an error message. Some text editors allow you to insert a control character by typing Ctrl-x where x is your control character but others do not. If your text editor does not insert control characters try printing out key events and then copying and pasting the control character into your program.

8. In the keyPressed method you should examine keycodes rather than keychars. The following codes may be useful:

• KeyEvent.VK_LEFT: left arrow
• KeyEvent.VK_RIGHT: right arrow
• KeyEvent.VK_DELETE: delete key
• KeyEvent.VK_BACK_SPACE: back space key
• KeyEvent.VK_ENTER: enter and carriage return key

9. You can use the test "Character.isISOControl(char)" in the keyTyped method to determine whether or not a control key was typed. This test returns true if the character is a control character, such as backspace, delete, carriage return, or tab, and false otherwise. This test allows you to determine whether or not a character is printable and hence whether or not it should be displayed.

10. CS594 students: Use the StringBuilder class to handle the editable strings. That way you will not always be creating a new string each time a character is added to or deleted from the string.

11. Remember to put repaint into your listener methods. If you do not do so, then your application will not repaint itself and you will find yourself wondering why your cursor is not moving when you click the mouse or press keys.

# Example Screenshots

Here is what a sample screenshot might look like with the cursor displayed:
`java selectText Times 20 VanderZanden HootyAndTheBlowfish Boo Hoo`

Here is what the same screen might look like with the cursor not selected: