FileChooser в JavaFX дает исключение NullPointerException

1

Это мой класс:

package com.movie;

import java.io.File;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.FileChooser;

public class MoviePlayerController implements Initializable {

    private BooleanProperty play = new SimpleBooleanProperty(true);

    @FXML
    private BorderPane borderPane;

    @FXML
    private MediaView mediaView;

    @FXML
    private ImageView playView;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        onStartUp();
        playView.setImage(new Image(getClass().getResource("Pause.png").toExternalForm()));
        playView.setVisible(false);
        playView.setOnMouseClicked(event -> onPlayView());
    }

    public void onStartUp() {
        try {
            FileChooser fileChooser = new FileChooser();
            File file = fileChooser.showOpenDialog(borderPane.getScene().getWindow());
            if(file != null) {
                mediaView.toFront();
                mediaView.setMediaPlayer(new MediaPlayer(new Media(file.toURI().toURL().toExternalForm())));
                mediaView.getMediaPlayer().play();
                playView.setVisible(true);
                playView.toFront();
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public void onPlayView() {
        if(play.get()) {
            playView.setImage(new Image(getClass().getResource("Resume.png").toExternalForm()));
            mediaView.getMediaPlayer().pause();
            play.set(false);
        } else {
            playView.setImage(new Image(getClass().getResource("Pause.png").toExternalForm()));
            mediaView.getMediaPlayer().play();
            play.set(true);
        }
    }
}

Я получаю эту ошибку:

java.lang.NullPointerException
    at com.movie.MoviePlayerController.onStartUp(MoviePlayerController.java:44)
    at com.movie.MoviePlayerController.initialize(MoviePlayerController.java:35)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2542)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2435)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3208)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3169)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3142)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3118)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3098)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3091)
    at com.movie.MoviePlayer.start(MoviePlayer.java:19)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
    at com.sun.javafx.application.LauncherImpl$$Lambda$51/1616271442.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
    at com.sun.javafx.application.PlatformImpl$$Lambda$44/1051754451.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
    at com.sun.javafx.application.PlatformImpl$$Lambda$47/1814330183.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
    at com.sun.javafx.application.PlatformImpl$$Lambda$46/1775282465.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
    at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)

Это строка 44: File file = fileChooser.showOpenDialog(borderPane.getScene().getWindow());

Это строка 35: playView.setOnMouseClicked(event → onPlayView());

До этого я использовал StackPane и вам нужно было щелкнуть по кнопке, чтобы открыть FileChooser и это сработало нормально, но теперь я использую BorderPane и я хочу, чтобы FileChooser открывался, когда приложение открывается. И да, я установил все fx:id в файле FXML.

Теги:
javafx
javafx-8

1 ответ

2
Лучший ответ

Слишком рано открыть диалоговое окно файла в методе initialize контроллера JavaFX. Когда этот метод вызывается, дерево узлов FXML все еще находится в фазе загрузки + инициализации, поэтому оно еще не привязано к Scene.

Таким образом getScene() возвращает значение null.

Вы должны вызвать onStartup() позже, когда график сцены полностью инициализирован. Вы можете сделать это через Platform.runLater():

@Override
public void initialize(URL location, ResourceBundle resources) {
    playView.setImage(new Image(getClass().getResource("Pause.png").toExternalForm()));
    playView.setVisible(false);
    playView.setOnMouseClicked(event -> onPlayView());
    Platform.runLater(this::onStartup);
}
  • 0
    Спасибо, это сработало!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню