如何在单独的类中处理媒体元数据?

时间:2018-11-01 07:18:07

标签: javafx media

我正在使用JavaFX Media类制作媒体播放器。我制作了一个SongModel类,该类封装了文件中的所有元数据,并创建了Media和MediaPlayer实例。

它看起来像这样:

private final StringProperty album =
            new SimpleStringProperty(this, "album");

public String getAlbum(){ return album.get(); }
public void setAlbum(String value){ album.set(value); }
public StringProperty albumProperty() { return album; }

也有类似的艺术家,年份,标题和专辑封面字段。此外,MediaPlayer属性也显示为只读:

public MediaPlayer getMediaPlayer(){ return mediaPlayer.get(); }
    public ReadOnlyObjectProperty<MediaPlayer> mediaPlayerProperty(){
        return mediaPlayer.getReadOnlyProperty();
    }

我使用MapChangelistener检查该字段是否可用,然后将其传递给handleMetadata方法:

private void initializeMedia(String url){

        try {
            final Media media = new Media(url);
            media.getMetadata().addListener(new MapChangeListener<String, Object>(){
                @Override
                public void onChanged(MapChangeListener.Change<? extends String, ? extends Object> ch) {
                    if(ch.wasAdded()){
                        handleMetadata(ch.getKey(), ch.getValueAdded());
                    }
                }                
            });

            mediaPlayer.setValue(new MediaPlayer(media));
            mediaPlayer.get().setOnError(new Runnable() {
                @Override
                public void run() {
                    String errorMessage = mediaPlayer.get().getError().getMessage();
                    System.out.println("MediaPlayer error: "+errorMessage);
                }
            });

        }catch(RuntimeException e){
            System.out.println("Construction error: "+e);
        }
    }

    private void handleMetadata(String key, Object value){
        if(key.equals("album")){
            setAlbum(value.toString());
        } else if (key.equals("artist")){
            setArtist(value.toString());
        } if (key.equals("title")){
            setTitle(value.toString());
        } if (key.equals("year")){
            setYear(value.toString());
        } if (key.equals("image")){
            setAlbumCover((Image)value);
        }
    }

然后我制作了一个AbstractView类,该类提供对SongModel的访问:

public abstract class AbstractView {
    protected final SongModel songModel;
    protected final Node viewNode;

    public AbstractView(SongModel songModel){
        this.songModel = songModel;
        this.viewNode = initView();
        }

        public Node getViewNode() {
            return viewNode;
        }

        protected abstract Node initView();
}

但是当我尝试制作MetadataView类时,遇到了一些问题。 这是它的外观:

public class MetadataView extends AbstractView{
    public Label artist;
    public Label album;
    public Label title;
    public Label year;
    public ImageView albumCover;

    public MetadataView(SongModel songModel) {
        super(songModel);
    }

    @Override
    protected Node initView() {
        artist = new Label();
        artist.setId("artist");
        album = new Label();
        album.setId("album");
        title = new Label();
        title.setId("title");
        year = new Label();
        year.setId("year");

        final Reflection reflection = new Reflection();
        reflection.setFraction(0.2);

        final URL url = getClass().getResource("resources/defaultAlbum.png");
        Image image = new Image(url.toString());

        albumCover = new ImageView(image);
        albumCover.setFitWidth(240);
        albumCover.setPreserveRatio(true);
        albumCover.setSmooth(true);
        albumCover.setEffect(reflection);

        final GridPane gp = new GridPane();
        gp.setPadding(new Insets(10));
        gp.setHgap(20);
        gp.add(albumCover, 0,0,1, GridPane.REMAINING);
        gp.add(title, 1,0);
        gp.add(artist, 1,1);
        gp.add(album, 1,2);
        gp.add(year, 1,3);

        final ColumnConstraints c0 = new ColumnConstraints();
        final ColumnConstraints c1 = new ColumnConstraints();

        c1.setHgrow(Priority.ALWAYS);
        gp.getColumnConstraints().addAll(c0,c1);

        final RowConstraints r0 = new RowConstraints();
        r0.setValignment(VPos.TOP);
        gp.getRowConstraints().addAll(r0,r0,r0,r0);


        return gp;

    }

}

以下是我在start方法中的调用方式:

metaDataView = new MetadataView(songModel);

问题在于它仅显示默认元数据,而没有从songmodel类中获取它。我尝试在一个类中运行元数据视图代码以及数据处理,并且一切正常,但是当我尝试将它们放在单独的类中时,它却没有。音乐运行良好,只是没有显示数据。有人可以告诉我我想念什么吗?如何使其显示SongModel类中的元数据?我已经花了很多时间,不想浪费它。

1 个答案:

答案 0 :(得分:0)

经过一天的搜索,我找到了答案:绑定。我要做的就是将SongModel类的label属性绑定到MetadataView类的label属性:

title.textProperty().bind(songModel.titleProperty());
artist.textProperty().bind(songModel.artistProperty());
album.textProperty().bind(songModel.albumProperty());
year.textProperty().bind(songModel.yearProperty());
albumCover.imageProperty().bind(songModel.albumCoverProperty());