Bug 427546 - SmartField Menu Button (Arrow) is enabled initialy also whitout any Menus defined

https://bugs.eclipse.org/bugs/show_bug.cgi?id=427546

Add property change listener on actions.
Enable handle drop down when enabling scout field.

Change-Id: I3f1645734d17f989a11de295aa730f512947cf0e
Reviewed-on: https://git.eclipse.org/r/23206
Tested-by: Hudson CI
Reviewed-by: Matthias Villiger <mvi@bsiag.com>
Reviewed-by: Ken Lee <kle@bsiag.com>
IP-Clean: Ken Lee <kle@bsiag.com>
diff --git a/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtilityTest.java b/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtilityTest.java
index b3177c7..79ff68b 100644
--- a/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtilityTest.java
+++ b/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtilityTest.java
@@ -10,9 +10,13 @@
  ******************************************************************************/
 package org.eclipse.scout.rt.client.ui.action.menu;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
 import org.easymock.EasyMock;
 import org.eclipse.scout.rt.client.ui.action.keystroke.IKeyStroke;
-import org.junit.Assert;
+import org.eclipse.scout.rt.client.ui.form.fields.IValueField;
+import org.eclipse.scout.rt.client.ui.form.fields.button.IButton;
 import org.junit.Test;
 
 /**
@@ -28,19 +32,156 @@
     EasyMock.replay(menu);
     IMenu[] menus = new IMenu[]{menu};
     IKeyStroke[] keyStrokes = MenuUtility.getKeyStrokesFromMenus(menus);
-    Assert.assertEquals("should return 1 menu", keyStrokes.length, 1);
-    Assert.assertEquals("keyStroke should be f11", keyStrokes[0].getKeyStroke(), "f1");
+    assertEquals("should return 1 menu", keyStrokes.length, 1);
+    assertEquals("keyStroke should be f11", keyStrokes[0].getKeyStroke(), "f1");
 
     keyStrokes = MenuUtility.getKeyStrokesFromMenus(null);
-    Assert.assertNotNull(keyStrokes);
-    Assert.assertEquals("null Paramter should return empty array", keyStrokes.length, 0);
+    assertNotNull(keyStrokes);
+    assertEquals("null Parameter should return empty array", keyStrokes.length, 0);
 
     menu = EasyMock.createNiceMock(IMenu.class);
     EasyMock.expect(menu.getKeyStroke()).andReturn(" "); //invalid keyStroke definition
     EasyMock.replay(menu);
     menus = new IMenu[]{menu};
     keyStrokes = MenuUtility.getKeyStrokesFromMenus(menus);
-    Assert.assertNotNull(keyStrokes);
-    Assert.assertEquals("KeyStrokes should be empty, since ' ' is an invalid keyStroke", keyStrokes.length, 0);
+    assertNotNull(keyStrokes);
+    assertEquals("KeyStrokes should be empty, since ' ' is an invalid keyStroke", keyStrokes.length, 0);
   }
+
+  @Test
+  public void testFilterValidMenusValueFieldDisabled() {
+    @SuppressWarnings("unchecked")
+    IValueField<String> valueField = (IValueField<String>) EasyMock.createMock(IValueField.class);
+    EasyMock.expect(valueField.getValue()).andReturn("testValue");
+    EasyMock.expect(valueField.isEnabled()).andReturn(false);
+
+    IMenu menu = EasyMock.createMock(IMenu.class);
+    EasyMock.expect(menu.isInheritAccessibility()).andReturn(true);
+    EasyMock.replay(valueField, menu);
+
+    IMenu[] menus = new IMenu[]{menu};
+    IMenu[] filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false);
+
+    assertNotNull(filteredMenus);
+    assertEquals(0, filteredMenus.length);
+  }
+
+  @Test
+  public void testFilterValidMenusInheritAccessibilityAndSingleSelectionMenu() {
+    @SuppressWarnings("unchecked")
+    IValueField<String> valueField = (IValueField<String>) EasyMock.createMock(IValueField.class);
+    EasyMock.expect(valueField.getValue()).andReturn("testValue").times(1);
+    EasyMock.expect(valueField.getValue()).andReturn(null).times(1);
+    EasyMock.expect(valueField.isEnabled()).andReturn(false).anyTimes();
+
+    IMenu menu = EasyMock.createMock(IMenu.class);
+    EasyMock.expect(menu.isInheritAccessibility()).andReturn(false).anyTimes();
+    EasyMock.expect(menu.isEmptySpaceAction()).andReturn(false).anyTimes();
+    EasyMock.expect(menu.isSingleSelectionAction()).andReturn(true).anyTimes();
+    EasyMock.expect(menu.isVisible()).andReturn(true).anyTimes();
+    EasyMock.replay(valueField, menu);
+
+    IMenu[] menus = new IMenu[]{menu};
+    IMenu[] filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false);
+    assertNotNull(filteredMenus);
+    assertEquals(1, filteredMenus.length);
+    assertEquals(menu, filteredMenus[0]);
+
+    filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false); // value of field is null
+    assertNotNull(filteredMenus);
+    assertEquals(0, filteredMenus.length);
+  }
+
+  @Test
+  public void testFilterValidMenusEmptySpaceActionMenu() {
+    @SuppressWarnings("unchecked")
+    IValueField<String> valueField = (IValueField<String>) EasyMock.createMock(IValueField.class);
+    EasyMock.expect(valueField.getValue()).andReturn("testValue").anyTimes();
+    EasyMock.expect(valueField.isEnabled()).andReturn(true).anyTimes();
+
+    IMenu menuWithEmptySpaceAction = EasyMock.createMock(IMenu.class);
+    EasyMock.expect(menuWithEmptySpaceAction.isInheritAccessibility()).andReturn(false).anyTimes();
+    EasyMock.expect(menuWithEmptySpaceAction.isEmptySpaceAction()).andReturn(true).anyTimes();
+    EasyMock.expect(menuWithEmptySpaceAction.isVisible()).andReturn(true).times(1);
+    EasyMock.expect(menuWithEmptySpaceAction.isVisible()).andReturn(false).times(2);
+    EasyMock.replay(valueField, menuWithEmptySpaceAction);
+
+    IMenu[] menus = new IMenu[]{menuWithEmptySpaceAction};
+    IMenu[] filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false);
+    assertNotNull(filteredMenus);
+    assertEquals(1, filteredMenus.length);
+    assertEquals(menuWithEmptySpaceAction, filteredMenus[0]);
+
+    filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false);
+    assertNotNull(filteredMenus);
+    assertEquals(0, filteredMenus.length);
+  }
+
+  @Test
+  public void testFilterValidMenusPrepareAction() {
+    @SuppressWarnings("unchecked")
+    IValueField<String> valueField = (IValueField<String>) EasyMock.createMock(IValueField.class);
+    EasyMock.expect(valueField.getValue()).andReturn("testValue").anyTimes();
+    EasyMock.expect(valueField.isEnabled()).andReturn(true).anyTimes();
+
+    final IMenu menuWithEmptySpaceAction = EasyMock.createMock(IMenu.class);
+    EasyMock.expect(menuWithEmptySpaceAction.isInheritAccessibility()).andReturn(false).anyTimes();
+    EasyMock.expect(menuWithEmptySpaceAction.isEmptySpaceAction()).andReturn(true).anyTimes();
+    EasyMock.expect(menuWithEmptySpaceAction.isVisible()).andReturn(true).anyTimes();
+
+    menuWithEmptySpaceAction.prepareAction();
+    EasyMock.expectLastCall().once();
+    EasyMock.replay(valueField, menuWithEmptySpaceAction);
+
+    IMenu[] menus = new IMenu[]{menuWithEmptySpaceAction};
+    IMenu[] filteredMenus = MenuUtility.filterValidMenus(valueField, menus, true);
+    assertNotNull(filteredMenus);
+    assertEquals(1, filteredMenus.length);
+    assertEquals(menuWithEmptySpaceAction, filteredMenus[0]);
+    EasyMock.verify(menuWithEmptySpaceAction);
+
+    filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false);
+    EasyMock.verify(menuWithEmptySpaceAction);
+  }
+
+  @Test
+  public void testFilterValidMenusOnButton() {
+    IButton button = EasyMock.createMock(IButton.class);
+    final IMenu menu = EasyMock.createMock(IMenu.class);
+    EasyMock.expect(menu.isVisible()).andReturn(true).times(1);
+    EasyMock.expect(menu.isVisible()).andReturn(false).times(1);
+    EasyMock.replay(button, menu);
+
+    IMenu[] menus = new IMenu[]{menu};
+    IMenu[] filteredMenus = MenuUtility.filterValidMenusOnButton(button, menus, false);
+    assertNotNull(filteredMenus);
+    assertEquals(1, filteredMenus.length);
+    assertEquals(menu, filteredMenus[0]);
+
+    filteredMenus = MenuUtility.filterValidMenusOnButton(button, menus, false);
+    assertNotNull(filteredMenus);
+    assertEquals(0, filteredMenus.length);
+  }
+
+  @Test
+  public void testFilterValidMenusOnButtonPrepareAction() {
+    IButton button = EasyMock.createMock(IButton.class);
+    final IMenu menu = EasyMock.createMock(IMenu.class);
+    EasyMock.expect(menu.isVisible()).andReturn(true).anyTimes();
+
+    menu.prepareAction();
+    EasyMock.expectLastCall().once();
+    EasyMock.replay(button, menu);
+
+    IMenu[] menus = new IMenu[]{menu};
+    IMenu[] filteredMenus = MenuUtility.filterValidMenusOnButton(button, menus, true);
+    assertNotNull(filteredMenus);
+    assertEquals(1, filteredMenus.length);
+    assertEquals(menu, filteredMenus[0]);
+    EasyMock.verify(menu);
+
+    filteredMenus = MenuUtility.filterValidMenusOnButton(button, menus, false);
+    EasyMock.verify(menu);
+  }
+
 }
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/AbstractAction.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/AbstractAction.java
index e7fe8f0..6065e42 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/AbstractAction.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/AbstractAction.java
@@ -35,16 +35,13 @@
   private boolean m_initialized;
   private final EventListenerList m_listenerList = new EventListenerList();
   private final IActionUIFacade m_uiFacade;
-  private boolean m_inheritAccessibility;
   // enabled is defined as: enabledGranted && enabledProperty && enabledProcessing
   private boolean m_enabledGranted;
   private boolean m_enabledProperty;
   private boolean m_enabledProcessingAction;
   private boolean m_visibleProperty;
   private boolean m_visibleGranted;
-  private boolean m_singleSelectionAction;
   private boolean m_multiSelectionAction;
-  private boolean m_emptySpaceAction;
   private boolean m_toggleAction;
 
   public AbstractAction() {
@@ -459,12 +456,12 @@
 
   @Override
   public boolean isInheritAccessibility() {
-    return m_inheritAccessibility;
+    return propertySupport.getPropertyBool(PROP_INHERIT_ACCESSIBILITY);
   }
 
   @Override
   public void setInheritAccessibility(boolean b) {
-    m_inheritAccessibility = b;
+    propertySupport.setPropertyBool(PROP_INHERIT_ACCESSIBILITY, b);
   }
 
   /**
@@ -552,12 +549,12 @@
 
   @Override
   public boolean isSingleSelectionAction() {
-    return m_singleSelectionAction;
+    return propertySupport.getPropertyBool(PROP_SINGLE_SELECTION);
   }
 
   @Override
   public void setSingleSelectionAction(boolean b) {
-    m_singleSelectionAction = b;
+    propertySupport.setProperty(PROP_SINGLE_SELECTION, b);
   }
 
   @Override
@@ -572,12 +569,12 @@
 
   @Override
   public boolean isEmptySpaceAction() {
-    return m_emptySpaceAction;
+    return propertySupport.getPropertyBool(PROP_EMPTY_SPACE);
   }
 
   @Override
   public void setEmptySpaceAction(boolean b) {
-    m_emptySpaceAction = b;
+    propertySupport.setProperty(PROP_EMPTY_SPACE, b);
   }
 
   @Override
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/IAction.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/IAction.java
index c84ac15..263d61d 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/IAction.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/IAction.java
@@ -41,6 +41,9 @@
    * property-type: String
    */
   String PROP_SEPARATOR = "separator";
