2016-02-16 29 views
0

我有以下的tableView在FXML为什么我不能在cellFactory上指定NamedArgs和item元素?

<TableView fx:id="tableView" prefHeight="525.0" prefWidth="814.0"> 
    <columns> 
    <TableColumn prefWidth="75.0"> 
     <graphic><ToggleButton fx:id="mainToggleButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" onAction="#onMainToggleButtonAction" text="Start all" /></graphic> 
     <cellFactory><ToggleButtonTableCellFactory maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" activatedText="Started" deactivatedText="Stopped"/></cellFactory> 
     <cellValueFactory><PropertyValueFactory property="state"/></cellValueFactory> 
    </TableColumn> 
    <TableColumn prefWidth="75.0" text="Side"> 
     <cellValueFactory><PropertyValueFactory property="side"/></cellValueFactory> 
    </TableColumn> 
    <TableColumn prefWidth="75.0" text="Source"> 
     <cellValueFactory><PropertyValueFactory property="sourceContract"/></cellValueFactory> 
    </TableColumn> 
    <TableColumn prefWidth="75.0" text="Reference" editable="true"> 
     <cellFactory> 
     <ChoiceBoxTableCellFactory maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"> 
      <items> 
      <FXCollections fx:factory="observableArrayList"> 
       <String fx:value="r01" /> 
       <String fx:value="r02" /> 
      </FXCollections> 
      </items> 
     </ChoiceBoxTableCellFactory> 
     </cellFactory> 
     <cellValueFactory><PropertyValueFactory property="referenceContract"/></cellValueFactory> 
    </TableColumn> 
    <TableColumn prefWidth="75.0" text="Destination"> 
     <cellValueFactory><PropertyValueFactory property="destinationContract"/></cellValueFactory> 
    </TableColumn> 
    <TableColumn prefWidth="75.0" text="Margin" editable="true"> 
     <cellFactory><SpinnerTableCellFactory maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" min="0" max="1" initialValue="0" amountToStepBy="0.025" decimalFormat="0.000"/></cellFactory> 
     <cellValueFactory><PropertyValueFactory property="margin"/></cellValueFactory> 
    </TableColumn> 
    <TableColumn prefWidth="75.0" text="Bot"> 
     <cellValueFactory><PropertyValueFactory property="bot"/></cellValueFactory> 
    </TableColumn> 
    <TableColumn prefWidth="75.0" text="Price"> 
     <cellValueFactory><PropertyValueFactory property="price"/></cellValueFactory> 
    </TableColumn> 
    <TableColumn prefWidth="75.0" text="Volume"> 
     <cellValueFactory><PropertyValueFactory property="volume"/></cellValueFactory> 
    </TableColumn> 
    </columns> 
    <items> 
    <FXCollections fx:factory="observableArrayList"> 
     <GridRowModel state="false" side="BID" sourceContract="s01" referenceContract="r01" destinationContract="d01" margin="0" bot="MinMax" price="15.125" volume="0" /> 
     <GridRowModel state="false" side="ASK" sourceContract="s02" referenceContract="r01" destinationContract="d02" margin="0" bot="MinMax" price="15.125" volume="0" /> 
    </FXCollections> 
    </items> 
</TableView> 

ChoiceBoxTableCellFactory有一个构造函数从FXML和项目元素的制定者既需要命名的参数。

public class ChoiceBoxTableCellFactory<S, T> implements Callback<TableColumn<S, String>, TableCell<S, String>> { 

    private ObservableList<String> items; 
    private double maxHeight; 
    private double maxWidth; 

    public ChoiceBoxTableCellFactory() { 
    } 

    public ChoiceBoxTableCellFactory(
    @NamedArg("maxHeight") double maxHeight, 
    @NamedArg("maxWidth") double maxWidth) { 
    this.maxHeight = maxHeight; 
    this.maxWidth = maxWidth; 
    } 

    @Override 
    public TableCell<S, String> call(TableColumn<S, String> param) { 
    return new TableCell<S, String>() { 

     ChoiceBox<String> choiceBox = new ChoiceBox<>(getItems()); 

     { 
     choiceBox.setMaxHeight(maxHeight); 
     choiceBox.setMaxWidth(maxWidth); 
     choiceBox.valueProperty().addListener((obs, oldValue, newValue) -> { 
      ObservableValue<String> value = getTableColumn().getCellObservableValue(getIndex()); 
      if (value instanceof WritableValue) { 
      ((WritableValue<String>) value).setValue(newValue); 
      } 
     }); 
     } 

     @Override 
     protected void updateItem(String item, boolean empty) { 
     super.updateItem(item, empty); 
     if (empty) { 
      setText(null); 
      setGraphic(null); 
     } else { 
      if (isEditing()) { 
      setText(null); 
      setGraphic(null); 
      } else { 
      choiceBox.setValue(item); 
      setText(null); 
      setGraphic(choiceBox); 
      } 
     } 
     } 
    }; 
    } 

    public ObservableList<String> getItems() { 
    return items; 
    } 

    public void setItems(ObservableList<String> items) { 
    this.items = items; 
    } 
} 

,但是当我删除maxHeightmaxWidth属性的物品场通过setter正确设置抛出该异常

Caused by: java.lang.IllegalArgumentException: Unable to coerce [[r01, r02]] to interface javafx.collections.ObservableList. 
    at com.sun.javafx.fxml.BeanAdapter.coerce(BeanAdapter.java:496) 
    at com.sun.javafx.fxml.builder.ProxyBuilder$Setter.invoke(ProxyBuilder.java:533) 
    at com.sun.javafx.fxml.builder.ProxyBuilder.createObjectFromDefaultConstructor(ProxyBuilder.java:338) 
    ... 144 more 

。通过这些属性,项目值被包装在一个附加数组中。我怎样才能达到预期的效果?

+0

看起来喜欢它应该工作。你需要代码中其他任何地方的'setItems'方法吗?如果没有,你可以尝试删除它,并使用' ...'。 –

+0

当我删除'setItems' setter我得到这个错误 '由于:java.lang.RuntimeException:不能创建com.rwe.st.cao.gas.attila.ui.control.ChoiceBoxTableCellFactory的实例与给定的属性集:[maxHeight,items,maxWidth]' – mrt181

回答

1

这看起来应该起作用。我尝试了一个更简单的测试,下面的解决方法似乎在这里工作:

如果您不需要代码中其他任何地方的setItems()方法,请将其删除并使用read only list properties方法。即完全移除setItems(...)方法,并在FXML做

<ChoiceBoxTableCellFactory maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"> 
     <items> 
     <String fx:value="r01" /> 
     <String fx:value="r02" /> 
     </items> 
    </ChoiceBoxTableCellFactory> 

的另一种方式,似乎周围是使用一个<fx:define>块中定义的项目,并使用属性初始化:

<fx:define> 
    <FXCollections fx:factory="observableArrayList" fx:id="items"> 
     <String fx:value="r01"/> 
     <String fx:value="r02"/> 
    </FXCollections> 
<fx:define> 
<ChoiceBoxTableCellFactory maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" 
    items="$items" /> 
+0

用fx选择了解决方案:define,works。我的第一个方法看起来像javafx中的错误。 – mrt181

+0

是的,当你混合属性属性和元素属性时,它似乎被'@ NamedArg'弄糊涂了。 –

+0

我可以在某处填写错误报告吗? – mrt181

相关问题