changeset 1309:e66baba3918e

Add new decorators for labels (part I) review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-November/008653.html reviwed: omajid
author Mario Torre <neugens.limasoftware@gmail.com>
date Fri, 08 Nov 2013 14:22:51 +0100
parents 41126b42f1e3
children 6e5580aa0165
files client/core/src/main/java/com/redhat/thermostat/client/ui/ReferenceFieldLabelDecorator.java client/living-vm-filter/swing/pom.xml client/living-vm-filter/swing/src/main/java/com/redhat/thermostat/client/filter/host/swing/HostLabelDecorator.java client/living-vm-filter/swing/src/main/java/com/redhat/thermostat/client/filter/vm/swing/LivingVMDecoratorProvider.java client/living-vm-filter/swing/src/main/java/com/redhat/thermostat/client/filter/vm/swing/VMFilterActivator.java client/living-vm-filter/swing/src/main/java/com/redhat/thermostat/client/filter/vm/swing/VMLabelDecorator.java client/living-vm-filter/swing/src/test/java/com/redhat/thermostat/client/filter/vm/swing/VMFilterActivatorTest.java client/swing/pom.xml client/swing/src/main/java/com/redhat/thermostat/client/swing/IconResource.java client/swing/src/main/java/com/redhat/thermostat/client/swing/ReferenceFieldDecoratorLayout.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostIconDecoratorProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/RegistryFactory.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/registry/decorator/DecoratorRegistryController.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/registry/decorator/DecoratorRegistryFactory.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/registry/decorator/InfoLabelDecoratorRegistry.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/registry/decorator/MainLabelDecoratorRegistry.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceComponent.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceTitle.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/UIDefaults.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorManager.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorNotifier.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorProviderExtensionListener.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/HostTreeController.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/LabelDecoratorListener.java client/swing/src/main/resources/computer_24.png client/swing/src/main/resources/computer_32.png client/swing/src/main/resources/java_application_identifier_24.png client/swing/src/main/resources/java_application_identifier_32.png client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/registry/decorator/DecoratorRegistryControllerTest.java laf-utils/src/main/java/com/redhat/thermostat/internal/utils/laf/ThemeManager.java
diffstat 32 files changed, 1078 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/ReferenceFieldLabelDecorator.java	Fri Nov 08 14:22:51 2013 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ * 
+ * This file is part of Thermostat.
+ * 
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ * 
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ * 
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ * 
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.ui;
+
+import com.redhat.thermostat.storage.core.Ref;
+
+/**
+ *
+ */
+public interface ReferenceFieldLabelDecorator {
+
+    public static final String ID = "ReferenceFieldLabelDecorator_ID";
+    
+    String getLabel(String originalLabel, Ref reference);
+}
--- a/client/living-vm-filter/swing/pom.xml	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/living-vm-filter/swing/pom.xml	Fri Nov 08 14:22:51 2013 +0100
@@ -27,9 +27,12 @@
         <extensions>true</extensions>
         <configuration>
           <instructions>
-            <Private-Package>com.redhat.thermostat.client.filter.vm.swing</Private-Package>
             <Bundle-Activator>com.redhat.thermostat.client.filter.vm.swing.VMFilterActivator</Bundle-Activator>
             <Bundle-SymbolicName>com.redhat.thermostat.filter.livingvm.swing</Bundle-SymbolicName>
+            <Private-Package>
+            com.redhat.thermostat.client.filter.vm.swing,
+            com.redhat.thermostat.client.filter.host.swing
+            </Private-Package>
             <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
             <!-- Do not autogenerate uses clauses in Manifests -->
             <_nouses>true</_nouses>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/living-vm-filter/swing/src/main/java/com/redhat/thermostat/client/filter/host/swing/HostLabelDecorator.java	Fri Nov 08 14:22:51 2013 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ * 
