Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Indeterminate "Select All" CheckBox

 
Mike Matthews
Ranch Hand
Posts: 49
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey Ranchers,

I have a number of checkboxes that I want to bind to another Select All checkbox. Here's what I'm trying to achieve:
  • Checked state for Select All - all checkboxes get checked,
  • Unchecked state for Select All - all checkboxes get unchecked,
  • Indeterminate state for Select All - no change to other checkboxes,
  • A checkbox gets checked so that all are checked - Select All checkbox gets checked,
  • A checkbox gets unchecked so that all are unchecked - Select All checkbox gets unchecked,
  • A checkbox gets checked/unchecked so that states of checkboxes differ - Select All checkbox's state changes to indeterminate.

  • I tinkered with bidirectional binding, binding and adding a listener. I believe that adding a listener could help, but the code would be most likely unnecessarily long. Thank you in advance.
     
    John Damien Smith
    Ranch Hand
    Posts: 299
    14
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    The trickiness here is there is not a single property of the checkbox that you can listen or bind to for determining its current state. Instead there is both a selected property and an indeterminate property and the changes for those properties fire independently of each other. So if you write a binding or a change listener it will be fired with only partial information (e.g. if you check the indeterminate state in the selected property listener when the state changes from indeterminate to selected, then the indeterminate check will return true even though the checkbox is in the process of changing from indeterminate to selected). If there was a single state property you could listen to, this would be easier, but there is not. So what you need is some way to coalesce the property changes such that in a single method you can process the end state of the control after both the indeterminate and selected properties have changed. In that way you can correctly determine what to do. The way I have done that in the code below is by scheduling a runnable to be run later if either of the selected or indeterminate properties are changed. I also prevent the individual checkboxes from modifying the select all state if the runnable has been scheduled - this prevents the two different ways of modifying the select all state from interfering with each others processing.



    An alternate implementation might be to use Tomas Mikula's ReactFX framework which has a provision for what he terms Inhibitable Bindings, which (if I understand their purpose correctly), would also allow you to accomplish the same task without resorting to a runnable implementation in your code. However, I haven't used ReactFX, so I couldn't say for sure if this would be a good fit for your problem.
     
    Mike Matthews
    Ranch Hand
    Posts: 49
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Huge thanks! This is perfect. I still need to analyse your code further, but I already learned new things, some of which I might use elsewhere in my code. I'll need a closer look at Runnable interface (something I avoided in the past) and the framework you referred to. I can now mark this thread as resolved.

    Edit:
    I adjusted your code slightly to fit in my code and allow reusability. It works wonders. Thank you kindly.

    The only (small) issue is that the indeterminate checkbox is smaller than its checked and unchecked states, which causes the GridPane to resize upon changing the state of Select All checkbox. It doesn't influence the usability of checkboxes so I'll let it be for the time being.
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic