Search code examples
cssuser-interfacetabsjavafx-2tabpanel

JavaFX. Can't remove extra-space at the right of TabPane


I'm developing full-screen application on JavaFX 2.2 with tab navigation. Tab's should fill all screen width. But I found that I have 10px space at the right side of headers region.. And what's interesting: this space appear only after I switch to the last tab and disappear only after I will switch to the first tab. Other tabs don't change this space, it's appear, only after selecting last tab, and disappear after selecting first one. Here the screenshots which explain the issue (this margin is yellow):

enter image description here

enter image description here

Tab's width I calculating by the simple formula:

double tabWidth = tabPane.getWidth() / tabPane.getTabs().size();
tabPane.setTabMinWidth(tabWidth);
tabPane.setTabMaxWidth(tabWidth);

All padding's removed in CSS-classes. Also i set special colors, to understand who is the owner of this space.. and looks like it's the main headers-region. Here the CSS-calsses:

.tab-pane .headers-region {
 -fx-background-color: yellow;
 -fx-padding: 0;
 -fx-background-insets: 0;
 -fx-effect: null;
}

.tab-pane {
 -fx-background-color: white;
 -fx-background-insets:0;
 -fx-padding: 0;
}

*.tab-header-background {
 -fx-padding:0;
 -fx-background-insets:0;
}

.tab-pane *.tab-header-background {
 -fx-padding:0;
 -fx-background-insets:0;
}

.tab:selected {
 -fx-background-color: white;
 -fx-background-insets: 0;
 -fx-background-radius: 0;    
}

.tab {
 -fx-background-color: white;
 -fx-padding: 0;
 -fx-background-insets: 0;   
}

.tab:top {
 -fx-padding: 0;
 -fx-background-insets: 0;
}

.tab:right {
 -fx-padding: 0;
 -fx-background-insets: 0;
}

.tab:bottom {
 -fx-padding: 0;
 -fx-background-insets: 0;
}

.tab:left {
 -fx-padding: 0;
 -fx-background-insets: 0;
}

.tab:hover {
 -fx-padding: 0;
 -fx-background-insets: 0;
}

.tab-header-area {
 -fx-padding: 0;
 -fx-background-insets: 0;
}

.tab-pane:top *.tab-header-area {
 -fx-background-insets: 0;
 -fx-padding: 0;
}

.tab-pane:bottom *.tab-header-area {
 -fx-background-insets: 0;
 -fx-padding: 0;
}

.tab-pane:left *.tab-header-area {
 -fx-background-insets: 0;
 -fx-padding: 0;
}

.tab-pane:right *.tab-header-area {
 -fx-background-insets: 0;
 -fx-padding: 0;
}

.control-buttons-tab {
 -fx-background-insets: 0;
 -fx-background-radius: 0;
 -fx-padding: 0;
}

.tab-down-button {
 -fx-background-color: green;
 -fx-padding: 0;
}

.tab-down-button .arrow {
 -fx-background-insets: 0;
 -fx-background:black;
 -fx-width:0;
 -fx-padding: 0;
 -fx-shape: " ";
}

.arrow {
 -fx-background-insets: 0;
 -fx-background:black;
 -fx-width:0;
 -fx-padding: 0;
 -fx-shape: " ";
}

Solution

  • The problem is the class TabPaneSkin, which converts Tabs into Nodes. It needs to scroll the TabHeaderArea to the left (or the right) when his offset is greater than his width. Look at the method scrollToSelectedTab(double selected, double previous) in the class TabHeaderArea.

    The only way I've found to solve this is to create your custom MyTabPaneSkin (inspired from TabPaneSkin) and change the behavior of the method scrollToSelectedTab (As all of its members are private, extending it would not be helpful).

    Then, override the method createDefaultSkin of the class TabPane like this:

    TabPane tabPane = new TabPane(){
        @Override
        protected Skin<?> createDefaultSkin() {
            return new MyTabPaneSkin(this);
        }   
    };
    

    Keep in mind that you will lose all improvements or fixes from the original TabPaneSkin.

    Ideally, JavaFX should implement this feature by allowing to disable the autoscroll...

    (See https://javafx-jira.kenai.com/browse/RT-38014)