不确定如何使用初始化从 SceneBuilder 注入 FXML 变量而不抛出空异常

问题描述 投票:0回答:0

我正在设计一个 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>

如果这很混乱,我非常抱歉,这是我的第一个问题,我不确定如何格式化它以便于理解。如果需要更多文件或代码,请告诉我。

javafx scenebuilder
© www.soinside.com 2019 - 2024. All rights reserved.