setManaged(false);
final TabPane tabPane = getSkinnable();
headerClip = new Rectangle();
headersRegion = new StackPane() {
@Override protected double computePrefWidth(double height) {
double width = 0.0F;
for (Node child : getChildren()) {
TabHeaderSkin tabHeaderSkin = (TabHeaderSkin)child;
if (tabHeaderSkin.isVisible()) {
width += tabHeaderSkin.prefWidth(height);
}
}
return snapSize(width) + snappedLeftInset() + snappedRightInset();
}
@Override protected double computePrefHeight(double width) {
double height = 0.0F;
for (Node child : getChildren()) {
TabHeaderSkin tabHeaderSkin = (TabHeaderSkin)child;
height = Math.max(height, tabHeaderSkin.prefHeight(width));
}
return snapSize(height) + snappedTopInset() + snappedBottomInset();
}
@Override protected void layoutChildren() {
if (tabsFit()) {
setScrollOffset(0.0);
} else {
if (!removeTab.isEmpty()) {
double offset = 0;
double w = tabHeaderArea.getWidth() - snapSize(controlButtons.prefWidth(-1)) - firstTabIndent() - SPACER;
Iterator i = getChildren().iterator();
while (i.hasNext()) {
TabHeaderSkin tabHeader = (TabHeaderSkin)i.next();
double tabHeaderPrefWidth = snapSize(tabHeader.prefWidth(-1));
if (removeTab.contains(tabHeader)) {
if (offset < w) {
isSelectingTab = true;
}
i.remove();
removeTab.remove(tabHeader);
if (removeTab.isEmpty()) {
break;
}
}
offset += tabHeaderPrefWidth;
}
} else {
isSelectingTab = true;
}
}
if (isSelectingTab) {
double offset = 0;
double selectedTabOffset = 0;
double selectedTabWidth = 0;
double previousSelectedTabOffset = 0;
double previousSelectedTabWidth = 0;
for (Node node: getChildren()) {
TabHeaderSkin tabHeader = (TabHeaderSkin)node;
// size and position the header relative to the other headers
double tabHeaderPrefWidth = snapSize(tabHeader.prefWidth(-1));
if (selectedTab != null && selectedTab.equals(tabHeader.getTab())) {
selectedTabOffset = offset;
selectedTabWidth = tabHeaderPrefWidth;
}
if (previousSelectedTab != null && previousSelectedTab.equals(tabHeader.getTab())) {
previousSelectedTabOffset = offset;
previousSelectedTabWidth = tabHeaderPrefWidth;
}
offset+=tabHeaderPrefWidth;
}
if (selectedTabOffset > previousSelectedTabOffset) {
scrollToSelectedTab(selectedTabOffset + selectedTabWidth, previousSelectedTabOffset);
} else {
scrollToSelectedTab(selectedTabOffset, previousSelectedTabOffset);
}
isSelectingTab = false;
}
Side tabPosition = getSkinnable().getSide();
double tabBackgroundHeight = snapSize(prefHeight(-1));
double tabX = (tabPosition.equals(Side.LEFT) || tabPosition.equals(Side.BOTTOM)) ?
snapSize(getWidth()) - getScrollOffset() : getScrollOffset();
updateHeaderClip();
for (Node node : getChildren()) {
TabHeaderSkin tabHeader = (TabHeaderSkin)node;
// size and position the header relative to the other headers
double tabHeaderPrefWidth = snapSize(tabHeader.prefWidth(-1));
double tabHeaderPrefHeight = snapSize(tabHeader.prefHeight(-1));
tabHeader.resize(tabHeaderPrefWidth, tabHeaderPrefHeight);
// This ensures that the tabs are located in the correct position
// when there are tabs of differing heights.
double startY = tabPosition.equals(Side.BOTTOM) ?
0 : tabBackgroundHeight - tabHeaderPrefHeight - snappedBottomInset();
if (tabPosition.equals(Side.LEFT) || tabPosition.equals(Side.BOTTOM)) {
// build from the right
tabX -= tabHeaderPrefWidth;
tabHeader.relocate(tabX, startY);
} else {
// build from the left
tabHeader.relocate(tabX, startY);
tabX += tabHeaderPrefWidth;
}
}
}
};
headersRegion.getStyleClass().setAll("headers-region");
headersRegion.setClip(headerClip);
headerBackground = new StackPane();
headerBackground.getStyleClass().setAll("tab-header-background");
int i = 0;
for (Tab tab: tabPane.getTabs()) {
addTab(tab, i++, true);