如何在JavaFX节点上侦听psuedo-classes中的更改

时间:2018-02-21 15:35:11

标签: java javafx javafx-8

我原以为我可以在Node.getPseudoClassStates()上听取ObservableSet类型的更改,但不会触发更改事件或失效。

是否有其他方法可以监听在节点上设置伪类的更改。

public class PsuedoEvents extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        Button horse = new Button("horse");
        horse.getPseudoClassStates().addListener(new InvalidationListener() {
            @Override
            public void invalidated(Observable arg0) {
                System.out.println("invalidated " + arg0);
            }
        });
        horse.getPseudoClassStates().addListener(new SetChangeListener<>() {
            @Override
            public void onChanged(Change<? extends PseudoClass> arg0) {
                System.out.println("changed " + arg0);
            }
        });
        stage.setScene(new Scene(new HBox(horse), 300, 300));
        PseudoClass fooClass = PseudoClass.getPseudoClass("foo");

        horse.setOnAction(event -> {
            horse.pseudoClassStateChanged(fooClass, !horse.getPseudoClassStates().contains(fooClass));
            System.out.println("Toggle state... " + horse.getPseudoClassStates());
        });
        stage.show();
    }

}

1 个答案:

答案 0 :(得分:2)

我设法识别问题... getPseudoClassStates()返回一个不可修改的包装器。

public final ObservableSet<PseudoClass> getPseudoClassStates() {
    return FXCollections.unmodifiableObservableSet(pseudoClassStates);
}

包装器类型UnmodifiableObservableSet使用弱侦听器来跟踪支持列表,但是由于没有对包装器的强引用,因此它是垃圾回收。

我可以使用

解决此问题
private ObservableSet<PseudoClass> states;  // <=== strong ref

@Override
public void start(Stage stage) throws Exception {
    Button horse = new Button("horse");

    states = horse.getPseudoClassStates();
    states.addListener(new InvalidationListener() {
        @Override
        public void invalidated(Observable arg0) {
            System.out.println("invalidated " + arg0);
        }
    });