Java URI语法和转换为字符串的困难

Java URI语法和转换为字符串的困难,java,javafx,uri,media-player,Java,Javafx,Uri,Media Player,我和我的朋友一直在做一个Java项目,使用media、MediaPlayer和MediaView类创建一个简单的媒体播放器。然而,从一开始,我们就在成功打开我们用作测试文件的视频时遇到了问题。在经历了许多令人愤怒的运行时异常之后,我们终于发现问题的根源是传递给每个对象的字符串(媒体需要一个以URI格式表示文件路径的字符串)。经过一些修改后,我们发现以下URI在我的计算机上工作以打开文件: Media m = new Media("file:///C:/Users/mewww/Google%20D

我和我的朋友一直在做一个Java项目,使用media、MediaPlayer和MediaView类创建一个简单的媒体播放器。然而,从一开始,我们就在成功打开我们用作测试文件的视频时遇到了问题。在经历了许多令人愤怒的运行时异常之后,我们终于发现问题的根源是传递给每个对象的字符串(媒体需要一个以URI格式表示文件路径的字符串)。经过一些修改后,我们发现以下URI在我的计算机上工作以打开文件:

Media m = new Media("file:///C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXO-MonsterMV.mp4");
MediaPlayer mp = new MediaPlayer(m);
MediaView mv = new MediaView(mp);
但是,我们后来尝试实现一个开放方法,允许用户选择要播放的文件(作为文件对象)。执行此操作时,我们使用以下命令打开文件:

File currentFile = new File(null);

FileChooser fc = new FileChooser();
fc.setTitle("Open");
currentFile = fc.showOpenDialog(null);

Media m = new Media(currentFile.toURI().toString());
MediaPlayer mp = new MediaPlayer(m);
MediaView mv = new MediaView(mp);
这再次给了我们运行时异常,因此我们在控制台中使用println来找出问题所在。现在使用的字符串比预期值少了两个“/”:

"file:/C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXO-MonsterMV.mp4"
但是,即使在修改字符串后,我们仍然会在选择文件时收到相同的运行时错误:

Exception in Application start method
java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
然后我们注释掉了整个Open方法并返回到原始代码,但仍然收到相同的错误

我们的完整代码可在此处获得:

智能游戏课程

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import java.io.File;
import javafx.stage.FileChooser;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.application.Platform;

public class SmartPlay extends Application {
    File currentFile;
    Scene scene;

  @Override
  public void start(Stage primary) {
    primary.setTitle("SmartPlay");
    selectCurrentFileToOpen();
  //Player(currentFile.toURI().toString().substring(0,5)+"//"+currentFile.toURI().toString().substring(5));
    Player player = new Player("file:///C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXOMonsterMV.mp4");

    scene = new Scene(player, 720, 480, Color.BLACK);
    player.setTop(makeMenus());

    primary.setScene(scene);
    primary.show();
  }

  private MenuBar makeMenus() {
      MenuBar mb = new MenuBar();
      Menu fileMenu = new Menu("File");
      MenuItem openItem = new MenuItem("Open...");
      openItem.setOnAction(e -> {
          selectCurrentFileToOpen();
          scene.setRoot(new Player(currentFile.toURI()));
      });
      MenuItem quitItem = new MenuItem("Quit");
      quitItem.setOnAction(e -> Platform.exit());
      fileMenu.getItems().addAll(openItem, quitItem);
      return mb;
  }

  public boolean selectCurrentFileToOpen() {
      FileChooser fc = new FileChooser();
      fc.setTitle("Open");
      currentFile = fc.showOpenDialog(null);
      return true;
  }

  public void stop() {
  }

  public static void main(String[] args) {
      launch(args);
  }
}
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import java.net.URI;

public class Player extends BorderPane {
    Media m;
    MediaPlayer mp;
    MediaView mv;
    Pane p;
    MediaBar bar;

    public Player(String file) {
        m = new Media(file);
        mp = new MediaPlayer(m);
        mv = new MediaView(mp);

        p = new Pane();
        p.getChildren().addAll(mv);
        setCenter(p);

        bar = new MediaBar(mp);

        setBottom(bar);

        setStyle("-fx-background-color:#cccccc");

        mp.play();
    }
}
import javafx.scene.layout.HBox;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.media.MediaPlayer;
import javafx.scene.layout.Priority;
import javafx.scene.control.Slider;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.util.Duration;

public class MediaBar extends HBox {
    Slider time = new Slider();
    Slider vol = new Slider();

    Button playButton = new Button("Pause");
    Button halfSpeed = new Button("0.5x");
    Button normalSpeed = new Button("1.0x");
    Button doubleSpeed = new Button("2.0x");

    Label volume = new Label("Volume: ");
    Label nowTime;

    MediaPlayer player;

    public MediaBar(MediaPlayer play) {
        player = play;

        setAlignment(Pos.CENTER);
        setPadding(new Insets(5,10,5,10));

        vol.setPrefWidth(70);
        vol.setMinWidth(30);
        vol.setValue(100);

        nowTime = new Label(formatTime(player.getCurrentTime()) + "/" + formatTime(player.getTotalDuration()));
        HBox.setHgrow(time, Priority.ALWAYS);

        playButton.setPrefWidth(30);

        getChildren().addAll(playButton,time,nowTime,volume,vol);        
    }

    public static String formatTime(Duration duration) {  //StackOverflow: Jon Skeet
        long seconds = (long) duration.toSeconds();
        long absSeconds = Math.abs(seconds);
        String positive = String.format(
            "%d:%02d:%02d",
            //absSeconds / 3600,
            (absSeconds % 3600) / 60,
            absSeconds % 60);
        return seconds < 0 ? "-" + positive : positive;
    }
}
玩家等级

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import java.io.File;
import javafx.stage.FileChooser;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.application.Platform;

public class SmartPlay extends Application {
    File currentFile;
    Scene scene;

  @Override
  public void start(Stage primary) {
    primary.setTitle("SmartPlay");
    selectCurrentFileToOpen();
  //Player(currentFile.toURI().toString().substring(0,5)+"//"+currentFile.toURI().toString().substring(5));
    Player player = new Player("file:///C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXOMonsterMV.mp4");

    scene = new Scene(player, 720, 480, Color.BLACK);
    player.setTop(makeMenus());

    primary.setScene(scene);
    primary.show();
  }

  private MenuBar makeMenus() {
      MenuBar mb = new MenuBar();
      Menu fileMenu = new Menu("File");
      MenuItem openItem = new MenuItem("Open...");
      openItem.setOnAction(e -> {
          selectCurrentFileToOpen();
          scene.setRoot(new Player(currentFile.toURI()));
      });
      MenuItem quitItem = new MenuItem("Quit");
      quitItem.setOnAction(e -> Platform.exit());
      fileMenu.getItems().addAll(openItem, quitItem);
      return mb;
  }

  public boolean selectCurrentFileToOpen() {
      FileChooser fc = new FileChooser();
      fc.setTitle("Open");
      currentFile = fc.showOpenDialog(null);
      return true;
  }

  public void stop() {
  }

  public static void main(String[] args) {
      launch(args);
  }
}
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import java.net.URI;

public class Player extends BorderPane {
    Media m;
    MediaPlayer mp;
    MediaView mv;
    Pane p;
    MediaBar bar;

    public Player(String file) {
        m = new Media(file);
        mp = new MediaPlayer(m);
        mv = new MediaView(mp);

        p = new Pane();
        p.getChildren().addAll(mv);
        setCenter(p);

        bar = new MediaBar(mp);

        setBottom(bar);

        setStyle("-fx-background-color:#cccccc");

        mp.play();
    }
}
import javafx.scene.layout.HBox;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.media.MediaPlayer;
import javafx.scene.layout.Priority;
import javafx.scene.control.Slider;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.util.Duration;

public class MediaBar extends HBox {
    Slider time = new Slider();
    Slider vol = new Slider();

    Button playButton = new Button("Pause");
    Button halfSpeed = new Button("0.5x");
    Button normalSpeed = new Button("1.0x");
    Button doubleSpeed = new Button("2.0x");

    Label volume = new Label("Volume: ");
    Label nowTime;

    MediaPlayer player;

    public MediaBar(MediaPlayer play) {
        player = play;

        setAlignment(Pos.CENTER);
        setPadding(new Insets(5,10,5,10));

        vol.setPrefWidth(70);
        vol.setMinWidth(30);
        vol.setValue(100);

        nowTime = new Label(formatTime(player.getCurrentTime()) + "/" + formatTime(player.getTotalDuration()));
        HBox.setHgrow(time, Priority.ALWAYS);

        playButton.setPrefWidth(30);

        getChildren().addAll(playButton,time,nowTime,volume,vol);        
    }

    public static String formatTime(Duration duration) {  //StackOverflow: Jon Skeet
        long seconds = (long) duration.toSeconds();
        long absSeconds = Math.abs(seconds);
        String positive = String.format(
            "%d:%02d:%02d",
            //absSeconds / 3600,
            (absSeconds % 3600) / 60,
            absSeconds % 60);
        return seconds < 0 ? "-" + positive : positive;
    }
}
MediaBar类

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import java.io.File;
import javafx.stage.FileChooser;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.application.Platform;

public class SmartPlay extends Application {
    File currentFile;
    Scene scene;

  @Override
  public void start(Stage primary) {
    primary.setTitle("SmartPlay");
    selectCurrentFileToOpen();
  //Player(currentFile.toURI().toString().substring(0,5)+"//"+currentFile.toURI().toString().substring(5));
    Player player = new Player("file:///C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXOMonsterMV.mp4");

    scene = new Scene(player, 720, 480, Color.BLACK);
    player.setTop(makeMenus());

    primary.setScene(scene);
    primary.show();
  }

  private MenuBar makeMenus() {
      MenuBar mb = new MenuBar();
      Menu fileMenu = new Menu("File");
      MenuItem openItem = new MenuItem("Open...");
      openItem.setOnAction(e -> {
          selectCurrentFileToOpen();
          scene.setRoot(new Player(currentFile.toURI()));
      });
      MenuItem quitItem = new MenuItem("Quit");
      quitItem.setOnAction(e -> Platform.exit());
      fileMenu.getItems().addAll(openItem, quitItem);
      return mb;
  }

  public boolean selectCurrentFileToOpen() {
      FileChooser fc = new FileChooser();
      fc.setTitle("Open");
      currentFile = fc.showOpenDialog(null);
      return true;
  }

  public void stop() {
  }

  public static void main(String[] args) {
      launch(args);
  }
}
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import java.net.URI;

public class Player extends BorderPane {
    Media m;
    MediaPlayer mp;
    MediaView mv;
    Pane p;
    MediaBar bar;

    public Player(String file) {
        m = new Media(file);
        mp = new MediaPlayer(m);
        mv = new MediaView(mp);

        p = new Pane();
        p.getChildren().addAll(mv);
        setCenter(p);

        bar = new MediaBar(mp);

        setBottom(bar);

        setStyle("-fx-background-color:#cccccc");

        mp.play();
    }
}
import javafx.scene.layout.HBox;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.media.MediaPlayer;
import javafx.scene.layout.Priority;
import javafx.scene.control.Slider;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.util.Duration;

public class MediaBar extends HBox {
    Slider time = new Slider();
    Slider vol = new Slider();

    Button playButton = new Button("Pause");
    Button halfSpeed = new Button("0.5x");
    Button normalSpeed = new Button("1.0x");
    Button doubleSpeed = new Button("2.0x");

    Label volume = new Label("Volume: ");
    Label nowTime;

    MediaPlayer player;

    public MediaBar(MediaPlayer play) {
        player = play;

        setAlignment(Pos.CENTER);
        setPadding(new Insets(5,10,5,10));

        vol.setPrefWidth(70);
        vol.setMinWidth(30);
        vol.setValue(100);

        nowTime = new Label(formatTime(player.getCurrentTime()) + "/" + formatTime(player.getTotalDuration()));
        HBox.setHgrow(time, Priority.ALWAYS);

        playButton.setPrefWidth(30);

        getChildren().addAll(playButton,time,nowTime,volume,vol);        
    }

    public static String formatTime(Duration duration) {  //StackOverflow: Jon Skeet
        long seconds = (long) duration.toSeconds();
        long absSeconds = Math.abs(seconds);
        String positive = String.format(
            "%d:%02d:%02d",
            //absSeconds / 3600,
            (absSeconds % 3600) / 60,
            absSeconds % 60);
        return seconds < 0 ? "-" + positive : positive;
    }
}
导入javafx.scene.layout.HBox;
导入javafx.geometry.Insets;
导入javafx.geometry.Pos;
导入javafx.scene.media.MediaPlayer;
导入javafx.scene.layout.Priority;
导入javafx.scene.control.Slider;
导入javafx.scene.control.Label;
导入javafx.scene.control.Button;
导入javafx.util.Duration;
公共类MediaBar扩展了HBox{
滑块时间=新滑块();
Slider vol=新滑块();
按钮播放按钮=新按钮(“暂停”);
按钮半速=新按钮(“0.5x”);
按钮正常速度=新按钮(“1.0x”);
按钮双速=新按钮(“2.0x”);
标签卷=新标签(“卷:”);
标签时间;
媒体播放器;
公共媒体栏(MediaPlayer播放){
玩家=游戏;
设置对齐(位置中心);
设置填充(新插图(5,10,5,10));
体积宽度(70);
体积最小宽度(30);
体积设定值(100);
nowTime=新标签(formatTime(player.getCurrentTime())+“/”+formatTime(player.getTotalDuration());
HBox.setHgrow(时间、优先级、始终);
playButton.setPrefWidth(30);
getChildren().addAll(播放按钮、时间、现在时间、音量、音量);
}
公共静态字符串formatTime(持续时间){//StackOverflow:Jon Skeet
long seconds=(long)duration.toSeconds();
long abs seconds=Math.abs(秒);
字符串正=String.format(
“%d:%02d:%02d”,
//秒/3600,
(秒数%3600)/60,
abs(60%);
返回秒数<0?-“+正:正;
}
}

因此,我在命令行中运行了您的代码,并获得了一个更具体的调试错误。因此,您在MediaBar中进行的时间格式化似乎是导致错误的原因。我不知道你到底想用它做什么,但是你设定时间的方式是不正确的。如果您将它以及其他用于添加时间格式化的内容注释掉,URI路径将是正确的,您的视频应该运行良好。我知道对于格式化,您缺少一个“%02d”。至于您正在格式化的内容,我不太确定,因此无法帮助您。

“文件:/C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXO MonsterMV.mp4”
您实际得到了什么,还是只看到了您认为看到的?如果是前者,为什么要加引号?请提供堆栈跟踪的其余部分。这正是控制台日志中打印的内容,我只是用引号将其标识为字符串。修改该字符串的实际结果是什么?
“file:///C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXO-蒙斯‌​terMV.mp4“
我尝试使用API指南来找出确切的所需语法,但是到URI资源指南的链接被破坏了。具体来说是2396。我相信对于您想要做的事情,使用java.time和Duration类中的toMinutes()和toSeconds()会更容易。这将有助于转换和格式化您想要的格式。