如果TabPane没有选项卡,则显示标签

时间:2016-02-06 09:30:05

标签: javafx javafx-8

我想在中心显示标签为空:

private TabPane tabPane = new TabPane();
private Text placeHolder = new Text("Empty");
placeHolder.setFont(Font.font(null, FontWeight.BOLD, 20));
placeHolder.visibleProperty().bind(Bindings.isEmpty(tabPane.getChildren()));

实现这个的正确方法是什么?

1 个答案:

答案 0 :(得分:5)

TabPane没有像TableView那样的现成占位符。您可以尝试3种不同的方法:

1)使用自定义皮肤,并通过-fx-skin进行设置。

package my.skin;

import com.sun.javafx.scene.control.skin.TabPaneSkin;

import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.TabPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;


public class CustomTabPaneSkin extends TabPaneSkin
{

    private final VBox placeHolder;
    private final Label placeHolderText;


    public CustomTabPaneSkin( TabPane tabPane )
    {
        super( tabPane );

        placeHolderText = new Label( "Empty" );
        placeHolderText.setFont( Font.font( null, FontWeight.BOLD, 20 ) );
        placeHolderText.setAlignment( Pos.CENTER );

        placeHolderText.minWidthProperty().bind( getSkinnable().widthProperty() );
        placeHolderText.minHeightProperty().bind( getSkinnable().heightProperty() );

        placeHolder = new VBox( placeHolderText );

        for ( Node node : getChildren() )
        {
            if ( node.getStyleClass().contains( "tab-header-area" ) )
            {
                Pane headerArea = ( Pane ) node;
                // Header area is hidden if there is no tabs, thus when the tabpane is "empty"
                headerArea.visibleProperty().addListener( ( observable, oldValue, newValue )
                        -> 
                        {
                            if ( newValue )
                            {
                                getChildren().remove( placeHolder );
                            }
                            else
                            {
                                getChildren().add( placeHolder );
                            }
                        }
                );

                break;
            }
        }
    }

}

并在自定义css文件中

.tab-pane {
  -fx-skin: "my.skin.CustomTabPaneSkin";
}

这就是全部。像往常一样使用tabpanes。

2)使用包含tabpane和占位符

的自定义包装器
@Override
public void start( Stage primaryStage )
{
    TabPaneHolder tabPaneHolder = new TabPaneHolder( new Tab( "tab 1" ) );
    tabPaneHolder.getTabs().add( new Tab( "tab 2" ) );

    Scene scene = new Scene( tabPaneHolder, 350, 200 );
    primaryStage.setScene( scene );
    primaryStage.show();
}

public class TabPaneHolder extends VBox
{
    private final TabPane tabPane;
    private final Text placeHolder;

    public TabPaneHolder( Tab... tabs )
    {
        this( "Empty", tabs );
    }

    public TabPaneHolder( String emptyMessage, Tab... tabs )
    {
        this.tabPane = new TabPane( tabs );
        placeHolder = new Text( emptyMessage );
        placeHolder.setFont( Font.font( null, FontWeight.BOLD, 20 ) );
        BooleanBinding bb = Bindings.isEmpty( tabPane.getTabs() );
        placeHolder.visibleProperty().bind( bb );
        placeHolder.managedProperty().bind( bb );
        getChildren().addAll( placeHolder, tabPane );

        alignmentProperty().bind( Bindings.when( bb ).then( Pos.CENTER ).otherwise( Pos.TOP_LEFT ) );
    }

    public ObservableList<Tab> getTabs()
    {
        return tabPane.getTabs();
    }
}

3)简单直接的方法

@Override
public void start( Stage primaryStage )
{
    TabPane tabPane = new TabPane();
    tabPane.getTabs().add( new Tab( "tab" ) );
    Text placeHolder = new Text( "Empty" );
    placeHolder.setFont( Font.font( null, FontWeight.BOLD, 20 ) );
    BooleanBinding bb = Bindings.isEmpty( tabPane.getTabs() );
    placeHolder.visibleProperty().bind( bb );
    placeHolder.managedProperty().bind( bb );

    Scene scene = new Scene( new VBox( placeHolder, tabPane ), 350, 200 );
    primaryStage.setScene( scene );
    primaryStage.show();
}