Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将CheckMenuItem.selectedProperty()绑定到另一个ObservableValue?_Java_Javafx_Binding_Menuitem - Fatal编程技术网

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);
    }
});