【发布时间】:2026-02-02 11:35:01
【问题描述】:
提供一些背景知识:我现在可以将文件加载到我的 mp3 程序中并播放它们,但是我的 tableview 中的所有值都是空的?
我的歌曲课
package application;
//imports here
public class Song {
private String title;
private String artist;
private String album;
private SimpleStringProperty pTitle;
private SimpleStringProperty pArtist;
private SimpleStringProperty pAlbum;
private Media music;
private MediaPlayer mp;
private Image coverArt;
public Song(File file) {
music = new Media(file.toURI().toString());
music.getMetadata().addListener((Change<? extends String, ? extends Object> c) -> {
if (c.wasAdded()) {
if ("artist".equals(c.getKey())) {
System.out.println(c.getKey()+":"+c.getValueAdded());
this.pArtist = new SimpleStringProperty(c.getValueAdded().toString());
//pArtist.set(c.getValueAdded().toString());
artist = c.getValueAdded().toString();
} else if ("title".equals(c.getKey())) {
title = c.getValueAdded().toString();
System.out.println(c.getKey()+":"+c.getValueAdded());
} else if ("album".equals(c.getKey())) {
album = c.getValueAdded().toString();
System.out.println(c.getKey()+":"+c.getValueAdded());
} else if ("image".equals(c.getKey())) {
coverArt = (Image) c.getValueAdded();
}
}
});
mp = new MediaPlayer(music);
System.out.println(pArtist);
System.out.println(artist);
//artist = (String) mp.getMedia().getMetadata().get("artist");
//title = (String) music.getMetadata().get("title");
//album = (String) music.getMetadata().get("album");
//artist = "test";
//album = "test";
//title = "test";
}
public void play() {
mp.play();
}
public void pause() {
mp.pause();
}
public void stop() {
mp.stop();
}
public String getTitle(){
return title;
}
public void setTitle(String title){
this.title = title;
}
public String getArtist(){
return artist;
}
public void setArtist(String artist){
this.artist = artist;
}
public String getAlbum(){
return album;
}
public void setAlbum(String album){
this.album = album;
}
public Image getCover(){
return coverArt;
}
public MediaPlayer getMP(){
return mp;
}
}
奇怪的是,起初我认为这是因为我的 String 变量设置不正确并且设置为 null,因为当我在构造 Song 对象时放置这些打印行来测试它时,它在控制台中显示为 null。这是我测试时的控制台示例。
null
null
artist:Foo Fighters
album:Saint Cecilia EP
title:Saint Cecilia
这是我的控制器类
public class SceneController implements Initializable{
@FXML
private Button stopBtn;
@FXML
private Slider volume;
@FXML
private Button loadBtn;
@FXML
private Button playBtn;
@FXML
private TableView<Song> table;
@FXML
private Label label;
@FXML
private ProgressBar proBar;
private TableColumn songCol,artistCol,albumCol;
ObservableList<Song> songList = FXCollections.observableArrayList();
List<File> list;
FileChooser fileChooser = new FileChooser();
Desktop desktop;
Song mySong;
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
TableColumn songCol = new TableColumn("Song");
TableColumn artistCol = new TableColumn("Artist");
TableColumn albumCol = new TableColumn("Album");
songCol.setCellValueFactory(
new PropertyValueFactory<Song,String>("title"));
//songCol.setCellFactory(new Callback);
artistCol.setCellValueFactory(
new PropertyValueFactory<Song,String>("artist"));
albumCol.setCellValueFactory(
new PropertyValueFactory<Song,String>("album"));
volume.setMin(0);
volume.setMax(100);
volume.setValue(100);
volume.valueProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
mySong.getMP().setVolume(volume.getValue()/100.0);
}
});
}
// Event Listener on Button[#loadBtn].onAction
@FXML
public void loadFile(ActionEvent event) {
Node source = (Node) event.getSource();
Window theStage = source.getScene().getWindow();
//set fileChooser filter
FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("MP3 files", "*.mp3");
fileChooser.getExtensionFilters().add(extFilter);
fileChooser.setTitle("Select MP3 files");
//File file = fileChooser.showOpenDialog(theStage);
//mySong = new Song(file);
list = fileChooser.showOpenMultipleDialog(theStage);
if(list!=null){
for(File x: list) {
mySong = new Song(x);
System.out.println(mySong.getTitle());
songList.add(mySong);
}
}
table.setItems(songList);
}
@FXML
public void playSong(ActionEvent event) {
mySong.play();
}
@FXML
public void stopSong(ActionEvent event) {
//mySong.pause();
System.out.println("song title: "+mySong.getArtist()+mySong.getTitle());
ImageView img = new ImageView(mySong.getCover());
//img.fitWidthProperty().bind(label.widthProperty());
//img.fitHeightProperty().bind(label.heightProperty());
img.setFitHeight(120);
img.setFitWidth(200);
label.setGraphic(img);
//label.setGraphic(new ImageView(mySong.getCover()));
}
但是我在控制器类中为我的“停止”按钮制作了另一条测试打印线,在加载完所有内容并按下它之后,它会很好地打印出艺术家和标题。我看到了这个other thread 并检查了我的getter 方法,它们似乎是正确的?我真的很迷茫,如果有人能提供一些见解和解决方案,是因为我的变量是空的还是我的 PropertyValueFactory 没有正确完成
我还注意到空值首先出现,尽管它们不应该是最后打印的东西,因为当我在控制器类中创建新歌曲对象时,运行的第一行打印行在 if 语句中?
【问题讨论】:
-
当您调用
setCellValueFactory(...)时,请尝试使用全部小写。我认为引号中的单词必须与Song类中的变量名匹配。我说认为,因为我以不同的方式设置单元格值。 -
我尝试使用小写和大写没有区别
-
您在哪里将列添加到
TableView?我看到你在哪里添加了songList,但没有看到TableColumns。此外,您似乎已在顶部声明了三列,但随后在initialize中重新声明并初始化它们。尝试删除initialize方法中的声明并在那里初始化它们。 -
我相信这些列已经添加到我的 fxml 文档中的 tableview 中,如果您查看图像的样子,则在原始帖子中,否则我不确定如何将列添加到表格视图
-
查看@jewelsea 的回答,了解您出错的地方。
标签: java javafx reflection