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

Javafx 按下鼠标键时保持运行的鼠标事件,javafx,Javafx,我正在处理一个自定义滚动条,当我按住鼠标主键时,滚动条会移动。我试过setOnMousePressed,但这只运行了一次。当我按下一把钥匙时,是否有一个事件持续运行 编辑:我应该提到,自定义滚动条实际上是一个普通窗格,我在其中显示更大范围的滚动窗格中显示的图形。将滚动条添加到一个更容易实现的拖动方式将滚动条添加到一个更容易实现的拖动方式如注释中所述,这是滚动条的默认行为。但是,如果您想自己实现类似的功能,出于某种原因,一个选项是将AnimationTimer与鼠标侦听器结合使用: Animati

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


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

将滚动条添加到一个更容易实现的拖动方式

将滚动条添加到一个更容易实现的拖动方式

如注释中所述,这是滚动条的默认行为。但是,如果您想自己实现类似的功能,出于某种原因,一个选项是将
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);
    }
}
导入javafx.animation.AnimationTimer;
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.layout.ancorpane;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.Pane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Rectangle;
导入javafx.stage.stage;
公共类ScrollingExample扩展了应用程序{
私有矩形矩形;
专用窗格和矩形窗格;
@凌驾
公共无效开始(阶段primaryStage){
rect=新矩形(0,200,40,40);
珊瑚色;
左标签=新标签(“左”);
标签右侧=新标签(“右侧”);
ScrollTimer ScrollTimer=新的ScrollTimer();
左。设置鼠标按下(e->{
scrollTimer.setDirection(方向.左);
scrollTimer.start();
});
left.setOnMouseReleased(e->scrollTimer.stop());
右。设置鼠标按下(e->{
scrollTimer.setDirection(Direction.RIGHT);
scrollTimer.start();
});
右键。setOnMouseReleased(e->scrollTimer.stop());
AnchorPane按钮=新的AnchorPane(左、右);
AnchorPane.setLeftAnchor(左,5.0);
AnchorPane.setRightAnchor(右,5.0);
rectPane=新窗格(rect);
BorderPane根=新的BorderPane(矩形窗格);
root.setTop(按钮);
场景=新场景(根,800800);
初级阶段。场景(场景);
primaryStage.show();
}
公共枚举方向{
左(-1),右(1);
私有整数乘法器;
方向(整数乘法器){
这个乘数=乘数;
}
公共双倍乘(双倍值){
返回值*乘数;
}
}
公共类ScrollTimer扩展了AnimationTimer{
专用双速=250;//像素/秒
专用方向=Direction.LEFT;
私人长期更新;
@凌驾
公开作废开始(){
lastUpdate=-1;
super.start();
}
@凌驾
公共无效句柄(长){
如果(上次更新<0){
lastUpdate=now;
返回;
}
long elapsednos=now-lastUpdate;
双elapsedSeconds=ElapsedNano/1_000_000_000.0;
双deltaX=延时秒*方向。倍增(速度);
setX(clamp(rect.getX()+deltaX,0,rectPane.getWidth()-rect.getWidth());
lastUpdate=now;
}
专用双夹(双值、双最小值、双最大值){
如果(值最大值)返回最大值;
返回值;
}
公共空间设置方向(方向){
这个方向=方向;
}
}
公共静态void main(字符串[]args){
发射(args);
}
}

正如注释中指出的,这是滚动条的默认行为。但是,如果您想自己实现类似的功能,出于某种原因,一个选项是将
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);
    }
}
导入javafx.animation.AnimationTimer;
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.layout.ancorpane;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.Pane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Rectangle;
导入javafx.stage.stage;
公共类ScrollingExample扩展了应用程序{
私有矩形矩形;
专用窗格和矩形窗格;
@凌驾
公共无效开始(阶段primaryStage){
rect=新矩形(0,200,40,40);
珊瑚色;
左标签=新标签(“左”);
标签右侧=新标签(“右侧”);
ScrollTimer ScrollTimer=新的ScrollTimer();
左。设置鼠标按下(e->{
scrollTimer.setDirection(方向.左);
scrollTimer.start();
});
left.setOnMouseReleased(e->scrollTimer.stop());
右。设置鼠标按下(e->{
scrollTimer.setDirection(Direction.RIGHT);
scrollTimer.start();
});
右键。setOnMouseReleased(e->scrollTimer.stop());
AnchorPane按钮=新的AnchorPane(左、右);
AnchorPane.setLeftAnchor(左,5.0);
AnchorPane.setRightAnchor(右,5.0);
rectPane=新窗格(rect);
BorderPane根=新的BorderPane(矩形窗格);
root.setTop(按钮);
场景=新场景(根,800800);
初级阶段。场景(场景);
primaryStage.show();
}
公共枚举方向{
左(-1),右(1);
私有整数乘法器;
方向(整数乘法器){
这个乘数=乘数;
}
公共双倍乘(双倍值){
返回值*乘数;
}