【问题标题】:Update JavaFX ImageView's image?更新 JavaFX ImageView 的图像?
【发布时间】:2019-03-02 17:23:19
【问题描述】:

我的 JavaFX 应用程序的 Stackpane 中嵌套了一个 ImageView:

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"));
    }
}

考虑到我实际上是在修改现有项目,我提取了相关部分。

在这里,我尝试创建一个单独的方法updateView(),我将在我的程序的另一个类中将其调用为new ImagePanel().updateView()

但在这种情况下,无论我怎么称呼updateView(),图像都不会改变。

【问题讨论】:

  • 是什么阻止您使用所需的Image 实例调用ImageView#setImage()
  • 我试过了,但它似乎根本没有改变图像。
  • 您能告诉我们您是如何更改图像的吗?
  • 谢谢,我在我的问题中添加了更多关于实现的细节。
  • 您确实意识到在调用new ImagePanel(). updateView() 时您正在创建一个新的(不相关的)实例,对吧? (曾经读过/听说过java中的静态与非静态?)。简而言之:获取MainWindow 中的实例并调用updateView 以使其工作。

标签: java javafx imageview


【解决方案1】:

编辑:发布此答案后问题发生了变化。

这是一个 MVCE,可以满足您的需求(启动缓慢,因为它使用 Web 资源)。
运行,然后将其与您的图像交换以验证:

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);
    }
}

【讨论】:

  • 我认为只需调用 .setImage 就应该使用新图像刷新 GUI?
  • 是的。你跑了吗?行得通吗?尝试将它与您的图像一起使用。你在使用 Eclipse IDE 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 2018-03-12
  • 1970-01-01
  • 2018-06-16
  • 2017-07-30
  • 2016-08-29
相关资源
最近更新 更多