/**
  * Base constructor for invocation by the subclasses. Subclass implementations should make sure
  * that this constructor can be invoked outside of the JavaFX thread.
  *
  * @param c the editor controller (should not be null).
  */
 protected AbstractPanelController(EditorController c) {
   assert c != null;
   this.editorController = c;
   startListeningToEditorSelection();
   startListeningToJobManagerRevision();
   editorController
       .fxomDocumentProperty()
       .addListener(
           new ChangeListener<FXOMDocument>() {
             @Override
             public void changed(
                 ObservableValue<? extends FXOMDocument> ov, FXOMDocument od, FXOMDocument nd) {
               assert editorController.getFxomDocument() == nd;
               if (od != null) {
                 od.sceneGraphRevisionProperty().removeListener(fxomDocumentRevisionListener);
               }
               fxomDocumentDidChange(od);
               if (nd != null) {
                 nd.sceneGraphRevisionProperty().addListener(fxomDocumentRevisionListener);
               }
             }
           });
   if (editorController.getFxomDocument() != null) {
     editorController
         .getFxomDocument()
         .sceneGraphRevisionProperty()
         .addListener(fxomDocumentRevisionListener);
   }
 }
  private void handleMouseEvent(MouseEvent me) {
    // Handle cursor
    final Scene scene = getScene();

    if (scene == null) {
      return;
    }

    // When another window is focused (just like the preview window),
    // we use default cursor
    if (scene.getWindow() != null && !scene.getWindow().isFocused()) {
      setCursor(Cursor.DEFAULT);
      return;
    }

    final LibraryListItem listItem = getItem();
    ILibraryItem item = null;

    if (listItem != null) {
      item = listItem.getLibItem();
    }

    boolean isSection = false;
    if (listItem != null && listItem.getSectionName() != null) {
      isSection = true;
    }

    if (me.getEventType() == MouseEvent.MOUSE_ENTERED) {
      if (isEmpty() || isSection) {
        setCursor(Cursor.DEFAULT);
      } else {
        setCursor(Cursor.OPEN_HAND);
      }
    } else if (me.getEventType() == MouseEvent.MOUSE_PRESSED) {
      if (isEmpty() || isSection) {
        setCursor(Cursor.DEFAULT);
      } else {
        setCursor(Cursor.CLOSED_HAND);
      }
    } else if (me.getEventType() == MouseEvent.MOUSE_RELEASED) {
      if (isEmpty() || isSection) {
        setCursor(Cursor.DEFAULT);
      } else {
        setCursor(Cursor.OPEN_HAND);
      }
    } else if (me.getEventType() == MouseEvent.MOUSE_EXITED) {
      setCursor(Cursor.DEFAULT);
    } else if (me.getEventType() == MouseEvent.MOUSE_CLICKED) {
      // On double click ask for addition of the drag able item on Content
      if (me.getClickCount() == 2 && me.getButton() == MouseButton.PRIMARY) {
        if (!isEmpty() && !isSection && item != null) {
          if (editorController.canPerformInsert(item)) {
            editorController.performInsert(item);
          }
        }
      }
    }
  }
 /**
  * Removes the listener which invokes {@link #jobManagerRevisionDidChange} each time the job
  * manager has executed, undone or redone a job. Subclasses may invoke this routine to temporarily
  * stop listening to the job manager from the editor controller. Use {@link
  * AbstractPanelController#startListeningToJobManagerRevision} to re-enable job manager listening.
  */
 protected final void stopListeningToJobManagerRevision() {
   editorController.getJobManager().revisionProperty().removeListener(jobManagerRevisionListener);
 }
 /**
  * Removes the listener which invokes {@link #editorSelectionDidChange} each time the editor
  * controller changes the selected objects. Subclasses may invoke this routine to temporarily stop
  * listening to the selection changes from the editor controller. Use {@link
  * AbstractPanelController#startListeningToEditorSelection} to re-enable selection listening.
  */
 protected final void stopListeningToEditorSelection() {
   editorController.getSelection().revisionProperty().removeListener(editorSelectionListener);
 }