获取文件资源的静态方式

时间:2016-06-07 18:17:36

标签: java javafx

更新: 我想让媒体播放器保持静态,但如果我制作静态则不起作用。 请注意,我想要mediaPlayer静态的原因是我想从其他类访问它。(该行已注释。) 这是我的代码:

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.text.Font;
import javafx.stage.Stage;

import java.net.URL;

public class Main extends Application {
    static boolean isSoundOn = false;
    static double soundVolume = .5;
    MediaPlayer mediaPlayer = new MediaPlayer(new Media(Main.class.getResource("song.mp3").toString()));

public static void main(String[] args) {
    Application.launch(args);
}

@Override
public void start(Stage primaryStage) {
    mediaPlayer.play();
    primaryStage.setTitle("duet by what");

//        primaryStage.setFullScreen(true);


    //Group gamePaused = new Group();
    //Scene _gamePaused = new Scene(gamePaused, 1200, 700);
    //Group gameOver = new Group();
    //Scene _gameOver = new Scene(gameOver, 1200, 700);
    //Group game = new Group();
    //Scene _game = new Scene(game, 1200, 700);

    GUI gui = new GUI();
    primaryStage.setScene(gui.getMainMenu().getScene());
    primaryStage.show();
}
}

class GUI {
    private MainMenu mainMenu = new MainMenu();



 public class MainMenu {
        private Scene scene;

        private MainMenu() {
            VBox vBox = new VBox();
            scene = new Scene(vBox, 400, 500);
            scene.getStylesheets().add("stylesheet.css");

            Label info = new Label(
                    "welcome the the what version\n" +
                            "of the well known Duet game!\n\n" +
                            "press \"I wanna play!\" to begin the game.\n\n" +
                            "please note that you can change\n" +
                            "the sound settings.");
            info.setId("info");
            vBox.getChildren().add(info);

            Button startGame = new Button("i wanna play right now!");
            startGame.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    System.out.println("game started!");
                }
            });
            vBox.getChildren().add(startGame);

            Label highScore = new Label("__highScore should be added here__");
            highScore.setId("highScore");
            vBox.getChildren().add(highScore);

            Button quitGame = new Button("get me out of this game!");
            quitGame.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    System.out.println("game quitted!");
                }
            });
            vBox.getChildren().add(quitGame);

            CheckBox soundOn = new CheckBox("soundOn?");
            Tooltip tooltip = new Tooltip("if this box is checked, music will be played!");
            tooltip.setFont(new Font("Arial", 16));
            soundOn.setTooltip(tooltip);
            soundOn.selectedProperty().addListener(new ChangeListener<Boolean>() {
                public void changed(ObservableValue<? extends Boolean> ov,
                                    Boolean old_val, Boolean new_val) {
                    Main.isSoundOn = soundOn.isSelected();
                    System.out.println(Main.isSoundOn);
                }
            });
            vBox.getChildren().add(soundOn);

            HBox changeVolumeWrapper = new HBox();
            changeVolumeWrapper.setId("hBox");
            Label sliderLabel = new Label("sound volume: ");
            changeVolumeWrapper.getChildren().add(sliderLabel);

            Slider soundVolume = new Slider(0, 1, .5);
            soundVolume.valueProperty().addListener(new ChangeListener<Number>() {
                public void changed(ObservableValue<? extends Number> ov,
                                    Number old_val, Number new_val) {
                    Main.soundVolume = new_val.doubleValue();
                    //Main.mediaPlayer.setVolume(Main.soundVolume);  here is why i need media player static.
                    System.out.printf("%.2f\n", Main.soundVolume);
                }
            });
            changeVolumeWrapper.getChildren().add(soundVolume);
            vBox.getChildren().add(changeVolumeWrapper);
        }

        public Scene getScene() {
            return scene;
        }
    }

    public MainMenu getMainMenu() {
        return mainMenu;
    }
}

我的代码的任何其他修复将不胜感激。 顺便说一句,这些是我得到的错误:

  