+ * This file is part of Thermostat.
+ * 
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ * 
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ * 
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ * 
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.filter.host.swing;
+
+import java.util.List;
+
+import com.redhat.thermostat.client.ui.ReferenceFieldLabelDecorator;
+import com.redhat.thermostat.storage.core.HostRef;
+import com.redhat.thermostat.storage.core.Ref;
+import com.redhat.thermostat.storage.dao.NetworkInterfaceInfoDAO;
+import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
+
+public class HostLabelDecorator implements ReferenceFieldLabelDecorator {
+
+    private NetworkInterfaceInfoDAO dao;
+    
+    public HostLabelDecorator(NetworkInterfaceInfoDAO  dao) {
+        this.dao = dao;
+    }
+    
+    @Override
+    public String getLabel(String originalLabel, Ref reference) {
+        
+        if (!(reference instanceof HostRef)) {
+            return originalLabel;
+        }
+        
+        List<NetworkInterfaceInfo> infos =
+                dao.getNetworkInterfaces((HostRef) reference);
+        StringBuilder result = new StringBuilder();
+        
+        for (NetworkInterfaceInfo info : infos) {
+            // filter out the loopbak
+            if (!info.getInterfaceName().equals("lo")) {
+                if (info.getIp4Addr() != null) {
+                    result.append(info.getIp4Addr()).append("; ");
+                } else if (info.getIp6Addr() != null) {
+                    result.append(info.getIp6Addr()).append("; ");
+                }
+            }
+        }
+        result.deleteCharAt(result.length() - 2);
+        return result.toString();
+    }
+}
--- a/client/living-vm-filter/swing/src/main/java/com/redhat/thermostat/client/filter/vm/swing/LivingVMDecoratorProvider.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/living-vm-filter/swing/src/main/java/com/redhat/thermostat/client/filter/vm/swing/LivingVMDecoratorProvider.java	Fri Nov 08 14:22:51 2013 +0100
@@ -58,7 +58,7 @@
         public IconDescriptor getIconDescriptor() {
             IconDescriptor icon = null;
             try {
-                icon = IconResource.JAVA_APPLICATION.toIconDescriptor();
+                icon = IconResource.JAVA_APPLICATION_24.toIconDescriptor();
             } catch (IOException ioe) {
                 ioe.printStackTrace();
                 Logger.getLogger(LivingVMDecoratorProvider.class.getName()).log(Level.SEVERE, ioe.getMessage(), ioe);
--- a/client/living-vm-filter/swing/src/main/java/com/redhat/thermostat/client/filter/vm/swing/VMFilterActivator.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/living-vm-filter/swing/src/main/java/com/redhat/thermostat/client/filter/vm/swing/VMFilterActivator.java	Fri Nov 08 14:22:51 2013 +0100
@@ -48,11 +48,16 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
+import com.redhat.thermostat.client.filter.host.swing.HostLabelDecorator;
+import com.redhat.thermostat.client.swing.ReferenceFieldDecoratorLayout;
 import com.redhat.thermostat.client.ui.DecoratorProvider;
+import com.redhat.thermostat.client.ui.ReferenceFieldLabelDecorator;
 import com.redhat.thermostat.common.Constants;
 import com.redhat.thermostat.common.MultipleServiceTracker;
+import com.redhat.thermostat.storage.core.HostRef;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.dao.HostInfoDAO;
+import com.redhat.thermostat.storage.dao.NetworkInterfaceInfoDAO;
 import com.redhat.thermostat.storage.dao.VmInfoDAO;
 
 public class VMFilterActivator implements BundleActivator {
@@ -69,7 +74,8 @@
         Class<?> [] services =  new Class<?> [] {
                 VmInfoDAO.class,
                 HostInfoDAO.class,
-            };
+                NetworkInterfaceInfoDAO.class,
+        };
         
         tracker = new MultipleServiceTracker(context, services, new MultipleServiceTracker.Action() {
             
@@ -103,6 +109,25 @@
                 registration = context.registerService(DecoratorProvider.class.getName(),
                                                        decorator, decoratorProperties);
                 registeredServices.add(registration);
+                
+                VMLabelDecorator vmLabelDecorator = new VMLabelDecorator(vmDao);
+                decoratorProperties = new Hashtable<>();
+                decoratorProperties.put(ReferenceFieldLabelDecorator.ID, ReferenceFieldDecoratorLayout.LABEL_INFO.name());
+
+                registration = context.registerService(ReferenceFieldLabelDecorator.class.getName(),
+                        vmLabelDecorator, decoratorProperties);
+                
+                NetworkInterfaceInfoDAO networkDao = (NetworkInterfaceInfoDAO)
+                            services.get(NetworkInterfaceInfoDAO.class.getName());
+                
+                HostLabelDecorator hostLabelDecorator = new HostLabelDecorator(networkDao);
+                decoratorProperties = new Hashtable<>();
+                decoratorProperties.put(ReferenceFieldLabelDecorator.ID, ReferenceFieldDecoratorLayout.LABEL_INFO.name());
+                
+                registration = context.registerService(ReferenceFieldLabelDecorator.class.getName(),
+                        hostLabelDecorator, decoratorProperties);
+                
+                registeredServices.add(registration);
             }
         });
         tracker.open();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/living-vm-filter/swing/src/main/java/com/redhat/thermostat/client/filter/vm/swing/VMLabelDecorator.java	Fri Nov 08 14:22:51 2013 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ * 
+ * This file is part of Thermostat.
+ * 
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ * 
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ * 
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ * 
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.filter.vm.swing;
+
+import com.redhat.thermostat.client.ui.ReferenceFieldLabelDecorator;
+import com.redhat.thermostat.storage.core.HostRef;
+import com.redhat.thermostat.storage.core.Ref;
+import com.redhat.thermostat.storage.core.VmRef;
+import com.redhat.thermostat.storage.dao.VmInfoDAO;
+
+/**
+ * Replaces the given ReferenceField label with the pid of the current
+ * {@link VmRef}.
+ */
+public class VMLabelDecorator implements ReferenceFieldLabelDecorator {
+
+    private VmInfoDAO dao;
+    
+    public VMLabelDecorator(VmInfoDAO dao) {
+        this.dao = dao;
+    }
+    
+    @Override
+    public String getLabel(String originalLabel, Ref reference) {
+        
+        if (!(reference instanceof VmRef)) {
+            return originalLabel;
+        }
+        
+        // replace the label with the information we really care about
+        int pid =  dao.getVmInfo((VmRef) reference).getVmPid();
+        return "Pid: " + pid;
+    }
+}
--- a/client/living-vm-filter/swing/src/test/java/com/redhat/thermostat/client/filter/vm/swing/VMFilterActivatorTest.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/living-vm-filter/swing/src/test/java/com/redhat/thermostat/client/filter/vm/swing/VMFilterActivatorTest.java	Fri Nov 08 14:22:51 2013 +0100
@@ -41,8 +41,11 @@
 
 import org.junit.Test;
 
+import com.redhat.thermostat.client.filter.host.swing.HostLabelDecorator;
 import com.redhat.thermostat.client.ui.DecoratorProvider;
+import com.redhat.thermostat.client.ui.ReferenceFieldLabelDecorator;
 import com.redhat.thermostat.storage.dao.HostInfoDAO;
+import com.redhat.thermostat.storage.dao.NetworkInterfaceInfoDAO;
 import com.redhat.thermostat.storage.dao.VmInfoDAO;
 import com.redhat.thermostat.testutils.StubBundleContext;
 
@@ -56,11 +59,16 @@
         
         VmInfoDAO vmDao = mock(VmInfoDAO.class);
         HostInfoDAO hostDao = mock(HostInfoDAO.class);
-       
+        NetworkInterfaceInfoDAO netDao = mock(NetworkInterfaceInfoDAO.class);
+
         ctx.registerService(VmInfoDAO.class, vmDao, null);
         ctx.registerService(HostInfoDAO.class, hostDao, null);
+        ctx.registerService(NetworkInterfaceInfoDAO.class, netDao, null);
 
         assertTrue(ctx.isServiceRegistered(DecoratorProvider.class.getName(), LivingVMDecoratorProvider.class));
         assertTrue(ctx.isServiceRegistered(DecoratorProvider.class.getName(), DeadVMDecoratorProvider.class));
+        
+        assertTrue(ctx.isServiceRegistered(ReferenceFieldLabelDecorator.class.getName(), VMLabelDecorator.class));
+        assertTrue(ctx.isServiceRegistered(ReferenceFieldLabelDecorator.class.getName(), HostLabelDecorator.class));
     }
 }
