0

I have been learning JavaFX.

one of the Samples I made was an image viewer showing all images in a folder.

however the application runs very slowly and takes anywhere between 900-1000MB memory in task-manager.

adding the images one by one to an array works better but still not as snappy as it should be.

Ideally I want it to show at least 200-300 images

any way to keep memory down and perhaps not bring everything to a crawl

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.io.*;
import java.net.MalformedURLException;
import java.util.ArrayList;

public class Main extends Application {
    ArrayList<File> files = new ArrayList<>();
    final ScrollPane sp = new ScrollPane();
    final VBox vb = new VBox();
    final Label fileName = new Label();
    /*final File [] imageNames = new File[]{
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 01.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 02.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 03.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 04.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 05.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 06.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 07.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 08.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 09.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 10.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 11.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 12.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 13.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 14.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 15.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 16.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 17.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 18.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 19.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 20.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 21.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 22.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 23.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 24.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 25.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 26.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 27.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 28.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 29.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 30.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 31.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 32.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 33.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 34.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 35.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 36.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 37.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 38.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 39.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 40.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 41.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 42.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 43.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 44.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 45.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 46.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 47.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 48.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 49.jpg"),
            new File("C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images\\08-05-10 01 50.jpg")
    };
    final Image[] images = new Image[imageNames.length];
    final ImageView[] pics = new ImageView[imageNames.length];
*/
    @Override
    public void start(Stage stage) {
        VBox box = new VBox();
        Scene scene = new Scene(box, 600, 400);
        stage.setScene(scene);
        stage.setTitle("Scroll Pane");
        box.getChildren().addAll(sp, fileName);
        VBox.setVgrow(sp, Priority.ALWAYS);
/*       
        for (int i = 0; i < imageNames.length; i++) {
            try {
                images[i] = new Image(imageNames[i].toURI().toURL().toString());
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            pics[i] = new ImageView(images[i]);
           // pics[i].setFitWidth(100);
            pics[i].setPreserveRatio(true);
            vb.getChildren().add(pics[i]);
        }*/
        initialize();
        //sp.setVmax(440);
        //sp.setPrefSize(100, 100);
        sp.setContent(vb);
        stage.show();
    }
     void initialize(){
        getImages(new File( "C:\\Users\\user\\IdeaProjects\\untitled\\src\\sample\\images"));

        for(File file: files){
            addImage(file);

        }
        files.clear();
    }

    void addImage(File f){
        // load the image
        Image image = null;
        try {
            //FileInputStream inputStream=new FileInputStream(f);
            image = new Image(f.toURI().toURL().toString());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        ImageView iv = new ImageView();
        iv.setImage(image);
        //iv.setFitWidth(100);
        iv.setPreserveRatio(true);
        iv.setSmooth(true);
        iv.setCache(true);

        vb.getChildren().add(iv);
    }

    void getImages(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i = 0; i < children.length; i++) {
                getImages(new File(dir, children[i]));
            }
        }else
        {
            files.add(dir);

        }
    }
    public static void main(String[] args) {
        launch(args);
    }
}
noona
  • 1
  • 1
  • @MouseEvent I actually did use that to test the app since Image accepts an iostream or a url. I forgot to comment it out before I posted. however whether I use FileInputStream doesn't make a difference – noona Jun 27 '17 at 05:29
  • Some relevant suggestions may be fount in this question: https://stackoverflow.com/questions/36318197/javafx-images-in-gridpane-slowing-down-performance-drastically – Itai Jun 27 '17 at 06:47
  • @sillyfly I had come cross this and tried everything. not much of a difference – noona Jun 27 '17 at 09:15
  • Use a `ListView` and load the images in the cell. That way you will only have *visible* images in memory. – James_D Jun 27 '17 at 11:16
  • There's an example of a `ListView` displaying thumbnail images [here](https://stackoverflow.com/questions/29515396/javafx-listview-with-images-instead-of-strings); you can adapt this so it shows the full image in the list view and it should work fine. – James_D Jun 27 '17 at 12:18
  • @James_D am I to understand that this only shows one full image at a time. Current selected being changed with side thumbnails – noona Jun 29 '17 at 02:28
  • That example does, yes. But you can use exactly the same technique to show the full images in the list view (omit the "main" image, and don't scale down the images in the cells). – James_D Jun 29 '17 at 02:36
  • Thanks for every thing @James_D – noona Jun 29 '17 at 06:02

1 Answers1

0

How big are your images? For example if one image is around 10 MB, then 100 images would explain your memory usage... I have tested it with around 200 images which take about 1.9 GB space usage. Of course if you load them all with their original size, it will be slow. But you can specify the image size during loading:

void addImage(File f) {
    // load the image
    Image image = null;
    try {
        // much better memory footprint
        image = new Image(f.toURI().toURL().toString(),400,400,true, true, true);
        //image = new Image(f.toURI().toURL().toString()); // bad idea with many big images
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }

    ImageView iv = new ImageView();
    iv.setImage(image);
    iv.setPreserveRatio(true);
    iv.setSmooth(true);
    iv.setCache(true);

    vb.getChildren().add(iv);
}
Phil
  • 306
  • 1
  • 8
  • truthfully I want it to work with images of any size. i never dealt with something like this. I thought it would be easier since multiple times I have seen large image up to 200 on a single page in a browser. I am baffled how that is done. maybe they only deal with what is in the view-port – noona Jun 27 '17 at 07:49
  • The problem is the same in the browser, even worse because you need to transfer the data via internet instead of loading them from your disc. You can handle this if you show small image resolutions as preview and asyncronously load the images outside your viewport on demand. – Phil Jun 27 '17 at 08:28
  • browsers seem to be doing a much better job of it. I tested it local and internet. not much of a difference in fact Firefox didn't go over 400MB in memory and surprisingly chrome never even went 150MB even with 20 tabs open. the images I used to test were 1200x800 300KB+ jpgs – noona Jun 27 '17 at 09:13