1 Reply Latest reply: Sep 12, 2013 3:34 AM by wzberger RSS

    Resize operation by MouseDrag is jerky

    wzberger

      When trying to resize a panel by mouse dragging the drag operation is not smooth for some reason. Below there are two tests with a different approach. Unfortunately both lead to the same result - the resize operation is very jerky.

       

       

      import javafx.application.Application;
      import javafx.beans.binding.Bindings;
      import javafx.event.EventHandler;
      import javafx.scene.Group;
      import javafx.scene.Node;
      import javafx.scene.Scene;
      import javafx.scene.control.Label;
      import javafx.scene.control.ProgressIndicator;
      import javafx.scene.control.Slider;
      import javafx.scene.input.MouseEvent;
      import javafx.scene.layout.BorderPane;
      import javafx.scene.layout.HBox;
      import javafx.scene.layout.Pane;
      import javafx.stage.Stage;
      
      //see http://docs.oracle.com/javafx/2/events/DraggablePanelsExample.java.htm
      public final class ResizePanelTest extends Application
      {
        @Override
        public void start(final Stage stage)
        {
          final Node progressPanel = makeDraggable(createResizeablePanel());
          progressPanel.relocate(0, 106);
      
          final Pane panelsPane = new Pane();
          panelsPane.getChildren().add(progressPanel);
      
          final BorderPane sceneRoot = new BorderPane();
          sceneRoot.setCenter(panelsPane);
      
          final Scene scene = new Scene(sceneRoot, 400, 300);
          stage.setScene(scene);
          stage.show();
        }
      
        public static void main(final String[] args)
        {
          launch(args);
        }
      
        private Node makeDraggable(final Node node)
        {
          final DragContext dragContext = new DragContext();
          final Group wrapGroup = new Group(node);
      
          wrapGroup.addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>()
          {
            public void handle(final MouseEvent mouseEvent)
            {
              // disable mouse events for all children
              mouseEvent.consume();
            }
          });
      
          wrapGroup.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>()
          {
            public void handle(final MouseEvent mouseEvent)
            {
              dragContext.mouseAnchorX = mouseEvent.getX();
              dragContext.mouseAnchorY = mouseEvent.getY();
              dragContext.initialWidth = ((Pane)node).getWidth();
              dragContext.initialHeight = ((Pane)node).getHeight();
            }
          });
      
          wrapGroup.addEventFilter(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>()
          {
            public void handle(final MouseEvent mouseEvent)
            {
              ((Pane)node).setPrefSize(dragContext.initialWidth+mouseEvent.getX() - dragContext.mouseAnchorX, dragContext.initialHeight+mouseEvent.getY() - dragContext.mouseAnchorY);
            }
          });
      
          return wrapGroup;
        }
      
        private static Node createResizeablePanel()
        {
          final Slider slider = new Slider();
          final ProgressIndicator progressIndicator = new ProgressIndicator(0);
          progressIndicator.progressProperty().bind(Bindings.divide(slider.valueProperty(), slider.maxProperty()));
      
          final HBox panel = new HBox(10);
          panel.getChildren().addAll(new Label("Progress:"), slider, progressIndicator);
          panel.setStyle("-fx-background-color: white;" + "-fx-border-color: black;" + "-fx-border-width: 1;" + "-fx-border-radius: 6;" + "-fx-padding: 6;");
      
          return panel;
        }
      
        private static final class DragContext
        {
          public double mouseAnchorX;
          public double mouseAnchorY;
          public double initialWidth;
          public double initialHeight;
        }
      }
      

       

       

       

      import javafx.application.Application;
      import javafx.beans.binding.Bindings;
      import javafx.event.EventHandler;
      import javafx.event.EventType;
      import javafx.scene.Node;
      import javafx.scene.Scene;
      import javafx.scene.control.Label;
      import javafx.scene.control.ProgressIndicator;
      import javafx.scene.control.Slider;
      import javafx.scene.input.MouseEvent;
      import javafx.scene.layout.BorderPane;
      import javafx.scene.layout.HBox;
      import javafx.scene.layout.Pane;
      import javafx.stage.Stage;
      
      public final class ResizePanelTest2 extends Application
      {
        @Override
        public void start(final Stage stage)
        {
          final Node resizablePanel = createResizablePanel();
          resizablePanel.relocate(0, 106);
      
          final Pane panelsPane = new Pane();
          panelsPane.getChildren().add(resizablePanel);
      
          final BorderPane sceneRoot = new BorderPane();
          sceneRoot.setCenter(panelsPane);
         
          final Scene scene = new Scene(sceneRoot, 400, 300);
          stage.setScene(scene);
          stage.setTitle(getClass().getSimpleName());
          stage.show();
        }
      
        public static void main(final String[] args)
        {
          launch(args);
        }
      
        private static Node createResizablePanel()
        {
          final Slider slider = new Slider();
          final ProgressIndicator progressIndicator = new ProgressIndicator(0);
          progressIndicator.progressProperty().bind(Bindings.divide(slider.valueProperty(), slider.maxProperty()));
      
          final Pane panel = new ResizablePanel();
          panel.getChildren().addAll(new Label("Progress:"), slider, progressIndicator);
          panel.setStyle("-fx-background-color: white;" + "-fx-border-color: black;" + "-fx-border-width: 1;" + "-fx-border-radius: 6;" + "-fx-padding: 6;");
      
          return panel;
        }
      
        public static class ResizablePanel extends HBox
        {
          public ResizablePanel()
          {
            setSpacing(10);
            addEventHandler(MouseEvent.ANY, new MouseEventHandler<MouseEvent>());     
          }
         
          private class MouseEventHandler<T extends MouseEvent> implements EventHandler<MouseEvent>
          {
            private double x;
            private double y;
            private double w;
            private double h;
      
            @Override
            public void handle(MouseEvent evt)
            {
              EventType<?> type = evt.getEventType();
              if (type == MouseEvent.MOUSE_PRESSED)
              {
                x = evt.getSceneX();
                y = evt.getSceneY();
                w = getWidth();
                h = getHeight();
              }
              else if (type == MouseEvent.MOUSE_DRAGGED)
              {
                double dx = evt.getSceneX() - x;
                double dy = evt.getSceneY() - y;
                setPrefSize(w + dx, h + dy);
                evt.consume();
              }
            }
          }
        }
      }