2015-08-14 58 views
0

我想使用TableView來顯示任意Labels(每個單元一個Label)。 Oracle教程引用Person類,但我寧願沒有後備類,因爲它們是任意列(每個Label都會執行它自己的操作)TableView與組件單元

我看到可以創建支持Map的表,但我發現使用String屬性的例子,我需要Labels

(具體而言,我需要檢測的行號和列號,當一個人將鼠標懸停的細胞,並顯示一個適當的值在相關聯的面板)

是否有將組件添加到一個TableView中沒有任何文件支持類?

回答

2

您不應該使用Label s作爲您的表的數據類型。屬性表示數據; Label是一個用於顯示數據的圖形組件。使用單元格值工廠來確定應在每個單元格中顯示的數據,並使用單元格工廠創建單元格以顯示數據。您可以使用您創建的單元註冊鼠標偵聽器來更新關聯面板中的顯示。

下面是一個完整的例子,你可能會喜歡學習:

import java.util.Random; 
import java.util.stream.Collectors; 
import java.util.stream.IntStream; 

import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.ReadOnlyStringWrapper; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.control.TableCell; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 

public class TableWithArrayData extends Application { 

    final Random rng = new Random(); 

    @Override 
    public void start(Stage primaryStage) { 
     final int numRows = 100 ; 
     final int numCols = 10 ; 

     final int numChars = 6 ; 

     TableView<String[]> table = new TableView<>(); 

     ObservableList<String[]> data = FXCollections.observableArrayList(); 

     table.setItems(data); 

     for (int rowIndex = 0; rowIndex < numRows; rowIndex++) { 
      String[] row = new String[numCols]; 
      data.add(row); 
      for (int colIndex = 0 ; colIndex < numCols; colIndex++) { 
       row[colIndex] = randomString(numChars); 
      } 
     } 

     IntegerProperty hoverRow = new SimpleIntegerProperty(); 
     IntegerProperty hoverCol = new SimpleIntegerProperty(); 

     for (int colIndex = 0 ; colIndex < numCols; colIndex++) { 
      TableColumn<String[], String> column = new TableColumn<>("Column "+colIndex); 
      final int index = colIndex ; 

      column.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue()[index])); 

      column.setCellFactory(col -> { 
       TableCell<String[], String> cell = new TableCell<String[], String>(){ 
        @Override 
        public void updateItem(String item, boolean empty) { 
         super.updateItem(item, empty); 
         if (empty) { 
          setText(null); 
         } else { 
          setText(item); 
         } 
        } 
       }; 
       cell.setOnMouseEntered(e -> { 
        hoverCol.set(index); 
        hoverRow.set(cell.getIndex()); 
       }); 
       cell.setOnMouseExited(e -> { 
        hoverCol.set(-1); 
        hoverRow.set(-1); 
       }); 

       return cell ; 
      }); 

      table.getColumns().add(column); 
     } 

     Label label = new Label(); 
     label.textProperty().bind(Bindings.createStringBinding(() -> { 
      if (hoverCol.get() < 0 || hoverRow.get() < 0) { 
       return null ; 
      } else { 
       return String.format("Mouse is in [%d, %d]", hoverCol.get(), hoverRow.get()); 
      } 
     }, hoverCol, hoverRow)); 

     BorderPane root = new BorderPane(table, null, null, label, null); 
     Scene scene = new Scene(root, 600, 600); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private String randomString(int numChars) { 
     return IntStream.rangeClosed(0, numChars) 
       .mapToObj(i -> { 
        char c = (char) ('a' + rng.nextInt(26)); 
        return Character.toString(c); 
       }) 
       .collect(Collectors.joining()); 
    } 

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

我希望我能再次給予好評這一點,它真的很重要!爲什麼Oracle文檔不能爲這種常見用例提供解決方案! –

+0

可能因爲它實際上並不常見。通常你代表真實的域對象。 –