2014-07-03 95 views
0

我有一個數據模型:
客戶端 - 名稱
在客戶端對象類中聲明的地圖。TreeTableView困境

客戶
-Title - 價值
-Title - 價值
-Title - 價值
客戶
-Title - 價值
-Title - 價值
-Title - 價值

據因爲我知道TreeTableView必須只遵守一種數據類型有沒有一種方法,我可以讓它保持客戶端和Map或我是否使Map的一部分客戶端?
使用javatuples會起作用嗎?

public TreeTableView createContent() { 

    TreeItem<String> root = new TreeItem<>(); 
    //treeTableView.setRoot(root); 
    root.setExpanded(true); 
    //final TreeItem<String> rootItem = new TreeItem<>(); 
    ArrayList<TreeItem<String>> rootList = new ArrayList<TreeItem<String>>(); 
    ArrayList<TreeItem<String>> titleList = new ArrayList<TreeItem<String>>(); 
    ArrayList<TreeItem<String>> valueList = new ArrayList<TreeItem<String>>(); 
    TreeItem<String> rootItem = new TreeItem<>(); 

     for(Client client:clients){ 
      rootItem = new TreeItem<>(client.getName());//.getName()); 
     //rootItem.setValue(client.getName());//nameProperty().getValue()); 
     rootList.add(rootItem); 
    } 

     for(Entry<Title, DoubleProperty> map1:map.entrySet()){ 
      final TreeItem<Entry<Title, DoubleProperty>> mapItem = new TreeItem<>(map1);//.getKey(),map1.getValue()); 
      final TreeItem<String> child2Item = new TreeItem<>(map1.getKey().getName());//, map1.getValue().getValue().toString()); 
      final TreeItem<String> child3Item = new TreeItem<>(map1.getValue().getValue().toString()); 
      titleList.add(child2Item); 
      valueList.add(child3Item); 
     } 

     /*for(Title title:titles){ 
      //final TreeItem child1Item = new TreeItem<>(client.getValue(title)); 
      final TreeItem<String> child2Item = new TreeItem<>(title.getName());//title.getName()); 
     titleList.add(child2Item); 
     }*/ 

     for(TreeItem<String> root1:rootList){ 
      root.getChildren().add(root1); 
      for(TreeItem<String> title1:titleList){ 
      root1.getChildren().add(title1); 
     } 
      for(TreeItem<String> value:valueList){ 
       root1.getChildren().add(value); 
      } 
     } 

    // Name column 
    final TreeTableColumn<Client, String> nameColumn = new TreeTableColumn<>("Name"); 
    nameColumn.setEditable(false); 
    nameColumn.setMinWidth(150); 
    //nameColumn.setCellValueFactory(new TreeItemPropertyValueFactory<Client, String>("value")); 
    nameColumn.setCellValueFactory(//param -> param.getValue().getValue().nameProperty()); 
      new Callback<TreeTableColumn.CellDataFeatures<Client, String>, ObservableValue<String>>() { 
     @Override 
     public ObservableValue<String> call(TreeTableColumn.CellDataFeatures<Client, String> p) { 
      return new ReadOnlyObjectWrapper(p.getValue().getValue()); 
     } 
    }); 

    // Data column 
    TreeTableColumn<Client, String> dataColumn = new TreeTableColumn<>("Values"); 
    dataColumn.setEditable(true); 
    dataColumn.setMinWidth(50); 
    // dataColumn.setCellValueFactory(new MapValueFactory<>("mapvalue"); 
      //new TreeItemPropertyValueFactory<Client, String>("name")); 
    //dataColumn.setCellValueFactory(new TreeItemPropertyValueFactory<Client, String>("name")); 
    dataColumn.setCellValueFactory(
      new Callback<TreeTableColumn.CellDataFeatures<Client, String>, ObservableValue<String>>() { 
     @Override 
     public ObservableValue<String> call(TreeTableColumn.CellDataFeatures<Client, String> p) { 
     return new ReadOnlyStringWrapper(p.getValue().getValue().getValues().values().toString()); 
} 
}); 

    final TreeTableView<Client> treeTableView = new TreeTableView(root);//rootItem); 
    treeTableView.setShowRoot(false); 
    treeTableView.getColumns().add(nameColumn); 
    treeTableView.getColumns().add(dataColumn); 
    treeTableView.setEditable(true); 
    treeTableView.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY); 
    treeTableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 
    treeTableView.setPrefSize(515, 100); 
    treeTableView.setLayoutX(10); 
    treeTableView.setLayoutY(10); 

    return treeTableView; 
} 
} 

