Tuesday, May 20, 2014

A Java Slider/Text Combo

A few years back I was coding (in Java, of course) the <shudder>GUI</shudder> for a research program. I needed to provide controls that would let a user specify priorities (0-100) scale for various things. Two possibilities occurred to me, with pretty much diametrically opposed strengths and weaknesses.

Sliders have a few virtues.
  • Grabbing and yanking the handle is usually faster than typing.
  • When you have more than one, they provide a sort of quasi-horizontal bar graph of the inputs -- it's easy to tell from their relative positions which inputs are larger than which others.
  • It's immediately obvious if you are the absolute maximum or minimum value for the input.
When your input range is something like {1, 2, 3, 4, 5}, it's pretty easy to look at a slider and see what the exact value is. When your input range is {0, 1, ..., 100}, that's a lot harder, which led me to consider text fields. Text fields have their own virtues.
  • It's easy to be precise, regardless of the legal range of inputs. (Try hitting exactly 58, rather than 57, on a 0-100 slider.)
  • You can immediately see exactly what value is being set.
On the other hand, the sort of approximate ratio information you get just by looking at two sliders requires a bit of mental arithmetic with two text fields. Also, if the range of legal values is not obvious to the user, it can be hard to know whether a particular input is at (or near) the maximum or minimum legal value.

Hoping for the best of both worlds, I went looking for Java Swing control that combined a slider with an editable text entry field, and did not find one I liked (which may say more about how picky I am and how good my search skills are than about their availability). So I rolled my own.

Fast-forward to this month, where I'm working on a program for an entirely different research project and once again wanted a slider/text combo control. I dusted off the old code and decided to pretty it up a (very) little, add some documentation and release it into the wild. The project name is ComboSlider, and you can find its repository on Bitbucket. I released it under the EPL 1.0 open source license. Source code, a compiled jar file and documentation are all in the repository. The jar file includes a small demonstration program.

Here is a screen shot of the demo program:


The ComboSlider control is in the orange rectangle. Pull the slider and the text field updates. Type a legal value in the text field and the slider automatically repositions.

The top two text fields demonstrate how to redefine the domain of the ComboSlider on the fly. The bottom text label updates automatically when you change the input value, demonstrating how to use a change listener to monitor the ComboSlider's value. (In an ordinary input dialog, though, you would not need the change listener; you would just wait for the dialog to complete and then use ComboSlider.getValue() to find out what the input value is.)

There are two limitations I probably should mention: it only accepts integer inputs (positive or negative); and, while you can set the size of the entire ComboSlider using the usual setters for minimum/maximum/preferred size, the separate dimensions of the slider and text field are hard coded in the constructor.

2 comments:

  1. You might want to replace the JTextField with a JSpinner (if and only if it's never empty).

    ReplyDelete
    Replies
    1. Geoffrey: I think I considered a JSpinner when I first created the ComboSlider, and decided it either looked too "busy" or ate up a little too much space. Now that I'm releasing it OS, though, I shouldn't impose my aesthetic judgment on the next user. Thanks for the suggestion. I've added an "issue" to remind me. When I get time, I'll add the spinner version as another class.

      Delete

If this is your first time commenting on the blog, please read the Ground Rules for Comments. In particular, if you want to ask an operations research-related question not relevant to this post, consider asking it on OR-Exchange.