+  String PROP_INHERIT_ACCESSIBILITY = "inheritAccessibility";
+  String PROP_EMPTY_SPACE = "emptySpace";
+  String PROP_SINGLE_SELECTION = "singleSelection";
 
   /**
    * called to perform action
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtility.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtility.java
index 4762624..c91024f 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtility.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtility.java
@@ -10,10 +10,13 @@
  ******************************************************************************/
 package org.eclipse.scout.rt.client.ui.action.menu;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 
 import org.eclipse.scout.rt.client.ui.action.keystroke.IKeyStroke;
 import org.eclipse.scout.rt.client.ui.action.keystroke.KeyStroke;
+import org.eclipse.scout.rt.client.ui.form.fields.IValueField;
+import org.eclipse.scout.rt.client.ui.form.fields.button.IButton;
 
 /**
  * Utility class for menus
@@ -39,4 +42,65 @@
     }
     return ksMap.values().toArray(new IKeyStroke[ksMap.size()]);
   }
+
+  /**
+   * Filters a given array of menus belonging to a specific value field by returning an array containing only valid
+   * menus.
+   * A menu is considered to be valid if at least the value field is enabled or if the menu does not inherit its
+   * accessibility.
+   * Additionally, the menu has either to be
+   * <ul>
+   * <li>an empty space action and visible menu or</li>
+   * <li>a single selection action and visible menu and the value field contains a non-null value</li>
+   * </ul>
+   * The method prepareAction of a valid menu is executed if the parameter executePrepareAction is <code>true</code>
+   * 
+   * @since 4.0.0-M6
+   */
+  public static <T> IMenu[] filterValidMenus(IValueField<T> valueField, IMenu[] menusToFilter, boolean executePrepareAction) {
+    T value = valueField.getValue();
+    ArrayList<IMenu> filteredMenus = new ArrayList<IMenu>();
+    for (IMenu m : menusToFilter) {
+      IMenu validMenu = null;
+      if ((!m.isInheritAccessibility()) || valueField.isEnabled()) {
+        if (m.isEmptySpaceAction()) {
+          validMenu = m;
+        }
+        else if (m.isSingleSelectionAction()) {
+          if (value != null) {
+            validMenu = m;
+          }
+        }
+      }
+      if (validMenu != null) {
+        if (executePrepareAction) {
+          validMenu.prepareAction();
+        }
+        if (validMenu.isVisible()) {
+          filteredMenus.add(validMenu);
+        }
+      }
+    }
+    return filteredMenus.toArray(new IMenu[0]);
+  }
+
+  /**
+   * Filters a given array of menus belonging to a button by returning an array containing only valid
+   * menus. A menu is considered to be valid if the menu is visible.
+   * The method prepareAction of a valid menu is executed if the parameter executePrepareAction is <code>true</code>
+   * 
+   * @since 4.0.0-M6
+   */
+  public static IMenu[] filterValidMenusOnButton(IButton button, IMenu[] menusToFilter, boolean executePrepareAction) {
+    ArrayList<IMenu> filteredMenus = new ArrayList<IMenu>();
+    for (IMenu menu : menusToFilter) {
+      if (executePrepareAction) {
+        menu.prepareAction();
+      }
+      if (menu.isVisible()) {
+        filteredMenus.add(menu);
+      }
+    }
+    return filteredMenus.toArray(new IMenu[0]);
+  }
 }
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/AbstractButton.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/AbstractButton.java
index 8605ece..03e6bc8 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/AbstractButton.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/AbstractButton.java
@@ -413,14 +413,8 @@
   private IMenu[] fireButtonPopup() {
     ButtonEvent e = new ButtonEvent(this, ButtonEvent.TYPE_POPUP);
     // single observer add our menus
-    IMenu[] a = getMenus();
-    for (int i = 0; i < a.length; i++) {
-      IMenu m = a[i];
-      m.prepareAction();
-      if (m.isVisible()) {
-        e.addPopupMenu(m);
-      }
-    }
+    IMenu[] menus = MenuUtility.filterValidMenusOnButton(this, getMenus(), true);
+    e.addPopupMenus(menus);
     fireButtonEvent(e);
     return e.getPopupMenus();
   }
