当前位置: 首页 > 知识库问答 >
问题:

如何使用动画使一个JavaFX滑块旋钮只移动到刻度线?

严亦
2023-03-14

继续本问题中的讨论,如何使JavaFX滑块以离散的步骤移动?我添加了一个“播放”按钮和一个时间线,这样当用户单击“播放”按钮时,滑块的旋钮就会重复地前进到下一个刻度线,直到滑块的末端或用户单击“停止”按钮。不幸的是,动画运行的时间越长,旋钮在刻度线之间的移动就越多(是的,setSnaptoticks是真的)。而且,滑块的值也不是我所期望的。理想情况下,它应该是“-60、-59、-58等”,但时间线每次以很小的分数移动滑块旋钮(例如-55.188833333333335)。这个问题我已经研究了很长时间了。下面是我的代码:

public class SliderTest extends Application {
StringConverter<Double> stringConverter = new StringConverter<>() {

    @Override
    public String toString( Double object ) {
        long seconds = object.longValue();
        long minutes = TimeUnit.SECONDS.toMinutes( seconds );
        long remainingseconds = Math.abs( seconds - TimeUnit.MINUTES.toSeconds( minutes ) );
        return String.format( "%02d", minutes ) + ":" + String.format( "%02d", remainingseconds );
    }

    @Override
    public Double fromString( String string ) {
        return null;
    }
};

@Override
public void start( Stage primaryStage ) throws Exception {
    try {
        Pane pane = new Pane();
        pane.setStyle( "-fx-background-color: black;" );

        Slider slider = new Slider( -60, 0, -60 );
        slider.setBlockIncrement( 60 );
        slider.setMajorTickUnit( 60 );
        slider.setMinorTickCount( 60 );
        slider.setShowTickLabels( true );
        slider.setShowTickMarks( true );
        slider.setSnapToTicks( true );
        slider.setLabelFormatter( stringConverter );
        slider.setPrefWidth( 1303 );

        Button playStopButton = new Button( "Play" );
        HBox buttonHBox = new HBox( playStopButton );
        buttonHBox.setAlignment( Pos.CENTER );
        Text sliderTime = new Text( "Time" );
        sliderTime.setFont( new Font( 12 ) );
        sliderTime.setFill( Color.WHITE );
        sliderTime.setText( stringConverter.toString( slider.getValue() ) );

        HBox hbox = new HBox( slider, sliderTime, buttonHBox );
        hbox.setPrefWidth( 1428 );
        hbox.setSpacing( 10 );
        hbox.setAlignment( Pos.TOP_CENTER );

        pane.getChildren().add( hbox );

        Scene scene = new Scene( pane );
        scene.getStylesheets().add( getClass().getResource( "/css/slider.css" ).toExternalForm() );
        primaryStage.setScene( scene );
        primaryStage.show();

        Timeline timeline = new Timeline(
                new KeyFrame( Duration.ZERO, new KeyValue( slider.valueProperty(), slider.getValue() ) ),
                new KeyFrame( Duration.seconds( -slider.getValue() ), new KeyValue( slider.valueProperty(), 0 ) ) );

        slider.valueProperty().addListener( ( observable, oldValue, newValue ) -> {
            slider.setValue( newValue.intValue() );
            
            System.out.println( slider.getValue() + " | " + newValue.doubleValue() );

            // Set the text to the slider's new value.
            sliderTime.setText( stringConverter.toString( slider.getValue() ) );

            if ( newValue.doubleValue() == 0 ) {
                // Reset the timeline and the text for the sliderButton.
                timeline.stop();
                timeline.getKeyFrames().clear();
                playStopButton.setText( "Stop" );
            }
        } );

        slider.setOnMousePressed( event -> {
            // On mouse down, reset the timeline.
            timeline.stop();
            timeline.getKeyFrames().clear();
        } );

        slider.setOnMouseReleased( event -> {
            // Set the new start position of the timeline.
            timeline.getKeyFrames().add(
                    new KeyFrame( Duration.ZERO, new KeyValue( slider.valueProperty(), slider.getValue() ) ) );
            timeline.getKeyFrames().add( new KeyFrame( Duration.seconds( -slider.getValue() ),
                    new KeyValue( slider.valueProperty(), 0 ) ) );

            // Play the animation only if it was playing before.
            if ( playStopButton.getText().equals( "Pause" ) ) {
                timeline.play();
            }
            // Change the image for the playStopButton to stop when the thumb is moved to zero.
            else if ( playStopButton.getText().equals( "Stop" ) && ( slider.getValue() < 0 ) ) {
                playStopButton.setText( "Play" );
            }
        } );

        playStopButton.setOnMouseClicked( event -> {
            // Ignore mouse clicks on the playStopButton when the slider is at time zero.
            if ( slider.getValue() != 0 ) {
                if ( ( timeline.getStatus() == Status.STOPPED ) || ( timeline.getStatus() == Status.PAUSED ) ) {
                    playStopButton.setText( "Pause" );
                    timeline.play();
                }
                else if ( timeline.getStatus() == Status.RUNNING ) {
                    playStopButton.setText( "Play" );
                    timeline.pause();
                }
            }
        } );
    } catch ( Exception e ) {
        e.printStackTrace();
    }
}

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

共有1个答案

许彦
2023-03-14

部分问题是在滑块的设置中出现的。问题的另一部分是我对时间线的定义。基本上,我让Java来定义滑块按钮的所有值,不管刻度线在哪里,这不是我想要的(尽管它确实有助于平滑的动画)。但是在做了以下更改后,滑块的按钮每秒钟都会前进到下一个刻度线,这就是我想要的。与以前相比,滑块的按钮总是在两个刻度线之间。

