Java 如何将CheckMenuItem.selectedProperty()绑定到另一个ObservableValue?
我想将一个Java 如何将CheckMenuItem.selectedProperty()绑定到另一个ObservableValue?,java,javafx,binding,menuitem,Java,Javafx,Binding,Menuitem,我想将一个CheckMenuItem的selectedProperty绑定到另一个可观察的值,比如cmi.selectedProperty().bind(myObs)。但是,这是不可能的,因为框架在单击check菜单项时设置selection属性(请参见ContextMenuContent.java的部分) 有没有一种方法可以截获点击,这样我就可以进行自己的自定义处理,并且仍然可以将选择属性绑定到另一个可观察对象 我想我认为点击是一个更新某些状态的请求。用户单击菜单项,然后程序尝试相应地更改某些
CheckMenuItem
的selectedProperty
绑定到另一个可观察的值,比如cmi.selectedProperty().bind(myObs)
。但是,这是不可能的,因为框架在单击check菜单项时设置selection属性(请参见ContextMenuContent.java的部分)
有没有一种方法可以截获点击,这样我就可以进行自己的自定义处理,并且仍然可以将选择属性绑定到另一个可观察对象
我想我认为点击是一个更新某些状态的请求。用户单击菜单项,然后程序尝试相应地更改某些状态,如果状态成功更新,则选择将更改。在“正常”条件下,每次单击都应切换检查;但是,如果发生了不好的情况,我希望该检查不会切换,而是反映程序的真实状态。实现这一点的一种方法(不必为菜单项编写外观)是使用图形滚动您自己的菜单项。您只需为图形使用一个区域,就可以从标准modena样式表中窃取CSS。然后将图形的visible属性绑定到observable值,并在菜单项的action handler中切换observable值:
import java.util.Random;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Region;
import javafx.stage.Stage;
public class VetoableMenuItemWithCheck extends Application {
@Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
MenuBar menuBar = new MenuBar() ;
Menu choices = new Menu("Choices");
// observable boolean value to which we're going to bind:
BooleanProperty selected = new SimpleBooleanProperty();
// graphic for displaying checkmark
Region checkmark = new Region();
checkmark.getStyleClass().add("check-mark");
// bind visibility of graphic to observable value:
checkmark.visibleProperty().bind(selected);
MenuItem option = new MenuItem("Option", checkmark);
choices.getItems().add(option);
Random rng = new Random();
// when menu item action occurs, randomly fail (with error alert),
// or update boolean property (which will result in toggling check mark):
option.setOnAction(e -> {
if (rng.nextDouble() < 0.25) {
Alert alert = new Alert(AlertType.ERROR, "I'm sorry Dave, I'm afraid I can't do that", ButtonType.OK);
alert.showAndWait();
} else {
selected.set(! selected.get());
}
});
menuBar.getMenus().add(choices);
root.setTop(menuBar);
Scene scene = new Scene(root, 400, 400);
scene.getStylesheets().add("check-menu.css");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
可能有一种更简单的方法,但这似乎并不太糟糕
一个可否决的收音机菜单项的版本可以遵循相同的基本思想,但有
ObjectProperty<MenuItem> selectedItem = new SimpleObjectProperty<>();
“绑定”意味着所选属性将始终等于要将其绑定到的属性的值,这与允许用户更改值不一致。所以现在还不清楚你想在这里做什么。您可能应该绑定所选属性并禁用“检查”菜单项,或者应该对可观察值使用侦听器,而不是绑定。(或者可能你的方法完全错了…?)我又加了一段;希望这能更好地解释我想做什么。
checkmark.visibleProperty().bind(selectedItem.isEqualTo(option));
option.setOnAction(e -> {
if (successful()) {
selectedItem.set(option);
}
});