设置为ImageView时,图像不可见

时间:2022-01-14 17:00:12

I have a method that allows the user to select an image from the file system. Part of my layout, including the Toolbar and MenuBar are created in FXML, but the main Image, ImageView, BorderPane and ScrollPane are set in the Main Application Class. Previously, I was able to show the selected image in the appropriate ImageView, but now it is just invisible. I tested to see if the image was being retrieved correctly, and sure enough I can retrieve its file path and width when debugging, but the screen still doesn't show the image. What is going wrong?

我有一个方法,允许用户从文件系统中选择一个图像。我的部分布局(包括工具栏和MenuBar)是在FXML中创建的,但主要的Image,ImageView,BorderPane和ScrollPane都是在主应用程序类中设置的。以前,我能够在适当的ImageView中显示所选图像,但现在它只是不可见。我测试了是否正确检索图像,并且确实可以在调试时检索其文件路径和宽度,但屏幕仍然不显示图像。出了什么问题?

FXML:

<VBox prefHeight="600" prefWidth="800" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">

    <VBox alignment="TOP_CENTER">
        <ToolBar minHeight="50.0" prefHeight="50.0" prefWidth="800.0" stylesheets="@style.css" GridPane.rowIndex="1">
            <ImageView fitHeight="35.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true">
                <Image url="@react-toolbar-logo.png" />
            </ImageView>
        </ToolBar>
        <MenuBar fx:id="menuBar" prefHeight="0.0" prefWidth="0.0" />
    </VBox>

</VBox>

Main Application Class:

主要应用类别:

public class Main extends Application {

    private Image mainImage;
    private final Group selectionGroup = new Group();

    @Override
    public void start(Stage primaryStage) throws Exception {

        // Basic stage settings
        primaryStage.setTitle("Picture Viewer");
        primaryStage.setResizable(true);

        // Set task bar primary icon
        primaryStage.getIcons().add(new javafx.scene.image.Image("main/react-app-icon.png"));

        // Declare UI variables
        final BorderPane borderPane = new BorderPane();
        final ScrollPane scrollPane = new ScrollPane();
        final Scene scene = new Scene(borderPane, 800, 600);

        ImageView mainImageView = new ImageView();

        // Select main layout file
        FXMLLoader loader = new  FXMLLoader(getClass().getResource("/main/scene.fxml"));
        loader.setController(new MainController(primaryStage, selectionGroup, mainImage, mainImageView));
        Parent root = loader.load();

        // Add custom stylesheet URL
        scene.getStylesheets().add("main/style.css");

        // Set UI element properties
        selectionGroup.getChildren().add(mainImageView);
        scrollPane.setContent(selectionGroup);
        scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);

        // Show primary stage
        // primaryStage.setScene(scene);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();

    }

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

}

Main Controller:

class MainController implements Initializable {

    private Stage primaryStage;
    private Group selectionGroup;

    private Image mainImage;
    private ImageView mainImageView;

    MainController(Stage primaryStage, Group selectionGroup, Image mainImage, ImageView mainImageView) {
        this.primaryStage = primaryStage;
        this.selectionGroup = selectionGroup;
        this.mainImage = mainImage;
        this.mainImageView = mainImageView;
    }

    private boolean isAreaSelected = false;
    private final AreaSelection areaSelection = new AreaSelection();

    @FXML
    private
    MenuBar menuBar;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        // Declare menus
        final Menu menu1 = new Menu("File");
        final Menu menu2 = new Menu("Options");

        // Define menu 1 items
        final MenuItem open = new MenuItem("Open");
        final MenuItem clear = new MenuItem("Clear");
        final MenuItem exit = new MenuItem("Exit");

        // Define menu 2 items
        // final MenuItem select = new MenuItem("Select Area");
        final MenuItem crop = new MenuItem("Crop & Upload");
        final MenuItem clearSelectionItem = new MenuItem("Clear Selection");

        // Set menu items
        menu1.getItems().addAll(open, clear, exit);
        menu2.getItems().addAll(crop, clearSelectionItem);

        // Set menu click events
        setMenu1ClickEvents(primaryStage, open, clear, exit);
        setMenu2ClickEvents(crop, clearSelectionItem);

