2012-06-08 14 views

Antwort

7

Ich kam mit der folgenden Funktion auf:

private void makeHeaderWrappable(TableColumn col) { 
    Label label = new Label(col.getText()); 
    label.setStyle("-fx-padding: 8px;"); 
    label.setWrapText(true); 
    label.setAlignment(Pos.CENTER); 
    label.setTextAlignment(TextAlignment.CENTER); 

    StackPane stack = new StackPane(); 
    stack.getChildren().add(label); 
    stack.prefWidthProperty().bind(col.widthProperty().subtract(5)); 
    label.prefWidthProperty().bind(stack.prefWidthProperty()); 
    col.setGraphic(stack); 
} 

Ein vollständiges ausführbares Beispiel ist in this gist (erfordert die 2.2 developer preview as a minimum).

import javafx.application.Application; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.collections.FXCollections; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.Pane; 
import javafx.scene.layout.StackPane; 
import javafx.scene.layout.VBox; 
import javafx.scene.text.TextAlignment; 
import javafx.stage.Stage; 

public class TableWrappedHeaders extends Application { 
    public static void main(String[] args) { launch(args); } 

    @Override public void start(Stage stage) { 
    TableColumn firstNameCol = new TableColumn("First Name (which is a really long name)"); 
    makeHeaderWrappable(firstNameCol); 
    firstNameCol.setPrefWidth(100); 
    firstNameCol.setCellValueFactory(new PropertyValueFactory<Person,String>("firstName")); 
    TableColumn lastNameCol = new TableColumn("Last Name"); 
    lastNameCol.setPrefWidth(100); 
    lastNameCol.setCellValueFactory(new PropertyValueFactory<Person,String>("lastName")); 

    TableView table = new TableView(); 
    table.getColumns().addAll(firstNameCol, lastNameCol); 
    table.setItems(FXCollections.observableArrayList(
     new Person("Jacob", "Smith"), 
     new Person("Isabella", "Johnson"), 
     new Person("Ethan", "Williams") 
    )); 
    table.setPrefSize(250, 200); 

    Pane layout = new VBox(10); 
    layout.setStyle("-fx-padding: 10;"); 
    layout.getChildren().addAll(table); 
    stage.setScene(new Scene(layout)); 
    stage.show(); 
    } 

    private void makeHeaderWrappable(TableColumn col) { 
    Label label = new Label(col.getText()); 
    label.setStyle("-fx-padding: 8px;"); 
    label.setWrapText(true); 
    label.setAlignment(Pos.CENTER); 
    label.setTextAlignment(TextAlignment.CENTER); 

    StackPane stack = new StackPane(); 
    stack.getChildren().add(label); 
    stack.prefWidthProperty().bind(col.widthProperty().subtract(5)); 
    label.prefWidthProperty().bind(stack.prefWidthProperty()); 
    col.setText(null); 
    col.setGraphic(stack); 
    } 

    public static class Person { 
    private final SimpleStringProperty firstName; 
    private final SimpleStringProperty lastName; 

    private Person(String fName, String lName) { 
     this.firstName = new SimpleStringProperty(fName); 
     this.lastName = new SimpleStringProperty(lName); 
    } 

    public String getFirstName() { return firstName.get(); } 
    public void setFirstName(String fName) { firstName.set(fName); } 
    public String getLastName() { return lastName.get(); } 
    public void setLastName(String fName) { lastName.set(fName); } 
    } 
} 

Es gibt wahrscheinlich einen besseren Weg, dies zu tun, aber die Funktion oben tat zumindest für mich Arbeit in meinem Testfall.

Ich dachte, das wäre mit einem einfachen CSS-Stil erreichbar, aber ich konnte es nicht über CSS allein arbeiten.

+2

Zuerst jewelsea ... ich Ihre Antworten immer schätzen. Ich bemerke ein merkwürdiges Verhalten in Java 8 mit dieser Lösung. Anfangs sieht alles gut aus, aber wenn ich auf die Spaltenüberschriften doppelklicke (die Größe der Spalte wird normalerweise an den Inhalt angepasst), erhöht sich die Breite der Spalte. Es wird nie kleiner, nur größer. Irgendwelche Vorschläge oder Ideen, warum das passieren könnte? – Tommo

+0

Der Inhalt wird nicht kompiliert. –

+0

Kompiliert und läuft gut für mich auf JavaFX 9.0.4, leidet immer noch das Problem von Tommo hingewiesen. – jewelsea

3

Der einfachste Weg, Kopftext auszurichten ist mit CSS-Stil, wie folgt aus:

.table-view .column-header .label { 
    -fx-text-alignment: center; 
} 

Verwenden Sie neue Linie Escape-Sequenz „\ n“ in String-Kopf Text, um ihn in mehrere Zeilen aufgeteilt.

6

ist einfacher, mit einem Etikett in der Header-Grafik der Säule:

  1. ein Etikett in der Spaltenüberschrift Grafik hinzufügen (wenn die Spalte einen Text als Titel löschen es hat).
  2. das Label Set Wrap Text zu ermöglichen (Scene Builder -> gehen Sie zu Eigenschaften des Etiketts und wählen Wrap Text oder in-Code -> label.setWrapText (true))
  3. Set Etikettenbreite und Höhe wünschen wir

