我正在设计一个 JavaFX 程序,我试图让一个
Slider volumeSlider
控制在 MediaPlayer mediaPlayer
类中初始化的 Main
的音量。 volumeSlider
在名为 settings.fxml
的场景中,通过单击程序的第一个场景 interface.fxml
中的按钮访问该场景。我有设置 volumeSlider 值的代码,并根据我的 initialize
方法中滑块的值设置 mediaPlayer。如果我在第一个场景中添加一个名为 volumeSlider
的滑块,则该滑块和 settings.fxml
中的滑块都可以工作。但是,当我的程序更改为没有具有该名称的滑块的场景时,它会抛出Caused by: java.lang.NullPointerException: Cannot invoke "javafx.scene.control.Slider.setValue(double)" because "this.volumeSlider" is null
@FXML Slider volumeSlider;
@Override
public void initialize(URL location, ResourceBundle resources){
volumeSlider.setValue(mediaPlayer.getVolume() * 100);
volumeSlider.valueProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
mediaPlayer.setVolume(volumeSlider.getValue() / 100);
}
});
}
为了解决这个问题,我从初始化方法中删除了代码,而是将其放在
onClickSettings
中,这是当用户点击设置按钮时抛出的方法。但是,似乎 volumeSlider 没有初始化,因为单击设置按钮会抛出与之前相同的错误消息Caused by: java.lang.NullPointerException: Cannot invoke "javafx.scene.control.Slider.setValue(double)" because "this.volumeSlider" is null at com.example.cribbage/com.example.cribbage.MainController.onClickSettings(MainController.java:934) ... 57 more
onClickSettings
方法:
@FXML
public void onClickSettings(ActionEvent event) throws IOException {
volumeSlider.setValue(mediaPlayer.getVolume() * 100);
volumeSlider.valueProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
mediaPlayer.setVolume(volumeSlider.getValue() / 100);
}
});
root = FXMLLoader.load(getClass().getResource("settings.fxml"));
root.setId("pane");
stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
scene = new Scene(root);
scene.getStylesheets().addAll(this.getClass().getResource("style.css").toExternalForm());
stage.setScene(scene);
stage.show();
}
settings.fxml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.cribbage.MainController">
<children>
<Label layoutX="354.0" layoutY="75.0" text="Settings">
<font>
<Font name="Copperplate Gothic Bold" size="60.0" />
</font></Label>
<Button layoutX="51.0" layoutY="37.0" mnemonicParsing="false" onAction="#onClickMenu" prefHeight="38.0" prefWidth="82.0" text="Back">
<font>
<Font name="Copperplate Gothic Light" size="19.0" />
</font></Button>
<CheckBox layoutX="534.0" layoutY="262.0" mnemonicParsing="false" onAction="#onClickFullScreen" prefHeight="91.0" prefWidth="169.0" />
<Label layoutX="354.0" layoutY="262.0" prefHeight="91.0" prefWidth="145.0" text="Fullscreen">
<font>
<Font size="29.0" />
</font>
</Label>
<Slider fx:id="volumeSlider" layoutX="534.0" layoutY="371.0" value="50.0" />
<Label layoutX="354.0" layoutY="340.0" prefHeight="91.0" prefWidth="145.0" text="Volume">
<font>
<Font size="29.0" />
</font>
</Label>
</children>
</AnchorPane>
Main
班级:
package com.example.cribbage;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import javafx.scene.media.Media;
public class Main extends Application {
public static MediaPlayer mediaPlayer;
@Override
public void start(Stage stage) {
Parent root;
try {
Media media = new Media("https://soundimage.org/wp-content/uploads/2017/05/Car-Theft-101.mp3");
mediaPlayer = new MediaPlayer(media);
mediaPlayer.setAutoPlay(true);
mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE);
mediaPlayer.setVolume(50);
mediaPlayer.play();
root = FXMLLoader.load(getClass().getResource("/com/example/cribbage/interface.fxml"));
root.setId("pane");
Scene scene = new Scene(root);
scene.getStylesheets().addAll(this.getClass().getResource("style.css").toExternalForm());
stage.setScene(scene);
stage.show();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println(e);
}
}
public static void main(String[] args) {
launch(args);
}
}
initialize
方法:
@FXML Slider volumeSlider;
@Override
public void initialize(URL location, ResourceBundle resources){
}
interface.fxml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="600.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.cribbage.MainController">
<children>
<Button layoutX="407.0" layoutY="201.0" mnemonicParsing="false" onAction="#onClickPlay" prefHeight="69.0" prefWidth="188.0" text="Play">
<font>
<Font name="Copperplate Gothic Bold" size="40.0" />
</font>
</Button>
<Button layoutX="374.0" layoutY="314.0" mnemonicParsing="false" onAction="#onClickTutorial" prefHeight="71.0" prefWidth="254.0" text="Chart">
<font>
<Font name="Copperplate Gothic Bold" size="40.0" />
</font>
</Button>
<Button layoutX="374.0" layoutY="428.0" mnemonicParsing="false" onAction="#onClickSettings" prefHeight="71.0" prefWidth="254.0" text="Settings">
<font>
<Font name="Copperplate Gothic Bold" size="40.0" />
</font>
</Button>
<Label layoutX="251.0" layoutY="49.0" prefHeight="108.0" prefWidth="656.0" text="Cribbage">
<font>
<Font name="Copperplate Gothic Bold" size="96.0" />
</font>
</Label>
</children>
</AnchorPane>
如果这很混乱,我非常抱歉,这是我的第一个问题,我不确定如何格式化它以便于理解。如果需要更多文件或代码,请告诉我。