--- a/client/swing/pom.xml	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/pom.xml	Fri Nov 08 14:22:51 2013 +0100
@@ -182,6 +182,7 @@
               com.redhat.thermostat.client.swing.internal.vmlist,
               com.redhat.thermostat.client.swing.internal.vmlist.controller,
               com.redhat.thermostat.client.swing.internal.accordion,
+              com.redhat.thermostat.client.swing.internal.registry.decorator,
             </Private-Package>
             <!-- Do not autogenerate uses clauses in Manifests -->
             <_nouses>true</_nouses>
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/IconResource.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/IconResource.java	Fri Nov 08 14:22:51 2013 +0100
@@ -51,8 +51,14 @@
     
     private boolean fromFileSytem = false;
        
+    public static final IconResource JAVA_APPLICATION_32 = new IconResource("java_application_identifier_32.png");
+    public static final IconResource JAVA_APPLICATION_24 = new IconResource("java_application_identifier_24.png");
     public static final IconResource JAVA_APPLICATION = new IconResource("java_application_identifier.png");
+    
+    public static final IconResource HOST_32 = new IconResource("computer_32.png");
+    public static final IconResource HOST_24 = new IconResource("computer_24.png");
     public static final IconResource HOST = new IconResource("computer.png");
+    
     public static final IconResource SEARCH = new IconResource("search.png");
     public static final IconResource RECORD = new IconResource("record.png");
     public static final IconResource SAMPLE = new IconResource("sample.png");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/ReferenceFieldDecoratorLayout.java	Fri Nov 08 14:22:51 2013 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ * 