        // Instantiate menus
        menuBar.getMenus().addAll(menu1, menu2);

    }

    private void setMenu1ClickEvents(Stage primaryStage, MenuItem open, MenuItem clear, MenuItem exit) {
        // Open file system to select image
        open.setOnAction(event -> {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("Open Image File");
            fileChooser.getExtensionFilters().addAll(
                    new FileChooser.ExtensionFilter("Image Files", "*.png", "*.jpg"));

            File selectedFile = fileChooser.showOpenDialog(primaryStage);

            if (selectedFile != null) {
                clearSelection(selectionGroup);
                this.mainImage = convertFileToImage(selectedFile);
                System.out.println("selectedFile: " + selectedFile);
                mainImageView.setImage(mainImage);
                System.out.println("mainImage.getWidth(): " + mainImage.getWidth());
                changeStageSizeImageDimensions(primaryStage, mainImage);
            }
        });

        // Clear the current image
        clear.setOnAction(event -> {
            clearSelection(selectionGroup);
            mainImageView.setImage(null);
            System.gc();
        });

        // Exit the application
        exit.setOnAction(event -> {
            Platform.exit();
            System.exit(0);
        });
    }

    private void setMenu2ClickEvents(MenuItem crop, MenuItem clearSelectionItem) {
        // Set menu 2 click events

        crop.setOnAction(event -> {
            if (isAreaSelected()) {
                cropImage(areaSelection.selectArea(selectionGroup).getBoundsInParent(), mainImageView);
            }
        });

        clearSelectionItem.setOnAction(event -> clearSelection(selectionGroup));
    }
}

convertFileToImage:

private Image convertFileToImage(File imageFile) {
        Image image = null;
        try (FileInputStream fileInputStream = new FileInputStream(imageFile)) {
            image = new Image(fileInputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return image;
    }

1 个解决方案

#1


1  

You never display the ImageView, or indeed any of the controls you create in the Java code.

您永远不会显示ImageView,或者实际上您在Java代码中创建的任何控件。

According to the comments, you want the content of the FXML in the top of the border pane, and the scroll pane containing the group with the image view in the center.

根据评论,您希望FXML的内容位于边框窗格的顶部,滚动窗格包含具有图像视图的组在中心。

So you should do:

所以你应该这样做:

public class Main extends Application {

    private Image mainImage;
    private final Group selectionGroup = new Group();

    @Override
    public void start(Stage primaryStage) throws Exception {

        // Basic stage settings
        primaryStage.setTitle("Picture Viewer");
        primaryStage.setResizable(true);

        // Set task bar primary icon
        primaryStage.getIcons().add(new javafx.scene.image.Image("main/react-app-icon.png"));

        // Declare UI variables
        final BorderPane borderPane = new BorderPane();
        final ScrollPane scrollPane = new ScrollPane();
        final Scene scene = new Scene(borderPane, 800, 600);

        ImageView mainImageView = new ImageView();

        // Select main layout file
        FXMLLoader loader = new  FXMLLoader(getClass().getResource("/main/scene.fxml"));
        loader.setController(new MainController(primaryStage, selectionGroup, mainImage, mainImageView));
        Parent root = loader.load();

        // Add custom stylesheet URL
        scene.getStylesheets().add("main/style.css");

        // Set UI element properties
        selectionGroup.getChildren().add(mainImageView);
        scrollPane.setContent(selectionGroup);
        scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);

        borderPane.setCenter(scrollPane);
        borderPane.setTop(root);

        // Show primary stage
        primaryStage.setScene(scene);
        // primaryStage.setScene(new Scene(root));
        primaryStage.show();

    }

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

}

#1


1  

You never display the ImageView, or indeed any of the controls you create in the Java code.

您永远不会显示ImageView,或者实际上您在Java代码中创建的任何控件。

According to the comments, you want the content of the FXML in the top of the border pane, and the scroll pane containing the group with the image view in the center.

根据评论,您希望FXML的内容位于边框窗格的顶部,滚动窗格包含具有图像视图的组在中心。

So you should do:

所以你应该这样做:

public class Main extends Application {

    private Image mainImage;
    private final Group selectionGroup = new Group();

    @Override
    public void start(Stage primaryStage) throws Exception {

        // Basic stage settings
        primaryStage.setTitle("Picture Viewer");
        primaryStage.setResizable(true);

        // Set task bar primary icon
        primaryStage.getIcons().add(new javafx.scene.image.Image("main/react-app-icon.png"));

        // Declare UI variables
        final BorderPane borderPane = new BorderPane();
        final ScrollPane scrollPane = new ScrollPane();
        final Scene scene = new Scene(borderPane, 800, 600);

        ImageView mainImageView = new ImageView();

        // Select main layout file
        FXMLLoader loader = new  FXMLLoader(getClass().getResource("/main/scene.fxml"));
        loader.setController(new MainController(primaryStage, selectionGroup, mainImage, mainImageView));
        Parent root = loader.load();

        // Add custom stylesheet URL
        scene.getStylesheets().add("main/style.css");

        // Set UI element properties
        selectionGroup.getChildren().add(mainImageView);
        scrollPane.setContent(selectionGroup);
        scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);

        borderPane.setCenter(scrollPane);
        borderPane.setTop(root);

        // Show primary stage
        primaryStage.setScene(scene);
        // primaryStage.setScene(new Scene(root));
        primaryStage.show();

    }

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

}