Wednesday, January 6, 2010

Day 3

Once again today I worked on finishing up the text box, getting mouse selection, copy paste cut, select all, and other similar features. I also sat in on an iteration meeting with one of 8thLight's clients.

What I learned today:

Underlining Principles of being a Software Craftsman:

* Customer Interaction - A Craftsman needs to always know that he can never know exactly what his customer wants. Most of the time, not even the customer knows what he/she wants at the start of a project. This is why it is important to have a constant feed back process and interaction between the Craftsman and the customer. When you consider any craft like wood work, designing a building, or painting a portrait, there is always in interaction between the crafter and his customer. A carpenter asks the customer what they want, and perhaps shows some styles that the customer might like before making the table, or dresser, or anything of the like. An architect will typically write up several drafts, present them, and the make changes according to the requests of the customer. A painter painting a portrait has his customer directly in front of him/her. All these crafts require Craftsman/Customer interaction.

Software has to take this interaction even one step further. Software isn't like a chair, that has one main purpose. It isn't like a building, that once built, requires minimal to no interaction at all with the architect. And it is quite different that painting a portrait, which has the complete specifications laid out in front of it and just needs some flavor. No, software is a constantly changing, continuously dynamic, and relentlessly evolving entity that can't simply be spelled out at the start. Software's interactive nature alone requires it to be nurtured to fruition. All these crafts have another thing in common though... When the customer gets the end result, they know whether or not they like it.
This is another thing that separates a coder from a Craftsman. A Craftsman must care about his/her craft and remain on a ceaseless quest to improve and satisfy. It is because of this truth that a Craftsman must always be working with the customer. If the customer isn't sure what they are looking for, then the Craftsman sure as h*ll better find out before spending weeks developing a product. If the customer knows what they are looking for, but can't quite explain it completely or clearly, then the Craftsman needs to be interacting and presenting little demos to divulge what the customer is picturing. However, this picture is always subject to change.

Even after discovering what the customer is looking for, they might not want that two months later, and instead have a new picture or strategy in mind. This is why the Agile Method teaches all programmers to use iterations. Don't write the whole project all at once. Write small bits at a time, and every one or two weeks (or sooner if it is reasonable) demonstrate the product and make sure you are still going in the write direction.

General Knowledge of Language:

* When using a language like Java, or C, with huge libraries already built in, be weary that anything you are writing might already exist in the library. I wrote a few methods today, nothing huge but still took a decent chunk of time, that already existed in the Java libraries. Though the preexisting methods weren't exactly what I needed, I at least could have used them as templates to save myself some time.

* String buffers rule. If ever you have a batch of text, constantly subject to change, use a StringBuffer instead of a regular String. Anytime you add to a String you are actually creating a whole new string with the new text included into it. With a StringBuffer you can just add stuff anywhere you want quite cheaply.

Specific Knowledge:

More on making text boxes.
* Making selection really useable. Once you have a batch of text selected, there is a lot you have to be able to do with it.
- Deselecting: There are actually hordes of ways to deselect text, such as: clicking but not dragging in the box, clicking and dragging on empty space inside the box, (depending on preferences) clicking outside the box, pressing an arrow key, pressing tab, and a few more too. All of these need to be implemented before you can even begin to think you have a tolerable selection system.
- Deleting selected text: Naturally you can do this by hitting the delete or BackSpace button, but you can also replace the text with another character. This can be a little interesting when replacing the text with a capital letter (holding shift - the same key you use to select with arrow keys. I checked to see if shift was pressed to see if I was in selection mode, so this popped up as a tiny bug), though not to difficult.
-Moving the cursor to opposite ends of the selection: When you select some texts starting on the left and ending on the right and then you hit the left arrow (while everything is still selected) you need to pop the cursor back to where it started instead of one left of where it is now.
- Batch selecting: Since there are a few keys you can hold to manipulate your scrolling (like holding command or alt and then an arrow key) you have to keep track of several manipulators at once.
*In Java, all the extra keys like shift, alt, cntrl, and command are manipulators with their own codes. When several of these are being held at once, the manipulators just add up to unique numbers. They are all actually 1 bit in a binary string, so for example shift is bit 1 and when it is held and you call e.getManipulators (where e is a KeyEvent) it returns 1.
Cntrl is bit 2, when getManipulators is called it returns 2.
Cmd is bit 3, and returns 4.
Alt is bit 4, and returns 8.
When shift and cmd are both pressed, getManipulators will return 5. So in order to tell if I still needed to be selecting text while multiple manipulators were being held, I just used the mod function to check to make sure the manipulators result was odd (thus shift is being held). Then I could cmd shift select all text, or alt select some of the text.
*To Alt select I also needed to search for the nearest space, to stop at the end of the word.

-Finally, there was the Copy Paste Cut ordeal. At first I tried out using a local string to be my personal clipboard. This worked painlessly enough. Just had to make sure the cursor ended up in the right spot, and the proper text was copied and unselected and such.
Then I had to put my fake clipboard into the real system clipboard. Luckily Java has a nice Toolkit that gives this to you. Toolkit.getDefaultToolkit().getSystemClipboard() - The system clipboard uses something called a Transferable for it contents.
Putting text in was easy enough. I used a StringSelection object (which is a Transferable) and then pushed that into the clipboard.
Getting the text back out was only slightly more complicated since a Transferable can be text or pictures, or other unedigeties, thus I had to make sure it was holding text. Did so with this:
Transferable contents = systemClipboard.getContents(null);
boolean hasText = (contents != null) && contents.isDataFlavorSupported(DataFlavor.stringFlavor);
Then if hasText was true, I did a try catch to see if I could put the text into a String and voila!

* Mouse selection: Fortunately there was some built in stuff to make mouse selection a little bit easier, but there was still a lot to think about to get it to work. The TextLayout object I was using to hold the text for the text box had a method called hitTextChar( int x, int y) which returns a TextHitInfo. You can then use the TextHitInfo to get the index of the character, see if you click the leading or trailing edge of the character, and all sorts of other useful tidbits.
Keeping track of the cursor, and selection indices could be a little tricky... especially around the edges, but not quite as hard as I had first imagined. I ended up using most of the same code I used for scroll selecting, with a few tweaks.

Thats pretty much all. There are probably some things I forgot to mention, and still a few things I have to do to make it completely smooth and wonderful. Then of course I have to rewrite most of it using TDD. It wasn't nearly as simple as I had first imagined. Such is always the case. Murphy's Law never fails. Things always take 3 times as long as you think. Even if you realize this, and compensate, it will take 3 times as long as your new estimate. Thats why I have decided to say everyone of my tasks and stories will take until the end of the universe to complete! Doncha want me on your corporate team now? I'll only ever surprise you with my speediness.


  1. "It is because of this truth that a Craftsman must always be working with the customer."

    Can a craftsman be his own customer?

  2. Absolutely. A Craftsman is always working for himself, even if he is making a product someone else, his work and methodology is his own. Since he is always looking to improve himself, then his product is only the means to the advancement of his skills. This is sets him aside from someone merely working to get a product done, because they will have only one customer. The Craftsman is a customer of his own work, and will reject it just as quickly as his employer or paying customer.