wiki:JComponentEnvironment

JComponentEnvironment and constructing Swing user interfaces using the VirtualHumanLoader

The JComponentEnvironment can be used to set up the user interface layout of demo in which the different UI elements are later filled out using the XML specification. The layout can be created using JPanels (or any other JComponent):

final JFrame jframe = new JFrame();
final AsapEnvironment ee = new AsapEnvironment();
final JComponentEnvironment jce = new JComponentEnvironment();
try
{
    SwingUtilities.invokeAndWait(new Runnable()
    {

        @Override
        public void run()
        {
            JPanel jPanel = new JPanel();
            jce.registerComponent("panel1", jPanel);
            jframe.setLayout(new BorderLayout());
            jframe.add(jPanel, BorderLayout.SOUTH);
        }
    });
}
catch (InvocationTargetException e)
{
    throw new RuntimeException(e);
}
catch (InterruptedException e)
{
    throw new RuntimeException(e);
}
ArrayList<Environment> environments = new ArrayList<Environment>();
environments.add(jce);
...
ee.init(environments, clock);
..
ee.loadVirtualHuman("humanoid", "", "humanoid.xml", "AsapRealizer demo");

The registered component can then be hooked up to a JComponentEmbodimentLoader in the VirtualHumanLoader:

<Loader id="panelembodiment" loader="hmi.jcomponentenvironment.loader.JComponentEmbodimentLoader">
  <JComponent id="panel1"/>             
</Loader>

Which can be used in any other loader, for example in a JLabelTextEmbodiment:

<Loader id="textembodiment" loader="asap.textengine.JLabelTextEmbodiment" requiredloaders="panelembodiment"/>
<Loader id="textengine" loader="asap.textengine.loader.TextEngineLoader" requiredloaders="textembodiment"/>

Creating your own loadable UI component

public class YourUIComponent implements Loader
{
  private JComponent yourComponent;
  private JComponentEmbodiment jce = null;

  public void readXML(XMLTokenizer tokenizer, String loaderId, String vhId, String vhName, Environment[] environments,
            Loader... requiredLoaders) throws IOException
  {
     
     for (EmbodimentLoader e : ArrayUtils.getClassesOfType(requiredLoaders, EmbodimentLoader.class))
     {
       if (e.getEmbodiment() instanceof JComponentEmbodiment)
       {
         jce = (JComponentEmbodiment) e.getEmbodiment();
       }
     }
     if (jce == null)
     {
       throw new RuntimeException("YourUIComponent requires an Embodiment of type JComponentEmbodiment");
     }

     yourComponent = ...
     SwingUtilities.invokeLater(new Runnable()
     {
       public void run()
       {
         jce.addJComponent(yourComponent);
       }
     });     
  }
  @Override
  public void unload()
  {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                jce.removeJComponent(yourComponent);
            }
        });
  }
  ...
}