@@ -319,30 +319,33 @@ public static void setCaptionWhen(Field<?> sourceField, Field<?> targetField, Ob
319319 }
320320 }
321321
322+ @ SuppressWarnings ("rawtypes" )
322323 public static Registration setVisibleWhen (
323324 final FieldGroup fieldGroup ,
324325 List <String > targetPropertyIds ,
325326 Map <?, ? extends List <?>> sourcePropertyIdsAndValues ,
326327 final boolean clearOnHidden ) {
327328
328- onValueChangedSetVisible (fieldGroup , targetPropertyIds , sourcePropertyIdsAndValues , clearOnHidden );
329+ // Resolve target fields eagerly so the listener holds direct references
330+ List <Field > targetFields =
331+ targetPropertyIds .stream ().map (id -> fieldGroup .getField (id )).filter (Objects ::nonNull ).collect (Collectors .toList ());
332+
333+ onValueChangedSetVisible (fieldGroup , targetFields , sourcePropertyIdsAndValues , clearOnHidden );
329334
330335 // Map from source property ID to the listener added to it (only for fields present in the fieldGroup)
331336 Map <Object , Property .ValueChangeListener > listenerMap = new HashMap <>();
332337 sourcePropertyIdsAndValues .forEach ((sourcePropertyId , sourceValues ) -> {
333- @ SuppressWarnings ("rawtypes" )
334338 Field sourceField = fieldGroup .getField (sourcePropertyId );
335339 if (sourceField == null ) {
336340 return ; // source field not yet bound — skip listener registration
337341 }
338342 Property .ValueChangeListener listener =
339- event -> onValueChangedSetVisible (fieldGroup , targetPropertyIds , sourcePropertyIdsAndValues , clearOnHidden );
343+ event -> onValueChangedSetVisible (fieldGroup , targetFields , sourcePropertyIdsAndValues , clearOnHidden );
340344 sourceField .addValueChangeListener (listener );
341345 listenerMap .put (sourcePropertyId , listener );
342346 });
343347
344348 return () -> listenerMap .forEach ((sourcePropertyId , listener ) -> {
345- @ SuppressWarnings ("rawtypes" )
346349 Field sourceField = fieldGroup .getField (sourcePropertyId );
347350 if (sourceField != null ) {
348351 sourceField .removeValueChangeListener (listener );
@@ -367,30 +370,19 @@ public static void setVisibleWhen(final Field targetField, Map<Field, ? extends
367370 .addValueChangeListener (event -> onValueChangedSetVisible (targetField , sourceFieldsAndValues , clearOnHidden )));
368371 }
369372
373+ @ SuppressWarnings ("rawtypes" )
370374 private static void onValueChangedSetVisible (
371375 final FieldGroup fieldGroup ,
372- List <String > targetPropertyIds ,
376+ List <Field > targetFields ,
373377 Map <?, ? extends List <?>> sourcePropertyIdsAndValues ,
374378 final boolean clearOnHidden ) {
375379
376- //a workaround variable to be modified in the forEach lambda
377- boolean [] visibleArray = {
378- true };
379-
380- sourcePropertyIdsAndValues .forEach ((sourcePropertyId , sourceValues ) -> {
381- @ SuppressWarnings ("rawtypes" )
382- Field sourceField = fieldGroup .getField (sourcePropertyId );
383- if (sourceField == null || !sourceValues .contains (sourceField .getValue ()))
384- visibleArray [0 ] = false ;
380+ boolean visible = sourcePropertyIdsAndValues .entrySet ().stream ().allMatch (entry -> {
381+ Field sourceField = fieldGroup .getField (entry .getKey ());
382+ return sourceField != null && entry .getValue ().contains (sourceField .getValue ());
385383 });
386384
387- boolean visible = visibleArray [0 ];
388-
389- for (Object targetPropertyId : targetPropertyIds ) {
390- @ SuppressWarnings ("rawtypes" )
391- Field targetField = fieldGroup .getField (targetPropertyId );
392- if (targetField == null )
393- continue ; // defensive: field may have been unbound by a caller that did not remove its Registration
385+ for (Field targetField : targetFields ) {
394386 targetField .setVisible (visible );
395387 if (!visible && clearOnHidden && targetField .getValue () != null ) {
396388 targetField .clear ();
0 commit comments