Carrein
Carrein

Reputation: 3361

Update JavaFX ImageView's image?

I have a ImageView nested in a Stackpane in my JavaFX application:

UiManager.java

 @Override
    public void start(Stage primaryStage) {
        logger.info("Starting UI...");

        //Set the application icon.
        primaryStage.getIcons().add(getImage(ICON_APPLICATION));

        try {
            mainWindow = new MainWindow(primaryStage, logic);
            mainWindow.show(); //This should be called before creating other UI parts
            mainWindow.fillInnerParts();

        } catch (Throwable e) {
            logger.severe(StringUtil.getDetails(e));
            showFatalErrorDialogAndShutdown("Fatal error during initializing", e);
        }
    }

MainWindow.java

// Independent Ui parts residing in this Ui container
private ImagePanel imagePanel;
private PersonListPanel personListPanel;
private ResultDisplay resultDisplay;
private HelpWindow helpWindow;

@FXML
private StackPane imagePlaceholder;

@FXML
private StackPane commandBoxPlaceholder;

@FXML
private MenuItem helpMenuItem;

@FXML
private StackPane personListPanelPlaceholder;

@FXML
private StackPane resultDisplayPlaceholder;

@FXML
private StackPane statusbarPlaceholder;

void fillInnerParts() {
        imagePanel = new ImagePanel();
        imagePlaceholder.getChildren().add(imagePanel.getRoot());

        personListPanel = new PersonListPanel(logic.getFilteredPersonList(), logic.selectedPersonProperty(),
                logic::setSelectedPerson);
        personListPanelPlaceholder.getChildren().add(personListPanel.getRoot());

        resultDisplay = new ResultDisplay();
        resultDisplayPlaceholder.getChildren().add(resultDisplay.getRoot());

        StatusBarFooter statusBarFooter = new StatusBarFooter(logic.getAddressBookFilePath(), logic.getAddressBook());
        statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot());

        CommandBox commandBox = new CommandBox(this::executeCommand, logic.getHistory());
        commandBoxPlaceholder.getChildren().add(commandBox.getRoot());

        //imagePlaceholder.getChildren().add(imagePanel.getRoot());
    }

ImagePanel.java

public class ImagePanel extends UiPart<Region> {

    private static final String FXML = "ImagePanel.fxml";

    @FXML
    private ImageView imageView;

    public ImagePanel() {
        super(FXML);
        imageView.setImage(new Image("/assets/1.png"));
    }

    public void updateView() {
        imageView.setImage(new Image("/assets/3.png"));
    }
}

I extracted the relevant parts considering i am actually modifying an existing project.

Here I tried to create a separated method updateView() which I would call in another class in my program as new ImagePanel().updateView()

But in this case, no matter how I seem to call updateView(), the image does not change.

Upvotes: 0

Views: 721

Answers (1)

c0der
c0der

Reputation: 18792

Edit: the question was changes after posting this answer.

This is an MVCE that does what you need (slow startup because it uses web resources).
Run, and then swap it with your images to verify:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class Test extends Application{

    private static int counter =0;
    private ImageView iv;
    private Image[] images;
    private final String[] urls = {
            "https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/160/lg/57/tropical-fish_1f420.png",
            "https://www.shareicon.net/data/128x128/2015/03/28/14104_animal_256x256.png",
            "https://cdn1.iconfinder.com/data/icons/DarkGlass_Reworked/128x128/apps/gnome-fish.png",
            "http://www.iconsalot.com/asset/icons/freepik/pet-shop-13/128/010-fish-2-icon.png"
    };

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        images = new Image[urls.length];
        for(int i=0; i< urls.length; i++) {
            images[i] = new Image(urls[i]);
        }

        iv = new ImageView(images[counter++]);
        Button swapImage = new Button("Swap Image");
        swapImage.setOnAction(e->swapImage());
        BorderPane root = new BorderPane(iv);
        root.setBottom(swapImage);
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.sizeToScene();
        primaryStage.show();
    }

    private void swapImage() {
        counter = counter +1 >= images.length ? 0 : counter;
        iv.setImage(images[counter++]);
    }

    public static void main(String[] args)  {
        Application.launch(args);
    }
}

Upvotes: 1

Related Questions