您的代码有一些问题。
- JavaFX 代码应该在 JavaFX 应用程序线程上执行,而不是在 Swing 事件调度线程上执行。
不要使用EventQueue.invokeLater
在 Swing 线程上执行,而是使用Platform.runLater在 JavaFX 线程上执行。
您的程序只使用 JavaFX 控件,所以不要在 Swing 线程上运行任何东西。
即使使用EventQueue.invokeLater
是错误的,在这种情况下,您甚至都不需要这样做,Platform.runLater
因为无论如何只有 JavaFX 应用程序线程应该修改 Slider 值。您可以在 JavaFX节点文档中看到一条规则:
应用程序必须在 JavaFX 应用程序线程上将节点附加到场景,并修改已附加到场景的节点。
你数到一亿的循环只会阻塞应用程序线程,导致 UI 冻结,因为控制永远不会返回给框架来更新 UI。
在 UI 控件上设置值后,必须将控件返回给 JavaFX 框架,以允许值更改反映在控件中并反映给用户。
试试下面的代码,它通过使用Timeline和Binding来解决上述所有问题。
import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.event.*;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.media.*;
import javafx.stage.Stage;
import javafx.util.Duration;
public class EngineSound extends Application {
private static final String MEDIA_URL =
"http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv";
private static final Duration FADE_DURATION = Duration.seconds(2.0);
public static void main(String[] args) { launch(args); }
@Override public void start(Stage stage) throws Exception {
final MediaPlayer mediaPlayer = new MediaPlayer(
new Media(
MEDIA_URL
)
);
final MediaView mediaView = new MediaView(mediaPlayer);
HBox layout = new HBox(5);
layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");
layout.getChildren().addAll(
createVolumeControls(mediaPlayer),
mediaView
);
stage.setScene(new Scene(layout, 650, 230));
stage.show();
mediaPlayer.play();
}
public Region createVolumeControls(final MediaPlayer mediaPlayer) {
final Slider volumeSlider = new Slider(0, 1, 0);
volumeSlider.setOrientation(Orientation.VERTICAL);
mediaPlayer.volumeProperty().bindBidirectional(volumeSlider.valueProperty());
final Timeline fadeInTimeline = new Timeline(
new KeyFrame(
FADE_DURATION,
new KeyValue(mediaPlayer.volumeProperty(), 1.0)
)
);
final Timeline fadeOutTimeline = new Timeline(
new KeyFrame(
FADE_DURATION,
new KeyValue(mediaPlayer.volumeProperty(), 0.0)
)
);
Button fadeIn = new Button("Fade In");
fadeIn.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent t) {
fadeInTimeline.play();
}
});
fadeIn.setMaxWidth(Double.MAX_VALUE);
Button fadeOut = new Button("Fade Out");
fadeOut.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent t) {
fadeOutTimeline.play();
}
});
fadeOut.setMaxWidth(Double.MAX_VALUE);
VBox controls = new VBox(5);
controls.getChildren().setAll(
volumeSlider,
fadeIn,
fadeOut
);
controls.setAlignment(Pos.CENTER);
VBox.setVgrow(volumeSlider, Priority.ALWAYS);
controls.disableProperty().bind(
Bindings.or(
Bindings.equal(Timeline.Status.RUNNING, fadeInTimeline.statusProperty()),
Bindings.equal(Timeline.Status.RUNNING, fadeOutTimeline.statusProperty())
)
);
return controls;
}
}
该代码控制视频,但使其仅播放音频只需将媒体 URL 设置为仅音频格式,例如 mp3 或 aac。