import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Skin;
import javafx.scene.control.skin.ButtonSkin;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ButtonPanning extends Application
{
  private Node viewPort;
  private MouseEvent lastFiredEvent;

  public static void main(String[] args)
  {
    launch(args);
  }

  @Override
  public void start(Stage primaryStage) throws Exception
  {
    boolean fix = true;
    primaryStage.setTitle("Hello World!");
    VBox box = new VBox();
    addBtns(box, 30, fix);
    ScrollPane pane = new ScrollPane(box)
    {

      @Override
      protected Skin<?> createDefaultSkin()
      {
        Skin<?> skin = super.createDefaultSkin();
        for (Node ch : getChildren())
        {
          if (ch.getStyleClass().contains("viewport"))
          {
            viewPort = ch;
            break;
          }
        }
        return skin;
      }
    };
    pane.addEventFilter(MouseEvent.MOUSE_PRESSED, e ->
    {
      if (fix && lastFiredEvent != e)
      {
        lastFiredEvent = e.copyFor(e.getSource(), viewPort);
        viewPort.fireEvent(lastFiredEvent); //This fix is needed for JAVA >8
      }
    });
    pane.setPannable(true);

    primaryStage.setScene(new Scene(pane, 300, 250));
    primaryStage.show();
  }

  private void addBtns(VBox box, int count, boolean fix)
  {
    for (int i = 0; i < count; i++)
    {
      box.getChildren().add(new Button("" + (i + 1))
      {
        @Override
        protected Skin<?> createDefaultSkin()
        {
          return new FixedButtonSkin(this, fix);
        }
      });
    }
  }

  class FixedButtonSkin extends ButtonSkin
  {

    public FixedButtonSkin(Button control, boolean fix)
    {
      super(control);
      if (fix)
        consumeMouseEvents(false);//this fix alone was enough for JAVA 8
    }

  }
} 