        slider.setMajorTickUnit( 1 );

        Timeline timeline = new Timeline(
                new KeyFrame( Duration.seconds( 1 ), event -> {
                    slider.setValue( slider.getValue() + 1 );
                } ) );
        timeline.setCycleCount( Math.abs( Double.valueOf( slider.getValue() ).intValue() ) );
 类似资料:
  • 如何在侧滑块中制作一些不同类型的动画。有图书馆吗?如果有图书馆,请提供我。

  • 问题内容: 我想做的只是为移动设备添加左/右触摸滑动功能。我怎样才能做到这一点? 另外,如何使显示在悬停时的上一个/下一个按钮变小,以用于移动/ ipad版本? 谢谢 问题答案: 更新: 当我刚接触Web设计时,我想到了此解决方案。既然我年纪大一些又聪明了, 马克·希尔拉迪 ( Mark Shiraldi) 给出的答案似乎是一个更好的选择。参见下一个最佳答案;这是一个更有效率的解决方案。 我最近参

  • 问题内容: 我想制作selenium脚本,该脚本移动以下站点上给出的滑块 示例名称是如何更改jQuery UI Slider的方向 http://jqueryui.com/demos/slider/ 我不知道该怎么做 问题答案: 产生行动链 Actions链生成器实现了Builder模式,以创建包含一组其他操作的CompositeAction。这应该通过配置一个Actions链生成器实例并调用它的

  • 问题内容: 我是新手,并且使用Java swing设计接口。我希望抽屉在单击按钮时以滑动动画拉出。首先,是否可以这样做,如果可以,我该怎么做。谢谢。对于某些特定的方法信息,我将不胜感激。 问题答案: 根据要实现的目标,您可以采用多种可能的方法。 基本方法是简单地绘制图形和摆动 这样您就可以简单地更新一个变量,该变量将作为绘制大小的基础,例如… 这真的很基础,并且没有考虑到概念变慢/变慢等问题。对于

  • 我想沿x轴水平移动一些记号的标签,而不移动相应的记号。 更具体地说,当使用

  • 我总是使用以下代码在一个视图和另一个视图之间制作翻转动画: 这工作得很好,给人一种自然的感觉。 但是,当我在使用自动布局在故事板上定义的视图上使用它时,事情开始变得一团糟——在这个动画之后,视图被调整大小并移动。 有没有办法通过设置约束动画来设置这种翻转的动画?