线程“Thread-0”中的异常java.lang.IllegalStateException:   工具包未初始化为   com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:273)     在   com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:268)     在javafx.application.Platform.runLater(Platform.java:83)at   javafx.scene.media.Media $ _MetadataListener.onMetadata(Media.java:541)     在   com.sun.media.jfxmediaimpl.MetadataParserImpl.done(MetadataParserImpl.java:120)     在   com.sun.media.jfxmediaimpl.platform.java.ID3MetadataParser.parse(ID3MetadataParser.java:237)     在   com.sun.media.jfxmediaimpl.MetadataParserImpl.run(MetadataParserImpl.java:103)   线程“main”中的异常java.lang.ExceptionInInitializerError at   java.lang.Class.forName0(Native Method)at   java.lang.Class.forName(Class.java:264)at   com.intellij.rt.execution.application.AppMain.main(AppMain.java:122)   引起:java.lang.IllegalStateException:Toolkit未初始化     在   com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:273)     在   com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:268)     在javafx.application.Platform.runLater(Platform.java:83)at   javafx.scene.media.MediaPlayer.init(MediaPlayer.java:515)at   javafx.scene.media.MediaPlayer。(MediaPlayer.java:414)at   Main。(Main.java:22)......还有3个

1 个答案:

答案 0 :(得分:4)

在没有上下文对象的情况下调用getClass()的解释与任何其他实例方法相同:this.getClass()

在静态上下文中,您可以使用ClassName.class引用该类;即你可以做到

static URL resource = Main.class.getResource("a.mp3");

但是,在这种情况下,为什么你希望这些变量是静态的,这一点都不清楚;每个JVM实例只能创建一个Application子类的实例,而这些实例都是该实例的固有属性。

在您(更新)问题的具体示例中,我将定义一个单独的类,封装MediaPlayer以及您当前使其静态的其他属性。请注意,MediaPlayer本身定义了volume属性和muted属性。所以你可以这样做:

public class SoundPlayer {

    private final MediaPlayer mediaPlayer ;

    public SoundPlayer(URL url) {
        this.mediaPlayer = new MediaPlayer(new Media(url));
    }

    public void play() {
        mediaPlayer.play();
    }

    public double getVolume() {
        return mediaPlayer.getVolume();
    }

    public void setVolume(double volume) {
        mediaPlayer.setVolume(volume);
    }

    public boolean isSoundOn() {
        return ! mediaPlayer.isMuted();
    }

    public void setSoundOn(boolean soundOn) {
        mediaPlayer.setMuted(! soundOn);
    }
}

现在您的Main课程可以是:

public class Main extends Application {

    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        SoundPlayer soundPlayer = new SoundPlayer(getClass().getResource("song.mp3"));
        soundPlayer.play();


        primaryStage.setTitle("duet by Aran Mohyeddin");

        GUI gui = new GUI(soundPlayer);

        primaryStage.setScene(gui.getMainMenu().getScene());
        primaryStage.show();
    }

}

并更新您的GUIMainMenu类,以引用SoundPlayer

public class MainMenu {
        private Scene scene;

        private final SoundPlayer soundPlayer ;

        private MainMenu(SoundPlayer soundPlayer) {

            this.soundPlayer = soundPlayer ;

            // existing code omitted...

            CheckBox soundOn = new CheckBox("soundOn?");
            Tooltip tooltip = new Tooltip("if this box is checked, music will be played!");
            tooltip.setFont(new Font("Arial", 16));
            soundOn.setTooltip(tooltip);
            soundOn.selectedProperty().addListener(new ChangeListener<Boolean>() {
                public void changed(ObservableValue<? extends Boolean> ov,
                                    Boolean old_val, Boolean new_val) {

                    soundPlayer.setSoundOn(new_val);
                }
            });

            // ...


            Slider soundVolume = new Slider(0, 1, .5);
            soundVolume.valueProperty().addListener(new ChangeListener<Number>() {
                public void changed(ObservableValue<? extends Number> ov,
                                    Number old_val, Number new_val) {

                    soundPlayer.setVolumn(new_val.doubleValue());
                    System.out.printf("%.2f\n", Main.soundVolume);
                }
            });
            changeVolumeWrapper.getChildren().add(soundVolume);
            vBox.getChildren().add(changeVolumeWrapper);
        }

        public Scene getScene() {
            return scene;
        }
    }

    public MainMenu getMainMenu() {
        return mainMenu;
    }
}

另请注意,如果从SoundPlayer公开实际属性对象,例如:

public class SoundPlayer {

    private final MediaPlayer mediaPlayer ;

    // ...


    public DoubleProperty volumeProperty() {
        return mediaPlayer.volumeProperty();
    }

    // ...
}

然后你可以简化你的一些代码:

    Slider soundVolume = new Slider(0, 1, .5);
    // instead of the listener, just do:
    soundPlayer.volumeProperty().bindBidirectional(soundVolume.valueProperty());

(将mutedProperty转换为soundOnProperty稍微不那么优雅。)