/**
   * Invoked when a property changes. <code>MetalRootPaneUI</code> is primarily interested in events
   * originating from the <code>JRootPane</code> it has been installed on identifying the property
   * <code>windowDecorationStyle</code>. If the <code>windowDecorationStyle</code> has changed to a
   * value other than <code>JRootPane.NONE</code>, this will add a <code>Component</code> to the
   * <code>JRootPane</code> to render the window decorations, as well as installing a <code>Border
   * </code> on the <code>JRootPane</code>. On the other hand, if the <code>windowDecorationStyle
   * </code> has changed to <code>JRootPane.NONE</code>, this will remove the <code>Component</code>
   * that has been added to the <code>JRootPane</code> as well resetting the Border to what it was
   * before <code>installUI</code> was invoked.
   *
   * @param e A PropertyChangeEvent object describing the event source and the property that has
   *     changed.
   */
  public void propertyChange(PropertyChangeEvent e) {
    super.propertyChange(e);

    String propertyName = e.getPropertyName();
    if (propertyName == null) {
      return;
    }

    if (propertyName.equals("windowDecorationStyle")) {
      JRootPane root = (JRootPane) e.getSource();
      int style = root.getWindowDecorationStyle();

      // This is potentially more than needs to be done,
      // but it rarely happens and makes the install/uninstall process
      // simpler. MetalTitlePane also assumes it will be recreated if
      // the decoration style changes.
      uninstallClientDecorations(root);
      if (style != JRootPane.NONE) {
        installClientDecorations(root);
      }
    } else if (propertyName.equals("ancestor")) {
      uninstallWindowListeners(root);
      if (((JRootPane) e.getSource()).getWindowDecorationStyle() != JRootPane.NONE) {
        installWindowListeners(root, root.getParent());
      }
    }
    return;
  }
  /**
   * Invokes supers implementation to uninstall any of its state. This will also reset the <code>
   * LayoutManager</code> of the <code>JRootPane</code>. If a <code>Component</code> has been added
   * to the <code>JRootPane</code> to render the window decoration style, this method will remove
   * it. Similarly, this will revert the Border and LayoutManager of the <code>JRootPane</code> to
   * what it was before <code>installUI</code> was invoked.
   *
   * @param c the JRootPane to uninstall state from
   */
  public void uninstallUI(JComponent c) {
    super.uninstallUI(c);
    uninstallClientDecorations(root);

    layoutManager = null;
    mouseInputListener = null;
    root = null;
  }
 /**
  * Invokes supers implementation of <code>installUI</code> to install the necessary state onto the
  * passed in <code>JRootPane</code> to render the metal look and feel implementation of <code>
  * RootPaneUI</code>. If the <code>windowDecorationStyle</code> property of the <code>JRootPane
  * </code> is other than <code>JRootPane.NONE</code>, this will add a custom <code>Component
  * </code> to render the widgets to <code>JRootPane</code>, as well as installing a custom <code>
  * Border</code> and <code>LayoutManager</code> on the <code>JRootPane</code>.
  *
  * @param c the JRootPane to install state onto
  */
 public void installUI(JComponent c) {
   super.installUI(c);
   root = (JRootPane) c;
   int style = root.getWindowDecorationStyle();
   if (style != JRootPane.NONE) {
     installClientDecorations(root);
   }
 }