JavaFX Adding Dynamic Tabs Permanently - javafx

Is there a way where I could add a permanent tab in javafx dynamically? I mean, I have already created a code which can add a tab dynamically on a button click, but when I close the window and open it again, the tab I just added is gone.
Here's my code snippet..
//on button click
#FXML
private void addNewTab(ActionEvent event) {
add_tab_button.setOnAction(e -> {
main_tab.getTabs().add(createTab()); //main_tab is the TabPane
main_tab.getSelectionModel().selectLast();
});
}
//the new tab to be created
private Tab createTab() {
tabIndex++;
Tab newTab = new Tab ("Tab " + tabIndex);
//content of tab goes here..
return newTab;
}
Everything goes well, except that, again, when I close the window and open it again, the newly created tab gets removed.. Is there a way to add it permanently? As if I'm overriding the fxml file of the view?

Related

Gluon AppBar keep in the view

I'm trying to build a message window with App Bar on the top
This screen consist of Gluon App Bar on the top and VBox in bottom which has rest of the element shown in the screen.
Issue is when i click on the text area to enter text the App Bar goes out of scope.
Is there a way I can set App Bar to be always on top?
If you are deploying your app on Android, the TextField and TextArea controls include a built-in check: when those input controls get focused, if required the scene is moved up to prevent the software keyboard from hiding the control.
These translation affects the whole scene, so all the nodes in it (View, VBox, TextField, TextArea, AppBar, ...), will be translated as well.
So if you want to keep the AppBar node always visible and in the same top position, a possible fix could be counteracting that translation whenever it happens.
If you have a BasicView for instance (Gluon IDE plugin -> single view project), with a TextField control at the bottom of the view:
public BasicView() {
Label label = new Label("Hello JavaFX World!");
Button button = new Button("Change the World!");
button.setGraphic(new Icon(MaterialDesignIcon.LANGUAGE));
button.setOnAction(e -> label.setText("Hello JavaFX Universe!"));
VBox controls = new VBox(15.0, label, button, new TextField());
controls.setAlignment(Pos.BOTTOM_CENTER);
controls.setPadding(new Insets(20));
setCenter(controls);
}
you can modify it like this:
public BasicView() {
...
setOnShown(e -> {
MobileApplication.getInstance().getAppBar().translateYProperty()
.bind(controls.getScene().getRoot().translateYProperty().multiply(-1));
});
}
Make sure that the view is already added to the scene when you add this binding (to prevent a NPE).
Now when the textfield gets the focus, the whole scene will be moved up, and the appBar will be moved down the same amount:

How do I create a JavaFX Alert with a check box for "Do not ask again"?

I would like to use the standard JavaFX Alert class for a confirmation dialog that includes a check box for "Do not ask again". Is this possible, or do I have to create a custom Dialog from scratch?
I tried using the DialogPane.setExpandableContent() method, but that's not really what I want - this adds a Hide/Show button in the button bar, and the check box appears in the main body of the dialog, whereas I want the check box to appear in the button bar.
Yes, it is possible, with a little bit of work. You can override DialogPane.createDetailsButton() to return any node you want in place of the Hide/Show button. The trick is that you need to reconstruct the Alert after that, because you will have got rid of the standard contents created by the Alert. You also need to fool the DialogPane into thinking there is expanded content so that it shows your checkbox. Here's an example of a factory method to create an Alert with an opt-out check box. The text and action of the check box are customizable.
public static Alert createAlertWithOptOut(AlertType type, String title, String headerText,
String message, String optOutMessage, Consumer<Boolean> optOutAction,
ButtonType... buttonTypes) {
Alert alert = new Alert(type);
// Need to force the alert to layout in order to grab the graphic,
// as we are replacing the dialog pane with a custom pane
alert.getDialogPane().applyCss();
Node graphic = alert.getDialogPane().getGraphic();
// Create a new dialog pane that has a checkbox instead of the hide/show details button
// Use the supplied callback for the action of the checkbox
alert.setDialogPane(new DialogPane() {
#Override
protected Node createDetailsButton() {
CheckBox optOut = new CheckBox();
optOut.setText(optOutMessage);
optOut.setOnAction(e -> optOutAction.accept(optOut.isSelected()));
return optOut;
}
});
alert.getDialogPane().getButtonTypes().addAll(buttonTypes);
alert.getDialogPane().setContentText(message);
// Fool the dialog into thinking there is some expandable content
// a Group won't take up any space if it has no children
alert.getDialogPane().setExpandableContent(new Group());
alert.getDialogPane().setExpanded(true);
// Reset the dialog graphic using the default style
alert.getDialogPane().setGraphic(graphic);
alert.setTitle(title);
alert.setHeaderText(headerText);
return alert;
}
And here is an example of the factory method being used, where prefs is some preference store that saves the user's choice
Alert alert = createAlertWithOptOut(AlertType.CONFIRMATION, "Exit", null,
"Are you sure you wish to exit?", "Do not ask again",
param -> prefs.put(KEY_AUTO_EXIT, param ? "Always" : "Never"), ButtonType.YES, ButtonType.NO);
if (alert.showAndWait().filter(t -> t == ButtonType.YES).isPresent()) {
System.exit();
}
And here's what the dialog looks like:

