MGogic MGogic - 5 months ago 40
Java Question

How to populate table with images from array list in JavaFX?

I am in process of learning JavaFX, and I want to populate one table column with images of books and other with summary. Can I do that? When I tried I only succeeded to get one image for all books. Simple example

package tableviewexample;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import javafx.scene.image.Image;


public class Book {
public static String path = "src/tableviewexample/Opis/";
public static ArrayList<Book> list = new ArrayList<>();
private boolean checked;
private boolean isItAvailable;
private String bookName;
private String isbn;
private String authorName;
private int numberOfPages;
private String summary;
private String publisher;
private String mainPage;
private double cost;
private int quantity;
private String genre;
private Image image;
public Book() {

}
public Book(boolean checked, boolean isItAvailable, String bookName, String isbn, String authorName, int numberOfPages,
String summary, String publisher, String mainPage, double cost,
int quantity, String genre) {
this.isItAvailable = isItAvailable;
this.checked = checked;
this.bookName = bookName;
this.isbn = isbn;
this.authorName = authorName;
this.numberOfPages = numberOfPages;
this.summary = summary;
this.publisher = publisher;
this.mainPage = mainPage;
this.cost = cost;
this.quantity = quantity;
this.genre = genre;
}
public String getBookName() {
return bookName.get();
}

public void setBookName(String bookName) {
this.bookName.set(bookName);
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getIsbn() {
return isbn;
}

public void setIsbn(String isbn) {
this.isbn = isbn;
}

public String getAuthorName() {
return authorName;
}

public void setAuthorName(String authorName) {
this.authorName = authorName;
}

public int getNumberOfPages() {
return numberOfPages;
}

public void setNumberOfPages(int numberOfPages) {
this.numberOfPages = numberOfPages;
}

public String getSummary() {
return summary;
}


public void setSummary(String summary) {
this.summary = summary;
}


public String getPublisher() {
return publisher;
}


public void setPublisher(String publisher) {
this.publisher = publisher;
}


public String getMainPage() {
return mainPage;
}


public void setMainPage(String mainPage) {
this.mainPage = mainPage;
}

public double getCost() {
return cost;
}

public void setCost(double cost) {
this.cost = cost;
}


public int getQuantity() {
return quantity;
}


public void setQuantity(int quantity) {
this.quantity = quantity;
}

public void setGenre(String genre) {
this.genre = genre;
}

public String getGenre() {
return genre;
}

public boolean getChecked() {
return checked;
}

public void setChecked(boolean checked) {
this.checked = checked;
}

public boolean getIsItAvailable() {
return isItAvailable;
}

public void setIsItAvailable(boolean isItAvailable) {
this.isItAvailable = isItAvailable;
}

public String toString() {
return "AUTHOR: " + getAuthorName() + "\nPUBLISHER:" + getPublisher() +
"\nNAME:" + getBookName() + "\nPRICE: " + getCost();
}

//helper function from file to string convertor
public static String fromFileToString(File file)
throws IOException {
int len;
char[] chr = new char[4096];
final StringBuffer buffer = new StringBuffer();
final FileReader reader = new FileReader(file);
try {
while ((len = reader.read(chr)) > 0) {
buffer.append(chr, 0, len);
}
} finally {
reader.close();
}
return buffer.toString();
}
public static void init() {
ArrayList<String> txtSummary = new ArrayList<>();
txtSummary.add("basara.txt");
txtSummary.add("igraPrestola.txt");
txtSummary.add("sudar_kraljeva.txt");
txtSummary.add("oluja_maceva.txt");

try {
Book pBasara = new Book(false, true, "Fama o biciklistima", "978-86-521-1090-2", "Svetislav Basara",
334," ","Dereta", "src/tableviewexample/Images/basara.jpg", 16.50, 20, "filozofsko - religijski roman, istorijska");
pBasara.setSummary(Book.fromFileToString(new File(path + txtSummary.get(0))));

Book pIgraPrestola = new Book(false, true, "Igra prestola", "978-86-743-6099-6", "Dzordz R.R. Martin",
599,"","Laguna", "src/tableviewexample/Images/igraPrestola.jpg", 20 , 2, "epska fantastika, politicka strategija");
pIgraPrestola.setSummary(Book.fromFileToString(new File(path + txtSummary.get(1))));

Book pSudarKraljeva = new Book(false, true,"Sudar Kraljeva", "978-86-743-6140-5", "Dzordz R.R. Martin",
672,"","Laguna", "src/tableviewexample/Images/sudar_kraljeva.jpg", 26.20 , 2, "epska fantastika, politicka strategija");
pSudarKraljeva.setSummary(Book.fromFileToString(new File(path + txtSummary.get(2))));

Book pOlujaMaceva = new Book(false, true, "Oluja maceva -deo prvi: Celik i sneg", "978-86-743-6185-6", "Dzordz R.R. Martin",
384,"","Laguna", "src/tableviewexample/Images/oluja_maceva.jpg", 20.50 , 2, "epska fantastika, politicka strategija");
pOlujaMaceva.setSummary(Book.fromFileToString(new File(path + txtSummary.get(3))));
list.add(pBasara);
list.add(pIgraPrestola);
list.add(pSudarKraljeva);
list.add(pOlujaMaceva);
} catch(Exception e) {
e.printStackTrace();
}


}
}


And tableview example

package tableviewexample;

import java.io.File;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;


public class TableViewExample extends Application {

Button catalogue;
Button back;
Stage stage;
Scene sceneTable;
Scene sceneFirst;
GridPane pane;
@Override
public void start(Stage primaryStage) {

catalogue = new Button("Catalogue");
Book.init();
StackPane root = new StackPane();
stage = primaryStage;
pane = new GridPane();
sceneFirst = new Scene(pane,200, 200);
pane.add(catalogue, 0, 0);
catalogue.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event){
ObservableList<Book> data = FXCollections.observableArrayList(Book.list);
TableView<Book> table = new TableView<Book>();
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
TableColumn<Book, String> imageCol = new TableColumn<Book, String>();
TableColumn<Book, String> descriptionCol = new TableColumn<Book, String>();
Callback<TableColumn<Book, String>, TableCell<Book, String>> cellFactory;
table.setItems(data);

back = new Button("Back");
AnchorPane root = new AnchorPane();
sceneTable = new Scene(root, 500, 500);

imageCol.setCellValueFactory(new PropertyValueFactory<Book, String>("mainPage"));
descriptionCol.setCellValueFactory(new PropertyValueFactory<Book, String>("summary"));

cellFactory = new Callback<TableColumn<Book, String>, TableCell<Book, String>>() {
@Override
public TableCell call(final TableColumn param) {
final HBox box= new HBox();
ImageView imageview = new ImageView();
final TableCell cell = new TableCell() {
@Override
public void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (item != null) {
box.setSpacing(10) ;
box.setPadding(new Insets(10, 10, 10, 10));
Image img = null;
//if i put foor loop here, it wil set image of last book in list
//this is confusing part for me
// how to make to get exact image for every book
//this line is only for example, just to show something in table

Book book = Book.list.get(0);
img = new Image(new File(book.getMainPage()).toURI().toString());

imageview.setImage(img);
imageview.setFitHeight(320.0);
imageview.setFitWidth(200.0);
box.getChildren().add(imageview);

}
}
};
cell.setGraphic(box);
return cell;
}
};
imageCol.setCellFactory(cellFactory);
table.getColumns().addAll(imageCol, descriptionCol);
AnchorPane.setTopAnchor(table, 30.0);
AnchorPane.setLeftAnchor(table, 10.0);
AnchorPane.setRightAnchor(table, 10.0);
AnchorPane.setBottomAnchor(table, 10.0);
// refresh(table, data);
root.getChildren().addAll(table, back);
back.setOnAction(e -> ButtonClicked(e));
stage.setScene(sceneTable);
}

public void ButtonClicked(ActionEvent e) {
if(e.getSource() == back) {
stage.setScene(sceneFirst);
}

}
});


primaryStage.setScene(sceneFirst);
primaryStage.show();
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}

}

Answer

This is because you always get the first book in the list : Book book = Book.list.get(0);

Try changing that to: Book book = (Book)item;

Comments