JavaFx:上下文菜单动态样式

问题描述 投票:0回答:1

我对上下文菜单有疑问。上下文菜单中的项目可以设置样式,但不能动态运行。我的意思是,例如,在初始化时,我向MenuItem添加了一个样式类,并通过事件将其删除,但是样式仍然保留在那里。如何解决?

这是一个简单的示例:

Controller.java

public class Controller implements Initializable {

    private static final String STYLED = "styled";
    @FXML
    private ListView<String> listView;
    @FXML
    private Button change;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        ContextMenu cm = new ContextMenu();

        MenuItem miAdd = new MenuItem("Add");
        miAdd.setOnAction(event -> listView.getItems().add("Apple"));

        MenuItem miRemove = new MenuItem("Remove");
        miRemove.disableProperty().bind(listView.getSelectionModel().selectedItemProperty().isNull());
        miRemove.setOnAction(event -> listView.getItems().remove(listView.getSelectionModel().getSelectedItem()));
        cm.getItems().addAll(miAdd, miRemove);

        listView.setContextMenu(cm);
        miRemove.getStyleClass().add(STYLED);
        change.setOnAction(event -> {
            if (!miRemove.getStyleClass().contains(STYLED)) {
                miRemove.getStyleClass().add(STYLED);
            } else {
                miRemove.getStyleClass().remove(STYLED);
            }
        });

    }
}

View.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<AnchorPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="textField.Controller"
            stylesheets="css/layout.css">
    <VBox>
        <Button fx:id="change" text="ChangeStyle"/>
        <ListView fx:id="listView"/>
    </VBox>
</AnchorPane>

layout.css

.styled .text {
    -fx-strikethrough: true;
}

.styled {
    -fx-background-color: gray;
}

我如何设法为我的MenuItem添加/删除样式?

css javafx javafx-8 contextmenu javafx-css
1个回答
0
投票

如果检查Node类,您会发现该类使用TrackableObservableList<String>存储样式类。该列表扩展了ModifiableObservableListBase<E>,在调用remove(Object)时不会触发更改事件。另外,您可以使用remove(index)触发更改事件并强制进行更新:

change.setOnAction(event -> {
    int index = miRemove.getStyleClass().indexOf(STYLED);
    if (index < 0) {
        miRemove.getStyleClass().add(STYLED);
    } else {
        miRemove.getStyleClass().remove(index);
    }
});
© www.soinside.com 2019 - 2024. All rights reserved.