繁体   English   中英

JavaFx Slider 拇指监听器

[英]JavaFx Slider thumb listener

我正在尝试使用 java fx 滑块创建媒体播放器。 我想将播放按钮与滑块拇指合并。 因此,当用户单击滑块的拇指时,它将激活媒体播放器进行播放,并且滑块在播放时会相应地移动。 从文档中,侦听器是针对滑块的,而不是针对滑块的拇指。 任何建议或想法如何实施监听器?

我不认为 Slider 控件是为此目的而实现的,它可能是可能的,但需要大量的黑客攻击,为什么你必须这样限制自己?

我建议实现一个简单的自定义控件并将它的样式设置为看起来像一个滑块,或者更好的是您可以在拇指内添加一个图标,以指示状态(播放/暂停),您基本上可以用它做任何您想做的事情。

我编写了以下示例,该示例使用 StackPane 作为父级,然后将 StackPanes 用于子级(全角栏和进度条,还有拇指):

我将类命名为 MediaSlider,它扩展了 StackPane

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;

public class MediaSlider extends StackPane {
    private String main = "#6200ee";
    private String sec = "#c6aee6";

    private DoubleProperty value;

    private StackPane thumb;

    private ImageView icon;
    private Image playImage, pauseImage;

    public MediaSlider() {
        setAlignment(Pos.CENTER_LEFT);
        setMaxHeight(50);

        value = new SimpleDoubleProperty(0);

        StackPane bar = createRect(sec);
        bar.maxWidthProperty().bind(widthProperty());

        StackPane fill = createRect(main);
        fill.maxWidthProperty()
                .bind(widthProperty().subtract(heightProperty()).multiply(value).add(heightProperty().divide(2)));

        thumb = new StackPane();
        thumb.setMaxWidth(Region.USE_PREF_SIZE);
        thumb.setMinWidth(Region.USE_PREF_SIZE);
        thumb.prefWidthProperty().bind(heightProperty());
        thumb.setCursor(Cursor.HAND);

        Circle circle = new Circle();
        circle.radiusProperty().bind(heightProperty().divide(2));
        circle.setFill(Color.web(main));

        playImage = new Image(getClass().getResourceAsStream("/play.png"));
        pauseImage = new Image(getClass().getResourceAsStream("/pause.png"));

        icon = new ImageView(playImage);
        icon.fitWidthProperty().bind(thumb.widthProperty().divide(2));
        icon.fitHeightProperty().bind(thumb.heightProperty().divide(2));
        
        thumb.getChildren().addAll(circle, icon);
        thumb.setEffect(new DropShadow(10, Color.gray(.0, .4)));
        thumb.translateXProperty().bind(widthProperty().subtract(thumb.widthProperty()).multiply(value));

        getChildren().addAll(bar, fill, thumb);

    }

    public void setOnThumbClicked(EventHandler<MouseEvent> handler) {
        thumb.setOnMouseClicked(handler);
    }

    public void pause() {
        icon.setImage(playImage);
    }

    public void play() {
        icon.setImage(pauseImage);
    }

    public void setValue(double value) {
        this.value.set(value);
    }

    public double getValue() {
        return value.get();
    }

    public DoubleProperty valueProperty() {
        return value;
    }

    private StackPane createRect(String color) {
        StackPane res = new StackPane();
        res.maxHeightProperty().bind(heightProperty().divide(5));
        res.setStyle("-fx-background-color: " + color + ";-fx-background-radius: 5;");
        return res;
    }
}

然后通过以下方式在应用程序中使用它

import java.io.IOException;
import java.net.URISyntaxException;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaPlayer.Status;
import javafx.stage.Stage;
import javafx.util.Duration;

public class App extends Application {

    @Override
    public void start(Stage stage) throws IOException, URISyntaxException {
        StackPane root = new StackPane();
        root.setPadding(new Insets(20));
        root.setStyle("-fx-background-color: #e5e5e5");

        //load media
        MediaPlayer player = new MediaPlayer(new Media(getClass().getResource("/song.mp3").toURI().toString()));
        
        //instantiate your custom slider class
        MediaSlider s = new MediaSlider();

        //bind slider position to media position
        s.valueProperty().bind(Bindings.createDoubleBinding(() -> {
            double val = player.getCurrentTime().toSeconds() / player.getTotalDuration().toSeconds();
            return Double.isNaN(val) ? .0 : val;
        }, player.currentTimeProperty()));

        //handle click events
        s.setOnThumbClicked(event -> {
            if (player.getStatus().equals(Status.PLAYING)) {
                s.pause();
                player.pause();
                player.seek(player.getCurrentTime());
            } else {
                s.play();
                player.play();
            }
        });

        //replay on end of media
        player.setOnEndOfMedia(() -> player.seek(Duration.ZERO));

        root.getChildren().add(s);

        Scene scene = new Scene(root, 600, 300);
        stage.setScene(scene);
        stage.show();
    }

}

这是它的外观:

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM