JavaFX from the Trenches – JFXtras Spinner Controls

Up until now I have been happy to use the standard set of JavaFX controls in Evidentia, my commercial product written in JavaFX. However I have an enhancement in the works for which I wanted a little something extra, and a spinner control made sense.
spinnershot1

Enter JFXtras.

I basically wanted to present the user the ability to choose fields from the spinners to populate the fields on the left. Spinners made sense to me since there could be a lot of trial and error on the users part, and spinners were faster than drop down lists for experimenting.

JFXtras is a sort of laboratory for controls that haven’t made it into JavaFX (yet?) or which are beyond what one would expect in a basic framework. There are some really cool stuff in the ‘toolbox’, but being unofficial means minimal documentation, and some features you might expect in a standard control may or may not be present.

The Form

If you start up Ensemble, the JFXtras demo application, you can view the suite of controls available. It also provides sample code for using the controls. I’ll just show you the spinners:
Ensemble_spinners

I downloaded the library and added it to my project in Netbeans easy enough. I have gotten used to using FXML, so I had to adjust back to the traditional programming model, which was no big deal. I added a spinner to a grid…

        srcRefNoSpinner = new ListSpinner<>(srcRefList)
                               .withCyclic(true)
                               .withArrowDirection(ListSpinner.ArrowDirection.HORIZONTAL)
                               .withArrowPosition(ListSpinner.ArrowPosition.SPLIT)
                               .withAlignment(Pos.CENTER)
                               ;
        GridPane.setConstraints(srcRefNoSpinner,4,1);

…where srcRefList referenced an ObservableList.

The first issue I had was that the meaningful part of the control was not vertically centered.spinnershot2

This is when I realized how dependent I had become on SceneBuilder to sort out these kind of issues. I searched around for styling instructions and was encouraged to join the JFXtras mailing list, which I did.

Still, couldn’t find much information, and I never did really resolve it. I finally addressed the issue by managing the height of the control, which was ultimately what I was going to want to do anyway.

        srcRefNoSpinner = new ListSpinner<>(srcRefList)
                               .withCyclic(true)
                               .withArrowDirection(ListSpinner.ArrowDirection.HORIZONTAL)
                               .withArrowPosition(ListSpinner.ArrowPosition.SPLIT)
                               .withAlignment(Pos.CENTER)
                               ;
        srcRefNoSpinner.setPrefHeight(20.0);
        srcRefNoSpinner.setMinHeight(20.0);
        srcRefNoSpinner.setMaxHeight(20.0);
        GridPane.setConstraints(srcRefNoSpinner,4,1);

The Function

I struggled a bit with how to attach a ChangeListener to the ListSpinner control. I kept looking for a selection model for the control. I eventually found I had to attach it to the value property:

        srcRefNoSpinner.valueProperty().addListener(new RefNoSpinnerListener());
...
        private class RefNoSpinnerListener implements ChangeListener {
 
            @Override
            public void changed(ObservableValue<? extends String> ov, String t, String t1) {
                String id = "";
                switch(t1) {
                    case "XREF":
...
                }
                srcRefNo.setText(id);
            }
        }

Pretty straightforward.

The last challenge was initializing the selected value of the spinner based on an action the user takes on another tab. Again, I looked for a selection model to work with, but the solution was actually simpler:

     srcRefNoSpinner.setValue("XREF");

Summary

All in all adding a spinner to my application was pretty straight forward, and functionally there have been no issues. Some of the issues I ran into were my own doing (I thought setValue() didn’t work, created a rather embarrassing post on the email list, only to discover I had put it on the wrong code path).

Styling is still a mystery, as there is no documentation, but I find styling of the standard JavaFX controls can be just as challenging.

I also am still scratching my head – should I have expected the control to have a selection model? if it had been part of the standard JavaFX control set would I have been right in expecting it to follow the selection model design? Was the lack of one just a victim of a control in a laboratory that hasn’t fully matured?

Either way I was grateful for the work someone had done to create this control, and the simplicity with which I was able to add it to my application.

Hope this helps!

This entry was posted in JavaFX. Bookmark the permalink.

3 Responses to JavaFX from the Trenches – JFXtras Spinner Controls

  1. Pingback: Java desktop links of the week, January 28 | Jonathan Giles

  2. Pingback: JavaFX links of the week, January 28 // JavaFX News, Demos and Insight // FX Experience

  3. Tom says:

    Well, all in all I must say I’m not too displeased with your experiences using ListSpinner. I never though about vertically centering, I’ll put that on my todo list. I’m waiting for these kinds of feedback before moving the controls over to the official distribution.

    ListSpinner and the CalendarPicker were written using JFX2.0, which when it was released was missing a lot of maturity code, and I believe there was no SelectionModel present. But putting that in for ListSpinner is on my todo list.

    One of the problems I have with SelectionModel is that is very strongly depends on supporting an index. For ListSpinner that will work out fine, but for CalendarPicker I have no way of mapping an index to a date. So I’m not too pleased with it, but for compatibility I’ll add it.

Add Comment Register



Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>