Reputation: 437
In my programm I want to switch dark mode on and off via a MenuItem. And it's is working, but I've a little problem and I don't understand what causes this problem.
The problem is, that I've to select the CheckMenuItem serveral times before the selectedProperty
is doing something.
If you run my mvce, you should see it (I think you have to click it 3 times).
But after the selectedProperty
was active for the first time, it works without any problems until you restart the application.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.MenuButton;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class DarkModeMVCE extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
BorderPane pane = new BorderPane();
Scene scene = new Scene(pane, 500, 500);
MenuButton menuButton = new MenuButton("Menu");
CheckMenuItem checkMenuItem = new CheckMenuItem("Darkmode");
checkMenuItem.setSelected(false);
checkMenuItem.setOnAction(aE -> checkMenuItem.selectedProperty().addListener((obs, wasSelected, isSelected) -> {
if (isSelected) {
pane.setStyle("-fx-background-color: black");
}
else {
pane.setStyle("-fx-background-color: white");
}
}));
menuButton.getItems().add(checkMenuItem);
pane.setCenter(menuButton);
primaryStage.setScene(scene);
primaryStage.setTitle("MVCE");
primaryStage.show();
}
}
Can anyone please explain why this is happening? Is this a bug or an error in the code?
Upvotes: 2
Views: 181
Reputation: 528
This is the simple way to achieve this :-)
checkMenuItem.setOnAction(event -> {
if (checkMenuItem.isSelected()) {
pane.setStyle("-fx-background-color: black");
} else {
pane.setStyle("-fx-background-color: white");
}
});
Upvotes: 0
Reputation: 674
setOnAction()
listener listen to any action applies on the MenuItem so when you click the menuItem it execute the code inside the listener
which at this point assign a new listener to the property of selection on the menuItem which gonna listen if the menuItem is gonna be selected or not next time any action is applied so the first action is not counted the next you do is deselect the menuItem whchi in your case do nothing and re-select it again make the desired action so no need to make two listener to the same property you can just make a listener to the change of the selection property
checkMenuItem.selectedProperty().addListener((obs, wasSelected, isSelected) -> {
if (isSelected) {
pane.setStyle("-fx-background-color: black");
}
else {
pane.setStyle("-fx-background-color: white");
}
});
Upvotes: 3