2016-08-23 139 views
1

我試圖在TableView中顯示旅行連接。到目前爲止,這就像一個魅力。現在我有點卡住試圖獲取連接的細節顯示在表格行之間。這應該發生在選擇一個表項上。JavaFX TableView:打開點擊行之間的詳細信息

問題是,細節與我顯示的連接格式不同。所以我需要在兩個表格行之間放置一個面板。這是可能嗎?

+0

也許你應該考慮使用['TreeView'(HTTP://文檔.oracle.com/JavaFX的/ 2/ui_controls /樹view.htm)。但我想你需要一個'TableView'提供的列。但是,「TreeView」中的節點可以修改爲看起來像一個表。 –

+0

['TreeTableView'](http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TreeTableView.html)具有樹形視圖結構和表格提供的列,如果爲你需要的東西工作。但是「細節與我正在顯示的連接不同的格式」暗示這不會是你需要的。 –

回答

4

執行此操作的「正確」方法是創建一個TableRow的自定義外觀,並在安裝了自定義外觀的表上返回TableRow的表上使用rowFactory。但是,由於皮膚類在撰寫本文時不是公共API(儘管它們將在Java 9中),這意味着完全從頭開始實現皮膚類(佈置表格單元格等),這將會非常漂亮難。

一個不太「官方」的方法,但稍微簡單一點,就是直接覆蓋TableRow中的各種佈局方法,並掛接到超類實現中。

這工作,但感覺有點脆弱:

import java.util.Random; 
import java.util.function.Function; 

import javafx.application.Application; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.ObjectProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.beans.value.ObservableValue; 
import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableRow; 
import javafx.scene.control.TableView; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

public class TableWithCustomRow extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     TableView<Item> table = new TableView<>(); 

     table.setRowFactory(tv -> new TableRow<Item>() { 
      Node detailsPane ; 
      { 
       selectedProperty().addListener((obs, wasSelected, isNowSelected) -> { 
        if (isNowSelected) { 
         getChildren().add(detailsPane); 
        } else { 
         getChildren().remove(detailsPane); 
        } 
        this.requestLayout(); 
       }); 
       detailsPane = createDetailsPane(itemProperty()); 
      } 

      @Override 
      protected double computePrefHeight(double width) { 
       if (isSelected()) { 
        return super.computePrefHeight(width)+detailsPane.prefHeight(getWidth()); 
       } else { 
        return super.computePrefHeight(width); 
       } 
      } 

      @Override 
      protected void layoutChildren() { 
       super.layoutChildren(); 
       if (isSelected()) { 
        double width = getWidth(); 
        double paneHeight = detailsPane.prefHeight(width); 
        detailsPane.resizeRelocate(0, getHeight()-paneHeight, width, paneHeight); 
       } 
      } 
     }); 

     Random random = new Random(); 
     for (int i = 1 ; i <= 100 ; i++) { 
      table.getItems().add(new Item("Item "+i, random.nextInt(100))); 
     } 
     table.getColumns().add(column("Item", Item::nameProperty)); 
     table.getColumns().add(column("Value", Item::valueProperty)); 

     Scene scene = new Scene(table, 800, 600); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 

    } 

    private Node createDetailsPane(ObjectProperty<Item> item) { 
     BorderPane detailsPane = new BorderPane(); 
     Label detailsLabel = new Label(); 
     VBox labels = new VBox(5, new Label("These are the"), detailsLabel); 
     labels.setAlignment(Pos.CENTER_LEFT); 
     labels.setPadding(new Insets(2, 2, 2, 16)); 
     detailsPane.setCenter(labels); 

     Label icon = new Label("Icon"); 
     icon.setStyle("-fx-background-color: aqua; -fx-text-fill: darkgreen; -fx-font-size:18;"); 
     BorderPane.setMargin(icon, new Insets(6)); 
     icon.setMinSize(40, 40); 
     detailsPane.setLeft(icon); 

     detailsPane.setStyle("-fx-background-color: -fx-background; -fx-background: skyblue;"); 

     item.addListener((obs, oldItem, newItem) -> { 
      if (newItem == null) { 
       detailsLabel.setText(""); 
      } else { 
       detailsLabel.setText("details for "+newItem.getName()); 
      } 
     }); 


     return detailsPane ; 
    } 

    private static <S,T> TableColumn<S,T> column(String title, Function<S, ObservableValue<T>> property) { 
     TableColumn<S,T> col = new TableColumn<>(title); 
     col.setCellValueFactory(cellData -> property.apply(cellData.getValue())); 
     col.setPrefWidth(150); 
     return col ; 
    } 

    public static class Item { 
     private final StringProperty name = new SimpleStringProperty() ; 
     private final IntegerProperty value = new SimpleIntegerProperty() ; 

     public Item(String name, int value) { 
      setName(name); 
      setValue(value); 
     } 

     public final StringProperty nameProperty() { 
      return this.name; 
     } 


     public final java.lang.String getName() { 
      return this.nameProperty().get(); 
     } 


     public final void setName(final java.lang.String name) { 
      this.nameProperty().set(name); 
     } 


     public final IntegerProperty valueProperty() { 
      return this.value; 
     } 


     public final int getValue() { 
      return this.valueProperty().get(); 
     } 


     public final void setValue(final int value) { 
      this.valueProperty().set(value); 
     } 



    } 

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

這給出了以下:

enter image description here

+0

這工作出色。你介意我是否在博客上發佈了這個解決方案?這不會是一個直接的副本,而是一個通用版本。 –

+0

這很好;請參考這篇文章。 (順便說一下,我只是在啓用了多項選擇的情況下才進行非常簡短的測試;如果您還沒有選擇,您可能也想在那裏測試它。) –