Last night and this morning I spent a lot of time building a really nice image to illustrate the taxation and subsidies pages; here’s the taxation image I built:
Then I realized that the taxation and subsidy pages are user input pages that include a slider, which means that there’s not enough screen space for the image. However, I figured that if I change the images to have less height, I can still make everything fit. A tougher problem is raised by the subsidy input. The trick here is that subsidy values for different recipients are interdependent: if you increase the subsidy for one recipient, you necessarily reduce the subsidy for all the others (I require a balanced budget). Back in 1988 I came up with a nice solution to this problem in Guns & Butter: a pie chart input device looking like this:
The little black circles are handles; if you click and drag one, it will change the size of the two sectors it separates. This is a truly elegant control, but it does have one weakness: the user seldom seeks to increase one sector at the expense of one other, and when he does so, it might not be the case that the increased sector is adjacent to the decreased sector. Thus, the user ends up decreasing one sector and then adjusting all the other sectors to reflect the change correctly. This is clumsy. Another approach is a stack of sliders:
This would have the special constraint that, as you increase one slider, all the others decrease in proportion. In other words, the change in one slider is distributed equally among the other three sliders. All in all, this is probably the best approach.
Well, I ran into a nasty problem with the stacked scrollbars. They answer to only a single type of input event: an AdjustmentListener, which triggers whenever their value is altered. The problem is that, when the player adjusts a single scrollbar, that requires me to adjust the other scrollbars — which triggers AdjustmentEvents for each of those, and the process snowballs until the stack overflows. I need to mask out such events. I might be able to do it by looking at the source of the Event, but I’m doubtful that will work. There are lots of other possibilities to consider, but there is no straightforward solution to this problem; one way or the other, I have to find some sneaky feature in Java that lets me do this. I hate this situation, where I’m dependent upon the language designer to have anticipated my problem.
Argh!!! I’ve spent the last 90 minutes fighting Java. I simply can’t get the ScrollBars to behave as I intend. I’ve tried masking out adjustment events so that only actual scrollbar changes would trigger their AdjustmentListeners — no luck. Then I tried triggering only on getValueIsAdjusting(), making sure to clear the flag with setValueIsAdjusting(false) afterwards. Again, no luck. I have tried a number of other possibilities, none of which even got off the ground. I also considered triggering directly on MouseEvents, but that, it seems, doesn’t properly handle the ScrollBar properly without a great deal of code to deal with the mouse leaving the bounds of the ScrollBar.
I’m not sure where to turn now. I’m tempted to try my special pie-chart controller; even though it’s not as easy to use as the ScrollBars, it’s infinitely more intuitive. I’m also thinking in larger terms about something else that slices the pie in a manner that is intuitively obvious. There are exactly four subsidized actions — I wonder if I couldn’t design some sort of two-dimensional balancing controller?
This is the design I’m looking at now. It’s just close enough to a conventional ScrollBar to be immediately recognizable, but different enough to insure that the player doesn’t expect it to behave exactly like a conventional ScrollBar:
The idea is that the three thumbs permit a ready adjustment of the apportionment of the total. I’m not sure whether I should retain the appearance of the standard thumbs or try something different. The biggest problem, of course, will be getting this thing to work despite Java’s close-mindedness about such things. I’ll get to work on it.