通過這樣做,我得到的值直屬每個標題不上的第二列,我覺得我欺騙自己使它成爲字符串我希望把它在未來可編輯,以便它改變實際地圖或客戶

客戶對象類中值:

public class Client { 
private final StringProperty name = new SimpleStringProperty(this, "name"); 
public final String getName() { 
    return name.get(); 
} 
public final void setName(String name) { 
    this.name.set(name); 
} 
public StringProperty nameProperty() { 
    return name ; 
} 
private final Map<Title, DoubleProperty> values = new HashMap<>(); 

public Client(String name) { 
    setName(name); 
} 

public DoubleProperty valueProperty(Title title) { 
    // In Java 8, just do 
    // return values.computeIfAbsent(title, t -> new SimpleDoubleProperty()); 

    DoubleProperty value = values.get(title); 
    if (value == null) { 
     value = new SimpleDoubleProperty(); 
     values.put(title, value); 
    } 
    return value ; 
} 

public final double getValue(Title title) { 
    return valueProperty(title).get(); 
} 

public final void setValue(Title title, double value) { 
    valueProperty(title).set(value); 
} 

public Map<Title, DoubleProperty> getValues() { 
    return values ; 
} 
} 
+0

你想'Title'和'Value'添加到同一節點? – ItachiUchiha

+0

不,我希望標題顯示爲孩子在客戶端父節點下,值在第二列lemme添加一些代碼來顯示我有什麼atm – izzypod5

回答

1

當我最初提出一個表,是你-client標題圖紙是什麼樣子。我認爲這就是你想要顯示數據的方式。這可能不是最好的方法。

如果您只顯示字符串,那麼只需在cellValueFactory中提供您自己的字符串很容易。不過,我只是嘗試使用<XYChart.Data<String, Integer>,它可以用一些技巧正常工作。

我沒有使用地圖或類似的東西。這就是爲什麼我建議樹表,因爲它與圖表數據結構相似。沒有必要將它存儲在兩個不同的地方。

TreeTables的問題是它們總是需要TreeItems,並且不會自動發生。當基礎數據發生變化時,常規表格和圖表都會自動更新。

import javafx.application.Application; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.chart.CategoryAxis; 
import javafx.scene.chart.NumberAxis; 
import javafx.scene.chart.StackedBarChart; 
import javafx.scene.chart.XYChart; 
import javafx.scene.control.TextField; 
import javafx.scene.control.TreeItem; 
import javafx.scene.control.TreeTableColumn; 
import javafx.scene.control.TreeTableView; 
import javafx.scene.control.cell.TextFieldTreeTableCell; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 
import javafx.util.converter.NumberStringConverter; 

public class StackedTTV extends Application { 

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

