Issue
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:
Solution
The implementation in the current version (JavaFX version 17) replicates Label
s and ImageView
s (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();
}
Answered By - James_D
Answer Checked By - Katrina (JavaFixing Volunteer)