Centering a button(s) is actually quite easy (nonetheless it could be simpler and better documented). It all comes down to “magical” buttonOrder
string passed to ButtonBar
's setButonOrder(String)
method.
But first, the essential code snippet:
@Override public void start(final Stage stage) throws Exception {
// …
var button = new ButtonType("Roger!", ButtonBar.ButtonData.OK_DONE);
var dialog = new Dialog<>();
dialog.setDialogPane(new DialogPane() {
@Override protected Node createButtonBar() {
var buttonBar = (ButtonBar)super.createButtonBar();
buttonBar.setButtonOrder("L_O_R");
return buttonBar;
}
});
dialog.getButtonTypes.addAll(button);
var pane = dialog.getDialogPane();
// Add whatever is needed to the pane here…
// …
dialog.showAndWait();
}
Explanation: the wrapping start(Stage)
method is of course Application
's start method. First I create a button of OK/DONE type and then a Dialog
instance. Nothing unusual so far.
And now: normally, after dialog gets created, we just add buttons and the content to dialog's pane. But here I actually create and set the pane first and a slightly modified one.
As you can see, I create anonymous class extending DialogPane
and immediately set it as dialog's pane. What needs to be done in here, is to override one single method createButtonBar
, and only for one, yet critical to our expectations, purpose: to change the way the button bar layouts its children (i.e. buttons). In this particular case I used the string '"L_O_R"' (not LOTR ;-).
So what is it? It's not clearly documented, but if to look at ButtonBar Javadoc, you will notice these few lines:
Windows: L_E+U+FBXI_YNOCAH_R
Mac OS: L_HE+U+FBIX_NCYOA_R
Linux: L_HE+UNYACBXIO_R
and accompanying pictures of buttons laid out on these OS-es. Each letter represents button type, and as per ButtonData.OK_DONE OK_DONE
type has assigned letter O
, while L
and R
mean left and right position respectively. The underscore _
is a spacer or gap. So with the string L_O_R
we are saying: put buttons marked as LEFT on the left, those marked as RIGHT on the right, and those marked as OK_DONE just in between (because two surrounding gaps). Of course you can mix other types as it pleases you, so for instance you could pass L_YXOCN_R
or whatever else you need.
If the Dialog
had setButtonOrder(String)
method, it would be much simpler to achieve desired effect. Anyway it's simpler that creating artificial spacers or messing with horizontal translations.