簡體   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