Image view size not respected in JavaFX tab pane dropdown

Viewed 49

I'm using a JavaFX TabPane with an image set for one of my tabs. The actual image is bigger than it needs to be, so I use ImageView.setFitHeight(int) and ImageView.setFitWidth(int) to change the image size.

It looks fine in the tab label itself, but when I add too many tabs and the tab drop down is added, the size in the dropdown is displayed in the original image size. Any ideas of how to change the image size in the dropdown?

Minimum reproducible example:

public class TabGraphicsIssueDemo extends Application {

    private static final int TAB_IMAGE_SIZE = 15;
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        
        TabPane pane = new TabPane();
        
        ImageView image = new ImageView(new Image(new FileInputStream("smile.jpg")));
        image.setFitHeight(TAB_IMAGE_SIZE);
        image.setFitWidth(TAB_IMAGE_SIZE);
        
        Tab imageTab = new Tab();
        imageTab.setGraphic(image);
        pane.getTabs().add(imageTab);
        
        for(int i = 0; i < 10; i++) {
            pane.getTabs().add(new Tab("Tab " + i));
        }
        
        
        primaryStage.setScene(new Scene(pane, 300, 300));
        primaryStage.show();
    }

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

Result:

enter image description here

1 Answers

The implementation in the current version (JavaFX version 17) replicates Labels and ImageViews (so they can appear both in the tab and the tabs menu) in a fairly primitive way. If the graphic for a Tab is an ImageView, a new ImageView is created with its ImageProperty bound to the original ImageView's imageProperty. However, other properties, such as fitWidth and fitHeight are not copied.

So a workaround is to resize the Image instead of the ImageView. This means the ImageView used by the tabs menu will reference the resized Image as well, and doesn't need fitHeight and fitWidth set:

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

        TabPane pane = new TabPane();

        ImageView image = new ImageView(new Image(new FileInputStream("smile.jpg"),
                                      TAB_IMAGE_SIZE, TAB_IMAGE_SIZE, true, true));

//        image.setFitHeight(TAB_IMAGE_SIZE);
//        image.setFitWidth(TAB_IMAGE_SIZE);


        Tab imageTab = new Tab();
        imageTab.setGraphic(image);
        pane.getTabs().add(imageTab);

        for(int i = 0; i < 10; i++) {
            pane.getTabs().add(new Tab("Tab " + i));
        }


        primaryStage.setScene(new Scene(pane, 300, 300));
        primaryStage.show();
    }
Related