    @Override 
    public void start(Stage stage) { 
     final ObservableList<XYChart.Series<String, Number>> chartdata = FXCollections.observableArrayList(); 
     final CategoryAxis xAxis = new CategoryAxis(
       FXCollections.observableArrayList("Wait","Agreed","Work")); 
     for (int i = 0; i < 4; i++) { 
      chartdata.add(new XYChart.Series<>("Test"+i, FXCollections.observableArrayList(
        new XYChart.Data(xAxis.getCategories().get(0), 1000), 
        new XYChart.Data(xAxis.getCategories().get(1), 1000), 
        new XYChart.Data(xAxis.getCategories().get(2), 1000) 
      ))); 
     } 
     final StackedBarChart sbc = new StackedBarChart(xAxis, new NumberAxis(), chartdata); 

     final TreeTableView<XYChart.Data<String, Number>> ttv = new TreeTableView<>(
       new TreeItem<XYChart.Data<String,Number>>(new XYChart.Data<>())); 
     ttv.setShowRoot(false); 

     for (XYChart.Series<String, Number> serie: chartdata){ 
      TreeItem<XYChart.Data<String,Number>> ti = new TreeItem<>(new XYChart.Data<>(serie.getName(), null)); 
      ttv.getRoot().getChildren().add(ti); 
      for (XYChart.Data<String,Number> data : serie.getData()){ 
       ti.getChildren().add(new TreeItem(data)); 
      } 
     } 

     TreeTableColumn<XYChart.Data<String,Number>,String> clientCol = new TreeTableColumn<>("client"); 
     clientCol.setCellValueFactory((param) -> { 
      return param.getValue().isLeaf() 
        ? new SimpleStringProperty("") 
        : param.getValue().getValue().XValueProperty(); 
     }); 
     clientCol.setCellFactory(TextFieldTreeTableCell.forTreeTableColumn()); 
     clientCol.setOnEditCommit((evt) ->{ 
      if (evt.getRowValue().isLeaf()) return; 
      for (XYChart.Series serie: chartdata){ 
       if (serie.getName().equals(evt.getOldValue())) 
        serie.setName(evt.getNewValue()); 
      } 
      evt.getRowValue().getValue().setXValue(evt.getNewValue()); 
     }); 

     TreeTableColumn<XYChart.Data<String,Number>,String> titleCol = new TreeTableColumn<>("title"); 
     titleCol.setCellValueFactory((param) -> { 
      return param.getValue().isLeaf() 
        ? param.getValue().getValue().XValueProperty() 
        : new SimpleStringProperty(""); 
     }); 
     titleCol.setCellFactory(TextFieldTreeTableCell.forTreeTableColumn()); 
     titleCol.setOnEditCommit((evt) -> { 
      final String ov = evt.getOldValue(); 
      final String nv = evt.getNewValue(); 
      //change the name for all series 
      for (XYChart.Series<String, Number> serie : chartdata) 
       for (XYChart.Data<String, Number> data : serie.getData()) 
        if(ov.equals(data.getXValue())) data.setXValue(nv); 
      xAxis.getCategories().set(xAxis.getCategories().indexOf(ov),nv); 
      //chart is confused as to which categories to listen to 
      //System.out.println(sbc.getXAxis().getTickMarks()); 
     }); 

     TreeTableColumn<XYChart.Data<String,Number>,Number> valueCol = new TreeTableColumn<>("value"); 
     valueCol.setCellValueFactory((param) -> { 
      return param.getValue().getValue().YValueProperty(); 
     }); 
     valueCol.setCellFactory(TextFieldTreeTableCell.forTreeTableColumn(new NumberStringConverter())); 
     valueCol.setOnEditCommit((evt) ->{ 
      evt.getRowValue().getValue().setYValue(evt.getNewValue()); 
     }); 

     ttv.getColumns().addAll(clientCol,titleCol,valueCol); 
     ttv.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY); 
     ttv.getSelectionModel().setCellSelectionEnabled(true); 
     ttv.setEditable(true); 

     final TextField txt = new TextField(); 
     txt.setPromptText("new title"); 
     txt.setOnAction((evt)->{ 
      //add to category axis 
      //todo - check for dup 
      xAxis.getCategories().add(txt.getText()); 
      //add new title to each series with 1000 and to table 
      for (XYChart.Series<String, Number> serie : chartdata) { 
       XYChart.Data<String, Number> newdata = new XYChart.Data<>(txt.getText(), 1000); 
       serie.getData().add(newdata); 
       for(TreeItem<XYChart.Data<String,Number>> ti: ttv.getRoot().getChildren()){ 
        if(ti.getValue().XValueProperty().get().equals(serie.getName())){ 
         ti.getChildren().add(new TreeItem<>(newdata)); 
        } 
       } 
      } 
     }); 
     final VBox sceneRoot = new VBox(ttv,sbc,txt); 
     final Scene scene = new Scene(sceneRoot); 
     stage.setScene(scene); 
     stage.show(); 
    } 
} 

enter image description here

+0

也許我沒有正確解釋自己我有一個類對象標題,將被固定所有客戶如此說有3個都必須有它們,但是當它們通過客戶機中的setvalue設置時,每個客戶機的值是不同的。我正在努力的是將每個客戶端的地圖數據檢索到樹視圖中。在Client對象類中存儲像這樣public static Map getValues(){ 返回值; } – izzypod5

+0

添加了我的客戶端對象類,以便您瞭解我想從哪裏獲得它 – izzypod5

+0

這可能仍然有助於我自己解決問題,因此感謝您的努力,現在我知道我可以使用XYChart數據 – izzypod5