Friday, February 24, 2012

JIDE upgrade and allowing user font size selection

Due to the new scheduler we needed to upgrade to the latest version of JIDE. First off JIDE has been a solid set of controls for our application but we don't upgrade very often so this was a multiple version number jump. JIDE is also very responsive to email requests and have fixed various issues we found in a timely manner. I highly recommend them if you need flexible grids, combobox tables, tree tables, etc.

During our upgrade we needed to toss out some code we used to override things JIDE did not do in the past and we also decided to allow the user to set the overall application font. Doing so brought up various cheats in our code. We had some of our controls return hard coded preferred dimensions. Now they use the current font to calculate their size. Some controls did not provide a preferred size. We use MigLayout pretty much everywhere so we had some hard coded "w 150!, h 22!" style parameters in the code which we removed.

We need to convert everything to MigLayout. I did a lot of the conversion from NetBeans FORM layout to MigLayout last year. Some of the panels used odd control overlaying - not card layout - so I left them alone. We know how to convert those and in fact have decided that overlay is really not the best way to handle the layout needs so we are replacing it anyway. Everyone will be happy to see all the forms gone. Removing the hard coding of sizes has caused us to clean up some of the MigLayout parameters too. Using size groups for buttons can keep things in a nice grid style layout along with better grow parameters have been a big help.

As far as preferred sizing goes the Mac needs slightly different sizes than the PC so we have some isMac() calls in the code to handle that. Under Win7 on the PC the drop down arrow to the right of a combobox sizes to match the overall combobox font, on the Mac it does not, that arrow is an image and sticks to one size.

We really should go through all the code and tag the buttons as OK, Cancel etc. so they show up in the right order on a Mac. Should have been done from the start and we are unsure if it would throw off our current Mac users to swap it at this point.

Our applications are used by medical staff to enter anesthesiology billing information. There are piles and piles of entry screens we are dealing with. The conversion has been handled by me and my boss over the past 10 days are we are nearing the finish. The ability to pick a larger font has been on our feature least for some time. A lot of the folks entering the data are 40+ years of age and they really want to have larger fonts. It will also help with demoing the product in a booth on a large monitor.

QA is going to have fun. They need to revisit every entry screen 4 times, PC large / small font then Mac large / small font. We have a FEST test script set up to bring up each screen and take a screen shot to assist in this area but you also need to verify TAB order and other oddness on the screen too. Now that JIDE has switched to using JComboBox etc. as their base classes for their controls it will be much easier to write FEST scripts for testing.

I have been doing all the Mac testing and tweaking up to this point. We don't want QA to start reporting things until we have given it a solid once over otherwise we will have a massive pile of issues of the type "we have not touched that code yet darn it" variety. Generally things have gone smoothly between the Mac and the PC. I do have one crash left on the Mac that does not occur on the PC. I am guessing this is related to something happening off the EDT that annoys the Mac. It is crashing way down in the Aqua Look and Feel.

I will probably move off of the conversion by the end of the day and move back on to the scheduler. All of this needed to be in place so I could have the new JAR files ready for me so it was a good breaking point. The new JIDE will go out with the next release but we don't know if the new scheduler will. I would rather have them go out in stages as both pieces will be a load for QA to digest.

Friday, February 10, 2012

Java needs a toDebugString to go with toString

toString() is a very handy Java method. It allows you and the debugger to display the value of an object in a nice format. The problem is toString() is not just used by the debugger and by your code for logging. This method is used by ListBoxes, Trees, ComboBoxes and other UI elements.

It would be great to add a second method toDebugString() that returns the string to be used by the debugger when inspecting objects and potentially for your logging leaving toString() for UI elements use. In the base Object toDebugString() would return toString() so unless you override toDebugString() they would both act identically. I have various objects that I want to use in a ListBox so I have to use toString() to return a very basic String for a variable usually called name or description. That is great for a ListBox but not for the debugger where I may want to know the name, colors, child count or any number of other things.

I just got done converting some handy debug toString() methods to the much simpler return name; variety in the scheduler code as I needed to show them in the UI. I just lost useful output in the debugger from this. I can easily do my own toDebugString() calls for logging and simple inspection but the Eclipse debugger will not call that when viewing then in a watch list.

