I'm looking to add a separator into a choice box and still retain the type safety.
On all of the examples I've seen, they just do the following:
ChoiceBox<Object> cb = new ChoiceBox<>();
cb.getItems().addAll("one", "two", new Separator(), "fadfadfasd", "afdafdsfas");
Has anyone come up with a solution to be able to add separators and still retain type safety?
I would expect that if I wanted to add separators, I should be able do something along the following:
ChoiceBox<T> cb = new ChoiceBox<T>();
cb.getSeparators().add(1, new Separator()); // 1 is the index of where the separator should be
I shouldn't have to sacrifice type safety just to add separators.
As already noted, are Separators only supported if added to the items (dirty, dirty). To support them along the lines expected in the question, we need to:
While the former is not a big deal, the latter requires a complete re-write (mostly c&p) of its skin, as everything is tightly hidden in privacy. If the re-write has happened anyway, then it's just a couple of lines more :-)
Just for fun, I'm experimenting with ChoiceBoxX that solves some nasty bugs in its selection handling, so couldn't resist to try.
First, add support to the ChoiceBoxx itself:
/**
* Adds a separator index to the list. The separator is inserted
* after the item with the same index. Client code
* must keep this list in sync with the data.
*
* @param separator
*/
public final void addSeparator(int separator) {
if (separatorsList.getValue() == null) {
separatorsList.setValue(FXCollections.observableArrayList());
}
separatorsList.getValue().add(separator);
};
Then some changes in ChoiceBoxXSkin
At its simplest, the listener re-builds the popup, the menuItem stores the dataIndex in its properties and all code that needs to access a popup by its dataIndex is delegated to a method that loops through the menuItems until it finds one that fits:
protected RadioMenuItem getMenuItemFor(int dataIndex) {
if (dataIndex < 0) return null;
int loopIndex = dataIndex;
while (loopIndex < popup.getItems().size()) {
MenuItem item = popup.getItems().get(loopIndex);
ObservableMap<Object, Object> properties = item.getProperties();
Object object = properties.get("data-index");
if ((object instanceof Integer) && dataIndex == (Integer) object) {
return item instanceof RadioMenuItem ? (RadioMenuItem)item : null;
}
loopIndex++;
}
return null;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With