+ * This file is part of Thermostat.
+ * 
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ * 
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ * 
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ * 
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing;
+
+public enum ReferenceFieldDecoratorLayout {    
+    LABEL_MAIN,
+    LABEL_INFO,
+    
+    ICON_TOP,
+    ICON_MAIN,
+    ICON_BOTTOM;
+}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostIconDecoratorProvider.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostIconDecoratorProvider.java	Fri Nov 08 14:22:51 2013 +0100
@@ -67,7 +67,7 @@
         public IconDecorator() {
             IconDescriptor icon = null;
             try {
-                icon = IconResource.HOST.toIconDescriptor();
+                icon = IconResource.HOST_24.toIconDescriptor();
             } catch (IOException ioe) {
                 ioe.printStackTrace();
             }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java	Fri Nov 08 14:22:51 2013 +0100
@@ -59,6 +59,7 @@
 import com.redhat.thermostat.client.swing.internal.osgi.HostContextActionServiceTracker;
 import com.redhat.thermostat.client.swing.internal.osgi.InformationServiceTracker;
 import com.redhat.thermostat.client.swing.internal.osgi.VMContextActionServiceTracker;
+import com.redhat.thermostat.client.swing.internal.registry.decorator.DecoratorRegistryController;
 import com.redhat.thermostat.client.swing.internal.vmlist.controller.ContextActionController;
 import com.redhat.thermostat.client.swing.internal.vmlist.controller.ContextHandler;
 import com.redhat.thermostat.client.swing.internal.vmlist.controller.DecoratorProviderExtensionListener;
@@ -177,6 +178,8 @@
     private VmFilterRegistry vmFilterRegistry;
     private HostFilterRegistry hostFilterRegistry;
     private FilterManager filterManager;
+
+    private DecoratorRegistryController decoratorController;
     
     public MainWindowControllerImpl(BundleContext context, ApplicationService appSvc,
             CountDownLatch shutdown) {
@@ -191,14 +194,16 @@
         this.appSvc = appSvc;
         this.view = view;
        
+        decoratorController = registryFactory.createDecoratorController();
+
         try {
-            
             vmFilterRegistry = registryFactory.createVmFilterRegistry();
             hostFilterRegistry = registryFactory.createHostFilterRegistry();
             
             hostDecoratorRegistry = registryFactory.createHostTreeDecoratorRegistry();
             vmDecoratorRegistry = registryFactory.createVMTreeDecoratorRegistry();
             menuRegistry = registryFactory.createMenuRegistry();
+            
             vmInfoRegistry = registryFactory.createVMInformationRegistry();
             
         } catch (InvalidSyntaxException e) {
@@ -374,6 +379,7 @@
     }
 
     private void installListenersAndStartRegistries() {
+        
         menuRegistry.addActionListener(menuListener);
         menuRegistry.start();
 
@@ -397,6 +403,9 @@
         vmInfoRegistry.start();
 
         setUpActionControllers();
+
+        decoratorController.init(hostTreeController);
+        decoratorController.start();
     }
 
     private void setUpActionControllers() {
@@ -433,6 +442,8 @@
         vmDecoratorRegistry.removeActionListener(vmDecoratorListener);
         vmDecoratorRegistry.stop();
 
+        decoratorController.stop();
+        
         vmInfoRegistry.removeActionListener(vmInfoRegistryListener);
         vmInfoRegistryListener = null;
         vmInfoRegistry.stop();
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/RegistryFactory.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/RegistryFactory.java	Fri Nov 08 14:22:51 2013 +0100
@@ -36,6 +36,8 @@
 
 package com.redhat.thermostat.client.swing.internal;
 
+import com.redhat.thermostat.client.swing.internal.registry.decorator.DecoratorRegistryController;
+import com.redhat.thermostat.client.swing.internal.registry.decorator.DecoratorRegistryFactory;
 import com.redhat.thermostat.client.ui.MenuRegistry;
 
 import org.osgi.framework.BundleContext;
@@ -71,5 +73,11 @@
     VMInformationRegistry createVMInformationRegistry() throws InvalidSyntaxException {
         return new VMInformationRegistry(context);
     }
+
+    DecoratorRegistryController createDecoratorController() {
+        DecoratorRegistryFactory decoratorRegistryFactory =
+                new DecoratorRegistryFactory(context);
+        return new DecoratorRegistryController(decoratorRegistryFactory);
+    }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/registry/decorator/DecoratorRegistryController.java	Fri Nov 08 14:22:51 2013 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ * 
+ * This file is part of Thermostat.
+ * 
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ * 
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ * 
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ * 
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.registry.decorator;
+
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.swing.internal.vmlist.controller.HostTreeController;
+
+public class DecoratorRegistryController {
+
+    private DecoratorRegistryFactory registryFactory;
+    private HostTreeController hostController;
+
+    private InfoLabelDecoratorRegistry infoLabel;
+    private MainLabelDecoratorRegistry mainLabel;
+    
+    public DecoratorRegistryController(DecoratorRegistryFactory registryFactory) {
+        this.registryFactory = registryFactory;
+    }
+
+    public void init(HostTreeController hostController) {
+        this.hostController = hostController;
+        
+        try {
+           
+            infoLabel = registryFactory.createInfoLabelDecoratorRegistry();
+            mainLabel = registryFactory.createMainLabelDecoratorRegistry();
+            
+        } catch (InvalidSyntaxException e) {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    public void start() {
+        infoLabel.addActionListener(hostController.getInfoLabelDecoratorListener());
+        infoLabel.start();
+        
+        mainLabel.addActionListener(hostController.getMainLabelDecoratorListener());
+        mainLabel.start();
+    }
+
+    public void stop() {
+        infoLabel.removeActionListener(hostController.getInfoLabelDecoratorListener());
+        infoLabel.stop();
+        
+        mainLabel.removeActionListener(hostController.getMainLabelDecoratorListener());
+        mainLabel.stop();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/registry/decorator/DecoratorRegistryFactory.java	Fri Nov 08 14:22:51 2013 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ * 
+ * This file is part of Thermostat.
+ * 
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ * 
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ * 
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ * 
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.registry.decorator;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+
+public class DecoratorRegistryFactory {
+    
+    private BundleContext context;
+    public DecoratorRegistryFactory(BundleContext context) {
+        this.context = context;
+    }
+
+    InfoLabelDecoratorRegistry createInfoLabelDecoratorRegistry() throws InvalidSyntaxException {
+        return new InfoLabelDecoratorRegistry(context);
+    }
+
+    MainLabelDecoratorRegistry createMainLabelDecoratorRegistry() throws InvalidSyntaxException {
+        return new MainLabelDecoratorRegistry(context);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/registry/decorator/InfoLabelDecoratorRegistry.java	Fri Nov 08 14:22:51 2013 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ * 
+ * This file is part of Thermostat.
+ * 
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ * 
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ * 
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ * 
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.registry.decorator;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.swing.ReferenceFieldDecoratorLayout;
+import com.redhat.thermostat.client.ui.ReferenceFieldLabelDecorator;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+
+public class InfoLabelDecoratorRegistry extends ThermostatExtensionRegistry<ReferenceFieldLabelDecorator> {
+
+    private static final String FILTER = "(&(" +
+            Constants.OBJECTCLASS + "=" + ReferenceFieldLabelDecorator.class.getName() +
+            ")(" +
+            ReferenceFieldLabelDecorator.ID + "=" + ReferenceFieldDecoratorLayout.LABEL_INFO +
+            "))";
+
+    public InfoLabelDecoratorRegistry(BundleContext context) throws InvalidSyntaxException {
+        super(context, FILTER, ReferenceFieldLabelDecorator.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/registry/decorator/MainLabelDecoratorRegistry.java	Fri Nov 08 14:22:51 2013 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ * 
+ * This file is part of Thermostat.
+ * 
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ * 
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ * 
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ * 
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.registry.decorator;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.swing.ReferenceFieldDecoratorLayout;
+import com.redhat.thermostat.client.ui.ReferenceFieldLabelDecorator;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+
+public class MainLabelDecoratorRegistry extends ThermostatExtensionRegistry<ReferenceFieldLabelDecorator> {
+
+    private static final String FILTER = "(&(" +
+            Constants.OBJECTCLASS + "=" + ReferenceFieldLabelDecorator.class.getName() +
+            ")(" +
+            ReferenceFieldLabelDecorator.ID + "=" + ReferenceFieldDecoratorLayout.LABEL_MAIN +
+            "))";
+
+    public MainLabelDecoratorRegistry(BundleContext context) throws InvalidSyntaxException {
+        super(context, FILTER, ReferenceFieldLabelDecorator.class);
+    }
+}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceComponent.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceComponent.java	Fri Nov 08 14:22:51 2013 +0100
@@ -43,30 +43,33 @@
 import java.awt.Graphics2D;
 
 import javax.swing.Box;
+import javax.swing.JLabel;
 import javax.swing.JPanel;
 
 import com.redhat.thermostat.client.swing.components.CompositeIcon;
 import com.redhat.thermostat.client.swing.components.Icon;
 import com.redhat.thermostat.client.swing.components.ShadowLabel;
+
 import com.redhat.thermostat.client.swing.internal.accordion.AccordionComponent;
-import com.redhat.thermostat.client.ui.Palette;
+
 import com.redhat.thermostat.storage.core.Ref;
 
 @SuppressWarnings("serial")
 public class ReferenceComponent extends JPanel implements AccordionComponent, ReferenceProvider {
 
     private ShadowLabel mainLabel;
-    
-    private boolean highlight;
-    
-    private boolean selected;
-    
+    private ShadowLabel infoLabel;
+
+    private JLabel iconLabel;
+
     private Icon selectedIcon;
     private Icon icon;
     
     private ReferenceComponentPainter painter;
-    
     private Ref vm;
+
+    private boolean highlight;
+    private boolean selected;
     
     public ReferenceComponent(Ref vm) {
         this(vm, true);
@@ -79,11 +82,27 @@
         
         setLayout(new BorderLayout());
 
+        PainterPanel labelsPane = new PainterPanel();
+        labelsPane.setLayout(new BorderLayout());
+
+        PainterPanel contentPane = new PainterPanel();
+        contentPane.setLayout(new BorderLayout());
+
+        iconLabel = new JLabel();
+        contentPane.add(iconLabel, BorderLayout.WEST);
+        contentPane.add(labelsPane);
+        
         mainLabel = new ShadowLabel();
-        mainLabel.setForeground(Palette.DROID_GRAY.getColor());
         mainLabel.setText(vm.getName());
-        add(mainLabel, BorderLayout.CENTER);
-
+        
+        infoLabel = new ShadowLabel();
+        infoLabel.setFont(infoLabel.getFont().deriveFont(8.0f));
+        infoLabel.setText(vm.getStringID());
+        
+        labelsPane.add(mainLabel, BorderLayout.CENTER);
+        labelsPane.add(infoLabel, BorderLayout.SOUTH);
+        
+        add(contentPane, BorderLayout.CENTER);
         if (addGap) {
             int gapSize = ReferenceTitle.ICON_GAP;
             Component gap = Box.createRigidArea(new Dimension(gapSize, gapSize));
@@ -101,17 +120,35 @@
         this.selected = selected;
         setState();
     }
-
+    
+    public void setMainLabelText(String text) {
+        mainLabel.setText(text);
+    }
+    
+    public String getMainLabelText() {
+        return mainLabel.getText();
+    }
+    
+    public void setInfoLabelText(String text) {
+        infoLabel.setText(text);
+    }
+    
+    public String getInfoLabelText() {
+        return infoLabel.getText();
+    }
+    
     private void setState() {
         UIDefaults palette = UIDefaults.getInstance();
         if (selected) {
             mainLabel.setForeground(palette.getSelectedComponentFGColor());
-            mainLabel.setIcon(selectedIcon);
+            infoLabel.setForeground(palette.getSelectedComponentFGColor());
+            iconLabel.setIcon(selectedIcon);
         } else if (!highlight) {
             mainLabel.setForeground(palette.getComponentFGColor());
-            mainLabel.setIcon(icon);
+            infoLabel.setForeground(palette.getComponentSecondaryFGColor());
+            iconLabel.setIcon(icon);
         }
-        repaint();        
+        repaint();
     }
     
     @Override
@@ -138,4 +175,11 @@
     public Icon getIcon() {
         return icon;
     }
+    
+    private class PainterPanel extends JPanel {
+        @Override
+        protected void paintComponent(Graphics g) {
+            painter.paint((Graphics2D) g, ReferenceComponent.this, getWidth(), getHeight());
+        }
+    }
 }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceTitle.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceTitle.java	Fri Nov 08 14:22:51 2013 +0100
@@ -61,4 +61,8 @@
     public void setIcon(Icon icon) {
         ((ReferenceComponent) getTitleComponent()).setIcon(icon);
     }
+    
+    public ReferenceComponent getReferenceComponent() {
+        return (ReferenceComponent) getTitleComponent();
+    }
 }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/UIDefaults.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/UIDefaults.java	Fri Nov 08 14:22:51 2013 +0100
@@ -66,7 +66,11 @@
         return color != null ? color : Palette.THERMOSTAT_BLU.getColor();
     }
 
+    public Color getComponentSecondaryFGColor() {
+        return Palette.DARK_GRAY.getColor();
+    }
+
     public int getIconSize() {
-        return 24;
+        return 32;
     }
 }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorManager.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorManager.java	Fri Nov 08 14:22:51 2013 +0100
@@ -46,10 +46,12 @@
 import com.redhat.thermostat.client.swing.internal.vmlist.ReferenceComponent;
 import com.redhat.thermostat.client.swing.internal.vmlist.ReferenceTitle;
 import com.redhat.thermostat.client.swing.internal.vmlist.UIDefaults;
+import com.redhat.thermostat.client.swing.internal.vmlist.controller.DecoratorNotifier.DecorationEvent;
 import com.redhat.thermostat.client.swing.internal.vmlist.controller.DecoratorProviderExtensionListener.Action;
 import com.redhat.thermostat.client.ui.Decorator;
 import com.redhat.thermostat.client.ui.DecoratorProvider;
 import com.redhat.thermostat.client.ui.IconDescriptor;
+import com.redhat.thermostat.client.ui.ReferenceFieldLabelDecorator;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.storage.core.HostRef;
@@ -61,21 +63,58 @@
     private DecoratorProviderExtensionListener<HostRef> hostDecorator = new DecoratorProviderExtensionListener<>();
     private DecoratorProviderExtensionListener<VmRef> vmDecorator = new DecoratorProviderExtensionListener<>();
     
+    private LabelDecoratorListener infoLabelDecorator = new LabelDecoratorListener();
+    private LabelDecoratorListener mainLabelDecorator = new LabelDecoratorListener();
+    
     private Map<Decorator, Icon> decoratorsCache = new HashMap<>();
     
     public void registerAndSetIcon(final ReferenceComponent component) {
-        component.setIcon(createIcon(vmDecorator, (VmRef) component.getReference()));
+        VmRef ref = (VmRef) component.getReference();
+        component.setIcon(createIcon(vmDecorator, ref));
+        component.setInfoLabelText(createComponentLabel(infoLabelDecorator, ref,
+                                                        component.getInfoLabelText()));
+        component.setMainLabelText(createComponentLabel(mainLabelDecorator, ref,
+                                                        component.getMainLabelText()));
+        
         // FIXME: this is a leak
         vmDecorator.addDecoratorChangeListener(new ActionListener<DecoratorProviderExtensionListener.Action>() {
             @Override
             public void actionPerformed(ActionEvent<Action> actionEvent) {
-                component.setIcon(createIcon(vmDecorator, (VmRef) component.getReference()));
+                VmRef ref = (VmRef) component.getReference();
+                component.setIcon(createIcon(vmDecorator, ref));
+            }
+        });
+        
+        // FIXME: this is a leak
+        infoLabelDecorator.addDecoratorChangeListener(new ActionListener<DecoratorNotifier.DecorationEvent>() {
+            @Override
+            public void actionPerformed(ActionEvent<DecorationEvent> actionEvent) {
+                VmRef ref = (VmRef) component.getReference();
+                component.setInfoLabelText(createComponentLabel(infoLabelDecorator, ref,
+                                                                component.getInfoLabelText()));
+            }
+        });
+        mainLabelDecorator.addDecoratorChangeListener(new ActionListener<DecoratorNotifier.DecorationEvent>() {
+            @Override
+            public void actionPerformed(ActionEvent<DecorationEvent> actionEvent) {
+                VmRef ref = (VmRef) component.getReference();
+                component.setMainLabelText(createComponentLabel(mainLabelDecorator, ref,
+                                                                component.getMainLabelText()));
             }
         });
     }
 
     public void registerAndSetIcon(final ReferenceTitle pane) {
-        pane.setIcon(createIcon(hostDecorator, (HostRef) pane.getReference()));
+        
+        HostRef ref = (HostRef) pane.getReference();
+        final ReferenceComponent component = pane.getReferenceComponent();
+        
+        pane.setIcon(createIcon(hostDecorator, ref));
+        component.setInfoLabelText(createComponentLabel(infoLabelDecorator, ref,
+                                                        component.getInfoLabelText()));
+        component.setMainLabelText(createComponentLabel(mainLabelDecorator, ref,
+                                                        component.getMainLabelText()));
+        
         // FIXME: this is a leak
         hostDecorator.addDecoratorChangeListener(new ActionListener<DecoratorProviderExtensionListener.Action>() {
             @Override
@@ -83,6 +122,33 @@
                 pane.setIcon(createIcon(hostDecorator, (HostRef) pane.getReference()));
             }
         });
+        
+        infoLabelDecorator.addDecoratorChangeListener(new ActionListener<DecoratorNotifier.DecorationEvent>() {
+            @Override
+            public void actionPerformed(ActionEvent<DecorationEvent> actionEvent) {
+                component.setInfoLabelText(createComponentLabel(infoLabelDecorator,
+                                                                component.getReference(),
+                                                                component.getInfoLabelText()));
+            }
+        });
+        mainLabelDecorator.addDecoratorChangeListener(new ActionListener<DecoratorNotifier.DecorationEvent>() {
+            @Override
+            public void actionPerformed(ActionEvent<DecorationEvent> actionEvent) {
+                component.setMainLabelText(createComponentLabel(mainLabelDecorator,
+                                                                component.getReference(),
+                                                                component.getMainLabelText()));
+            }
+        });
+    }
+    
+    private <R extends Ref> String createComponentLabel(LabelDecoratorListener listener,
+                                                        R reference,
+                                                        String label)
+    {        
+        for (ReferenceFieldLabelDecorator decorator : listener.getDecorators()) {
+            label = decorator.getLabel(label, reference);
+        }
+        return label;
     }
     
     private <R extends Ref> Icon createIcon(DecoratorProviderExtensionListener<R> listener, R ref)
@@ -166,11 +232,21 @@
         return new Icon(image);
     }
     
+    @Deprecated
     DecoratorProviderExtensionListener<HostRef> getHostDecoratorListener() {
         return hostDecorator;
     }
     
+    @Deprecated
     DecoratorProviderExtensionListener<VmRef> getVmDecoratorListener() {
         return vmDecorator;
     }
+
+    public LabelDecoratorListener getInfoLabelDecoratorListener() {
+        return infoLabelDecorator;
+    }
+
+    public LabelDecoratorListener getMainLabelDecoratorListener() {
+        return mainLabelDecorator;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorNotifier.java	Fri Nov 08 14:22:51 2013 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ * 
+ * This file is part of Thermostat.
+ * 
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ * 
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ * 
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ * 
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.vmlist.controller;
+
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ActionNotifier;
+
+/**
+ *
+ */
+public class DecoratorNotifier {
+    public enum DecorationEvent {
+        DECORATION_ADDED,
+        DECORATION_CHANGED,
+        DECORATION_REMOVED;
+    }
+    
+    private final ActionNotifier<DecorationEvent> notifier;
+    
+    public DecoratorNotifier() {
+        notifier = new ActionNotifier<>(this);
+    }
+    
+    public void addDecoratorChangeListener(ActionListener<DecorationEvent> listener) {
+        notifier.addActionListener(listener);
+    }
+    
+    public void removeDecoratorChangeListener(ActionListener<DecorationEvent> listener) {
+        notifier.removeActionListener(listener);
+    }
+    
+    public void fireDecorationRemoved() {
+        notifier.fireAction(DecorationEvent.DECORATION_REMOVED);
+    }
+    
+    public void fireDecorationAdded() {
+        notifier.fireAction(DecorationEvent.DECORATION_ADDED);
+    }
+    
+    public void fireDecorationChanged() {
+        notifier.fireAction(DecorationEvent.DECORATION_CHANGED);
+    }
+}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorProviderExtensionListener.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorProviderExtensionListener.java	Fri Nov 08 14:22:51 2013 +0100
@@ -50,11 +50,12 @@
 /*
  * Provide an implementation of a listener for Registry update. This listener
  * is only to be used to listen for DecoratorProvider changes and its sole
- * purpouse is to re-route the generic VmRef or HostRef DecoratorProvider
+ * purpose is to re-route the generic VmRef or HostRef DecoratorProvider
  * changes to the actual Decoration Manager.
  */
+@Deprecated
 public class DecoratorProviderExtensionListener<T extends Ref> implements ActionListener<ThermostatExtensionRegistry.Action>
-{   
+{
     public enum Action {
         DECORATOR_ADDED,
         DECORATOR_REMOVED,
@@ -89,7 +90,7 @@
         if (! (payload instanceof DecoratorProvider)) {
             throw new IllegalArgumentException("unexpected payload type. " +
                                                payload.getClass().getName() +
-                                               "not allowed here.");
+                                               " not allowed here.");
         }
 
         decorators.add((DecoratorProvider<T>) payload);
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/HostTreeController.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/HostTreeController.java	Fri Nov 08 14:22:51 2013 +0100
@@ -161,6 +161,7 @@
                     proxyModel.removeHeader(host);
                 }                
                 decoratorManager.getHostDecoratorListener().decorationChanged();
+                fireDecoratorChanged();
             }
         });
     }
@@ -274,18 +275,16 @@
                     proxyModel.removeComponent(vm.getHostRef(), vm);
                 }
                 decoratorManager.getVmDecoratorListener().decorationChanged();
+                fireDecoratorChanged();
             }
         });
     }
-
-    public DecoratorProviderExtensionListener<HostRef> getHostDecoratorListener() {
-        return decoratorManager.getHostDecoratorListener();
+            
+    private void fireDecoratorChanged() {
+        decoratorManager.getInfoLabelDecoratorListener().fireDecorationChanged();
+        decoratorManager.getMainLabelDecoratorListener().fireDecorationChanged();
     }
-    
-    public DecoratorProviderExtensionListener<VmRef> getVmDecoratorListener() {
-        return decoratorManager.getVmDecoratorListener();
-    }
-
+            
     public void addHostFilter(HostFilter filter) {
         hostFilters.add(filter);
         filter.addFilterEventListener(filterListener);
@@ -378,4 +377,22 @@
         R reference;
         boolean expanded;
     }
+    
+    // decorator accessors
+    
+    public DecoratorProviderExtensionListener<HostRef> getHostDecoratorListener() {
+        return decoratorManager.getHostDecoratorListener();
+    }
+    
+    public DecoratorProviderExtensionListener<VmRef> getVmDecoratorListener() {
+        return decoratorManager.getVmDecoratorListener();
+    }
+
+    public LabelDecoratorListener getInfoLabelDecoratorListener() {
+        return decoratorManager.getInfoLabelDecoratorListener();
+    }
+    
+    public LabelDecoratorListener getMainLabelDecoratorListener() {
+        return decoratorManager.getMainLabelDecoratorListener();
+    }
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/LabelDecoratorListener.java	Fri Nov 08 14:22:51 2013 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ * 
+ * This file is part of Thermostat.
+ * 
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ * 
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ * 
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ * 
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.vmlist.controller;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.client.ui.ReferenceFieldLabelDecorator;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry.Action;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.storage.core.Ref;
+
+/**
+ *
+ */
+public class LabelDecoratorListener extends DecoratorNotifier
+    implements ActionListener<ThermostatExtensionRegistry.Action>
+{
+    private static final Logger logger =
+            LoggingUtils.getLogger(LabelDecoratorListener.class);
+    
+    private CopyOnWriteArrayList<ReferenceFieldLabelDecorator> decorators;
+    
+    public LabelDecoratorListener() {
+        decorators = new CopyOnWriteArrayList<>();
+    }
+    
+    @Override
+    public void actionPerformed(ActionEvent<Action> actionEvent) {
+        Object payload = actionEvent.getPayload();
+        if (! (payload instanceof ReferenceFieldLabelDecorator)) {
+            // be permissive, but log this
+            logger.log(Level.WARNING, "Dropping unexpected payload type: " +
+                                      payload.getClass().getName());
+        } else {
+            @SuppressWarnings("unchecked")
+            ReferenceFieldLabelDecorator labelDecorator =
+                    (ReferenceFieldLabelDecorator) payload;
+            decorators.add(labelDecorator);
+            
+            switch (actionEvent.getActionId()) {
+            case SERVICE_ADDED:
+                fireDecorationAdded();
+                break;
+                
+            case SERVICE_REMOVED:
+                fireDecorationRemoved();
+                break;
+                
+            default:
+                fireDecorationChanged();
+                break;
+            }
+        }
+    }
+
+    public List<ReferenceFieldLabelDecorator> getDecorators() {
+        return decorators;
+    }
+}
Binary file client/swing/src/main/resources/computer_24.png has changed
Binary file client/swing/src/main/resources/computer_32.png has changed
Binary file client/swing/src/main/resources/java_application_identifier_24.png has changed
Binary file client/swing/src/main/resources/java_application_identifier_32.png has changed
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java	Fri Nov 08 14:22:51 2013 +0100
@@ -37,7 +37,6 @@
 package com.redhat.thermostat.client.swing.internal;
 
 import static org.junit.Assert.assertEquals;
-
 import static org.mockito.Matchers.isA;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doNothing;
@@ -45,6 +44,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.times;
 
 import java.util.concurrent.CountDownLatch;
 
@@ -66,6 +66,7 @@
 import com.redhat.thermostat.client.core.views.SummaryViewProvider;
 import com.redhat.thermostat.client.core.views.VmInformationView;
 import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
+import com.redhat.thermostat.client.swing.internal.registry.decorator.DecoratorRegistryController;
 import com.redhat.thermostat.client.swing.internal.vmlist.controller.ContextActionController;
 import com.redhat.thermostat.client.swing.internal.vmlist.controller.ContextHandler;
 import com.redhat.thermostat.client.swing.internal.vmlist.controller.DecoratorProviderExtensionListener;
@@ -96,7 +97,6 @@
 public class MainWindowControllerImplTest {
 
     private ActionListener<MainView.Action> l;
-    private ActionListener<HostTreeController.ReferenceSelection> hostTreeListener;
     
     private MainWindowControllerImpl controller;
 
@@ -125,6 +125,7 @@
     private VmInformationViewProvider vmInfoViewProvider;
     
     private HostTreeController treeController;
+    private DecoratorRegistryController decoratorController;
 
     private DecoratorProviderExtensionListener<HostRef> hostDecorators;
     private DecoratorProviderExtensionListener<VmRef> vmDecorators;
@@ -219,12 +220,15 @@
         menus = mock(MenuRegistry.class);
         shutdown = mock(CountDownLatch.class);
 
+        decoratorController = mock(DecoratorRegistryController.class);
+        
         when(registryFactory.createMenuRegistry()).thenReturn(menus);
         when(registryFactory.createHostTreeDecoratorRegistry()).thenReturn(hostDecoratorRegistry);
         when(registryFactory.createVMTreeDecoratorRegistry()).thenReturn(vmDecoratorRegistry);
         when(registryFactory.createHostFilterRegistry()).thenReturn(hostFilterRegistry);
         when(registryFactory.createVmFilterRegistry()).thenReturn(vmFilterRegistry);
         when(registryFactory.createVMInformationRegistry()).thenReturn(vmInfoRegistry);
+        when(registryFactory.createDecoratorController()).thenReturn(decoratorController);
         
         ArgumentCaptor<ActionListener> grabHostFiltersListener = ArgumentCaptor.forClass(ActionListener.class);
         doNothing().when(hostFilterRegistry).addActionListener(grabHostFiltersListener.capture());
@@ -244,7 +248,6 @@
         controller = new MainWindowControllerImpl(context, appSvc, view, registryFactory, shutdown);
         
         l = grabListener.getValue();
-        hostTreeListener = hostTreeCaptor.getValue();
     }
 
     private void setUpHostContextActions() {
@@ -293,6 +296,17 @@
     }
 
     @Test
+    public void verifyDecoratorsControllerRegisteredAndStarted() {
+        
+        controller.shutdownApplication();
+
+        verify(view, atLeastOnce()).getHostTreeController();
+        verify(decoratorController, times(1)).init(treeController);
+        verify(decoratorController, times(1)).start();
+        verify(decoratorController, times(1)).stop();
+    }
+    
+    @Test
     @SuppressWarnings({ "rawtypes", "unchecked" })
     public void verifyDecoratorsRegisteredAndStarted() {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/registry/decorator/DecoratorRegistryControllerTest.java	Fri Nov 08 14:22:51 2013 +0100
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ * 
+ * This file is part of Thermostat.
+ * 
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ * 
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ * 
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ * 
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.registry.decorator;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.swing.internal.vmlist.controller.HostTreeController;
+import com.redhat.thermostat.client.swing.internal.vmlist.controller.LabelDecoratorListener;
+
+/**
+ *
+ */
+public class DecoratorRegistryControllerTest {
+
+    private DecoratorRegistryFactory registryFactory;
+    private HostTreeController hostController;
+
+    private LabelDecoratorListener l0;
+    private LabelDecoratorListener l1;
+    
+    private InfoLabelDecoratorRegistry infoLabel;
+    private MainLabelDecoratorRegistry mainLabel;
+
+    @Before
+    public void setUp() throws InvalidSyntaxException {
+        
+        infoLabel = mock(InfoLabelDecoratorRegistry.class);
+        mainLabel = mock(MainLabelDecoratorRegistry.class);
+       
+        registryFactory = mock(DecoratorRegistryFactory.class);
+        
+        when(registryFactory.createInfoLabelDecoratorRegistry()).thenReturn(infoLabel);
+        when(registryFactory.createMainLabelDecoratorRegistry()).thenReturn(mainLabel);
+        
+        l0 = mock(LabelDecoratorListener.class);
+        l1 = mock(LabelDecoratorListener.class);
+        
+        hostController = mock(HostTreeController.class);
+        when(hostController.getInfoLabelDecoratorListener()).thenReturn(l0);
+        when(hostController.getMainLabelDecoratorListener()).thenReturn(l1);
+    }
+    
+    @Test
+    public void testInit() throws InvalidSyntaxException {
+        DecoratorRegistryController controller =
+                new DecoratorRegistryController(registryFactory);
+        controller.init(hostController);
+        
+        verify(registryFactory).createInfoLabelDecoratorRegistry();
+        verify(registryFactory).createMainLabelDecoratorRegistry();
+    }
+
+    @Test
+    public void testStart() throws InvalidSyntaxException {
+        DecoratorRegistryController controller =
+                new DecoratorRegistryController(registryFactory);
+        controller.init(hostController);
+        
+        controller.start();
+        
+        verify(infoLabel).addActionListener(l0);
+        verify(infoLabel).start();
+        
+        verify(mainLabel).addActionListener(l1);
+        verify(mainLabel).start();
+        
+        verify(mainLabel).addActionListener(l1);
+        verify(mainLabel).start();
+        
+        verify(mainLabel).addActionListener(l1);
+        verify(mainLabel).start();
+    }
+
+    @Test
+    public void testStop() throws InvalidSyntaxException {
+        DecoratorRegistryController controller =
+                new DecoratorRegistryController(registryFactory);
+        controller.init(hostController);
+        
+        // since it's all mocked, we don't need to start anything
+        // controller.start();
+        
+        controller.stop();
+
+        verify(infoLabel).removeActionListener(l0);
+        verify(infoLabel).stop();
+        
+        verify(mainLabel).removeActionListener(l1);
+        verify(mainLabel).stop();
+        
+        verify(mainLabel).removeActionListener(l1);
+        verify(mainLabel).stop();
+        
+        verify(mainLabel).removeActionListener(l1);
+        verify(mainLabel).stop();
+    } 
+}
--- a/laf-utils/src/main/java/com/redhat/thermostat/internal/utils/laf/ThemeManager.java	Fri Nov 08 04:24:41 2013 -0500
+++ b/laf-utils/src/main/java/com/redhat/thermostat/internal/utils/laf/ThemeManager.java	Fri Nov 08 14:22:51 2013 +0100
@@ -145,9 +145,10 @@
         }
         
         // TODO: document those or place them into a proper UI class
-        UIManager.put("thermostat-fg-color", Palette.DROID_BLACK);
-        UIManager.put("thermostat-selection-fg-color", Palette.THERMOSTAT_BLU);        
-        UIManager.put("thermostat-selection-bg-color", Palette.LIGHT_GRAY);
+        UIManager.put("thermostat-fg-color", Palette.DROID_BLACK.getColor());
+        UIManager.put("thermostat-bg-color", Palette.PALE_GRAY.getColor());
+        UIManager.put("thermostat-selection-fg-color", Palette.THERMOSTAT_BLU.getColor());        
+        UIManager.put("thermostat-selection-bg-color", Palette.LIGHT_GRAY.getColor());
         if (nimbusBased) {
             // very internal and very secret for now, should be moved
             // to a proper location but first needs to be appropriately tested
@@ -159,7 +160,10 @@
             UIManager.put("thermostat-selection-fg-color", color);
             
             color = UIManager.getDefaults().getColor("text");
-            UIManager.put("thermostat-fg-color", color);            
+            UIManager.put("thermostat-fg-color", color);
+            
+            color = UIManager.getDefaults().getColor("control");
+            UIManager.put("thermostat-bg-color", color);
         }
     }
 }