Of course Eclipse helps in this area by allowing you to create Detail Formatters. Under Window -> Preferences -> Java -> Debug -> Detail Formatters you can define what you want displayed for various object types. It means you get to go through some extra hoops but you can see the results you want. I really would like to avoid the hoops and have a call right in the code for the object as it is easier to maintain than diving deep into an Eclipse dialog to set things. During initial development I tend to refactor my objects quite a bit.This is not portable to another IDE and if you keep a lot of projects open under a workspace this can get rather cluttered.

I am going to attempt to use the Eclipse Detail Formatters while testing / debugging this project to see how it goes. It could be my fears are unjustified but I really would love a simple / clean solution to this issue easily supported by all IDE / Debuggers.

Wednesday, February 1, 2012

Some days you just rewrite what you did the previous day

Today was one of those days. I thought I came up with a really cool solution to block times and appointments sharing a cell span for the new appointment scheduler using JIDE. I had it all implemented yesterday and it appeared to be working nicely as I went home for the night and off to enjoy my son's band concert.

This morning I sat down and ran the program again just to see if I could get it to fail. Of course it did fail after a short time of testing. My fake data starts with one time block and two appointments with none of them overlapping. A time block is used to paint the background of the group of cells - say from 8 AM to noon - in a special hatched color pattern. This allows the provider to block a set of time for specific tasks such as OB or cancer only patients. You are allowed, encouraged actually, to schedule appointments in that time block. You can't move or resize the time block using the mouse, that is all done via a configuration dialog so you don't accidentally move it about during normal business activity. It needs to paint first and all appointments on top of it.

I had a bunch of code looking at each appointment as it was added to the schedule to see if the an existing cell span needed to be extended - either earlier start row or growing the row count. It worked most of the time unless I added appointments in a certain order and they overlapped but did not cause the cell span to grow. So the block was from 8 to noon and an appointment was from 9 to 10. It fits but I did not account for it thus I ended up adding two cell spans to JIDE table which annoys it when you try to delete them. I had added a cell span dump call to my table allowing me to see why the painting was all wacky. I tied the dump into an unused button on my test interface as I did not want the output filling up as I was dragging appointments around trying to get the problem to replicate. Once I really looked at the code I was not happy about adding a bunch more logic for special overlaps and cleaning up JIDE table Cell Spans and internal Cell Spans. Time to step back and take a new perspective.

What I decided to do is add the appointments as a collection. I can put each appointment in its column, then I can sort a column of appointments by row and row span. After sorting I can easily come up with unique cell spans. I add those spans to the JIDE grid then I also calculate which row / column to do the setValueAt call for adding appointments to a collection for that cell. You don't get paint calls for every cell in the table, only the one in the upper left corner of a cell span. I needed to consolidate all appointments for a span to that one callback spot. An earlier attempt at that had less than stellar results.

I ended up deleting a lot of code and making the logic a ton easier to debug and understand. Looking at the data to decide what to paint is also cleaner. Still runs slower on the Mac that I want so tuning will be in order but I want to get overlapped appointment painting to work first then I will tune things. I have a feeling it is JXLayer related on the Mac and I might not have much control over that. I have broken down and reconstructed the logic more than once already so no need to optimize yet.

Today's implementation appears to be pretty solid. I have been unable to get it to screw up after beating on it via lots of drag and drop and tossing numerous appointments at the grid. I even fixed a clipping issue that only occurred on the Mac. I am doing all my development on the PC but I copy the code over to the Mac as a backup being as I don't have a sandbox area in SVN to check anything in just yet. It is also good to run on more than one platform to catch any weird errors, graphical glitches or performance problems early in the process.

I have notes all over my whiteboard, scratch paper and in PSPad that I will go through so I can cross off the random thoughts that did not work. Next up is painting overlapping appointments by insetting them from the edge and tracking the mouse into them allowing you to change the Z order. Could get kind of hairy but I think the new way I am storing things is going to help. My plan today was to implement that once I felt the code was solid. Since the code was not solid I did not get around to it today. Guess that is why we have tomorrows.

Next scary piece will be implementing a pivot. Allowing time to run in the columns and column categories to run as the rows. I don't want an IF statement every other line so I might have an object ready for each layout type for processing rows vs. columns. I hate to duplicate code but if it becomes too messy it will be worth it. Double the testing for sure. Get that all in place and I get to do week and month views. Somewhere in there I will have to move this into our main application to replace the current MigLayout. It needs to be a fully working custom control before I do that so I can concentrate on the real appointment data at hand and not on fixing scrolling and painting bugs. Plus it will allow other developers here to help out with dialog boxes and all the other decorations needed by a scheduler.