=== modified file 'src/com/goldencode/p2j/ui/ComboBoxWidget.java'
--- old/src/com/goldencode/p2j/ui/ComboBoxWidget.java	2022-01-24 12:13:02 +0000
+++ new/src/com/goldencode/p2j/ui/ComboBoxWidget.java	2022-02-04 17:24:34 +0000
@@ -90,6 +90,7 @@
 **                           if the SCREEN-VALUE is still unknown. 
 **     AL2 20220122          Allow set of unknown value to simple and drop-down modes.
 **         20220124          Moved screen-value validity check in ControlSetEntity.
+**         20220204          Extend screen-value validation to update the value same as in 4GL.
 */ 
 /*
 ** This program is free software: you can redistribute it and/or modify
@@ -1323,26 +1324,6 @@
    }
    
    /**
-    * Set the current value in the screen buffer of the backing data for
-    * this widget.  If the given value is <code>null</code> then this
-    * widget will be set to the uninitialized value.
-    *
-    * @param    value
-    *           The new value for the widget, use <code>null</code> to set
-    *           the value as uninitialized.
-    */
-   @Override
-   protected void setScreenValueInt(character value)
-   {
-      if (!internalScreenValueUsage && !value.isUnknown() && value.getValue().isEmpty())
-      {
-         value = new character();
-      }
-      
-      super.setScreenValueInt(value);
-   }
-   
-   /**
     * Store array of items into config.
     * 
     * @param    items
@@ -1579,31 +1560,12 @@
    @Override
    boolean setScreenValue(ScreenBuffer frameBuf, Object value, boolean inUIStmt)
    {
-      if (!internalScreenValueUsage || inUIStmt)
+      if (!(value instanceof character))
       {
-         // it is valid to assign unknown value (?) only to character drop-down and simple combo-box
-         // for default and drop-down-list combo-box, the old screen-value should be kept
-         if (value == null ||
-            (value instanceof BaseDataType   && 
-            !(value instanceof character)    && 
-            ((BaseDataType) value).isUnknown()))
-         {
-            return false;
-         }
-         
-         boolean pairs = (config.pairs != null && config.pairs);
-         if ((!pairs || !getScreenValue().isUnknown())      && 
-             (value instanceof character)                   && 
-             (!((character) value).isUnknown())             &&
-             ((character) value).toJavaType().length() == 0)
-         {
-            // in pair mode an empty string is not allowed if the SCREEN-VALUE is already assigned to  
-            // something else, even if an empty string exists 
-            // in non-pair mode, an empty string is never allowed.
-            return false;
-         }
+         // we can't set non-character value to selection list
+         return false;
       }
-      
+
       return super.setScreenValue(frameBuf, value, inUIStmt);
    }
 
@@ -1619,10 +1581,10 @@
    protected boolean isValidScreenValue(character value)
    {
       ComboBoxConfig.Mode mode = getAttr("mode", () -> config.mode);
-      if (mode == SIMPLE || mode == DROP_DOWN)
+      if (mode == SIMPLE || mode == DROP_DOWN || value.isUnknown() || TextOps.isEmpty(value))
       {
-         // unknown is a valid screen value for a SIMPLE or DROP-DOWN combo-box widget
-         // the screen value to be set shouldn't be part of the item list
+         // for a SIMPLE or DROP-DOWN combo-box widget anything works
+         // unknown or empty string (or only spaces) clear selection for LIST
          return true;
       }
 
@@ -1694,4 +1656,52 @@
          setScreenValueInt(new character(" "));
       }
    }
+   
+   /**
+    * Validate the value(s) for SCREEN-VALUE attribute. If valid the passed in
+    * value will be updated to reflect the resulting value.
+    * 
+    * - empty string will set the value to unknown, unless a valid item value.
+    * - for unknown the result can be empty string if a valid item value.
+    * - first item found that match the value is used (case insensitive)
+    * 
+    * @param value
+    *        The to be validated as SCREEN-VALUE attribute.
+    * 
+    * @return <code>true</code> if the value is a valid screen-value.
+    */
+   @Override
+   boolean validateScreenValue(character value)
+   {
+      if (super.validateScreenValue(value))
+      {
+         // if valid update the screen-value 
+         if (value.isUnknown())
+         {
+            // looks like when unknown it tries to find an empty item first
+            value.assign("");
+         }
+         
+         ControlSetItem[] items = getAttr("items", () -> config.items);
+         
+         for (ControlSetItem item : items)
+         {
+            // item found, update value if different case
+            if (CompareOps._isEqual(value, item.getCharacterValue()))
+            {
+               value.assign(item.getCharacterValue());
+               return true;
+            }
+         }
+         
+         // if value is empty and no matching item found reset to unknown
+         if (TextOps.isEmpty(value))
+         {
+            value.setUnknown();
+         }
+         
+         return true;
+      }
+      return false;
+   }
 }