How to creat a button programmatically with JavaFX?

I want to make a button on an AnchorPane without drag it from the library in the FXML file I want to do it progammatically: if the search button clicked, should show a new button not existed in the AnchorPane before I did this code but I don't know what is wrong with it:
private void searchButton(ActionEvent evt) {
Button tab = new Button();
tab.setLayoutX(147);
tab.setLayoutY(102);
tab.setText("Tab1");
tab.setPrefHeight(27);
tab.setPrefWidth(69);
WebView wb = new WebView();
wb.setLayoutX(-1);
wb.setLayoutY(128);
wb.setPrefWidth(1604);
wb.setPrefWidth(700);
}
I am assuming that you searchButton method is in controller attached to some FXML. Then all you need to do is this:
yourAnchorPane.getChildren().add(tab);
If you don't have already published reference to anchorPane in your controller, then add this into your controller
#FXML
AnchorPane yourAnchorPane;
And in SceneBuilder select your anchorPane, go to code tab and enter "yourAnchorPane" as fx:id.
Further info on working with anchorpane is javadoc.
You probably also want to set some constraints on the tab to locate it at a position within the AnchorPane. For instance, the following code will locate your button tab relative to the top left corner of the AnchorPane: Ten pixels down and fifteen pixels to the right.
AnchorPane.setTopAnchor(tab, 10.0);
AnchorPane.setLeftAnchor(tab, 15.0);

JavaFX alert dialog ignores the focused button

Why does the JavaFX alert dialog fires the Platform.exit(); when I press the Enter key even though the focused button in the alert dialog is Cancel?
soaStage.setOnCloseRequest(new EventHandler<WindowEvent>()
{
#Override
public void handle(WindowEvent event)
{
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setTitle("Confirm");
alert.setHeaderText("Are you sure you want to exit?");
alert.setContentText("Press OK to exit, or Cancel to stay.");
alert.initOwner(soaStage);
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK)
{
Platform.exit();
}
else
{
event.consume();
}
}
});
Default buttons are fired on enter
The OK button is fired when you press enter because it is a default button.
A default Button is the button that receives a keyboard VK_ENTER press, if no other node in the scene consumes it.
In the default JavaFX 8 Modena stylesheet, the default button is indicated by being a blue color rather than than the gray color of a standard button.
How to remove default button behaviour
You can remove this behavior from the alert dialog by not making the OK button a default button:
Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK);
okButton.setDefaultButton(false);
I advise you not to do this, but instead to always leave a default button in alert dialogs.
On OS X, standard alert type dialogs have a default button which is triggered by enter even if another button is focused, so the standard behavior in JavaFX is consistent with that. Note: to allow this behavior in default dialogs in OS X it is necessary to enable full keyboard access.
If you do change the OK button to not be a default button, I suggest you change its text to something else (e.g. Exit for your case):
okButton.setText("Exit");
How to make enter fire focused buttons
Now, if you also want to make it so that the focused button fires when you press enter, then you can do this:
EventHandler<KeyEvent> fireOnEnter = event -> {
if (KeyCode.ENTER.equals(event.getCode())
&& event.getTarget() instanceof Button) {
((Button) event.getTarget()).fire();
}
};
DialogPane dialogPane = alert.getDialogPane();
dialogPane.getButtonTypes().stream()
.map(dialogPane::lookupButton)
.forEach(button ->
button.addEventHandler(
KeyEvent.KEY_PRESSED,
fireOnEnter
)
);
Note: In any case, focused buttons are always fired when you press space.
We can add ENTER binding to the whole buttons by creating a class that need to be instantiated once when the application starts.
public class EnableButtonEnterKey extends ButtonBehavior<Button> {
public EnableButtonEnterKey() {
super(new Button());
BUTTON_BINDINGS.add(new KeyBinding(ENTER, KEY_PRESSED, "Press"));
BUTTON_BINDINGS.add(new KeyBinding(ENTER, KEY_RELEASED, "Release"));
}
}
When starting the application, call
new EnableButtonEnterKey();
That's it.

How to save the changes permanently in fxml file while adding menuItems through code

The following piece of code works good as long as the window is open. Menuitem added through code is visible in dropdown as expected
#FXML
public static MenuButton youradd;
#FXML
public void static addingMenuItem()
{
yourAdd.getItems().addAll(new MenuItem(newName));
}
But the issue is , when the particular stage or window is closed, the added menuitem disappers in the dropdown. I want the menuitems added to be stored permanently in the fxml code so that the menuitems are visible everytime i run the stage
NOTE: MenuButton has been created through scenebuilder. but adding MenuItems through code

Resources