On Tue, 5 Mar 2024 07:34:32 GMT, John Hendrikx <jhendr...@openjdk.org> wrote:
>> modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/GlassSystemMenu.java >> line 226: >> >>> 224: mb.textProperty().when(active).addListener(valueModel -> >>> glassMenu.setTitle(parseText(mb))); >>> 225: mb.disableProperty().when(active).addListener(valueModel -> >>> glassMenu.setEnabled(!mb.isDisable())); >>> 226: >>> mb.mnemonicParsingProperty().when(active).addListener(valueModel -> >>> glassMenu.setTitle(parseText(mb))); >> >> Since you are not calling `get()` from the `when` resulting observable (to >> allow for invalidation), these need to use a `ChangeListener` instead of an >> `InvalidationListener`, otherwise, while `active` doesn't change, any change >> in those menuBase properties will trigger just one notification. >> >> Alternative, just replace `addListener` with `subscribe` (as it internally >> uses a `ChangeListener`). >> >> @hjohn does this make sense to you? > > This could be a problem normally, but I think in this case you won't be able > to get this to produce incorrect results. > > `parseText` is accessing the property (and it calls `isMnemonicParsing`), but > only if the text is not empty. It's sort of "safe" as an empty text can't > contain a mnemonic anyway, and you'd need to change the text at a minimum > first to see the effect of turning mnemonic parsing on/off. Changing the > text would trigger the `textProperty` listener, which will call `parseText` > and read the mnemonic property. > > A change listener would be more obviously correct, but it is not strictly > needed here. > > (not all `subscribe`s use change listener, the one that takes a `Runnable` > uses invalidation) There is an issue using `when()`, because you add the listener to a new property, not to the original property. Therefore, using an invalidation listener doesn't trigger notifications if you changing values more than once to the original property. Simply run this test: BooleanProperty b = new SimpleBooleanProperty(); BooleanProperty active = new SimpleBooleanProperty(true); b.addListener(o -> System.out.println("b: " + b.get())); b.when(active).addListener(o -> System.out.println("when: " + b.get())); b.set(true); b.set(false); It prints: b: true when: true b: false so with `when` we miss the changes! (I can go into details of why this happens, but just notice we have a new property after all, and not calling `when.get()` it doesn't get validated anymore). This can happen in this SystemMenuBar case with the disabled property of any given `Menu` or `MenuItem`, if you simply change it twice, while the application is active. My proposal of using `subscribe` implied using the `Consumer` (therefore the "replacement"). ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1283#discussion_r1512390742