RFR: 8353599: TabPaneSkin: add 'menuGraphicFactory' property
Andy Goryachev
angorya at openjdk.org
Wed Apr 16 18:08:07 UTC 2025
Tries to address the mystery of missing graphic in the TabPane overflow menu:
# Overflow Menu Graphic Property in the TabPaneSkin
Andy Goryachev
<andy.goryachev at oracle.com>
## Summary
Introduce a `menuGraphicFactory` property in the `TabPaneSkin` class eliminates the current limitation of this skin
in supporting menu item graphics other than an `ImageView` or `Label` with an `ImageView` graphic.
## Goals
The goals of this proposal are:
- to allow the application developers to customize the overflow menu items' graphic
- retain the backward compatibility with the existing application code
- clarify the behavior of the skin when the property is null (i.e. the current behavior)
## Non-Goals
The following are not the goals of this proposal:
- disable the overflow menu
- configure overflow menu graphic property via CSS
- add this property to the `TabPane` control itself
## Motivation
The existing `TabPaneSkin` does not allow the overflow menu to show graphic other than
an `ImageView` or `Label` with an `ImageView`.
This limitation makes it impossible for the application developer to use other graphic Nodes,
such as `Path` or `Canvas`, or in fact any other types. The situation becomes even more egregious
when the tabs in the `TabPane` have no text.
Example:
public class TabPaneGraphicFactoryExample {
public void example() {
Tab tab1 = new Tab("Tab1");
tab1.setGraphic(createGraphic(tab1));
Tab tab2 = new Tab("Tab2");
tab2.setGraphic(createGraphic(tab2));
TabPane tabPane = new TabPane();
tabPane.getTabs().addAll(tab1, tab2);
TabPaneSkin skin = new TabPaneSkin(tabPane);
// set overflow menu factory with the same method as was used to create the tabs
skin.setMenuGraphicFactory(this::createGraphic);
tabPane.setSkin(skin);
}
// creates graphic Nodes for tabs as well as the overflow menu
private Node createGraphic(Tab tab) {
switch (tab.getText()) {
case "Tab1":
return new Circle(10);
case "Tab2":
return new Canvas(10, 10);
default:
return null;
}
}
}
## Description
The proposed solution adds the `menuGraphicFactory` property in the `TabPaneSkin` class:
/**
* This property allows to control the graphic for the overflow menu items,
* by generating graphic {@code Node}s when the menu is shown.
* <p>
* When this property is {@code null}, the menu provides only the basic graphic copied from the corresponding
* {@link Tab} - either an {@link ImageView} or a {@link Label} with an {@link ImageView} as its graphic.
* <p>
* Changing this property while the menu is shown has no effect.
*
* @since 25
* @defaultValue null
*/
public final ObjectProperty<Function<Tab, Node>> menuGraphicFactoryProperty() {
public final Function<Tab,Node> getMenuGraphicFactory() {
public final void setMenuGraphicFactory(Function<Tab,Node> f) {
## Alternatives
Use graphic in tabs based on the `ImageView`, which is currently compatible with the overflow menu.
## Risks and Assumptions
The risk is minimal, as the proposed solution adds a new property and retains the existing behavior when
this property is not set.
There might be a need to update the application code if the `TabPane` uses a custom skin extended from
the `TabPaneSkin` which declares a property or a method (or methods) with the same signature.
## Dependencies
None.
## References
- [JDK-8353599 TabPaneSkin: add 'menuGraphicFactory' property](https://bugs.openjdk.org/browse/JDK-8353599)
- https://mail.openjdk.org/pipermail/openjfx-dev/2025-April/053306.html
- https://mail.openjdk.org/pipermail/openjfx-dev/2025-April/053338.html
- https://github.com/andy-goryachev-oracle/Test/blob/main/doc/TabPane/TabPaneGraphicFactory.md
-------------
Commit messages:
- Merge remote-tracking branch 'origin/master' into 8353599.menu.factory
- javadoc
- Merge remote-tracking branch 'origin/master' into 8353599.menu.factory
- graphic factory
Changes: https://git.openjdk.org/jfx/pull/1773/files
Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1773&range=00
Issue: https://bugs.openjdk.org/browse/JDK-8353599
Stats: 135 lines in 2 files changed: 100 ins; 17 del; 18 mod
Patch: https://git.openjdk.org/jfx/pull/1773.diff
Fetch: git fetch https://git.openjdk.org/jfx.git pull/1773/head:pull/1773
PR: https://git.openjdk.org/jfx/pull/1773
More information about the openjfx-dev
mailing list