@@ -457,6 +451,16 @@
     }
 
     /**
+     * {@inheritDoc} Uses {@link MenuUtility#filterValidMenus} to check if there are valid menus. Does not execute the
+     * method <code>prepareAction</code> on the menu objects.
+     */
+    @Override
+    public boolean hasValidMenusFromUI() {
+      IMenu[] menus = MenuUtility.filterValidMenusOnButton(AbstractButton.this, getMenus(), false);
+      return menus.length > 0;
+    }
+
+    /**
      * Toggle and Radio Buttons
      */
     @Override
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/IButtonUIFacade.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/IButtonUIFacade.java
index 20c4633..70a408e 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/IButtonUIFacade.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/IButtonUIFacade.java
@@ -4,7 +4,7 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * 
+ *
  * Contributors:
  *     BSI Business Systems Integration AG - initial API and implementation
  ******************************************************************************/
@@ -27,6 +27,14 @@
 
   IMenu[] fireButtonPopupFromUI();
 
+  /**
+   * Called from the UI to check whether there are valid menus defined in the model.
+   * 
+   * @return <code>true</code> if there is at least one valid menu. Otherwise, <code>false</code>.
+   * @since 4.0.0-M6
+   */
+  boolean hasValidMenusFromUI();
+
   void setSelectedFromUI(boolean b);
 
 }
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/AbstractFileChooserField.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/AbstractFileChooserField.java
index 8176707..8921ad7 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/AbstractFileChooserField.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/AbstractFileChooserField.java
@@ -476,16 +476,23 @@
 
   private class P_UIFacade implements IFileChooserFieldUIFacade {
 
+    /**
+     * Uses {@link MenuUtility#filterValidMenus} to filter the given menus for valid menus.
+     * The method <code>prepareAction</code> on the menu objects are executed.
+     */
     @Override
     public IMenu[] firePopupFromUI() {
-      ArrayList<IMenu> menus = new ArrayList<IMenu>();
-      for (IMenu menu : getMenus()) {
-        menu.prepareAction();
-        if (menu.isVisible()) {
-          menus.add(menu);
-        }
-      }
-      return menus.toArray(new IMenu[0]);
+      return MenuUtility.filterValidMenus(AbstractFileChooserField.this, getMenus(), true);
+    }
+
+    /**
+     * {@inheritDoc} Uses {@link MenuUtility#filterValidMenus} to check if there are valid menus. Does not execute the
+     * method <code>prepareAction</code> on the menu objects.
+     */
+    @Override
+    public boolean hasValidMenusFromUI() {
+      IMenu[] validMenus = MenuUtility.filterValidMenus(AbstractFileChooserField.this, getMenus(), false);
+      return validMenus.length > 0;
     }
 
     @Override
@@ -496,5 +503,4 @@
       return parseValue(newText);
     }
   }
-
 }
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/IFileChooserFieldUIFacade.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/IFileChooserFieldUIFacade.java
index 9834513..0a6425a 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/IFileChooserFieldUIFacade.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/IFileChooserFieldUIFacade.java
@@ -4,7 +4,7 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * 
+ *
  * Contributors:
  *     BSI Business Systems Integration AG - initial API and implementation
  ******************************************************************************/
@@ -16,6 +16,14 @@
 
   IMenu[] firePopupFromUI();
 
+  /**
+   * Called from the UI to check whether there are valid menus defined in the model.
+   * 
+   * @return <code>true</code> if there is at least one valid menu. Otherwise, <code>false</code>.
+   * @since 4.0.0-M6
+   */
+  boolean hasValidMenusFromUI();
+
   boolean setTextFromUI(String newText);
 
 }
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/AbstractSmartField.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/AbstractSmartField.java
index 3f2cfca..b34df8b 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/AbstractSmartField.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/AbstractSmartField.java
@@ -1489,31 +1489,23 @@
   private class P_UIFacade implements ISmartFieldUIFacade {
     private Map<ICell, LookupRow> m_validProposals;
 
+    /**
+     * Uses {@link MenuUtility#filterValidMenus} to filter the given menus for valid menus.
+     * The method <code>prepareAction</code> on the menu objects are executed.
+     */
     @Override
     public IMenu[] firePopupFromUI() {
-      T smartValue = getValue();
-      ArrayList<IMenu> filteredMenus = new ArrayList<IMenu>();
-      for (IMenu m : getMenus()) {
-        IMenu validMenu = null;
-        if ((!m.isInheritAccessibility()) || isEnabled()) {
-          if (m.isEmptySpaceAction()) {
-            validMenu = m;
-          }
-          else if (m.isSingleSelectionAction()) {
-            if (smartValue != null) {
-              validMenu = m;
-            }
-          }
-        }
-        //
-        if (validMenu != null) {
-          validMenu.prepareAction();
-          if (validMenu.isVisible()) {
-            filteredMenus.add(validMenu);
-          }
-        }
-      }
-      return filteredMenus.toArray(new IMenu[0]);
+      return MenuUtility.filterValidMenus(AbstractSmartField.this, getMenus(), true);
+    }
+
+    /**
+     * {@inheritDoc} Uses {@link MenuUtility#filterValidMenus} to check if there are valid menus. Does not execute the
+     * method <code>prepareAction</code> on the menu objects.
+     */
+    @Override
+    public boolean hasValidMenusFromUI() {
+      IMenu[] validMenus = MenuUtility.filterValidMenus(AbstractSmartField.this, getMenus(), false);
+      return validMenus.length > 0;
     }
 
     @Override
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/ISmartFieldUIFacade.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/ISmartFieldUIFacade.java
index e9f538a..7fd8583 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/ISmartFieldUIFacade.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/ISmartFieldUIFacade.java
@@ -27,4 +27,12 @@
   boolean setTextFromUI(String text);
 
   void unregisterProposalFormFromUI(ISmartFieldProposalForm form);
+
+  /**
+   * Called from the UI to check whether there are valid menus defined in the model.
+   * 
+   * @return <code>true</code> if there is at least one valid menu. Otherwise, <code>false</code>.
+   * @since 4.0.0-M6
+   */
+  boolean hasValidMenusFromUI();
 }
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/action/AbstractRwtScoutActionPropertyChangeListener.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/action/AbstractRwtScoutActionPropertyChangeListener.java
new file mode 100644
index 0000000..71f4ade
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/action/AbstractRwtScoutActionPropertyChangeListener.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2014 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.ui.rap.action;
+
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
+
+/**
+ * Property change listener that can be attached to particular Scout menus.
+ * 
+ * @since 4.0.0-M6
+ */
+public abstract class AbstractRwtScoutActionPropertyChangeListener implements PropertyChangeListener {
+
+  public void attachToScoutMenus(IMenu[] menus) {
+    for (IMenu menu : menus) {
+      menu.addPropertyChangeListener(this);
+    }
+  }
+
+  public void detachFromScoutMenus(IMenu[] menus) {
+    for (IMenu menu : menus) {
+      menu.removePropertyChangeListener(this);
+    }
+  }
+}
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/smartfield/RwtScoutSmartField.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/smartfield/RwtScoutSmartField.java
index fbe58ef..8d90edd 100644
--- a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/smartfield/RwtScoutSmartField.java
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/smartfield/RwtScoutSmartField.java
@@ -10,8 +10,10 @@
  *******************************************************************************/
 package org.eclipse.scout.rt.ui.rap.form.fields.smartfield;
 
+import java.beans.PropertyChangeEvent;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -23,6 +25,7 @@
 import org.eclipse.scout.commons.job.JobEx;
 import org.eclipse.scout.commons.logger.IScoutLogger;
 import org.eclipse.scout.commons.logger.ScoutLogManager;
+import org.eclipse.scout.rt.client.ui.action.IAction;
 import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
 import org.eclipse.scout.rt.client.ui.form.FormEvent;
 import org.eclipse.scout.rt.client.ui.form.FormListener;
@@ -31,6 +34,7 @@
 import org.eclipse.scout.rt.client.ui.form.fields.smartfield.ISmartFieldProposalForm;
 import org.eclipse.scout.rt.ui.rap.LogicalGridLayout;
 import org.eclipse.scout.rt.ui.rap.RwtMenuUtility;
