设置为ImageView时,图像不可见

时间:2017-08-07 13:46:20

标签: java javafx fxml

我有一个允许用户从文件系统中选择图像的方法。我的部分布局(包括工具栏和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>

主要应用类:

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

}

主要控制器:

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 个答案:

答案 0 :(得分:1)

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

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

所以你应该这样做:

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

}