I am converting the Java WebStart JIDE CellSpanTable based appointment scheduler to the iPad. It has a slightly different purpose on the iPad but needs to display the appointments in almost an identical way. The Java desktop application was recently converted from MigCalendar to JIDE CellSpanTable by me. I was pretty happy with the results but now I am thinking of refactoring it again.
Why bother? First there are some limitations to the CellSpanTable. I am using a JXLayer to get around some of them. That allows me to paint on top of the grid to show the current time line and for Drag and Drop support. Things are a little screwy when I attempt to scroll to a starting position in the grid. When I do that some of the paint offsets are incorrect. I have made all the adjustments in the code to handle this conflict between the JScrollPane and the CellSpanTable.
I also have issues with the time margin not fully painting in sync as you scroll the grid vertically. When you stop dragging the scroll bar everything lines up, just during the drag there is a stutter. This sort to thing always bothers me.
Since I am spanning cells based on appointment durations I can only pick one background color for the full cell span. This means if the appointment starts before normal business hours the spanned cells all get the "business is closed" background color which is not accurate. I also don't get the grid lines painting across any cell that has a spanning appointment.
I have to track extra information for cell spanning and the code is a bit difficult to grasp every time I look at it. I hate code like that. It is complex because it is not an easy process but it is hard to explain why I did what I did to make it work.
When I converted the code to the iPad I did not have a 3rd party grid control to help me out. The nice thing is I was able to concentrate on doing my own grid because I already knew how to do all the other appointment painting, time margin painting etc. I knew all the limitations of the JIDE grid that annoyed me. I was not overwhelmed with the full rewrite of something that I did not fully understand so I could initially concentrate on the grid. In fact I was forced to concentrate on how to get a grid to paint, there was no easy way out. I did some searches on the web just to make sure someone did not have a workable solution but I did not find anything to fit my needs.
I have written many a custom control so I was not afraid to tackle another one. I was able to use Quartz on the iPad to manually paint the grid and all the appointments. I solved numerous issues I had with the JIDE grid while coding the new control. I am fully in control of all the painting. I don't have any scrolling sync issues. I don't have to use an overlay painter - I paint things in the Z order I need. I am not using a grid data storage system that does not completely apply to what I am attempting to do. There are no scrolling coordinate offset issues.
This is not a generic cell spanning grid control for the iPad. This is a highly optimized grid for the purpose of painting an appointment schedule. Not that I couldn't take some time to make it more generic. My goal was to get something running that was super optimized for my painting needs. I want a very responsive UI for this application. I also will convert this to the Android platform in the near future. It should be a fairly straight forward port.
Based on the painting I did on the iPad I have already improved the look of the PC Java code. Taking a second look at things and being under less time pressure I was able to come up with a nicer look to the appointments with the start / end time in a darker color to visually highlight them to the user. I also drew a pointing ball in the margin to visually enforce the location of the current time line that can get a bit lost in the grid especially the current time falls on the hour. Just adds to the professional feel of the app.
I don't have the issue with grid lines not painting as I paint them first then overlay the appointments. The proper background color is painted for the cells too since that happens independent of the appointment paint.
The appointment memory storage is much cleaner because I am not taking what I need and forcing it into the memory layout of the grid so it can ask me to paint the appointments as it is painting each cell. Using Quartz I just paint my layers - verifying that what I am painting is visible on the screen based on paint offset and component size - avoiding all sorts of callbacks and other overhead.
On the PC your scroll with the scroll bars but on the iPad you scroll via touch. I really like the way touch scrolling works on the iPad and I miss it every time I run the PC app. I keep trying to click drag the PC app just like I do on the iPad simulator. Maybe I will have to implement that on the PC too!
Other than the auto-scrolling of the grid as you drag and drop an appointment I think the conversion will be pretty easy. The JIDE CellSpanGrid did the auto-scrolling for me. Not like this is some super secret magic bit of code, just need to write it up and make sure it feels right when it is done.
I am looking forward to tackling this on the PC then again on for Android devices. I am sure I will optimize it just a bit more on each one. The first time you write code it always stinks, you have too big of a picture in your head. On the rewrite you can concentrate on the minutia. You are basically doing a code review of your own work as you convert your logic to each language / platform.
There was a lot of learning around Quartz during this project. Sure I will learn more about Graphics2D under Java too. I have used it enough to have a pretty solid grasp there but something new pop-ups with each project.
Showing posts with label code. Show all posts
Showing posts with label code. Show all posts
Thursday, August 9, 2012
Tuesday, June 12, 2012
Testing your code, pretend you are an end user
What is one of the best ways to test your code? Pretend you are an end user. Run it like you bought it instead of like you are testing it.
Near the end of this release I add export to CSV for the scheduler. People want all sorts of reports so why not let them export the data and do whatever they fancy in Excel? Works like a charm. I was doing some other testing and though "Hey, I will just export the data so I can sort it and see it in Excel to fix this bug!". Whammo, I hit a bug right away in the Export dialog.
I just wanted to export the appointment ID, start time and duration so I deleted all the other fields in the list box but then I could not add any back. The list box was reporting a selected index of 4 (the original count of items in the list) even though there were no items in the list. I changed the code to ask the backing data model for the row count so I could insert at the proper place and one bug fixed.
Next I wanted to sort the exported data. The problem is recurring appointments exported with the start date of the recurrence not the data of the grid which means they sorted in front of non-recurring appointments. When I export data I want the date to be the same for all appointments and just for the time to change. I fixed that issue too in the fixes branch and trunk.
Here I am using the software like an end user and finding bugs. Most developers are afraid to test like an end user. We are scared of finding bugs. We tend to test in a little vacuum, testing small bits of code in very isolated conditions. No user runs your program like that. They dive in and hit every menu item and button trying to make it do what they want. They multi-select, drag and drop, double click, press disabled controls and have all sorts of fun. You need to do that too. Beat on your program like it owes you money.
For the days leading up the release I just ran the software and found a number of usability issues. Why can I set default cell width for open / closed business hours but not overall row height? Why is the pivot set per view and not just once for grid? Either you like Time as a row or a column and don't want that to change if you change the other axis to Category, Provider or Facility. Yes it annoyed the technical writer that I changed this late in the game but the code and writing took us an hour and this is something that would annoy the user every day. It annoyed me after playing with the program for an hour.
You can't depend on your QA staff to be an end user. A lot of the time they are running through regression testing scripts following a very narrow path through your code. They don't mind finding bugs so they will beat on things in odd ways but it is still a view with blinders on. Those test tend to skip over usability and look at functionality. Yes, you can follow these 10 steps to get from Y to Z but why are there 10 steps? Can we do it in 5? Export was two layers deep in a menu but is something that many will use everyday to print out a reminder call list. I put it as a button on the main toolbar. Once I did that I made a note to make the toolbar layout configurable so those who don't use that button don't need to see it. I plan on implementing that in the next release.
It is so easy to just keep adding features figuring that will make clients happy but remember they are still using the existing features on a daily basis and those should be easy to use with as few steps as possible. I save off the settings they used the last time the exported data. Who wants to reconfigure that everyday? Maybe you do three types of exports. I allow you save as many named export as you want. Where do you write the file? I default to the user home directory. What if you give that export definition to another person? They don't have a directory called c:\users\john.doe so I write out {home.dir} instead of c:\users\john.doe and do replacement text when you load the export definition. Don't annoy your users, computers are there to eliminate steps and avoid the mundane.
Allow multiple ways to do things. Some people are mouse / menu folks and others use hot keys. If you use hot keys use them all over otherwise heavy keyboard users will be annoyed. Some like toolbars and will use tooltips to see what they do if the icon is not obvious. Others are text oriented and want to find what they want in the menu. Menus need to be logically laid out with descriptive text. I hate a menu that has "Preferences", "Options" and "Tools" - those words mean the same thing to me and I always pick the wrong one when I want to change a setting. Microsoft I am looking at you here with nearly every Office application. Use you tech writing team or someone you consider to be a wordsmith to help here.
Take the time to nurture your application. Don't just keep throwing more stuff at it watching it bloat up. Consolidate smaller dialogs when possible. No one likes to bring up 10 dialogs to get their initial preferences in place or to have to remember where to find some obscure setting.
You want them to be able to quick find and use every feature you have. Why waste time coding it if no ones knows it is there?
Near the end of this release I add export to CSV for the scheduler. People want all sorts of reports so why not let them export the data and do whatever they fancy in Excel? Works like a charm. I was doing some other testing and though "Hey, I will just export the data so I can sort it and see it in Excel to fix this bug!". Whammo, I hit a bug right away in the Export dialog.
I just wanted to export the appointment ID, start time and duration so I deleted all the other fields in the list box but then I could not add any back. The list box was reporting a selected index of 4 (the original count of items in the list) even though there were no items in the list. I changed the code to ask the backing data model for the row count so I could insert at the proper place and one bug fixed.
Next I wanted to sort the exported data. The problem is recurring appointments exported with the start date of the recurrence not the data of the grid which means they sorted in front of non-recurring appointments. When I export data I want the date to be the same for all appointments and just for the time to change. I fixed that issue too in the fixes branch and trunk.
Here I am using the software like an end user and finding bugs. Most developers are afraid to test like an end user. We are scared of finding bugs. We tend to test in a little vacuum, testing small bits of code in very isolated conditions. No user runs your program like that. They dive in and hit every menu item and button trying to make it do what they want. They multi-select, drag and drop, double click, press disabled controls and have all sorts of fun. You need to do that too. Beat on your program like it owes you money.
For the days leading up the release I just ran the software and found a number of usability issues. Why can I set default cell width for open / closed business hours but not overall row height? Why is the pivot set per view and not just once for grid? Either you like Time as a row or a column and don't want that to change if you change the other axis to Category, Provider or Facility. Yes it annoyed the technical writer that I changed this late in the game but the code and writing took us an hour and this is something that would annoy the user every day. It annoyed me after playing with the program for an hour.
You can't depend on your QA staff to be an end user. A lot of the time they are running through regression testing scripts following a very narrow path through your code. They don't mind finding bugs so they will beat on things in odd ways but it is still a view with blinders on. Those test tend to skip over usability and look at functionality. Yes, you can follow these 10 steps to get from Y to Z but why are there 10 steps? Can we do it in 5? Export was two layers deep in a menu but is something that many will use everyday to print out a reminder call list. I put it as a button on the main toolbar. Once I did that I made a note to make the toolbar layout configurable so those who don't use that button don't need to see it. I plan on implementing that in the next release.
It is so easy to just keep adding features figuring that will make clients happy but remember they are still using the existing features on a daily basis and those should be easy to use with as few steps as possible. I save off the settings they used the last time the exported data. Who wants to reconfigure that everyday? Maybe you do three types of exports. I allow you save as many named export as you want. Where do you write the file? I default to the user home directory. What if you give that export definition to another person? They don't have a directory called c:\users\john.doe so I write out {home.dir} instead of c:\users\john.doe and do replacement text when you load the export definition. Don't annoy your users, computers are there to eliminate steps and avoid the mundane.
Allow multiple ways to do things. Some people are mouse / menu folks and others use hot keys. If you use hot keys use them all over otherwise heavy keyboard users will be annoyed. Some like toolbars and will use tooltips to see what they do if the icon is not obvious. Others are text oriented and want to find what they want in the menu. Menus need to be logically laid out with descriptive text. I hate a menu that has "Preferences", "Options" and "Tools" - those words mean the same thing to me and I always pick the wrong one when I want to change a setting. Microsoft I am looking at you here with nearly every Office application. Use you tech writing team or someone you consider to be a wordsmith to help here.
Take the time to nurture your application. Don't just keep throwing more stuff at it watching it bloat up. Consolidate smaller dialogs when possible. No one likes to bring up 10 dialogs to get their initial preferences in place or to have to remember where to find some obscure setting.
You want them to be able to quick find and use every feature you have. Why waste time coding it if no ones knows it is there?
Subscribe to:
Posts (Atom)