+import org.eclipse.scout.rt.ui.rap.action.AbstractRwtScoutActionPropertyChangeListener;
 import org.eclipse.scout.rt.ui.rap.ext.IDropDownButtonForPatch;
 import org.eclipse.scout.rt.ui.rap.ext.MenuAdapterEx;
 import org.eclipse.scout.rt.ui.rap.ext.StatusLabelEx;
@@ -94,6 +98,7 @@
   private P_KeyListener m_shiftTabKeyListener;
   private Set<IPopupSupportListener> m_popupEventListeners;
   private Object m_popupEventListenerLock;
+  private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
 
   public RwtScoutSmartField() {
     m_pendingProposalJobLock = new Object();
@@ -190,21 +195,47 @@
   protected void attachScout() {
     super.attachScout();
     setIconIdFromScout(getScoutObject().getIconId());
-    getUiBrowseButton().setDropdownEnabled(getScoutObject().hasMenus());
+    getUiBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
     setProposalFormFromScout(getScoutObject().getProposalForm());
+    if (m_scoutActionPropertyListener == null) {
+      m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+    }
+    m_scoutActionPropertyListener.attachToScoutMenus(getScoutObject().getMenus());
+  }
+
+  private boolean calculateDropDownButtonEnabled() {
+    final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+    Runnable t = new Runnable() {
+      @Override
+      public void run() {
+        hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+      }
+    };
+    JobEx job = getUiEnvironment().invokeScoutLater(t, 1200);
+    try {
+      job.join(1200);
+    }
+    catch (InterruptedException ex) {
+      //nop
+    }
+    return hasValidMenus.get();
   }
 
   @Override
   protected void detachScout() {
     // workaround since disposeFieldInternal in AbstractSmartField is never called.
     hideProposalPopup();
+    if (m_scoutActionPropertyListener != null) {
+      m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+      m_scoutActionPropertyListener = null;
+    }
     super.detachScout();
   }
 
   @Override
   protected void setDisplayTextFromScout(String s) {
+    getUiBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
     if (!CompareUtility.equals(s, getUiField().getText())) {
-      getUiBrowseButton().setDropdownEnabled(getScoutObject().hasMenus());
       if (s == null) {
         s = "";
       }
@@ -219,6 +250,7 @@
     super.setEnabledFromScout(b);
     m_browseButton.setButtonEnabled(b);
     getUiField().setEnabled(b);
+    handleDropDownButtonEnabled();
     if (b) {
       m_smartContainer.setData(RWT.CUSTOM_VARIANT, getSmartfieldVariant());
     }
@@ -556,6 +588,17 @@
     }
   }
 
+  protected void handleScoutActionPropertyChange(String name, Object newValue) {
+    if (IAction.PROP_INHERIT_ACCESSIBILITY.equals(name) || IAction.PROP_EMPTY_SPACE.equals(name) ||
+        IAction.PROP_SINGLE_SELECTION.equals(name) || IAction.PROP_VISIBLE.equals(name)) {
+      handleDropDownButtonEnabled();
+    }
+  }
+
+  protected void handleDropDownButtonEnabled() {
+    getUiBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
+  }
+
   protected void handleTextModifiedFromUi(ModifyEvent event) {
     if (getUpdateUiFromScoutLock().isAcquired()) {
       return;
@@ -819,4 +862,28 @@
     }
 
   }
+
+  private class P_ScoutActionPropertyChangeListener extends AbstractRwtScoutActionPropertyChangeListener {
+    @Override
+    public void propertyChange(final PropertyChangeEvent e) {
+      if (getUiEnvironment().getDisplay() != null && !getUiEnvironment().getDisplay().isDisposed()) {
+        Runnable t = new Runnable() {
+          @Override
+          public void run() {
+            if (!isUiDisposed()) {
+              try {
+                getUpdateUiFromScoutLock().acquire();
+                //
+                handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+              }
+              finally {
+                getUpdateUiFromScoutLock().release();
+              }
+            }
+          }
+        };
+        getUiEnvironment().invokeUiLater(t);
+      }
+    }
+  } // end class P_ScoutActionPropertyChangeListener
 }
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/action/AbstractSwingScoutActionPropertyChangeListener.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/action/AbstractSwingScoutActionPropertyChangeListener.java
new file mode 100644
index 0000000..1e8e6d4
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/action/AbstractSwingScoutActionPropertyChangeListener.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2014 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.ui.swing.action;
+
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.scout.commons.WeakEventListener;
+import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
+
+/**
+ * Property change listener that can be attached to particular Scout menus.
+ * 
+ * @since 4.0.0-M6
+ */
+public abstract class AbstractSwingScoutActionPropertyChangeListener implements PropertyChangeListener, WeakEventListener {
+
+  public void attachToScoutMenus(IMenu[] menus) {
+    for (IMenu menu : menus) {
+      menu.addPropertyChangeListener(this);
+    }
+  }
+
+  public void detachFromScoutMenus(IMenu[] menus) {
+    for (IMenu menu : menus) {
+      menu.removePropertyChangeListener(this);
+    }
+  }
+}
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/button/SwingScoutButton.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/button/SwingScoutButton.java
index 6690722..8446286 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/button/SwingScoutButton.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/button/SwingScoutButton.java
@@ -17,6 +17,8 @@
 import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
+import java.beans.PropertyChangeEvent;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.swing.AbstractButton;
 import javax.swing.ImageIcon;
@@ -27,8 +29,10 @@
 
 import org.eclipse.scout.commons.StringUtility;
 import org.eclipse.scout.commons.WeakEventListener;
+import org.eclipse.scout.commons.job.JobEx;
 import org.eclipse.scout.commons.logger.IScoutLogger;
 import org.eclipse.scout.commons.logger.ScoutLogManager;
+import org.eclipse.scout.rt.client.ui.action.IAction;
 import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
 import org.eclipse.scout.rt.client.ui.form.fields.button.ButtonEvent;
 import org.eclipse.scout.rt.client.ui.form.fields.button.ButtonListener;
@@ -38,6 +42,7 @@
 import org.eclipse.scout.rt.ui.swing.SwingLayoutUtility;
 import org.eclipse.scout.rt.ui.swing.SwingPopupWorker;
 import org.eclipse.scout.rt.ui.swing.SwingUtility;
+import org.eclipse.scout.rt.ui.swing.action.AbstractSwingScoutActionPropertyChangeListener;
 import org.eclipse.scout.rt.ui.swing.basic.IconGroup;
 import org.eclipse.scout.rt.ui.swing.basic.IconGroup.IconState;
 import org.eclipse.scout.rt.ui.swing.ext.JButtonEx;
@@ -57,6 +62,8 @@
   private ButtonListener m_scoutButtonListener;
   //ticket 86811: avoid double-action in queue
   private boolean m_handleActionPending;
+  private JDropDownButton m_dropDownButton;
+  private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
 
   public SwingScoutButton() {
   }
@@ -99,15 +106,16 @@
     swingFieldAsButton.addActionListener(new P_SwingActionListener());
     // check if button has menus
     if (getScoutObject().hasMenus()) {
-      JDropDownButton dropDownButton = new JDropDownButton(swingFieldAsButton);
-      dropDownButton.getMenuButton().addActionListener(new ActionListener() {
+      m_dropDownButton = new JDropDownButton(swingFieldAsButton);
+      m_dropDownButton.getMenuButton().setEnabled(calculateDropDownButtonEnabled());
+      m_dropDownButton.getMenuButton().addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
           handleSwingPopup((Component) e.getSource());
         }
       });
       container = new JPanelEx();
-      container.add(dropDownButton);
+      container.add(m_dropDownButton);
     }
     else {
       container = new JPanelEx();
@@ -137,6 +145,24 @@
     container.setLayout(new LogicalGridLayout(getSwingEnvironment(), 0, 0));
   }
 
+  private boolean calculateDropDownButtonEnabled() {
+    final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+    Runnable t = new Runnable() {
+      @Override
+      public void run() {
+        hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+      }
+    };
+    JobEx job = getSwingEnvironment().invokeScoutLater(t, 1200);
+    try {
+      job.join(1200);
+    }
+    catch (InterruptedException ex) {
+      //nop
+    }
+    return hasValidMenus.get();
+  }
+
   @Override
   protected void detachScout() {
     super.detachScout();
@@ -144,6 +170,10 @@
       getScoutButton().removeButtonListener(m_scoutButtonListener);
       m_scoutButtonListener = null;
     }
