I am trying to implement a change request and am concerned I've coded myself into a corner and was hoping for some thoughtful advice on the best way out.
I have an application that uses the values in a column of a JTable as keys to compute and store store other data that goes into other columns.
First, I have a class that performs operations on data that it stores based on a key. If the key is present it adds the value to an ArrayList. The class then has methods that run calculations on the ArrayLists and allows you to retrieve the result for any specific key.
Then I have an override of setValueAt that checks that all the columns the user enters are filled, then updates the program controlled column(s)
dropTRHRow removes the old entry from my instance of ComputeData and addTRHRow adds a new entry to the ComputeData instance and updates the table row with the new data.
That was fine until the new requirement that the user be allowed to choose different units for the data and this table (and several others) would update to reflect the new units.
I am trying to brainstorm what options I have-
1. Clear the ComputeData instance, then loop over the rows of the table, change the values of the column whose units have changed, change the value in the table and then add the data back into the ComputeData instance.
Advantages: everything uses the same values
Disadvantages: speed- several hundred thousand calculations need to be performed to compute the values that go into the table. It's not that noticeable when the user is typing one entry at a time, but will be if every row has to change at once- and all this is done despite the fact that the output is the same except for multiplying by a constant that depends on the units. I also need to keep track of the units I'm in in order to process another request to change units
2. Change the values only in the table, then convert them back when I need to do a key lookup.
Advantages: fast, underlying data never changes, just how it is viewed
Disadvantages: These are floating point keys and while the comparator I am using accounts for the fact that floating point numbers have no exact representation, I'm afraid enough cycles of converting from unit to unit to unit will produce enough round-off error to produce failures in my key matching
3. Maintain a second table with the original keys and do a lookup into that table when storing or retrieving by key
Advantages: I don't need to rebuild the data and I can do all the data conversion from the "source" key, so for example, if the original units were days, and I want weeks, I display daysToWeeks(v0) and if I then switch to years, run daysToYears(v0). I don't need a weeksToYears() or that I am now in weeks, not days.
Disadvantages: Seems kludgy as now I need to update two tables when I add, remove or change a value in the table. The ComputeData actually works off a composite key made of three columns, so I can't just store the information there. I need to know the mapping even before all three columns that make up the key are entered. There is also not a one-one mapping between table rows (can have duplicate keys) and the ComputeData map (can't have duplicates).
4. Try and pull a slight of hand by having the renderer display the converted value. I don't think this will work, as the user can edit the cells and if I switch to weeks, they won't want to see 1 when they view the table and 7 when they go to edit the value.
Comments much appreciated. I can make this code work, but I would prefer to understand how it ought to be handled and not just hack away at the code.