2016-05-16 223 views
0

我剛剛進入了編程階段,並正在使用Single Transferable Vote計算投票數。我有一個Excel文件,我的輸入數據看起來像這樣:在JavaFX中創建分層數據並將其添加到TreeTableView

this

其中候選的名字是在HashTable和低於第2行中的每一行代表從左邊的一個選民的喜好映射到數字在它之下向右。

我想補充的名稱和選票在TreeTableView看起來像這樣:

this

其中每個候選人是第二個偏好的根,每個第二個偏好是第三個偏好的根,每個第三個偏好是第四個偏好的根,等等。

我正在使用apache.poi庫來使用Excel文件。我正在尋找關於如何從表格中表示分層數據以及如何將其添加到TreeTabeView的提示。我怎麼能這樣做?

對不起,如果這是一個菜鳥問題。我不太瞭解如何使用分層數據。提前致謝!

回答

0

使用的物品類別中有2個性能

  • 候選人
  • 計票

會做的伎倆(=每列一個屬性)。例如。

public class VoteEntry { 

    // candidate INDEX 
    private final IntegerProperty candidate; 

    private final IntegerProperty voteCount; 

    public VoteEntry(int candidate, int count) { 
     this.voteCount = new SimpleIntegerProperty(count); 
     this.candidate = new SimpleIntegerProperty(candidate); 
    } 

    public final int getCandidate() { 
     return this.candidate.get(); 
    } 

    public final void setCandidate(int value) { 
     this.candidate.set(value); 
    } 

    public final IntegerProperty candidateProperty() { 
     return this.candidate; 
    } 

    public final int getVoteCount() { 
     return this.voteCount.get(); 
    } 

    public final void setVoteCount(int value) { 
     this.voteCount.set(value); 
    } 

    public final IntegerProperty voteCountProperty() { 
     return this.voteCount; 
    } 

} 

你可以組票對小亞組創建TreeItem層次:

private final List<int[]> votes = new ArrayList<>(); 

private void addVote(int... preferences) { 
    // convert to array of candidate indices sorted descendingly by preference 
    int[] votes = new int[preferences.length]; 
    for (int i = 0; i < preferences.length; i++) { 
     votes[preferences[i] - 1] = i; 
    } 
    this.votes.add(votes); 
} 

private static void createHierarchy(TreeItem<VoteEntry> parent, List<int[]> votes, int index) { 
    int max = votes.stream().mapToInt(a -> a.length).max().getAsInt(); 
    if (max > index) { 
     // group by candidate 
     Map<Integer, List<int[]>> groups = votes.stream().collect(Collectors.groupingBy(a -> a.length > index ? a[index] : -1)); 
     groups.forEach((candidate, vts) -> { 
      if (candidate != -1) { 
       VoteEntry entry = new VoteEntry(candidate, vts.size()); 
       TreeItem<VoteEntry> item = new TreeItem<>(entry); 
       parent.getChildren().add(item); 
       createHierarchy(item, vts, index + 1); 
      } 
     }); 

     // sort by candidate 
     parent.getChildren().sort(Comparator.comparingInt(ti -> ti.getValue().getCandidate())); 
    } 
} 

@Override 
public void start(Stage primaryStage) { 
    addVote(1, 2, 3, 4); 
    addVote(4, 3, 2, 1); 
    addVote(1, 3, 2, 4); 
    addVote(2, 1, 4, 3); 
    addVote(2, 4, 3, 1); 
    addVote(2, 1, 3, 4); 
    // ... 

    ObservableList<String> candidateNames = FXCollections.observableArrayList(
      "Candidate 1", 
      "Candidate 2", 
      "Candidate 3", 
      "Candidate 4" 
      ); 

    TreeItem<VoteEntry> root = new TreeItem<>(); 
    createHierarchy(root, votes, 0); 

    TreeTableView<VoteEntry> view = new TreeTableView<>(root); 
    view.setShowRoot(false); 

    TreeTableColumn<VoteEntry, String> candidateColumn = new TreeTableColumn<>("candidate"); 
    candidateColumn.setCellValueFactory(data -> Bindings.valueAt(candidateNames, data.getValue().getValue().candidateProperty())); 

    TreeTableColumn<VoteEntry, Integer> votesColumn = new TreeTableColumn<>("votes"); 
    votesColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("voteCount")); 

    view.getColumns().addAll(candidateColumn, votesColumn); 

    Scene scene = new Scene(view); 

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

注意,遞歸方法僅適用於候選人(stackoverflows)數量有限。但它應該適用於合理的候選人數字(用戶不想擴展數百個項目...)。

+0

非常感謝!工作,但我注意到一個問題。將int ... prefrences轉換爲數組無法正常工作。通過將for循環內的代碼更改爲「votes [i] = preferences [i] -1;」來修復它。 –

相關問題