2016-05-17 4 views
0

Ich möchte ein (JavaFX) TabPane verwenden, um den Inhalt von 20 verschiedenen Registerkarten anzuzeigen. Dies funktioniert gut mit dem standardmäßigen TabPane. Wenn der Bereich jedoch eine bestimmte Anzahl an Tabs erreicht, kann auf eine Schaltfläche/ComboBox geklickt werden, um auf einen der nicht sichtbaren Tabs zu klicken.JavaFx TabPane mit mehreren Zeilen von Tabs

Ich entwerfe eine Funktion, die auf einem Touchscreen verwendet wird, also ist dies nicht ideal. Ich denke, es wäre intuitiver, zwei separate Reihen von Tabs zu haben.

Wie kann ich zwei Registerkarten zu einem TabPane hinzufügen, oder was kann getan werden, um einen ähnlichen Effekt zu erzielen? Danke im Voraus.

Hier einige Beispiel-Code zu reproduzieren, was ich meine:

public class TabTest extends Application { 


public static void main(String args[]) { 
    Application.launch(args); 
} 

@Override 
public void start(Stage primaryStage) throws Exception { 
    primaryStage.setTitle("Tabs Test"); 
    Group root = new Group(); 
    Scene scene = new Scene(root, 450, 250, Color.WHITE); 

    TabPane tabPane = new TabPane(); 
    BorderPane borderPane = new BorderPane(); 

    for(int i = 0; i < 20; i++) 
    { 
     Tab tab = new Tab(); 
     tab.setText("Tab " + i); 
     HBox hbox = new HBox(); 
     hbox.getChildren().add(new Label("Tab " + i)); 
     tab.setContent(hbox); 
     tabPane.getTabs().add(tab); 
    } 

    borderPane.prefHeightProperty().bind(scene.heightProperty()); 
    borderPane.prefWidthProperty().bind(scene.widthProperty()); 

    borderPane.setCenter(tabPane); 
    root.getChildren().add(borderPane); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 

Link to tabbed view, since I can't post images yet

+0

Sie sollten den Code, den Sie bisher versucht haben, veröffentlichen, der nicht funktioniert. – ManoDestra

+1

@ManoDestra Danke, ich habe meine Frage mit Beispielcode und einem Link zu einem Bild aktualisiert. – Kornephoros

Antwort

0

Der Kopfbereich Registerkarte für TabPane ist im Grunde ein StackPane, deshalb denke ich, es ist nicht so einfach erstellen zwei Reihen Registerkarten anstelle von einem.

Meine Idee ist es, die ursprünglichen Registerkarten Ihrer TabPane auszublenden und eine Reihe von ToggleButton Objekte in eine ToggleGroup legen dann binden Sie die Auswahl der Umschalter mit der Auswahl der Registerkarten.

Auf diese Weise können Sie die "Tabs" in einen beliebigen Container (Fluss, Raster usw.) einfügen.

wirklich minimal Beispiel:

Main.java

public class Main extends Application { 

    TabPane tabPane; 
    private ToggleGroup toggleGroup; 

    @Override 
    public void start(Stage primaryStage) { 

     Group root = new Group(); 
     Scene scene = new Scene(root, 700, 400, Color.WHITE); 

     primaryStage.setTitle("Tabs Test"); 

     toggleGroup = new ToggleGroup(); 
     toggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() { 

      @Override 
      public void changed(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) { 
       if (newValue == null) 
        toggleGroup.selectToggle(oldValue); 
       else 
        tabPane.getSelectionModel().select((Tab) newValue.getUserData()); 
      } 
     }); 

     tabPane = new TabPane(); 
     tabPane.getStylesheets().add(getClass().getResource("application.css").toExternalForm()); 

     VBox vboxToggleOuterContainer = new VBox(); 
     HBox hboxToggleFirstRow = new HBox(); 
     HBox hboxToggleSecondRow = new HBox(); 

     vboxToggleOuterContainer.getChildren().addAll(hboxToggleFirstRow, hboxToggleSecondRow); 

     for (int i = 0; i < 20; i++) { 
      Tab tab = new Tab(); 
      tab.setText("Tab " + i); 
      HBox hbox = new HBox(); 
      hbox.getChildren().add(new Label("Tab " + i)); 
      tab.setContent(hbox); 
      tabPane.getTabs().add(tab); 

      ToggleButton tb = new ToggleButton("Tab" + i); 
      tb.setToggleGroup(toggleGroup); 
      tb.setUserData(tab); 

      if (i < 10) 
       hboxToggleFirstRow.getChildren().add(tb); 
      else 
       hboxToggleSecondRow.getChildren().add(tb); 
     } 

     toggleGroup.selectToggle(toggleGroup.getToggles().get(0)); 

     VBox vbox = new VBox(); 
     vbox.getChildren().addAll(vboxToggleOuterContainer, tabPane); 
     vbox.fillWidthProperty().set(true); 
     root.getChildren().add(vbox); 

     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

application.css

.tab-pane { 
    -fx-skin: "com.sun.javafx.scene.control.skin.TabPaneSkin"; 
    -fx-tab-min-height: 0; 
    -fx-tab-max-height: 0; 
} 

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

.tab-pane .tab-header-area .headers-region .tab { 

    -fx-padding: 0 0 1 0; 
} 

Das Beispiel wirklich minimal ist, zeigt nur den Ansatz, Sie kann das CSS verbessern, um die Kontrolle viel mehr zu haben E-fancy (oder wenn Sie wollen, ich kann es auch aktualisieren, wenn ich Zeit haben werde).

+0

Danke für Ihre Antwort. Ich wünschte, es gäbe einen saubereren Weg, aber das Beispiel macht genau das, was ich will. – Kornephoros