Javafx:TableView根据行列获取特定表格单元格的图形节点
Posted
技术标签:
【中文标题】Javafx:TableView根据行列获取特定表格单元格的图形节点【英文标题】:Javafx: TableView get graphic node of a particular Table cell based on row column 【发布时间】:2017-09-10 07:40:09 【问题描述】:我有一个 JavaFX 表视图组件,并且正在使用 ComboBox
为各个列动态加载数据作为 setGraphic
。我想在cellFactory
处添加ComboBox
。
现在当用户选择第一个ComboBox
时,必须相应地设置下一列ComboBox
。为此,我使用了一个选择侦听器,但我怎样才能获得其他TableColumn
的ComboBox
?
请找到我需要的快照:
这是TableView
的片段:
TableColumn< ModelInput, String > colCalibration = new TableColumn<>( "Calibration" );
TableColumn< ModelInput, String > colSamplingX = new TableColumn<>( "Sampling point X" );
TableColumn< ModelInput, String > colSamplingY = new TableColumn<>( "Sampling point Y" );
List< TableColumn< ModelInput, String > > tableColList =
Stream.of( colCalibration, colSamplingX, colSamplingY )
.collect( Collectors.toList() );
tableviewCalibMatching.getColumns().addAll( tableColList );
//initialize
colCalibration.setCellFactory( param -> new TableCell< ModelInput, String >()
@Override
public void updateItem( String item, boolean empty )
super.updateItem( item, empty );
if( empty )
setText( null );
else
ComboBox< String > comboBoxCalibMatchingNames = new ComboBox<>( listCalibNames );
comboBoxCalibMatchingNames.setPrefWidth( splitWidth );
comboBoxCalibMatchingNames.getSelectionModel().selectedItemProperty()
.addListener( (ChangeListener< String >)( observable, oldValue,
newValue ) ->
//TODO
//How can I get ComboBox of other TableColumn, need to set according to current //selection
);
setGraphic( comboBoxCalibMatchingNames );
setContentDisplay( ContentDisplay.GRAPHIC_ONLY );
);
colSamplingX.setCellFactory( param -> new TableCell< ModelInput, String >()
@Override
public void updateItem( String item, boolean empty )
super.updateItem( item, empty );
if( empty )
setText( null );
else
final ComboBox< String > comboBox = new ComboBox<>();
setGraphic( comboBox );
setContentDisplay( ContentDisplay.GRAPHIC_ONLY );
);
colSamplingY.setCellFactory( param -> new TableCell< ModelInput, String >()
@Override
public void updateItem( String item, boolean empty )
super.updateItem( item, empty );
if( empty )
setText( null );
else
final ComboBox< String > comboBox = new ComboBox<>();
setGraphic( comboBox );
setContentDisplay( ContentDisplay.GRAPHIC_ONLY );
);
【问题讨论】:
这三个列表是如何相互关联的?如果我选择一个特定的校准值,它应该生成一个全新的采样点 X 和 Y 列表?ModelInput
中的列表是否存在,它们是如何定义的?
@Jai SamplingPtX 和 SamplingPtY 组合列表是静态加载的。与ModelInput
无关。我需要执行的所有操作是选择校准组合框,我必须在 SamplingPtX & Y 中设置特定项目,组合框对应的行。
ModelInput 是否包含 3 列值?作为 SimpleStringProperty?它还遗漏了 seItems 部分和 setCellValueFactory 绑定。 (在全球范围内,我们需要更多资源来获得完整的可测试示例)
@pdem No ModelInput 实际上没有 3 Coulmns 的数据。还有另一列,其数据取自 ModelInput 作为 SimpleStringProperty。这在图像中不可见。
【参考方案1】:
试试这个:
public class Test
private final TableView<ModelInput> tableviewCalibMatching = new TableView<>();
private final TableColumn<ModelInput, String> colCalibration = new TableColumn<>("Calibration");
private final TableColumn<ModelInput, String> colSamplingX = new TableColumn<>("Sampling Point X");
private final TableColumn<ModelInput, String> colSamplingY = new TableColumn<>("Sampling Point Y");
private final ObservableList<String> listCalibNames = FXCollections.observableArrayList();
private final ObservableList<String> listSamplingXNames = FXCollections.observableArrayList();
private final ObservableList<String> listSamplingYNames = FXCollections.observableArrayList();
private final ObservableList<ModelInput> items = FXCollections.observableArrayList();
public Test()
tableviewCalibMatching.setItems(items);
tableviewCalibMatching.getColumns().addAll(colCalibration, colSamplingX, colSamplingY);
colCalibration.setCellFactory(ComboBoxTableCell.forTableColumn(listCalibNames));
colSamplingX.setCellFactory(ComboBoxTableCell.forTableColumn(listSamplingXNames));
colSamplingY.setCellFactory(ComboBoxTableCell.forTableColumn(listSamplingYNames));
colCalibration.setCellValueFactory(new PropertyValueFactory<>("calibration"));
colSamplingX.setCellValueFactory(new PropertyValueFactory<>("samplingX"));
colSamplingY.setCellValueFactory(new PropertyValueFactory<>("samplingY"));
colCalibration.setOnEditCommit(event ->
final String newCalibrationValue = event.getNewValue();
event.getRowValue().setCalibration(newCalibrationValue);
// You can change the logic here based on what you need
event.getRowValue().setSamplingX(listSamplingXNames.get(1));
event.getRowValue().setSamplingY(listSamplingXNames.get(1));
);
colSamplingX.setOnEditCommit(event ->
final String newSamplingXValue = event.getNewValue();
event.getRowValue().setSamplingX(newSamplingXValue);
);
colSamplingY.setOnEditCommit(event ->
final String newSamplingYValue = event.getNewValue();
event.getRowValue().setSamplingY(newSamplingYValue);
);
public static class ModelInput
private final StringProperty calibration = new SimpleStringProperty();
private final StringProperty samplingX = new SimpleStringProperty();
private final StringProperty samplingY = new SimpleStringProperty();
public final StringProperty calibrationProperty()
return this.calibration;
public final String getCalibration()
return this.calibrationProperty().get();
public final void setCalibration(final String calibration)
this.calibrationProperty().set(calibration);
public final StringProperty samplingXProperty()
return this.samplingX;
public final String getSamplingX()
return this.samplingXProperty().get();
public final void setSamplingX(final String samplingX)
this.samplingXProperty().set(samplingX);
public final StringProperty samplingYProperty()
return this.samplingY;
public final String getSamplingY()
return this.samplingYProperty().get();
public final void setSamplingY(final String samplingY)
this.samplingYProperty().set(samplingY);
【讨论】:
默认情况下,ComboBox
是不可见的。您必须在行元素上显式双击。
这个想法是用户必须使用 ComboBox,因此必须设置另一个 ComboBox。编辑每一行时没有提交任何内容。
@zIronManBox 虽然我不明白你为什么坚持不使用通常的 ComboBox-TextField 样式(我无法想象一个有 20 行显示 60 个 ComboBoxes 的表格),但另一种方法是制作一个 @ 987654323@,然后手动设置并获取updateItem()
中的ComboBox
。【参考方案2】:
您可以从 TableCell::getIndex() 中获取当前行。 首先,更新 TableView 项中包含的对象。
comboBoxCalibMatchingNames.setOnAction(event ->
tableView.getItems().get(getIndex()).someProperty().set(anyValue1);
tableView.getItems().get(getIndex()).otherProperty().set(anyValue2);
);
它使用新值触发更新列的 TableCell::updateItem(T, boolean)。 您必须在 updateItem 上更新 ComboBox 的选择。
// in updteItem code on colSamplingX
final ComboBox< String > comboBox = new ComboBox<>();
comboBox.getSelectionModel().select(item); // Select updated item.
setGraphic( comboBox );
setContentDisplay( ContentDisplay.GRAPHIC_ONLY );
【讨论】:
我问的问题是'在选择一个组合框时,我需要在另一个组合框中选择项目'。您所说的已添加到选择侦听器中。另外,我只需要知道,我怎样才能在对应行的另一个TableColumn
上设置GraphicNode
。
对不起,我的回答的重点是在这种情况下不需要gettnig GraphicNode来设置另一个ComboBox。
如果你看到了,我没有使用根元素来修改东西。填充到其他列的数据不是来自父元素。它在每列的cellFactory
的update
方法的运行时加载。
this question 中提到访问 Cell 不是好方法。您可以在Example 12-5 Setting Data Properties to Columns 中找到如何使用定义数据模型。不要忘记每个更新模型的属性会自动触发updateItem(T, boolean)
。以上是关于Javafx:TableView根据行列获取特定表格单元格的图形节点的主要内容,如果未能解决你的问题,请参考以下文章