0

I currently have a custom cell factory that contains videos played through javafx.scene.media. The problem is that when I add more than one video the application is laggy.

How can I put each cell on its own thread? Are there better ways to add the video to the cell that would have each video on its own thread?

CrontrolsFX Custom Cell Factory

gridView.setCellFactory(new Callback<GridView<MediaCard>, GridCell<MediaCard>>() {

        @Override
        public GridCell<MediaCard> call(GridView<MediaCard> param) {
            // TODO Auto-generated method stub
            return new MediaCell();
        }

    });

MediaCell.java

public class MediaCell extends GridCell<MediaCard>{

public MediaCell() {
    super();
}

@Override
protected void updateItem(MediaCard item, boolean empty) {

    if (item != null) {

        super.updateItem(item, empty);

        AnchorPane rootAnchorPane = new AnchorPane();

        File f = new File(item.getPath());

        Media media = new Media(f.toURI().toString());
        MediaPlayer mediaPlayer = new MediaPlayer(media);
        mediaPlayer.setAutoPlay(true);
        mediaPlayer.play();

        MediaView mv = new MediaView(mediaPlayer);
        mv.setPreserveRatio(true);

        Button viewMediaButton = new Button("View");

        VBox vbox = new VBox(mv, viewMediaButton);

        DoubleProperty mvw = mv.fitWidthProperty();
        DoubleProperty mvh = mv.fitHeightProperty();
        mvw.bind(Bindings.selectDouble(mv.parentProperty(), "width"));
        mvh.bind(Bindings.selectDouble(mv.parentProperty(), "height"));

        rootAnchorPane.getChildren().addAll(vbox);  
        AnchorPane.setTopAnchor(vbox, 0.0);
        AnchorPane.setBottomAnchor(vbox, 0.0);
        AnchorPane.setLeftAnchor(vbox, 0.0);
        AnchorPane.setRightAnchor(vbox, 0.0);

        setGraphic(rootAnchorPane);

    }
}

}

Failed attempt to move each cell to its own thread

gridView.setCellFactory(new Callback<GridView<MediaCard>, GridCell<MediaCard>>() {

        @Override
        public GridCell<MediaCard> call(GridView<MediaCard> param) {
            // TODO Auto-generated method stub

            new Thread(new Runnable() {

                @Override
                public void run() {
                    mediaCell = new MediaCell();
                }
            }).start();
            return mediaCell;
        }

    });
beepboop
  • 57
  • 6

1 Answers1

0

You just have to put the mediaPlayer.play() in a new Thread

Something like:

public class MediaCell extends GridCell<MediaCard> {

    public MediaCell() {
        super();
    }

    @Override
    protected void updateItem(MediaCard item, boolean empty) {

        if (item != null) {

            super.updateItem(item, empty);

            AnchorPane rootAnchorPane = new AnchorPane();

            File f = new File(item.getPath());

            Media media = new Media(f.toURI().toString());
            MediaPlayer mediaPlayer = new MediaPlayer(media);
            mediaPlayer.setAutoPlay(true);

            new Thread() {
                @Override
                public void run() {
                    mediaPlayer.play();
                }
            }.start();

            MediaView mv = new MediaView(mediaPlayer);
            mv.setPreserveRatio(true);

            Button viewMediaButton = new Button("View");

            VBox vbox = new VBox(mv, viewMediaButton);

            DoubleProperty mvw = mv.fitWidthProperty();
            DoubleProperty mvh = mv.fitHeightProperty();
            mvw.bind(Bindings.selectDouble(mv.parentProperty(), "width"));
            mvh.bind(Bindings.selectDouble(mv.parentProperty(), "height"));

            rootAnchorPane.getChildren().addAll(vbox);  
            AnchorPane.setTopAnchor(vbox, 0.0);
            AnchorPane.setBottomAnchor(vbox, 0.0);
            AnchorPane.setLeftAnchor(vbox, 0.0);
            AnchorPane.setRightAnchor(vbox, 0.0);

            setGraphic(rootAnchorPane);

        }
    }
}
Daniel
  • 645
  • 7
  • 11
  • This results in numerous threads being spawned in a unpredictable fashion. Everytime updateItem is called... frequently with cell factories... new threads are spawned. – beepboop Oct 16 '17 at 18:56
  • I would say to use a common CachedThreadPool executor for all your MediaCell's – Daniel Oct 16 '17 at 19:51
  • How would that solve the number of threads being spawned for each MediaCell? – beepboop Oct 17 '17 at 04:43
  • Instead of creating a new thread you would submit your task to the executor and leave it handle the thread allocation. But I think I should study more the MediaPlayer class. I guess it handles the thread allocation itself, so maybe invoking the play in another thread/executor may have no effect on your problem – Daniel Oct 17 '17 at 12:41