Hinweis: Dies ist in einem FXML (mit Scene Builder) einfacher als in Code.

Beispiel unten:

public class TableColumnLongTextLabel extends Application { 

    @Override 
    public void start(Stage stage) { 
     TableView table = new TableView(); 
     TableColumn tableColumnData1 = new TableColumn(), 
       tableColumnData2 = new TableColumn("Long Title without Text Wrap"); 

     tableColumnData1.setCellValueFactory(new PropertyValueFactory<SomeStructure, String>("data1")); 
     tableColumnData2.setCellValueFactory(new PropertyValueFactory<SomeStructure, String>("data2")); 

     table.getColumns().addAll(tableColumnData1, tableColumnData2); 

     Label columnTitle = new Label("Long Title with Text Wrapped"); 
     columnTitle.setPrefWidth(125); 
     columnTitle.setPrefHeight(50); 
     columnTitle.setWrapText(true); 
     columnTitle.setTextAlignment(TextAlignment.CENTER); 
     tableColumnData1.setGraphic(columnTitle); 

     table.setItems(FXCollections.observableArrayList(
       new SomeStructure("Java", "FX", 1), 
       new SomeStructure("Java", "Swing", 0), 
       new SomeStructure("Java", "Sample", 2), 
       new SomeStructure("Some", "Other", 10) 
     )); 

     Pane layout = new VBox(10); 
     layout.getChildren().addAll(table); 
     stage.setScene(new Scene(layout, 350, 350)); 
     stage.show(); 
    } 

    public static class SomeStructure { 

     private final SimpleStringProperty data1; 
     private final SimpleStringProperty data2; 
     private final SimpleIntegerProperty data3; 

     private SomeStructure(String data1, String data2, Integer data3) { 
      this.data1 = new SimpleStringProperty(data1); 
      this.data2 = new SimpleStringProperty(data2); 
      this.data3 = new SimpleIntegerProperty(data3); 
     } 

     public String getData1() { 
      return data1.get(); 
     } 

     public void setData1(String data1) { 
      this.data1.set(data1); 
     } 

     public String getData2() { 
      return data2.get(); 
     } 

     public void setData2(String data2) { 
      this.data2.set(data2); 
     } 

     public Integer getData3() { 
      return data3.get(); 
     } 

     public void setData3(Integer data3) { 
      this.data3.set(data3); 
     } 
    } 

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

Beispiel unter Verwendung von FXML (kein Code erforderlich :)):

<TableView prefHeight="251.0" prefWidth="556.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> 
     <columns> 
      <TableColumn editable="false" maxWidth="90.0" prefWidth="70.0" sortable="false" text="Player"> 
      <columns> 
       <TableColumn editable="false" maxWidth="80.0" prefWidth="50.0" text="ID" /> 
       <TableColumn editable="false" maxWidth="200.0" prefWidth="180.0" text="Name" /> 
      </columns> 
      </TableColumn> 
      <TableColumn maxWidth="80.0" minWidth="50.0" prefWidth="60.0" text="Game" /> 
      <TableColumn editable="false" maxWidth="160.0" minWidth="125.0" prefWidth="135.0" sortable="false" text="Team" visible="false" /> 
      <TableColumn editable="false" maxWidth="160.0" minWidth="107.0" prefWidth="107.0" sortable="false"> 
      <graphic> 
       <Label alignment="CENTER" text="Individual Points (Big Team)" textAlignment="CENTER" wrapText="true" /> 
      </graphic> 
      </TableColumn> 
      <TableColumn editable="false" maxWidth="160.0" minWidth="99.0" prefWidth="102.0" sortable="false"> 
      <graphic> 
       <Label alignment="CENTER" text="Team Points (Small Maps)" textAlignment="CENTER" wrapText="true" /> 
      </graphic> 
      </TableColumn> 
      <TableColumn editable="false" maxWidth="116.0" minWidth="55.0" prefWidth="55.0" sortable="false"> 
      <graphic> 
       <Label text="Total Points" textAlignment="CENTER" wrapText="true" /> 
      </graphic> 
      </TableColumn> 
     </columns> 
    </TableView> 

enter image description here

+0

Gibt es eine Chance, dass Sie den Code, der in der Spalte Player mit der ID und dem Namen darunter enthalten ist, einfügen können? – Tommo

+0

Sie meinen, wie Sie diese zwei Spalten unterhalb einer Master-Spalte hinzufügen? Wenn ja, ist der Code einfach: 'tableColumnPlayer.getColumns(). Add (tableColumnID); tableColumnPlayer.getColumns(). Add (tableColumnName); ' – Harry244

6

eine Lösung gefunden, ohne Etiketten zu verwenden. In Scene Builder 8.3.0 (Gluon), JavaFX 8, erscheint eine Schaltfläche beim Mouse Hover, direkt neben dem Textfeld, wo eine Mehrfachzeile aus dem Menü ausgewählt werden kann.

Menu for multi - line mode

Dies führt zu einem folgenden XML-Code:

<TableColumn fx:id="prodDisc" editable="false" prefWidth="50.0" text="Prod &#10;Disc" /> 
Verwandte Themen