我将setVolume设置为0.0,然后在while循环中逐位更改音量。然而,音量从0.0跳到1.0?如何顺畅地改变音量? 我试过了
public class EngineSound extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
mp3File = new File(metronom);
media = new Media(mp3File.toURI().toURL().toString());
mediaPlayer = new MediaPlayer(media);
mediaView = new MediaView(mediaPlayer);
mediaPlayer.play();
mediaPlayer.setVolume(0.0);
slider = new Slider();
slider.valueProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
mediaPlayer.setVolume(slider.getValue());
}
});
}
});
double count = 1;
while (count != 101) {
for (int i = 0; i < 100000000; i++) {
}
slider.setValue(count / 100);
count++;
System.out.println(mediaPlayer.getVolume());
}
}
}
答案 0 :(得分:2)
您的代码存在一些问题。
不使用EventQueue.invokeLater
在Swing线程上执行,而是使用Platform.runLater在JavaFX线程上执行。
你的程序只使用JavaFX控件,所以不要在Swing线程上运行任何东西。
ChangeListener
中的任何线程切换呼叫。即使使用EventQueue.invokeLater
是错误的,在这种情况下你甚至不需要Platform.runLater
,因为只有JavaFX应用程序线程应该修改Slider值。您可以在JavaFX Node文档中看到规则:
应用程序必须将节点附加到场景,并在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;
}
}
代码控制视频,但只使用音频只需将媒体网址设置为仅音频格式,如mp3或aac。