/**
   * 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;
  }
  /**
   * Installs the necessary state onto the JRootPane to render client decorations. This is ONLY
   * invoked if the <code>JRootPane</code> has a decoration style other than <code>JRootPane.NONE
   * </code>.
   */
  private void installClientDecorations(JRootPane root) {
    installBorder(root);

    JComponent titlePane = createTitlePane(root);

    setTitlePane(root, titlePane);
    installWindowListeners(root, root.getParent());
    installLayout(root);
    if (window != null) {
      root.revalidate();
      root.repaint();
    }
  }
  public void cancel(InputEvent e) {
    if (isDisposed()) return;

    if (myPopup != null) {
      if (!canClose()) {
        return;
      }
      storeDimensionSize(myContent.getSize());
      if (myUseDimServiceForXYLocation) {
        final JRootPane root = myComponent.getRootPane();
        if (root != null) {
          final Container popupWindow = root.getParent();
          if (popupWindow != null && popupWindow.isShowing()) {
            storeLocation(popupWindow.getLocationOnScreen());
          }
        }
      }

      if (e instanceof MouseEvent) {
        IdeEventQueue.getInstance().blockNextEvents(((MouseEvent) e));
      }

      myPopup.hide(false);

      if (ApplicationManagerEx.getApplicationEx() != null) {
        StackingPopupDispatcher.getInstance().onPopupHidden(this);
      }

      if (myInStack) {
        myFocusTrackback.setForcedRestore(!myOk && myFocusable);
        myFocusTrackback.restoreFocus();
      }

      disposePopup();

      if (myListeners != null) {
        for (JBPopupListener each : myListeners) {
          each.onClosed(new LightweightWindowEvent(this, myOk));
        }
      }
    }

    Disposer.dispose(this, false);
  }