=== modified file 'src/com/goldencode/p2j/ui/ControlSetEntity.java'
--- old/src/com/goldencode/p2j/ui/ControlSetEntity.java	2022-02-03 09:10:33 +0000
+++ new/src/com/goldencode/p2j/ui/ControlSetEntity.java	2022-02-04 17:19:39 +0000
@@ -2857,9 +2857,16 @@
    {
       if (inUIStmt || !internalScreenValueUsage)
       {
-         if (value instanceof character && !validateScreenValue((character) value))
+         if (value instanceof character)
          {
-            return false;
+            character val = new character((character) value);
+            
+            if (!validateScreenValue((character) val))
+            {
+               return false;
+            }
+            // the value might have been updated by validation
+            return super.setScreenValue(frameBuf, val, inUIStmt);
          }
       }
       
@@ -2867,10 +2874,11 @@
    }
    
    /**
-    * Validate the value(s) for SCREEN-VALUE attribute.
+    * Validate the value(s) for SCREEN-VALUE attribute. The value passed as
+    * input might be updated by specific widget validation.
     * 
     * @param value
-    * The to be validated as SCREEN-VALUE attribute.
+    *        The to be validated as SCREEN-VALUE attribute.
     * 
     * @return <code>true</code> if the value is a valid screen-value.
     */

=== modified file 'src/com/goldencode/p2j/ui/RadioSetWidget.java'
--- old/src/com/goldencode/p2j/ui/RadioSetWidget.java	2022-01-15 22:16:32 +0000
+++ new/src/com/goldencode/p2j/ui/RadioSetWidget.java	2022-02-04 17:32:08 +0000
@@ -61,6 +61,7 @@
 **     EVL 20210309          Fixed set screen value for several conditions when screen buffer is not updating.
 **     VVT 20220115          System-wide warningAlreadyRealized() method is now used to handle attempts to
 **                           set attribute of a realized widget. See also #5937-32.
+**     ME  20220204          Reuse/extend the screen-value validation from base class.
 */ 
 /*
 ** This program is free software: you can redistribute it and/or modify
@@ -1323,65 +1324,54 @@
       
       return super.getScreenValue(initialized, bdt, fmt, ignoreFormat);
    }
+
+   /**
+    * Check if the tested value is in the control-set values.
+    * Unknown is not valid, empty string is ignored if not a valid value.
+    *
+    * @param    value
+    *           The tested value
+    *
+    * @return   True if the tested value is in the control-set values, otherwise false.
+    */
+   @Override
+   protected boolean isValidScreenValue(character value)
+   {
+      return !value.isUnknown() && (TextOps.isEmpty(value) || super.isValidScreenValue(value));
+   }
    
    /**
-    * Internal worker for setting the SCREEN-VALUE on a per-widget basis.
-    * 
-    * @param   frameBuf
-    *          The frame buffer where to save the value.
-    * @param   value
-    *          The value to be set via SCREEN-VALUE attribute.
-    * @param   inUIStmt
-    *          Flag indicating this call originates from a UI statement.
-    *          
-    * @return  <code>true</code> if the caller can proceed, as the screen-value can be set.
+    * Validate the value(s) for SCREEN-VALUE attribute. If valid the passed in
+    * value will be updated to reflect the resulting value.
+    * 
+    * - empty string will set the value to unknown, unless a valid item value.
+    * - for unknown the result can be empty string if a valid item value.
+    * 
+    * @param value
+    *        The to be validated as SCREEN-VALUE attribute.
+    * 
+    * @return <code>true</code> if the value is a valid screen-value.
     */
    @Override
