So I'm trying to display images stored in my database as Blob to an image column in table view. All of the other data is displayed well except for those in the image column. I've been struggling for days but still unable to find a solution.
Here's what I have tried so far:
public void loadPropertyData() throws IOException {
try {
Connection connection = OracleConnect.getConnection();
String query = "SELECT id, property, image, price, contact, location, status FROM property" + getProfileName().getText();
PreparedStatement statement = connection.prepareStatement(query);
ResultSet resultSet = statement.executeQuery();
ObservableList<Property> propertyList = FXCollections.observableArrayList();
while (resultSet.next()) {
int id = resultSet.getInt("id");
String property = resultSet.getString("property");
Blob imageBlob = resultSet.getBlob("image");
Image image = null;
if (imageBlob != null) {
InputStream is = imageBlob.getBinaryStream();
image = new Image(is);
}
String price = resultSet.getString("price");
String contact = resultSet.getString("contact");
String location = resultSet.getString("location");
String status = resultSet.getString("status");
Property propertyObj = new Property(id, property, image, price, contact, location, status);
propertyList.add(propertyObj);
}
propertyIDColumn.setCellValueFactory(cellData -> cellData.getValue().idProperty().asObject());
propertyColumn.setCellValueFactory(cellData -> cellData.getValue().propertyProperty());
propertyImageColumn.setCellValueFactory(col -> col.getValue().imageProperty());
propertyImageColumn.setCellFactory(col -> {
TableCell<Property, Image> cell = new TableCell<Property, Image>() {
private final ImageView imageView = new ImageView();
{
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
@Override
protected void updateItem(Image item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
imageView.setImage(null);
setGraphic(null);
} else {
imageView.setImage(item);
setGraphic(imageView);
}
}
};
return cell;
});
propertyPriceColumn.setCellValueFactory(cellData -> cellData.getValue().priceProperty());
propertyContactColumn.setCellValueFactory(cellData -> cellData.getValue().contactProperty());
propertyLocationColumn.setCellValueFactory(cellData -> cellData.getValue().locationProperty());
propertyStatusColumn.setCellValueFactory(cellData -> cellData.getValue().statusProperty());
propertyTableView.setItems(propertyList);
resultSet.close();
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
Edit: Here is my Property model
Property {
private IntegerProperty id;
private StringProperty property;
private ObjectProperty<Image> image;
private StringProperty price;
private StringProperty contact;
private StringProperty location;
private StringProperty status;
public Property(int id, String property, Image image, String price, String contact, String location, String status) {
this.id = new SimpleIntegerProperty(id);
this.property = new SimpleStringProperty(property);
this.image = new SimpleObjectProperty<>(image);
this.price = new SimpleStringProperty(price);
this.contact = new SimpleStringProperty(contact);
this.location = new SimpleStringProperty(location);
this.status = new SimpleStringProperty(status);
}
public IntegerProperty idProperty() {
return id;
}
public int getId() {
return id.get();
}
public void setId(int id) {
this.id.set(id);
}
public StringProperty propertyProperty() {
return property;
}
public String getProperty() {
return property.get();
}
public void setProperty(String property) {
this.property.set(property);
}
public ObjectProperty<Image> imageProperty() {
return image;
}
public Image getImage() {
return image.get();
}
public void setImage(Image image) {
this.image.set(image);
}
public StringProperty priceProperty() {
return price;
}
public String getPrice() {
return price.get();
}
public void setPrice(String price) {
this.price.set(price);
}
public StringProperty contactProperty() {
return contact;
}
public String getContact() {
return contact.get();
}
public void setContact(String contact) {
this.contact.set(contact);
}
public StringProperty locationProperty() {
return location;
}
public String getLocation() {
return location.get();
}
public void setLocation(String location) {
this.location.set(location);
}
public StringProperty statusProperty() {
return status;
}
public String getStatus() {
return status.get();
}
public void setStatus(String status) {
this.status.set(status);
}
}
Here is what I used to create table in my database
@FXML
private void Signup() {
Connection connection = null;
PreparedStatement createTableStatement = null;
PreparedStatement createSequenceStatement = null;
PreparedStatement insertStatement = null;
try {
connection = OracleConnect.getConnection();
// Create table
String createTableProperty = "CREATE TABLE property" + signupTF.getText() +
" (" +
" id NUMBER," +
" property VARCHAR2(50)," +
" image BLOB," +
" price VARCHAR2(50)," +
" contact VARCHAR2(50)," +
" location VARCHAR2(50)," +
" status VARCHAR2(50)" +
")";
createTableStatement = connection.prepareStatement(createTableProperty);
createTableStatement.execute();
// Create sequence
String createSequenceProperty = "CREATE SEQUENCE property" +
signupTF.getText() + "_seq " +
"START WITH 1 " +
"INCREMENT BY 1 " +
"MINVALUE 1 " +
"NOCACHE";
createSequenceStatement = connection.prepareStatement(createSequenceProperty);
createSequenceStatement.execute();
// Insert data
String insertData = "INSERT INTO property" + signupTF.getText() +
" (id, property, image, price, contact, location, status)" +
" VALUES (property" + signupTF.getText() + "_seq.nextval, ?, ?, ?, ?, ?, ?)";
insertStatement = connection.prepareStatement(insertData);
insertStatement.setString(1, "Property Name"); // Set the property name
insertStatement.setBlob(2, new FileInputStream(new File("path/to/image.jpg"))); // Set the image file
insertStatement.setString(3, "Price"); // Set the price
insertStatement.setString(4, "Contact"); // Set the contact
insertStatement.setString(5, "Location"); // Set the location
insertStatement.setString(6, "Status"); // Set the status
insertStatement.execute();
} catch (SQLException e) {
if (e.getErrorCode() == 1400) {
JOptionPane.showMessageDialog(null, "Please enter required information");
} else {
JOptionPane.showMessageDialog(null, "An error occurred: " + e.getMessage());
}
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "Image file not found: " + e.getMessage());
} finally {
try {
if (insertStatement != null) {
insertStatement.close();
}
if (createSequenceStatement != null) {
createSequenceStatement.close();
}
if (createTableStatement != null) {
createTableStatement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(null, "An error occurred while closing the resources: " + e.getMessage());
}
}
}
Here is the data from my table in the database
Here is what's displayed in the table view







propertyImageColumn.setCellValueFactory. I think you must set a cell value factory for each column in theTableView. Note that I don't have access to your database so I can't verify whether your code that retrieves data from the database is correct.