Tuesday, January 5, 2010

Day 2

Today I spent most of my time working on making a text box. It sounds menial, but surprisingly there is a lot to it.

Let me first try out my organization strategy again, and with it I will explain what I learned about the challenges of the dreaded text box.

What I learned today:

Underlining Principles of being a Software Craftsman:

* Spiking - Although this is not directly an Agile method, it can be used as a strategy to practice being Agile. Spiking is a technique a developer will apply when they really have no idea how to write their project or task. Without knowledge of the organization, specific details, or even general gist of how he/she will write the code it is often exceedingly difficult to write any meaningful tests. In the end, this could slow him/her down. One way to get around this is to use spiking. The developer will just start writing code and trying several strategies to figure out which ones are the best fit to the problem. Whether it be just a few lines, or even a quick semi-functional program, Spiking can be used to gain a greater understanding of both the solution and the problem. Once he/she has sufficient understanding of the problem, or at least a good place to start, he/she would delete the written code and start again from scratch with TDD.

An analogy I thought of that describes this strategy or pattern is how one goes about solving a Rubik's Cube. If it is your first time ever solving a Rubik's Cube, you will likely try and do it one side at a time. You will do a few spins, move some blocks around, get your first side and leap with glee with your success. Then you will try getting another side, and in the process discover you have mess up the first side before you can get both. You plow on through and you start throwing confetti as you get your second side. Then comes the third side... and then the fourth... and the fifth... And finally when there is just the one side left, and you are terribly frustrated that it took you two years to get the fifth side, since you couldn't seem to keep the first and fourth ones together, you just throw down the cube. Every single turn you made messed up one or more sides. You never finish the cube.

This is the wrong way to solve a Rubik's Cube and the wrong way to write software. A learned cuber will know that you don't necessarily solve it one side at a time, but instead use strategies that allow you to decouple all the sides leaving you the ability to get them all at once. Though you wont get one side quite as fast (unless of course, as most learned cubers can, you can solve it uber fast), you will finish the whole cube much faster.

This is similar to the difference between writing clean, well tested, organized, decoupled, and readable code vs. just hacking away to get things to work. But to do this requires just a bit of foresight. Though in some cases you can simply write tests and they will lead you to an excellent solution, it is also possible you will write a flurry of tests that have nothing to do with an end solution. Just as it is important to know strategies to solve a Rubik's Cube, it is important to have some understanding of your software endeavor so that you may learn not to solve your problem one side at a time, and instead write effective tests that open the doors to solving the entire cube.

General Knowledge of Language:

Nothing that stands out. Lots of little tidbits about the Java libraries and mouse and key press events.

Specific Knowledge:

* Writing a text box requires a lot of work...
- The cursor: The cursor alone can be quite tricky to write. When you consider that it is just a vertical line that you draw in between letters and not some magical object that just glides to its proper location, you can likely see it requires some thought.
* First off, you need to make sure it doesn't get drawn on top of the letters. This means you must have some way to know the exact size and spacing that every single character requires.
* Then you must be certain it can scroll back and forth. Thus, there has to be something keeping track of where the cursor is in relation to not only the text box, the text itself. So it needs an X coordinate, as well as some character relation coordinate. I used a index that keeps track of its index in the string, and I update it for any left-right scrolling, deleting, and adding of characters.
* It has to be able to move with relation to spaces. Though easy, it is something to think about.
* It has to blink. I used a separate thread that pops it on and off with a 500ms sleep
* Finally, although there might be other things I am forgetting at the moment, it can't ever leave the text box. Thus your indexer wont always match the require X coordinate. I used an offset to make sure it never left the box when typing more than could in the box.

- Scrolling: Moving the visible letters side to side when there are more than can fit in the text box. Equally challenging as making the cursor since there are several offsets to keep track of, or at least many ways in which the text offset can change.
- Highlighting & Selecting with the arrows: Highlighting isn't too bad once you have a solid cursor. All you need to do is fill a rectangle from where the cursor was to where it is, and then draw the letters on top of that. Its selecting the letters that is more of the challenge. You need some way of grabbing the highlighted text, even though the highlight is just a rectangle. This can be done if you are keeping track of the relative index of the cursor to the characters, thus when you highlight you encapsulate both the X coordinates of the cursor, and characters of the text between the indices.
- Selecting with the mouse: This I am yet to complete, but it isn't easy by the looks of it. Since you no longer have any meaningful use of the cursor, you have to calculate which characters to select based solely on the X coors. This gets even more challenging since you can also be clicking on letters of varying sizes rather than conveniently between them.

There is a lot more to making text boxes than I had first imagined, and I haven't even dived fully into the issue, thus the scope of the problem is probably even lager than I imagine now.

It is a good thing I have been Spiking, because had I tried to write this straight away, I would have made a huge mess, and spent even longer doing it. Now at least when I write it for real, I will have some strategies to get it done right.

Other General coding goodies:

Nothing that comes to mind.

No comments:

Post a Comment