+    if (m_scoutActionPropertyListener != null) {
+      m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+      m_scoutActionPropertyListener = null;
+    }
   }
 
   public IButton getScoutButton() {
@@ -155,6 +185,10 @@
     return (AbstractButton) getSwingField();
   }
 
+  protected JDropDownButton getDropDownButton() {
+    return m_dropDownButton;
+  }
+
   @Override
   protected void attachScout() {
     super.attachScout();
@@ -166,6 +200,12 @@
     setIconIdFromScout(b.getIconId());
     setImageFromScout(b.getImage());
     setSelectionFromScout(b.isSelected());
+    if (getDropDownButton() != null) {
+      if (m_scoutActionPropertyListener == null) {
+        m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+      }
+      m_scoutActionPropertyListener.attachToScoutMenus(getScoutObject().getMenus());
+    }
   }
 
   @Override
@@ -346,6 +386,18 @@
     // end notify
   }
 
+  protected void handleScoutActionPropertyChange(String name, Object newValue) {
+    if (IAction.PROP_VISIBLE.equals(name)) {
+      handleDropDownButtonEnabled();
+    }
+  }
+
+  protected void handleDropDownButtonEnabled() {
+    if (getDropDownButton() != null) {
+      getDropDownButton().getMenuButton().setEnabled(calculateDropDownButtonEnabled());
+    }
+  }
+
   /*
    * Listeners
    */
@@ -408,6 +460,25 @@
         }
       }
     }
-  }
+  } // end private class P_ScoutButtonListener
 
+  private class P_ScoutActionPropertyChangeListener extends AbstractSwingScoutActionPropertyChangeListener {
+    @Override
+    public void propertyChange(final PropertyChangeEvent e) {
+      Runnable t = new Runnable() {
+        @Override
+        public void run() {
+          try {
+            getUpdateSwingFromScoutLock().acquire();
+            //
+            handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+          }
+          finally {
+            getUpdateSwingFromScoutLock().release();
+          }
+        }
+      };
+      getSwingEnvironment().invokeSwingLater(t);
+    }
+  } // end private class P_ScoutActionPropertyChangeListener
 }
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/filechooserfield/SwingScoutFileChooserField.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/filechooserfield/SwingScoutFileChooserField.java
index 9bdf50d..acaf1be 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/filechooserfield/SwingScoutFileChooserField.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/filechooserfield/SwingScoutFileChooserField.java
@@ -12,7 +12,9 @@
 
 import java.awt.Point;
 import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeEvent;
 import java.io.File;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.swing.AbstractAction;
 import javax.swing.ActionMap;
@@ -27,12 +29,14 @@
 import org.eclipse.scout.commons.CompareUtility;
 import org.eclipse.scout.commons.holders.Holder;
 import org.eclipse.scout.commons.job.JobEx;
+import org.eclipse.scout.rt.client.ui.action.IAction;
 import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
 import org.eclipse.scout.rt.client.ui.basic.filechooser.IFileChooser;
 import org.eclipse.scout.rt.client.ui.form.fields.filechooserfield.IFileChooserField;
 import org.eclipse.scout.rt.ui.swing.LogicalGridLayout;
 import org.eclipse.scout.rt.ui.swing.SwingPopupWorker;
 import org.eclipse.scout.rt.ui.swing.SwingUtility;
+import org.eclipse.scout.rt.ui.swing.action.AbstractSwingScoutActionPropertyChangeListener;
 import org.eclipse.scout.rt.ui.swing.basic.IconGroup;
 import org.eclipse.scout.rt.ui.swing.ext.IDropDownButtonListener;
 import org.eclipse.scout.rt.ui.swing.ext.JPanelEx;
@@ -43,6 +47,8 @@
 public class SwingScoutFileChooserField extends SwingScoutValueFieldComposite<IFileChooserField> implements ISwingScoutFileChooserField {
   private static final long serialVersionUID = 1L;
 
+  private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
+
   @Override
   protected void initializeSwing() {
     JPanelEx container = new JPanelEx();
@@ -114,17 +120,51 @@
     super.attachScout();
     IFileChooserField f = getScoutObject();
     setFileIconIdFromScout(f.getFileIconId());
+    if (m_scoutActionPropertyListener == null) {
+      m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+    }
+    m_scoutActionPropertyListener.attachToScoutMenus(f.getMenus());
     if (getSwingField() instanceof JTextFieldWithDropDownButton) {
-      ((JTextFieldWithDropDownButton) getSwingTextField()).setMenuEnabled(getScoutObject().hasMenus());
+      ((JTextFieldWithDropDownButton) getSwingTextField()).setMenuEnabled(calculateDropDownButtonEnabled());
     }
   }
 
   @Override
+  protected void detachScout() {
+    if (m_scoutActionPropertyListener != null) {
+      m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+      m_scoutActionPropertyListener = null;
+    }
+    super.detachScout();
+  }
+
+  @Override
   protected void setDisplayTextFromScout(String s) {
+    if (getSwingField() instanceof JTextFieldWithDropDownButton) {
+      ((JTextFieldWithDropDownButton) getSwingTextField()).setMenuEnabled(calculateDropDownButtonEnabled());
+    }
     JTextComponent swingField = getSwingTextField();
     swingField.setText(s);
   }
 
+  private boolean calculateDropDownButtonEnabled() {
+    final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+    Runnable t = new Runnable() {
+      @Override
+      public void run() {
+        hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+      }
+    };
+    JobEx job = getSwingEnvironment().invokeScoutLater(t, 1200);
+    try {
+      job.join(1200);
+    }
+    catch (InterruptedException ex) {
+      //nop
+    }
+    return hasValidMenus.get();
+  }
+
   @Override
   protected void setHorizontalAlignmentFromScout(int scoutAlign) {
     if (getSwingTextField() instanceof JTextField) {
@@ -139,6 +179,7 @@
     if (getSwingField() instanceof JTextFieldWithDropDownButton) {
       ((JTextFieldWithDropDownButton) getSwingTextField()).setDropDownButtonEnabled(b);
     }
+    handleDropDownButtonEnabled();
   }
 
   protected void setFileIconIdFromScout(String s) {
@@ -253,6 +294,20 @@
     }
   }
 
+  protected void handleScoutActionPropertyChange(String name, Object newValue) {
+    if (IAction.PROP_INHERIT_ACCESSIBILITY.equals(name) || IAction.PROP_EMPTY_SPACE.equals(name) ||
+        IAction.PROP_SINGLE_SELECTION.equals(name) || IAction.PROP_VISIBLE.equals(name)) {
+      handleDropDownButtonEnabled();
+    }
+  }
+
+  protected void handleDropDownButtonEnabled() {
+    if (getSwingField() instanceof JTextFieldWithDropDownButton) {
+      ((JTextFieldWithDropDownButton) getSwingField()).setMenuEnabled(calculateDropDownButtonEnabled());
+      getSwingField().repaint();
+    }
+  }
+
   /**
    * Swing action
    */
@@ -265,4 +320,24 @@
     }
   }// end private class
 
+  private class P_ScoutActionPropertyChangeListener extends AbstractSwingScoutActionPropertyChangeListener {
+    @Override
+    public void propertyChange(final PropertyChangeEvent e) {
+      Runnable t = new Runnable() {
+        @Override
+        public void run() {
+          try {
+            getUpdateSwingFromScoutLock().acquire();
+            //
+            handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+          }
+          finally {
+            getUpdateSwingFromScoutLock().release();
+          }
+        }
+      };
+      getSwingEnvironment().invokeSwingLater(t);
+    }
+  } // end private class P_ScoutActionPropertyChangeListener
+
 }
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/smartfield/SwingScoutSmartField.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/smartfield/SwingScoutSmartField.java
index 38f89d0..e6578ad 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/smartfield/SwingScoutSmartField.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/smartfield/SwingScoutSmartField.java
@@ -17,6 +17,8 @@
 import java.awt.Window;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.swing.AbstractAction;
 import javax.swing.ActionMap;
