按鼠标键时保持运行的鼠标事件

时间:2018-05-02 08:17:54

标签: javafx

我正在处理一个自定义滚动条,当我按住主鼠标键时它会移动。我试过setOnMousePressed,但这只运行一次。当我按下一个键时,是否有一个持续运行的事件?

编辑:我应该提到自定义滚动条实际上​​是一个普通的窗格,我在滚动窗格中显示更大范围的图形。

2 个答案:

答案 0 :(得分:3)

正如评论中所指出的,这是滚动条的默认行为。但是,如果你想自己实现这样的东西,出于某种原因,一个选择是将AnimationTimer与鼠标监听器结合使用:

AnimationTimer scrollDownTimer = new AnimationTimer() {

    long lastMoveTime = -1 ;

    @Override
    public void handle(long now) {
        if (lastMoveTime > 0) {
            long elapsedNanos = now-lastMoveTime ;
            // scroll down amount based on time elapsed...
        }
        lastMoveTime = now ;
    }

    @Override
    public void start() {
        lastMoveTime = -1 ;
        super.start();
    }
};

现在只是

scrollDownButton.setOnMousePressed(e -> scrollDownTimer.start());
scrollDownButton.setOnMouseReleased(e -> scrollDownTimer.stop());

这是一个完整的例子:

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class ScrollingExample extends Application {

    private Rectangle rect ;
    private Pane rectPane ;

    @Override
    public void start(Stage primaryStage) {
        rect = new Rectangle(0, 200, 40, 40);
        rect.setFill(Color.CORAL);

        Label left = new Label("Left");
        Label right = new Label("Right");

        ScrollTimer scrollTimer = new ScrollTimer(); 

        left.setOnMousePressed(e -> {
            scrollTimer.setDirection(Direction.LEFT);
            scrollTimer.start();
        });

        left.setOnMouseReleased(e -> scrollTimer.stop());

        right.setOnMousePressed(e -> {
            scrollTimer.setDirection(Direction.RIGHT);
            scrollTimer.start();
        });

        right.setOnMouseReleased(e -> scrollTimer.stop());

        AnchorPane buttons = new AnchorPane(left, right);
        AnchorPane.setLeftAnchor(left, 5.0);
        AnchorPane.setRightAnchor(right, 5.0);

        rectPane = new Pane(rect);

        BorderPane root = new BorderPane(rectPane);
        root.setTop(buttons);

        Scene scene = new Scene(root, 800, 800);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public enum Direction { 
        LEFT(-1), RIGHT(1) ; 
        private int multiplier ;

        Direction(int multiplier) {
            this.multiplier = multiplier ;
        }

        public double multiply(double value) {
            return value * multiplier ;
        }
    }

    public  class ScrollTimer extends AnimationTimer {
        private double speed = 250 ; // pixels/second

        private Direction direction = Direction.LEFT ;

        private long lastUpdate ;

        @Override
        public void start() {
            lastUpdate = -1 ;
            super.start();
        }

        @Override
        public void handle(long now) {

            if (lastUpdate < 0) {
                lastUpdate = now ;
                return ;
            }

            long elapsedNanos = now - lastUpdate ;

            double elapsedSeconds = elapsedNanos / 1_000_000_000.0 ;
            double deltaX = elapsedSeconds * direction.multiply(speed);


            rect.setX(clamp(rect.getX() + deltaX, 0, rectPane.getWidth() - rect.getWidth()));

            lastUpdate = now ;
        }

        private double clamp(double value, double min, double max) {
            if (value < min) return min ;
            if (value > max) return max ;
            return value ;
        }

        public void setDirection(Direction direction) {
            this.direction = direction ;
        }

    }

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

答案 1 :(得分:0)

使用更容易实现的拖动方法添加滚动条