-   boolean setScreenValue(ScreenBuffer frameBuf, Object value, boolean inUIStmt)
+   boolean validateScreenValue(character value)
    {
-      if (frameBuf.getWidgetValue(getId()) != null)
-      {
-         if (value instanceof character && "".equals(((character) value).toJavaType()))
-         {
-            return false;
-         }
-      }
-      
-      if (value instanceof BaseDataType && !isValidScreenValue(character.valueOf((BaseDataType) value)))
-      {
-         // show warning if it is from "set screen-value" statements but not from UI statements
-         if (!inUIStmt)
-         {
-            ErrorManager.recordOrShowError(4058, String.format(
-                     "Attribute SCREEN-VALUE for the %s %s has an invalid value of %s", type(),
-                     widgetName(), ((BaseDataType) value).isUnknown() ? "UNKNOWN" : value), false);
-         }
+      if (super.validateScreenValue(value))
+      {
+         ControlSetItem[] items = getAttr("items", () -> config.items);
          
-         return false;
-      }
-      
-      return super.setScreenValue(frameBuf, value, inUIStmt);
-   }
-
-   /**
-    * Set the current value in the screen buffer of the backing data for this widget. If the given
-    * value is <code>null</code> then this widget will be set to the uninitialized value.
-    *
-    * @param    value
-    *           The new value for the widget, use <code>null</code> to set the value as uninitialized.
-    */
-   @Override
-   protected void setScreenValueInt(character value)
-   {
-      if (value != null && "".equals(value.toStringMessage()))
-      {
-         // return silently
-         return;
-      }
-      
-      super.setScreenValueInt(value);
-   }
-
+         for (ControlSetItem item : items)
+         {
+            // item found, update value if different case
+            if (CompareOps._isEqual(value, item.getCharacterValue()))
+            {
+               value.assign(item.getCharacterValue());
+               return true;
+            }
+         }
+      }
+      return false;
+   }
+   
    /**
     * Report missing argument for replace().
     * 

=== modified file 'src/com/goldencode/p2j/ui/client/RadioSet.java'
--- old/src/com/goldencode/p2j/ui/client/RadioSet.java	2021-12-13 15:16:40 +0000
+++ new/src/com/goldencode/p2j/ui/client/RadioSet.java	2022-02-04 11:51:48 +0000
@@ -143,6 +143,7 @@
 **     EVL 20210309          Adding saving the currently selected button index.
 **     CA  20210803          If WINDOW:KEEP-FRAME-Z-ORDER is set, a DISPLAY can 'move-to-top' certain widgets.
 **     AL2 20211213          Set the current node when refreshing items list (only when not ChUI).
+**     ME  20220104          When setting screen-value select first item that match.
 */
 
 /*
@@ -403,8 +404,12 @@
          character btnValue = new character(button.getValue());
          character charValue = new character(value);
          
+         // first entry that matches (case insensitive)
          if (btnValue.equals(charValue))
+         {
             selectButton(button);
+            return;
+         }
       }
    }
 

=== modified file 'src/com/goldencode/p2j/ui/client/gui/ComboBoxGuiImpl.java'
--- old/src/com/goldencode/p2j/ui/client/gui/ComboBoxGuiImpl.java	2022-01-26 23:00:18 +0000
+++ new/src/com/goldencode/p2j/ui/client/gui/ComboBoxGuiImpl.java	2022-02-04 06:44:33 +0000
@@ -93,6 +93,7 @@
 **     CA  20210805 The entry-field for a combo-box must always be 'on top' of the combo-box.
 **     CA  20210818 Fixed setHidden, setVisible, moveToTop and moveToBottom for SIMPLE and DROP-DOWN mode. 
 **     VVT 20220126 Updated after methods 'index' and 'select(int)' were renamed in DefaultList. See #5937.
+**     ME  20220204 Unknown screen-value is shown as empty string instead of question mark.
 */
 
 /*
@@ -982,7 +983,15 @@
 
          if (entryField != null)
          {
-            entryField.setValue(listValue ? new character(model().selected()) : value);
+            if (listValue)
+            {
+               entryField.setValue(new character(model().selected()));
+            }
+            else 
+            {
+               // unknown is shown as empty string instead of question mark
+               entryField.setValue(value.isUnknown() ? new character("") : value);
+            }
          }
       }
    }