@@ -46,6 +48,7 @@
 import org.eclipse.scout.commons.exception.ProcessingException;
 import org.eclipse.scout.commons.holders.BooleanHolder;
 import org.eclipse.scout.commons.job.JobEx;
+import org.eclipse.scout.rt.client.ui.action.IAction;
 import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
 import org.eclipse.scout.rt.client.ui.form.FormEvent;
 import org.eclipse.scout.rt.client.ui.form.FormListener;
@@ -54,6 +57,7 @@
 import org.eclipse.scout.rt.ui.swing.LogicalGridLayout;
 import org.eclipse.scout.rt.ui.swing.SwingPopupWorker;
 import org.eclipse.scout.rt.ui.swing.SwingUtility;
+import org.eclipse.scout.rt.ui.swing.action.AbstractSwingScoutActionPropertyChangeListener;
 import org.eclipse.scout.rt.ui.swing.basic.IconGroup;
 import org.eclipse.scout.rt.ui.swing.basic.document.BasicDocumentFilter;
 import org.eclipse.scout.rt.ui.swing.ext.IDropDownButtonListener;
@@ -78,6 +82,7 @@
   private SwingScoutDropDownPopup m_proposalPopup;
   private P_PendingProposalJob m_pendingProposalJob;
   private Object m_pendingProposalJobLock;
+  private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
 
   @Override
   @SuppressWarnings("serial")
@@ -172,14 +177,22 @@
     ISmartField f = getScoutObject();
     setIconIdFromScout(f.getIconId());
     setProposalFormFromScout(f.getProposalForm());
+    if (m_scoutActionPropertyListener == null) {
+      m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+    }
+    m_scoutActionPropertyListener.attachToScoutMenus(f.getMenus());
     if (getSwingField() instanceof JTextFieldWithDropDownButton) {
-      ((JTextFieldWithDropDownButton) getSwingField()).setMenuEnabled(getScoutObject().hasMenus());
+      ((JTextFieldWithDropDownButton) getSwingField()).setMenuEnabled(calculateDropDownButtonEnabled());
     }
   }
 
   @Override
   protected void detachScout() {
     hideProposalPopup();
+    if (m_scoutActionPropertyListener != null) {
+      m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+      m_scoutActionPropertyListener = null;
+    }
     super.detachScout();
   }
 
@@ -194,6 +207,9 @@
   @Override
   protected void setDisplayTextFromScout(String s) {
     JTextComponent swingField = getSwingTextField();
+    if (swingField instanceof JTextFieldWithDropDownButton) {
+      ((JTextFieldWithDropDownButton) swingField).setMenuEnabled(calculateDropDownButtonEnabled());
+    }
     if (!CompareUtility.equals(swingField.getText(), s)) {
       swingField.setText(s);
       // ticket 77424
@@ -207,12 +223,31 @@
     }
   }
 
+  private boolean calculateDropDownButtonEnabled() {
+    final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+    Runnable t = new Runnable() {
+      @Override
+      public void run() {
+        hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+      }
+    };
+    JobEx job = getSwingEnvironment().invokeScoutLater(t, 1200);
+    try {
+      job.join(1200);
+    }
+    catch (InterruptedException ex) {
+      //nop
+    }
+    return hasValidMenus.get();
+  }
+
   @Override
   protected void setEnabledFromScout(boolean b) {
     super.setEnabledFromScout(b);
     if (getSwingField() instanceof JTextFieldWithDropDownButton) {
       ((JTextFieldWithDropDownButton) getSwingField()).setDropDownButtonEnabled(b);
     }
+    handleDropDownButtonEnabled();
   }
 
   protected void setIconIdFromScout(String iconId) {
@@ -600,6 +635,13 @@
     }
   }
 
+  protected void handleDropDownButtonEnabled() {
+    if (getSwingField() instanceof JTextFieldWithDropDownButton) {
+      ((JTextFieldWithDropDownButton) getSwingField()).setMenuEnabled(calculateDropDownButtonEnabled());
+      getSwingField().repaint();
+    }
+  }
+
   @Override
   protected void handleScoutPropertyChange(String name, Object newValue) {
     super.handleScoutPropertyChange(name, newValue);
@@ -611,6 +653,13 @@
     }
   }
 
+  protected void handleScoutActionPropertyChange(String name, Object newValue) {
+    if (IAction.PROP_INHERIT_ACCESSIBILITY.equals(name) || IAction.PROP_EMPTY_SPACE.equals(name) ||
+        IAction.PROP_SINGLE_SELECTION.equals(name) || IAction.PROP_VISIBLE.equals(name)) {
+      handleDropDownButtonEnabled();
+    }
+  }
+
   private class P_PendingProposalJob extends JobEx implements Runnable {
 
     private String m_text;
@@ -669,4 +718,23 @@
     return b.toString();
   }
 
+  private class P_ScoutActionPropertyChangeListener extends AbstractSwingScoutActionPropertyChangeListener {
+    @Override
+    public void propertyChange(final PropertyChangeEvent e) {
+      Runnable t = new Runnable() {
+        @Override
+        public void run() {
+          try {
+            getUpdateSwingFromScoutLock().acquire();
+            //
+            handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+          }
+          finally {
+            getUpdateSwingFromScoutLock().release();
+          }
+        }
+      };
+      getSwingEnvironment().invokeSwingLater(t);
+    }
+  } // end private class P_ScoutActionPropertyChangeListener
 }
