Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8088277

PopupWindow jumps back to original location when window of parent node was moved

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 8
    • javafx
    • None
    • JDK 8 Build 113, MacOS X (Maverick)

      When the user moves the parent stage of a popup window and then interacts with the popup then the popup will jump back to the location where it was initially shown.

      The error can be reproduced with the code below. Click on the button in the stage to bring up the popup window. Then move the stage to a different location and click somewhere in the popup. The popup will jump back to where it was initially shown.

      --------------------------------
      TestPopupEditor.java

      package com.dlsc.flexganttfx;

      import javafx.animation.KeyFrame;
      import javafx.animation.KeyValue;
      import javafx.animation.Timeline;
      import javafx.application.Application;
      import javafx.beans.property.DoubleProperty;
      import javafx.event.ActionEvent;
      import javafx.event.EventHandler;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.input.MouseEvent;
      import javafx.stage.Stage;
      import javafx.util.Duration;

      import org.scenicview.ScenicView;

      import com.dlsc.flexganttfx.view.popup.PopupEditor;
      import com.dlsc.flexganttfx.view.util.StageTitleMemoryDisplayThread;

      public class TestPopupEditor extends Application {

      @Override
      public void start(Stage stage) throws Exception {
      stage.setTitle("Test");

      final Button button = new Button("Test");
      final PopupEditor editor = new PopupEditor();

      button.setOnMouseClicked(new EventHandler<MouseEvent>() {
      @Override
      public void handle(MouseEvent evt) {
      if (editor.isShowing()) {
      editor.hide();
      } else {
      if (evt.getClickCount() == 2) {
      editor.show(button, evt.getScreenX(), evt.getScreenY() - 20);
      }
      }
      }
      });

      Scene scene = new Scene(button);
      stage.setScene(scene);

      stage.setWidth(300);
      stage.setHeight(300);

      scene.getStylesheets()
      .add(TestPopupEditor.class.getResource("popup.css")
      .toExternalForm());

      stage.show();
      }

      public static void main(String[] args) {
      Application.launch(args);
      }
      }

      --------------------------------
      PopupEditor.java

      package com.dlsc.flexganttfx.view.popup;

      import static javafx.stage.PopupWindow.AnchorLocation.CONTENT_TOP_LEFT;
      import javafx.scene.control.PopupControl;
      import javafx.scene.control.Skin;

      public class PopupEditor extends PopupControl {

      private static final String DEFAULT_STYLE_CLASS = "popup-editor";

      public PopupEditor() {
      super();

      getStyleClass().add(DEFAULT_STYLE_CLASS);

      setAutoFix(false);

      setAnchorLocation(CONTENT_TOP_LEFT);
      }

      @Override
      protected Skin<?> createDefaultSkin() {
      return new PopupEditorSkin(this);
      }
      }

      --------------------------------
      PopupEditorSkin.java

      package com.dlsc.flexganttfx.view.popup;

      import java.text.MessageFormat;

      import javafx.beans.InvalidationListener;
      import javafx.beans.Observable;
      import javafx.beans.value.ChangeListener;
      import javafx.beans.value.ObservableValue;
      import javafx.scene.Node;
      import javafx.scene.control.Accordion;
      import javafx.scene.control.Button;
      import javafx.scene.control.ListView;
      import javafx.scene.control.Skin;
      import javafx.scene.control.Slider;
      import javafx.scene.control.TitledPane;
      import javafx.scene.layout.StackPane;
      import javafx.scene.layout.VBox;
      import javafx.scene.shape.SVGPath;
      import javafx.scene.text.TextAlignment;

      public class PopupEditorSkin implements Skin<PopupEditor>, InvalidationListener {
      private PopupEditor editor;
      private Accordion accordion;
      private SVGPath path;
      private StackPane stackPane;

      public PopupEditorSkin(PopupEditor editor) {
      this.editor = editor;
      this.accordion = new Accordion();
      this.path = new SVGPath();
      this.stackPane = new StackPane();

      path.getStyleClass().add("decoration");
      path.setManaged(false);

      stackPane.getStyleClass().add("background");
      stackPane.getChildren().add(path);
      stackPane.getChildren().add(accordion);

      accordion.getPanes().add(createTitledPane("Start Time & Duration"));
      accordion.getPanes().add(createTitledPane("Dependencies"));
      accordion.getPanes().add(createTitledPane("Priority"));
      accordion.getPanes().add(createTitledPane("Assignments / Resources"));

      accordion.widthProperty().addListener(this);
      accordion.heightProperty().addListener(this);

      accordion.skinProperty().addListener(new ChangeListener<Skin<?>>() {
      @Override
      public void changed(ObservableValue<? extends Skin<?>> value,
      Skin<?> oldSkin, Skin<?> newSkin) {
      updatePath();
      }
      });
      }

      @Override
      public void invalidated(Observable observable) {
      updatePath();
      }

      private void updatePath() {
      double width = stackPane.getWidth();
      double height = stackPane.getHeight();
      double arrow = 12;

      String content = MessageFormat
      .format("M{2} 0 L{0} 0 L{0} {1} L{2} {1} L{2} 30 L0 20 L{2} 10 L{2} 0 Z",
      width, height, arrow);

      path.setContent(content);
      }

      private TitledPane createTitledPane(String title) {
      VBox box = new VBox(5);
      box.getChildren().add(new Button("Test"));
      box.getChildren().add(new Slider());

      ListView<String> view = new ListView<>();
      view.setPrefHeight(100);
      box.getChildren().add(view);
      TitledPane pane = new TitledPane(title, box);
      pane.setTextAlignment(TextAlignment.LEFT);
      return pane;
      }

      @Override
      public PopupEditor getSkinnable() {
      return editor;
      }

      @Override
      public Node getNode() {
      return stackPane;
      }

      @Override
      public void dispose() {
      editor = null;
      accordion = null;
      }
      }

      --------------------------------
      popup.css

      .popup-editor > .background {
      -fx-background-color: transparent;
      -fx-padding: 16;
      }

      .popup-editor > .background > .decoration {
      -fx-fill: rgba(255.0,255.0,255.0, 0.9);
      -fx-stroke: lightgray;
      -fx-effect: dropshadow(gaussian, lightgray, 10, 0, 2, 2);
      }

      .popup-editor > .background > .accordion {
      }

      .titled-pane {
      -fx-animated: true;
      }

      .titled-pane > .title {
      -fx-background-color: transparent;
      }

      .titled-pane > .content {
      -fx-background-color: transparent;
      -fx-border-color: null;
      -fx-padding: 10;
      }

      .titled-pane > .title > .arrow-button > .arrow {
      -fx-pref-width: 0.0;
      -fx-pref-height: 0.0;
      }


            Unassigned Unassigned
            dlemmermajfx Dirk Lemmermann (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Imported: