JavaFX绑定到嵌套列

JavaFX绑定到嵌套列,java,generics,javafx-2,guava,Java,Generics,Javafx 2,Guava,我目前正在尝试编写我的第一个JavaFX应用程序,它将从套接字解码的消息写入JavaFX表。该表需要是动态的,如果消息中包含当前表中不存在的数据,则应添加一个新列。有些字段嵌套在包装器类中,我试图使用嵌套列表示这些嵌套,如下所示: 我的问题是,我似乎无法获得绑定到嵌套列的正确数据。当我尝试为我的CustomType绑定到PropertyValueFactory(“one”)时,我从MessageType1获得了选项。我尝试了几种不同的方法,您将在下面的示例中看到: import java.uti

我目前正在尝试编写我的第一个JavaFX应用程序,它将从套接字解码的消息写入JavaFX表。该表需要是动态的,如果消息中包含当前表中不存在的数据,则应添加一个新列。有些字段嵌套在包装器类中,我试图使用嵌套列表示这些嵌套,如下所示:

我的问题是,我似乎无法获得绑定到嵌套列的正确数据。当我尝试为我的CustomType绑定到PropertyValueFactory(“one”)时,我从MessageType1获得了选项。我尝试了几种不同的方法,您将在下面的示例中看到:

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;


public class SampleTable extends Application {
  private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
  private final ObservableList<Message> msgList = FXCollections.observableArrayList();

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

  @Override
  public void start(Stage primaryStage) throws Exception {
    final TableView tableView = new TableView<>(msgList);
    tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);


    final TableColumn<Message, MessageType> msgTypeCol = new TableColumn<Message, MessageType>();
    msgTypeCol.setText("Message Type");
    msgTypeCol.setCellValueFactory(new PropertyValueFactory<Message, MessageType>("messageType"));

    final TableColumn<MessageType1, Optional<Integer>> intCol1 = new TableColumn<MessageType1, Optional<Integer>>();
    intCol1.setText("Int1");
    intCol1.setCellValueFactory(new PropertyValueFactory<MessageType1, Optional<Integer>>("one"));

    final TableColumn<MessageType1, Optional<Integer>> intCol2 = new TableColumn<MessageType1, Optional<Integer>>();
    intCol2.setText("Int2");
    intCol2.setCellValueFactory(new PropertyValueFactory<MessageType1, Optional<Integer>>("two"));

    final TableColumn<MessageType1, Optional<Integer>> intCol3 = new TableColumn<MessageType1, Optional<Integer>>();
    intCol3.setText("Int3");
    intCol3.setCellValueFactory(new PropertyValueFactory<MessageType1, Optional<Integer>>("three"));

    final TableColumn<MessageType2, List<String>> strCol = new TableColumn<MessageType2, List<String>>();
    strCol.setText("String List");
    strCol.setCellValueFactory(new PropertyValueFactory<MessageType2, List<String>>("list"));

   //final TableColumn<MessageType3, Optional<CustomType>> customTypeCol = new TableColumn<MessageType3, Optional<CustomType>>();
    final TableColumn customTypeCol = new TableColumn<>();
    customTypeCol.setText("Custom Type");

//    final TableColumn<CustomType, Boolean> customTypeCol1 = new TableColumn<CustomType, Boolean>();
//    customTypeCol1.setText("CT1");
//    customTypeCol1.setCellValueFactory(new PropertyValueFactory<CustomType, Boolean>("one"));
//    final TableColumn<CustomType, Boolean> customTypeCol2 = new TableColumn<CustomType, Boolean>();
//    customTypeCol2.setText("CT2");
//    customTypeCol2.setCellValueFactory(new PropertyValueFactory<CustomType, Boolean>("customTwo"));
//    final TableColumn<CustomType, Integer> customTypeCol3 = new TableColumn<CustomType, Integer>();
//    customTypeCol3.setText("CT3");
//    customTypeCol3.setCellValueFactory(new PropertyValueFactory<CustomType,Integer>("customThree"));
  final TableColumn<MessageType3, Boolean> customTypeCol1 = new TableColumn<MessageType3, Boolean>();
  customTypeCol1.setText("CT1");
  customTypeCol1.setCellValueFactory(new PropertyValueFactory<MessageType3, Boolean>("one"));
  final TableColumn<MessageType3, Boolean> customTypeCol2 = new TableColumn<MessageType3, Boolean>();
  customTypeCol2.setText("CT2");
  customTypeCol2.setCellValueFactory(new PropertyValueFactory<MessageType3, Boolean>("customTwo"));
  final TableColumn<MessageType3, Integer> customTypeCol3 = new TableColumn<MessageType3, Integer>();
  customTypeCol3.setText("CT3");
  customTypeCol3.setCellValueFactory(new PropertyValueFactory<MessageType3,Integer>("customThree"));

    customTypeCol.getColumns().addAll(customTypeCol1, customTypeCol2, customTypeCol3);


//    customTypeCol.setCellValueFactory(new PropertyValueFactory<MessageType3, Optional<CustomType>>("customType"));
//    customTypeCol.setCellFactory(
//        new Callback<TableColumn<MessageType3, Optional<CustomType>>, TableCell<MessageType3, Optional<CustomType>>>() {
//      @Override
//      public TableCell<MessageType3, Optional<CustomType>> call(
//          final TableColumn<MessageType3, Optional<CustomType>> param) {
//        return new TableCell<MessageType3, Optional<CustomType>>() {
//          @Override
//          protected void updateItem(Optional<CustomType> customType, boolean empty) {
//            super.updateItem(customType, empty);
//
//            if(!empty) {
//              //Tried this but didn't work either
////              final TableColumn<CustomType, Boolean> customTypeCol1 = new TableColumn<CustomType, Boolean>();
////              customTypeCol1.setText("CT1");
////              customTypeCol1.setCellValueFactory(new PropertyValueFactory<CustomType, Boolean>("one"));
////              final TableColumn<CustomType, Boolean> customTypeCol2 = new TableColumn<CustomType, Boolean>();
////              customTypeCol2.setText("CT2");
////              customTypeCol2.setCellValueFactory(new PropertyValueFactory<CustomType, Boolean>("customTwo"));
////              final TableColumn<CustomType, Integer> customTypeCol3 = new TableColumn<CustomType, Integer>();
////              customTypeCol3.setText("CT3");
////              customTypeCol3.setCellValueFactory(new PropertyValueFactory<CustomType,Integer>("customThree"));
//              //
//              final TableColumn<MessageType3, Boolean> customTypeCol1 = new TableColumn<MessageType3, Boolean>();
//              customTypeCol1.setText("CT1");
//              customTypeCol1.setCellValueFactory(new PropertyValueFactory<MessageType3, Boolean>("one"));
//              final TableColumn<MessageType3, Boolean> customTypeCol2 = new TableColumn<MessageType3, Boolean>();
//              customTypeCol2.setText("CT2");
//              customTypeCol2.setCellValueFactory(new PropertyValueFactory<MessageType3, Boolean>("customTwo"));
//              final TableColumn<MessageType3, Integer> customTypeCol3 = new TableColumn<MessageType3, Integer>();
//              customTypeCol3.setText("CT3");
//              customTypeCol3.setCellValueFactory(new PropertyValueFactory<MessageType3,Integer>("customThree"));
//
//              param.getColumns().addAll(customTypeCol1, customTypeCol2, customTypeCol3);
//            }
//          }
//        };
//      }
//    });
    tableView.getColumns().addAll(msgTypeCol, intCol1, intCol2, intCol3, strCol, customTypeCol);

    final Group root = new Group();
    primaryStage.setScene(new Scene(root));
    root.getChildren().add(tableView);

    //Simulate incoming DUMMY Messages
    executor.scheduleAtFixedRate(new Runnable() {
      private int i = 0;

      @Override
      public void run() {
        switch(i) {
        case 0:
          msgList.add(new MessageType1());
          i++;
          break;
        case 1:
          msgList.add(new MessageType2());
          i++;
          break;
          //System.exit(0);
        case 2:
          msgList.add(new MessageType3());
          i = 0;
          break;
        }
      }
    }, 0, 1, TimeUnit.SECONDS);

    primaryStage.show();
  }

  public enum MessageType { TYPE1, TYPE2, TYPE3 };
  public interface Message {
    MessageType getMessageType();
  }
  public static final class CustomType {
    private final boolean one = true;
    private final boolean customTwo = true;
    private final int customThree = 3;

    public Boolean getOne() { return one; }
    public Boolean getCustomTwo() { return customTwo; }
    public Integer getCustomThree() { return customThree; }
  }

  public static final class MessageType1 implements Message {
    private final List<Optional<Integer>> intList =
        ImmutableList.<Optional<Integer>>of(Optional.of(1),
            Optional.of(2),
            Optional.<Integer>absent());

    @Override
    public MessageType getMessageType() { return MessageType.TYPE1; }
    public Optional<Integer> getOne() { return intList.get(0); }
    public Optional<Integer> getTwo() { return intList.get(1); }
    public Optional<Integer> getThree() { return intList.get(2); }
  }

  public static final class MessageType2 implements Message {
    List<String> stringList = ImmutableList.of("one", "two", "three");

    @Override
    public MessageType getMessageType() { return MessageType.TYPE2; }
    public List<String> getList() { return stringList; }
  }

  public static final class MessageType3 implements Message {
    private final Optional<CustomType> obj = Optional.of(new CustomType());

    @Override
    public MessageType getMessageType() { return MessageType.TYPE3; }
    public Optional<CustomType> getCustomType() { return obj; }
  }
}
import java.util.List;
导入java.util.concurrent.Executors;
导入java.util.concurrent.ScheduledExecutorService;
导入java.util.concurrent.TimeUnit;
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.control.TableColumn;
导入javafx.scene.control.TableView;
导入javafx.scene.control.cell.PropertyValueFactory;
导入javafx.stage.stage;
导入com.google.common.base.Optional;
导入com.google.common.collect.ImmutableList;
公共类SampleTable扩展应用程序{
private final ScheduledExecutorService executor=Executors.newScheduledThreadPool(1);
private final ObservableList msgList=FXCollections.observableArrayList();
公共静态void main(最终字符串[]args){
发射(args);
}
@凌驾
public void start(Stage primaryStage)引发异常{
最终TableView TableView=新TableView(msgList);
tableView.setColumnResizePolicy(tableView.CONSTRAINED_RESIZE_策略);
final TableColumn msgTypeCol=新TableColumn();
msgTypeCol.setText(“消息类型”);
msgTypeCol.setCellValueFactory(新属性ValueFactory(“messageType”));
final TableColumn intCol1=新TableColumn();
intCol1.setText(“Int1”);
intCol1.setCellValueFactory(新属性ValueFactory(“一”);
final TableColumn intCol2=新TableColumn();
intCol2.setText(“Int2”);
intCol2.setCellValueFactory(新属性ValueFactory(“两”);
final TableColumn intCol3=新TableColumn();
intCol3.setText(“Int3”);
intCol3.setCellValueFactory(新属性ValueFactory(“三”);
final TableColumn strCol=新TableColumn();
strCol.setText(“字符串列表”);
strCol.setCellValueFactory(新属性ValueFactory(“列表”);
//final TableColumn customTypeCol=新TableColumn();
final TableColumn customTypeCol=新TableColumn();
customTypeCol.setText(“自定义类型”);
//final TableColumn customTypeCol1=新TableColumn();
//customTypeCol1.setText(“CT1”);
//customTypeCol1.setCellValueFactory(新属性ValueFactory(“一”);
//final TableColumn customTypeCol2=新TableColumn();
//customTypeCol2.setText(“CT2”);
//customTypeCol2.setCellValueFactory(新属性ValueFactory(“customTwo”);
//final TableColumn customTypeCol3=新TableColumn();
//customTypeCol3.setText(“CT3”);
//customTypeCol3.setCellValueFactory(新属性ValueFactory(“customThree”));
final TableColumn customTypeCol1=新TableColumn();
customTypeCol1.setText(“CT1”);
customTypeCol1.setCellValueFactory(新属性ValueFactory(“一”);
final TableColumn customTypeCol2=新TableColumn();
customTypeCol2.setText(“CT2”);
customTypeCol2.setCellValueFactory(新属性ValueFactory(“customTwo”);
final TableColumn customTypeCol3=新TableColumn();
customTypeCol3.setText(“CT3”);
customTypeCol3.setCellValueFactory(新属性ValueFactory(“customThree”));
customTypeCol.getColumns().addAll(customTypeCol1、customTypeCol2、customTypeCol3);
//customTypeCol.setCellValueFactory(新属性ValueFactory(“customType”));
//customTypeCol.setCellFactory(
//新回调函数(){
//@覆盖
//公用电话(
//最终表格(列参数){
//返回新的TableCell(){
//@覆盖
//受保护的void updateItem(可选customType,布尔空){
//super.updateItem(customType,空);
//
//如果(!空){
////尝试过这个,但也不起作用
////final TableColumn customTypeCol1=新TableColumn();
////customTypeCol1.setText(“CT1”);
////customTypeCol1.setCellValueFactory(新属性ValueFactory(“一”);
////final TableColumn customTypeCol2=新TableColumn();
////customTypeCol2.setText(“CT2”);
////customTypeCol2.setCellValueFactory(新属性ValueFactory(“customTwo”);
////final TableColumn customTypeCol3=新TableColumn();
////customTypeCol3.setText(“CT3”);
////customTypeCol3.setCellValueFactory(新属性ValueFactory(“customThree”));
//              //
//final TableColumn customTypeCol1=新TableColumn();
//customTypeCol1.setText(“CT1”);
//customTypeCol1.setCellValueFactory(新属性ValueFactory(“一”);
//final TableColumn customTypeCol2=新TableColumn();
//customTypeCol2.setText(“CT2”);
//customTypeCol2.setCellValueFactory(新属性ValueFactory(“customTwo”);
//final TableColumn customTypeCol3=新TableColumn();
//customTypeCol3.setText(“CT3”);
//customTypeCol3.setCellValueFactory(新属性ValueFactory(“customThree”));
//
//param.getColumns().addAll(customTypeCol1、customTypeCol2、customTypeCol3);
//            }
//          }
//        };
//      }
//    });
tableView.getColumns().addAll(msgTypeCol、intCol1、intCol2、intCol3、strCol、customTypeCol);
最终组根=新组();
primaryStage.setScene(新场景(根));
root.getChildren().add(tableView);
//模拟传入的虚拟消息
遗嘱执行人
new PropertyValueFactory<MessageType3, Boolean>("field")
customTypeCol1.setCellValueFactory(
                 new PropertyValueFactory<MessageType3, Boolean>("one"));
customTypeCol1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<MessageType3, Boolean>, ObservableValue<Boolean>>() {
    @Override
    public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<MessageType3, Boolean> p) {
        return new SimpleBooleanProperty(p.getValue().getOne());
    }
});
customTypeCol1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<MessageType3, Boolean>, ObservableValue<Boolean>>() {
    @Override
    public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<MessageType3, Boolean> p) {
        if (p.getValue() instanceof MessageType3) {
            return new SimpleBooleanProperty(p.getValue().getOne());
        } else {
            return null;
        }
    }
});