Monday, May 14, 2012

JDK 7 Beans.setDesignTime/Beans.isDesignTime

JDK 7 introduces a change to Beans.setDesignTime(bool value) and Beans.isDesignTime() where the design-time state instead of application global is now a thread group local variable. It's so multiple frameworks can be used simultaneously and they can be either design-time or run-time as needed. Basically it is an IDE requirement. Needless to say this change is a bit unorthodox with a bizarre side effect and most will want to bring back the old behavior. The simplest way of doing this is to iterate over each thread group and set the design-time state.

  Runnable runnable = new Runnable()
  {
    public void run()
    {
      Beans.setDesignTime(true);
    }
  };

  ThreadGroup root = Thread.currentThread().getThreadGroup();
 
  while (root.getParent() != null)
    root = root.getParent();

  ThreadGroup[] threadGroups = new ThreadGroup[root.activeGroupCount()];
  // ThreadGroup.enumerate copies all ThreadGroup subgroups, not including the root ThreadGroup.
  root.enumerate(threadGroups, true);

  new Thread(root, runnable).start();

  for (ThreadGroup group : threadGroups)
    new Thread(group, runnable).start();
If any thread groups are created after this code is run then design-time will not be set. So the best practices are all thread groups need to have design-time set, or any calls to Beans.isDesignTime() need to be synchronized to the EDT.