diff --git a/org.eclipse.scout.rt.ui.swt/resources/icons/internal/dropdownfield_arrowdown_disabled.gif b/org.eclipse.scout.rt.ui.swt/resources/icons/internal/dropdownfield_arrowdown_disabled.gif
new file mode 100644
index 0000000..08ec063
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.swt/resources/icons/internal/dropdownfield_arrowdown_disabled.gif
Binary files differ
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/SwtIcons.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/SwtIcons.java
index cba995d..02cbba5 100644
--- a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/SwtIcons.java
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/SwtIcons.java
@@ -15,6 +15,7 @@
  */
 public interface SwtIcons {
   String DropDownFieldArrowDown = "dropdownfield_arrowdown";
+  String DropDownFieldArrowDownDisabled = "dropdownfield_arrowdown_disabled";
   String Window = "window";
   String CheckboxYes = "checkbox_yes";
   String CheckboxNo = "checkbox_no";
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/action/AbstractSwtScoutActionPropertyChangeListener.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/action/AbstractSwtScoutActionPropertyChangeListener.java
new file mode 100644
index 0000000..0d6d902
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/action/AbstractSwtScoutActionPropertyChangeListener.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2014 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.ui.swt.action;
+
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
+
+/**
+ * Property change listener that can be attached to particular Scout menus.
+ * 
+ * @since 4.0.0-M6
+ */
+public abstract class AbstractSwtScoutActionPropertyChangeListener implements PropertyChangeListener {
+
+  public void attachToScoutMenus(IMenu[] menus) {
+    for (IMenu menu : menus) {
+      menu.addPropertyChangeListener(this);
+    }
+  }
+
+  public void detachFromScoutMenus(IMenu[] menus) {
+    for (IMenu menu : menus) {
+      menu.removePropertyChangeListener(this);
+    }
+  }
+}
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/ext/ButtonEx.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/ext/ButtonEx.java
index 747a91b..227604b 100644
--- a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/ext/ButtonEx.java
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/ext/ButtonEx.java
@@ -46,6 +46,7 @@
   private Listener[] m_actionSelectionListener;
   private Listener[] m_menuSelectionListener;
   private Image m_dropDownIcon;
+  private Image m_dropDownDisabledIcon;
 
   private P_DropDownPaintListener m_dropDownPaintListener;
   private Listener m_paintListener = new Listener() {
@@ -58,7 +59,8 @@
   public ButtonEx(Composite parent, int style) {
     super(parent, style);
     m_dropDownIcon = Activator.getIcon(SwtIcons.DropDownFieldArrowDown);
-    // dopdown
+    m_dropDownDisabledIcon = Activator.getIcon(SwtIcons.DropDownFieldArrowDownDisabled);
+    // dropdown
     P_DelegateSelectionListener delegateListener = new P_DelegateSelectionListener();
     if ((style & SWT.DROP_DOWN) != 0) {
       m_hasDropDown = true;
@@ -185,6 +187,7 @@
 
   public void setDropDownEnabled(boolean enabled) {
     m_dropDownEnabled = enabled;
+    redraw();
   }
 
   public boolean isDropDownEnabled() {
@@ -288,11 +291,15 @@
 
       Rectangle bounds = getBounds();
       gc.drawLine(bounds.width - 12, 3, bounds.width - 12, bounds.height - 4);
-      gc.drawImage(m_dropDownIcon, bounds.width - 11, (bounds.height - m_dropDownIcon.getBounds().height) / 2);
-      // gc.fillPolygon(new int[] { bounds.width - 10, bounds.height / 2,
-      // bounds.width - 6, bounds.height - 7, bounds.width - 3, bounds.height /
-      // 2 });
 
+      if (m_dropDownEnabled) {
+        gc.drawImage(m_dropDownIcon, bounds.width - 11, (bounds.height - m_dropDownIcon.getBounds().height) / 2);
+      }
+      else {
+        gc.drawImage(m_dropDownDisabledIcon, bounds.width - 11, (bounds.height - m_dropDownDisabledIcon.getBounds().height) / 2);
+      }
+//      gc.fillPolygon(new int[]{bounds.width - 10, bounds.height / 2,
+//          bounds.width - 6, bounds.height - 7, bounds.width - 3, bounds.height / 2});
     }
   } // end class P_DropDownPaintListener
 
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/button/SwtScoutButton.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/button/SwtScoutButton.java
index 2b90da8..73ba159 100644
--- a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/button/SwtScoutButton.java
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/button/SwtScoutButton.java
@@ -10,6 +10,8 @@
  ******************************************************************************/
 package org.eclipse.scout.rt.ui.swt.form.fields.button;
 
+import java.beans.PropertyChangeEvent;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.eclipse.scout.commons.OptimisticLock;
@@ -18,6 +20,7 @@
 import org.eclipse.scout.commons.job.JobEx;
 import org.eclipse.scout.commons.logger.IScoutLogger;
 import org.eclipse.scout.commons.logger.ScoutLogManager;
+import org.eclipse.scout.rt.client.ui.action.IAction;
 import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
 import org.eclipse.scout.rt.client.ui.form.fields.button.ButtonEvent;
 import org.eclipse.scout.rt.client.ui.form.fields.button.ButtonListener;
@@ -25,6 +28,7 @@
 import org.eclipse.scout.rt.ui.swt.LogicalGridData;
 import org.eclipse.scout.rt.ui.swt.LogicalGridLayout;
 import org.eclipse.scout.rt.ui.swt.SwtMenuUtility;
+import org.eclipse.scout.rt.ui.swt.action.AbstractSwtScoutActionPropertyChangeListener;
 import org.eclipse.scout.rt.ui.swt.ext.ButtonEx;
 import org.eclipse.scout.rt.ui.swt.ext.MultilineButton;
 import org.eclipse.scout.rt.ui.swt.ext.MultilineRadioButton;
@@ -61,6 +65,8 @@
   private boolean m_handleActionPending;
 
   private Menu m_contextMenu;
+  private boolean m_hasDropDown = false;
+  private P_ScoutActionPropertyListener m_scoutActionPropertyListener;
 
   public SwtScoutButton() {
     m_selectionLock = new OptimisticLock();
@@ -94,9 +100,10 @@
         int style = SWT.CENTER | SWT.PUSH;
         if (getScoutObject().hasMenus()) {
           style |= SWT.DROP_DOWN;
+          m_hasDropDown = true;
         }
         ButtonEx swtButton = getEnvironment().getFormToolkit().createButtonEx(container, style);
-        swtButton.setDropDownEnabled(true);
+        swtButton.setDropDownEnabled(calculateDropDownButtonEnabled());
         swtFieldAsButton = swtButton;
       }
     }
@@ -134,6 +141,24 @@
     getSwtContainer().setLayout(new LogicalGridLayout(0, 0));
   }
 
+  private boolean calculateDropDownButtonEnabled() {
+    final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+    Runnable t = new Runnable() {
+      @Override
+      public void run() {
+        hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+      }
+    };
+    JobEx job = getEnvironment().invokeScoutLater(t, 1200);
+    try {
+      job.join(1200);
+    }
+    catch (InterruptedException ex) {
+      //nop
+    }
+    return hasValidMenus.get();
+  }
+
   @Override
   protected void attachScout() {
     super.attachScout();
@@ -141,7 +166,12 @@
       m_scoutButtonListener = new P_ScoutButtonListener();
       getScoutObject().addButtonListener(m_scoutButtonListener);
     }
-
+    if (m_hasDropDown) {
+      if (m_scoutActionPropertyListener == null) {
+        m_scoutActionPropertyListener = new P_ScoutActionPropertyListener();
+      }
+      m_scoutActionPropertyListener.attachToScoutMenus(getScoutObject().getMenus());
+    }
   }
 
   @Override
@@ -151,6 +181,10 @@
       getScoutObject().removeButtonListener(m_scoutButtonListener);
       m_scoutButtonListener = null;
     }
+    if (m_scoutActionPropertyListener != null) {
+      m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+      m_scoutActionPropertyListener = null;
+    }
   }
 
   @Override
@@ -322,6 +356,18 @@
     }
   }
 
+  protected void handleScoutActionPropertyChange(String name, Object newValue) {
+    if (IAction.PROP_VISIBLE.equals(name)) {
+      handleDropDownButtonEnabled();
+    }
+  }
+
+  protected void handleDropDownButtonEnabled() {
+    if (m_hasDropDown) {
+      ((ButtonEx) getSwtField()).setDropDownEnabled(calculateDropDownButtonEnabled());
+    }
+  }
+
   private class P_SwtSelectionListener implements Listener {
     @Override
     public void handleEvent(Event event) {
@@ -417,4 +463,26 @@
     }
 
   } // end class P_ContextMenuListener
+
+  private class P_ScoutActionPropertyListener extends AbstractSwtScoutActionPropertyChangeListener {
+    @Override
+    public void propertyChange(final PropertyChangeEvent e) {
+      Runnable t = new Runnable() {
+        @Override
+        public void run() {
+          if (isHandleScoutPropertyChangeSwtThread()) {
+            try {
+              getUpdateSwtFromScoutLock().acquire();
+              //
+              handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+            }
+            finally {
+              getUpdateSwtFromScoutLock().release();
+            }
+          }
+        }
+      };
+      getEnvironment().invokeSwtLater(t);
+    }
+  } // end private class P_ScoutActionPropertyListener
 }
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/filechooserfield/SwtScoutFileChooserField.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/filechooserfield/SwtScoutFileChooserField.java
index a69ad37..c684bc8 100644
--- a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/filechooserfield/SwtScoutFileChooserField.java
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/filechooserfield/SwtScoutFileChooserField.java
@@ -10,17 +10,21 @@
  ******************************************************************************/
 package org.eclipse.scout.rt.ui.swt.form.fields.filechooserfield;
 
+import java.beans.PropertyChangeEvent;
 import java.io.File;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.eclipse.scout.commons.CompareUtility;
 import org.eclipse.scout.commons.holders.Holder;
 import org.eclipse.scout.commons.job.JobEx;
+import org.eclipse.scout.rt.client.ui.action.IAction;
 import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
 import org.eclipse.scout.rt.client.ui.basic.filechooser.IFileChooser;
 import org.eclipse.scout.rt.client.ui.form.fields.filechooserfield.IFileChooserField;
 import org.eclipse.scout.rt.ui.swt.LogicalGridLayout;
 import org.eclipse.scout.rt.ui.swt.SwtMenuUtility;
+import org.eclipse.scout.rt.ui.swt.action.AbstractSwtScoutActionPropertyChangeListener;
 import org.eclipse.scout.rt.ui.swt.ext.DropDownButton;
 import org.eclipse.scout.rt.ui.swt.ext.StatusLabelEx;
 import org.eclipse.scout.rt.ui.swt.form.fields.LogicalGridDataBuilder;
@@ -44,6 +48,7 @@
   private DropDownButton m_fileChooserButton;
   private Menu m_contextMenu;
   private TextFieldEditableSupport m_editableSupport;
