2012-06-08 223 views
6

是否可以用多行表头制作javaFX 2.0表格? 我在网上找到的所有例子都有表格,其中columnt header width =文本大小,没有包装。的我有什么,我需要的是一个显示屏幕上的exaple:enter image description hereJavaFX 2.0带多行表头的表格

回答

7

我想出了以下功能:

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); 
} 

完全可执行的例子是in this gist(需要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); } 
    } 
} 

可能有更好的方法来做到这一点,但上面的函数在我的测试用例中至少对我有用。

我认为这可以通过简单的CSS样式来实现,但我无法通过CSS单独使用它。

+2

首先,jewelsea ......我永远珍惜你的答案。使用此解决方案,我注意到Java 8中的一些奇怪行为。最初一切看起来都不错,但如果我双击列标题分隔符(通常调整列的大小以适应内容),它会不断增加列的宽度。它永远不会变小,只会变得更大。有关可能发生的原因的任何建议或想法? – Tommo

+0

该要点不能编译。 –

+0

在JavaFX 9.0.4上编译运行良好,仍然遭受Tommo指出的问题。 – jewelsea

3

对齐标题文本的最简单方法是使用CSS样式,像这样的:在标题文本字符串

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

使用新行转义序列“\ n”来将其分割成多行。

6

是一个在列的标题图形一个Label简单:

  1. 在列的标题图片添加标签(如果列有一些文字作为标题删除)。
  2. 设置标签,允许自动换行 (场景生成器 - >去标签,然后选择自动换行的属性或代码 - > label.setWrapText(真))
  3. 设置标签的宽度和高度,我们希望

注意:在FXML(使用Scene Builder)中执行此操作比在代码中更容易。下面

实施例:

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); 
    } 
} 

实施例使用FXML(无需代码:)):

<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

您有没有可能包含导致播放列中带有ID和名称的代码? – Tommo

+0

你的意思是如何在主列下面添加这两列?代码很简单: 'tableColumnPlayer.getColumns()。add(tableColumnID); tableColumnPlayer.getColumns()。add(tableColumnName);' – Harry244

6

找到一个解决方案,而无需使用标签。在Scene Builder 8.3.0(胶合),JavaFX 8中,鼠标悬停处出现一个按钮,位于文本框右侧,可从菜单中选择多行。

Menu for multi - line mode

这导致以下XML代码:

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