+  private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
 
   @Override
   protected void initializeSwt(Composite parent) {
@@ -95,11 +100,43 @@
   protected void attachScout() {
     super.attachScout();
     setFileIconIdFromScout(getScoutObject().getFileIconId());
-    getSwtFileChooserButton().setDropdownEnabled(getScoutObject().hasMenus());
+    if (m_scoutActionPropertyListener == null) {
+      m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+    }
+    m_scoutActionPropertyListener.attachToScoutMenus(getScoutObject().getMenus());
+    getSwtFileChooserButton().setDropdownEnabled(calculateDropDownButtonEnabled());
+  }
+
+  @Override
+  protected void detachScout() {
+    if (m_scoutActionPropertyListener != null) {
+      m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+      m_scoutActionPropertyListener = null;
+    }
+    super.detachScout();
+  }
+
+  private boolean calculateDropDownButtonEnabled() {
+    final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+    Runnable t = new Runnable() {
+      @Override
+      public void run() {
+        hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+      }
+    };
+    JobEx job = getEnvironment().invokeScoutLater(t, 1200);
+    try {
+      job.join(1200);
+    }
+    catch (InterruptedException ex) {
+      //nop
+    }
+    return hasValidMenus.get();
   }
 
   @Override
   protected void setDisplayTextFromScout(String s) {
+    getSwtFileChooserButton().setDropdownEnabled(calculateDropDownButtonEnabled());
     if (s == null) {
       s = "";
     }
@@ -112,6 +149,7 @@
   protected void setEnabledFromScout(boolean b) {
     super.setEnabledFromScout(b);
     m_fileChooserButton.setEnabled(b);
+    m_fileChooserButton.setDropdownEnabled(calculateDropDownButtonEnabled());
   }
 
   @Override
@@ -216,6 +254,17 @@
     }
   }
 
+  protected void handleScoutActionPropertyChange(String name, Object newValue) {
+    if (IAction.PROP_INHERIT_ACCESSIBILITY.equals(name) || IAction.PROP_EMPTY_SPACE.equals(name) ||
+        IAction.PROP_SINGLE_SELECTION.equals(name) || IAction.PROP_VISIBLE.equals(name)) {
+      handleDropDownButtonEnabled();
+    }
+  }
+
+  protected void handleDropDownButtonEnabled() {
+    getSwtFileChooserButton().setDropdownEnabled(calculateDropDownButtonEnabled());
+  }
+
   private class P_SwtFileChooserButtonListener extends SelectionAdapter {
     @Override
     public void widgetSelected(SelectionEvent e) {
@@ -263,4 +312,26 @@
     }
 
   } // end class P_ContextMenuListener
+
+  private class P_ScoutActionPropertyChangeListener extends AbstractSwtScoutActionPropertyChangeListener {
+    @Override
+    public void propertyChange(final PropertyChangeEvent e) {
+      Runnable t = new Runnable() {
+        @Override
+        public void run() {
+          if (isHandleScoutPropertyChangeSwtThread()) {
+            try {
+              getUpdateSwtFromScoutLock().acquire();
+              //
+              handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+            }
+            finally {
+              getUpdateSwtFromScoutLock().release();
+            }
+          }
+        }
+      };
+      getEnvironment().invokeSwtLater(t);
+    }
+  } // end class P_ScoutActionPropertyChangeListener
 }
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/smartfield/SwtScoutSmartField.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/smartfield/SwtScoutSmartField.java
index 0f27ee6..097b4bf 100644
--- a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/smartfield/SwtScoutSmartField.java
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/smartfield/SwtScoutSmartField.java
@@ -10,8 +10,10 @@
  ******************************************************************************/
 package org.eclipse.scout.rt.ui.swt.form.fields.smartfield;
 
+import java.beans.PropertyChangeEvent;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -23,6 +25,7 @@
 import org.eclipse.scout.commons.job.JobEx;
 import org.eclipse.scout.commons.logger.IScoutLogger;
 import org.eclipse.scout.commons.logger.ScoutLogManager;
+import org.eclipse.scout.rt.client.ui.action.IAction;
 import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
 import org.eclipse.scout.rt.client.ui.form.FormEvent;
 import org.eclipse.scout.rt.client.ui.form.FormListener;
@@ -30,6 +33,7 @@
 import org.eclipse.scout.rt.client.ui.form.fields.smartfield.ISmartFieldProposalForm;
 import org.eclipse.scout.rt.ui.swt.LogicalGridLayout;
 import org.eclipse.scout.rt.ui.swt.SwtMenuUtility;
+import org.eclipse.scout.rt.ui.swt.action.AbstractSwtScoutActionPropertyChangeListener;
 import org.eclipse.scout.rt.ui.swt.ext.DropDownButton;
 import org.eclipse.scout.rt.ui.swt.ext.StatusLabelEx;
 import org.eclipse.scout.rt.ui.swt.form.fields.IPopupSupport;
@@ -83,6 +87,7 @@
 
   private Set<IPopupSupportListener> m_popupEventListeners;
   private Object m_popupEventListenerLock;
+  private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
 
   public SwtScoutSmartField() {
     m_pendingProposalJobLock = new Object();
@@ -156,19 +161,27 @@
     super.attachScout();
     setIconIdFromScout(getScoutObject().getIconId());
     setProposalFormFromScout(getScoutObject().getProposalForm());
+    if (m_scoutActionPropertyListener == null) {
+      m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+    }
+    m_scoutActionPropertyListener.attachToScoutMenus(getScoutObject().getMenus());
   }
 
   @Override
   protected void detachScout() {
     // workaround since disposeFieldInternal in AbstractSmartField is never called.
     hideProposalPopup();
+    if (m_scoutActionPropertyListener != null) {
+      m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+      m_scoutActionPropertyListener = null;
+    }
     super.detachScout();
   }
 
   @Override
   protected void setDisplayTextFromScout(String s) {
+    getSwtBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
     if (!CompareUtility.equals(s, getSwtField().getText())) {
-      getSwtBrowseButton().setDropdownEnabled(getScoutObject().hasMenus());
       if (s == null) {
         s = "";
       }
@@ -178,10 +191,29 @@
     }
   }
 
+  private boolean calculateDropDownButtonEnabled() {
+    final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+    Runnable t = new Runnable() {
+      @Override
+      public void run() {
+        hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+      }
+    };
+    JobEx job = getEnvironment().invokeScoutLater(t, 1200);
+    try {
+      job.join(1200);
+    }
+    catch (InterruptedException ex) {
+      //nop
+    }
+    return hasValidMenus.get();
+  }
+
   @Override
   protected void setEnabledFromScout(boolean b) {
     super.setEnabledFromScout(b);
     m_browseButton.setButtonEnabled(b);
+    getSwtBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
   }
 
   @Override
@@ -465,6 +497,17 @@
     }
   }
 
+  protected void handleScoutActionPropertyChange(String name, Object newValue) {
+    if (IAction.PROP_INHERIT_ACCESSIBILITY.equals(name) || IAction.PROP_EMPTY_SPACE.equals(name) ||
+        IAction.PROP_SINGLE_SELECTION.equals(name) || IAction.PROP_VISIBLE.equals(name)) {
+      handleDropDownButtonEnabled();
+    }
+  }
+
+  protected void handleDropDownButtonEnabled() {
+    getSwtBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
+  }
+
   protected void handleTextModifiedFromUi(Event event) {
     if (getUpdateSwtFromScoutLock().isAcquired()) {
       return;
@@ -677,4 +720,26 @@
       handleSwtBrowseAction();
     }
   } // end class P_F2KeyStroke
+
+  private class P_ScoutActionPropertyChangeListener extends AbstractSwtScoutActionPropertyChangeListener {
+    @Override
+    public void propertyChange(final PropertyChangeEvent e) {
+      Runnable t = new Runnable() {
+        @Override
+        public void run() {
+          if (isHandleScoutPropertyChangeSwtThread()) {
+            try {
+              getUpdateSwtFromScoutLock().acquire();
+              //
+              handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+            }
+            finally {
+              getUpdateSwtFromScoutLock().release();
+            }
+          }
+        }
+      };
+      getEnvironment().invokeSwtLater(t);
+    }
+  } // end class P_ScoutActionPropertyChangeListener
 }