为 javaFx table 视图中的每一行动态填充组合框列表
Populate combo box list dynamically for each row in javaFx table view
我在 java Fx 中创建了一个 table 视图,table 视图中的其中一列包括
ComboBoxTableCell.Please 在下方找到 table 查看
的代码
public class TabViewController {
@FXML
private TabPane cnfmTab;
@FXML
private TableView<TabVO> partsTable;
@FXML
private TableColumn<TabVO, String> column1;
@FXML
private TableColumn<TabVO, String> column2;
@FXML
private TableColumn<TabVO, String> column3;
private ObservableList<TabVO> tableData = FXCollections.observableArrayList();
private ObservableList<String> column1List;
@FXML
public void initialize(){
tableData = FXCollections.observableArrayList(callDAO.getTableData(1));
column1.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getColumn1()));
column1
.setCellFactory(new Callback<TableColumn<tabVO, String>, TableCell<tabVO, String>>() {
@SuppressWarnings({ "rawtypes", "unchecked" })
public TableCell call(TableColumn p) {
ComboBoxTableCell cell = new ComboBoxTableCell(column1List){
@Override
public void updateItem(Object item, boolean empty) {
}
};
cell.setAlignment(Pos.CENTER);
return cell;
}
});
column1.setOnEditCommit(
new EventHandler<CellEditEvent<tabVO, String>>() {
@Override
public void handle(CellEditEvent<tabVO,String> t) {
};
}
);
}
partsTable.setItems(tableData);
}
数据对象:
public class TabVO {
private String column1;
private String column2;
private String column3;
private ObservableList<String> column1List;
/* Getters and Setters */
}
在上面的代码中,table 的每一行都是 TabVo 类型。
在 table 中,第 1 列是组合框类型。现在 column1 组合框的列表由
'column1List' 在 'TabViewController' 中声明,因此 table 视图的所有行都被填充
使用相同的下拉菜单。
但我希望 table 的每一行都填充有 TabVo 中存在的不同列表。
谁能告诉我如何访问 TabVo 对象并使用 TabVo 中存在的列表填充组合框?
您需要为单元格定义一个 CellValueFactory。该工厂通过使用给定行的 table 项列表的当前值来定义将在列中显示的值。看到这个 link:Cell factory in javafx
这是一个 MVCE,在问题中描述了用例:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Callback;
public class ComboBoxCellTableExample extends Application
{
private final TableView<TabVo> table = new TableView<>();
private final ObservableList<TabVo> data
= FXCollections.observableArrayList(
new TabVo( "2222", "column2", FXCollections.<String>observableArrayList( "111", "2222", "3333" ) ),
new TabVo( "bbbb", "column2", FXCollections.<String>observableArrayList( "aaaa", "bbbb", "ccccc" ) ),
new TabVo( "6666", "column2", FXCollections.<String>observableArrayList( "444", "5555", "6666" ) ),
new TabVo( "7777", "column2", FXCollections.<String>observableArrayList( "7777", "8888", "99999" ) ),
new TabVo( "hhhh", "column2", FXCollections.<String>observableArrayList( "hhhh", "jjjj", "kkkkk" ) )
);
@Override
public void start( Stage stage )
{
Scene scene = new Scene( new Group() );
stage.setWidth( 450 );
stage.setHeight( 550 );
table.setEditable( true );
Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>()
{
@Override
public TableCell call( TableColumn p )
{
return new ComboBoxCell();
}
};
TableColumn column1Col = new TableColumn( "Column 1" );
column1Col.setMinWidth( 100 );
column1Col.setCellValueFactory( new PropertyValueFactory<TabVo, String>( "column1" ) );
column1Col.setCellFactory( cellFactory );
column1Col.setOnEditCommit(
new EventHandler<TableColumn.CellEditEvent<TabVo, String>>()
{
@Override
public void handle( TableColumn.CellEditEvent<TabVo, String> t )
{
(( TabVo ) t.getTableView().getItems().get(
t.getTablePosition().getRow() )).setColumn1( t.getNewValue() );
}
}
);
TableColumn column2Col = new TableColumn( "Column 2" );
column2Col.setMinWidth( 100 );
column2Col.setCellValueFactory( new PropertyValueFactory<TabVo, String>( "column2" ) );
column2Col.setCellFactory( TextFieldTableCell.forTableColumn() );
column2Col.setOnEditCommit(
new EventHandler<TableColumn.CellEditEvent<TabVo, String>>()
{
@Override
public void handle( TableColumn.CellEditEvent<TabVo, String> t )
{
(( TabVo ) t.getTableView().getItems().get(
t.getTablePosition().getRow() )).setColumn2( t.getNewValue() );
}
}
);
table.setItems( data );
table.getColumns().addAll( column1Col, column2Col );
(( Group ) scene.getRoot()).getChildren().add( table );
stage.setScene( scene );
stage.show();
}
class ComboBoxCell extends TableCell<TabVo, String>
{
private ComboBox<String> comboBox;
public ComboBoxCell()
{
comboBox = new ComboBox<>();
}
@Override
public void startEdit()
{
if ( !isEmpty() )
{
super.startEdit();
comboBox.setItems( getTableView().getItems().get( getIndex() ).getColumn1List() );
comboBox.getSelectionModel().select( getItem() );
comboBox.focusedProperty().addListener( new ChangeListener<Boolean>()
{
@Override
public void changed( ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue )
{
if ( !newValue )
{
commitEdit( comboBox.getSelectionModel().getSelectedItem() );
}
}
} );
setText( null );
setGraphic( comboBox );
}
}
@Override
public void cancelEdit()
{
super.cancelEdit();
setText( ( String ) getItem() );
setGraphic( null );
}
@Override
public void updateItem( String item, boolean empty )
{
super.updateItem( item, empty );
if ( empty )
{
setText( null );
setGraphic( null );
}
else
{
if ( isEditing() )
{
setText( null );
setGraphic( comboBox );
}
else
{
setText( getItem() );
setGraphic( null );
}
}
}
}
public static void main( String[] args )
{
launch( args );
}
public static class TabVo
{
private String column1;
private String column2;
private ObservableList<String> column1List;
private TabVo( String column1, String column2, ObservableList<String> column1List )
{
this.column1 = column1;
this.column2 = column2;
this.column1List = column1List;
}
public String getColumn1()
{
return column1;
}
public void setColumn1( String column1 )
{
this.column1 = column1;
}
public String getColumn2()
{
return column2;
}
public void setColumn2( String column2 )
{
this.column2 = column2;
}
public ObservableList<String> getColumn1List()
{
return column1List;
}
public void setColumn1List( ObservableList<String> column1List )
{
this.column1List = column1List;
}
}
}
第一列在编辑模式下使用组合框,而第二列使用文本字段的默认工厂。
我在 java Fx 中创建了一个 table 视图,table 视图中的其中一列包括 ComboBoxTableCell.Please 在下方找到 table 查看
的代码public class TabViewController {
@FXML
private TabPane cnfmTab;
@FXML
private TableView<TabVO> partsTable;
@FXML
private TableColumn<TabVO, String> column1;
@FXML
private TableColumn<TabVO, String> column2;
@FXML
private TableColumn<TabVO, String> column3;
private ObservableList<TabVO> tableData = FXCollections.observableArrayList();
private ObservableList<String> column1List;
@FXML
public void initialize(){
tableData = FXCollections.observableArrayList(callDAO.getTableData(1));
column1.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getColumn1()));
column1
.setCellFactory(new Callback<TableColumn<tabVO, String>, TableCell<tabVO, String>>() {
@SuppressWarnings({ "rawtypes", "unchecked" })
public TableCell call(TableColumn p) {
ComboBoxTableCell cell = new ComboBoxTableCell(column1List){
@Override
public void updateItem(Object item, boolean empty) {
}
};
cell.setAlignment(Pos.CENTER);
return cell;
}
});
column1.setOnEditCommit(
new EventHandler<CellEditEvent<tabVO, String>>() {
@Override
public void handle(CellEditEvent<tabVO,String> t) {
};
}
);
}
partsTable.setItems(tableData);
}
数据对象:
public class TabVO {
private String column1;
private String column2;
private String column3;
private ObservableList<String> column1List;
/* Getters and Setters */
}
在上面的代码中,table 的每一行都是 TabVo 类型。
在 table 中,第 1 列是组合框类型。现在 column1 组合框的列表由 'column1List' 在 'TabViewController' 中声明,因此 table 视图的所有行都被填充 使用相同的下拉菜单。
但我希望 table 的每一行都填充有 TabVo 中存在的不同列表。
谁能告诉我如何访问 TabVo 对象并使用 TabVo 中存在的列表填充组合框?
您需要为单元格定义一个 CellValueFactory。该工厂通过使用给定行的 table 项列表的当前值来定义将在列中显示的值。看到这个 link:Cell factory in javafx
这是一个 MVCE,在问题中描述了用例:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Callback;
public class ComboBoxCellTableExample extends Application
{
private final TableView<TabVo> table = new TableView<>();
private final ObservableList<TabVo> data
= FXCollections.observableArrayList(
new TabVo( "2222", "column2", FXCollections.<String>observableArrayList( "111", "2222", "3333" ) ),
new TabVo( "bbbb", "column2", FXCollections.<String>observableArrayList( "aaaa", "bbbb", "ccccc" ) ),
new TabVo( "6666", "column2", FXCollections.<String>observableArrayList( "444", "5555", "6666" ) ),
new TabVo( "7777", "column2", FXCollections.<String>observableArrayList( "7777", "8888", "99999" ) ),
new TabVo( "hhhh", "column2", FXCollections.<String>observableArrayList( "hhhh", "jjjj", "kkkkk" ) )
);
@Override
public void start( Stage stage )
{
Scene scene = new Scene( new Group() );
stage.setWidth( 450 );
stage.setHeight( 550 );
table.setEditable( true );
Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>()
{
@Override
public TableCell call( TableColumn p )
{
return new ComboBoxCell();
}
};
TableColumn column1Col = new TableColumn( "Column 1" );
column1Col.setMinWidth( 100 );
column1Col.setCellValueFactory( new PropertyValueFactory<TabVo, String>( "column1" ) );
column1Col.setCellFactory( cellFactory );
column1Col.setOnEditCommit(
new EventHandler<TableColumn.CellEditEvent<TabVo, String>>()
{
@Override
public void handle( TableColumn.CellEditEvent<TabVo, String> t )
{
(( TabVo ) t.getTableView().getItems().get(
t.getTablePosition().getRow() )).setColumn1( t.getNewValue() );
}
}
);
TableColumn column2Col = new TableColumn( "Column 2" );
column2Col.setMinWidth( 100 );
column2Col.setCellValueFactory( new PropertyValueFactory<TabVo, String>( "column2" ) );
column2Col.setCellFactory( TextFieldTableCell.forTableColumn() );
column2Col.setOnEditCommit(
new EventHandler<TableColumn.CellEditEvent<TabVo, String>>()
{
@Override
public void handle( TableColumn.CellEditEvent<TabVo, String> t )
{
(( TabVo ) t.getTableView().getItems().get(
t.getTablePosition().getRow() )).setColumn2( t.getNewValue() );
}
}
);
table.setItems( data );
table.getColumns().addAll( column1Col, column2Col );
(( Group ) scene.getRoot()).getChildren().add( table );
stage.setScene( scene );
stage.show();
}
class ComboBoxCell extends TableCell<TabVo, String>
{
private ComboBox<String> comboBox;
public ComboBoxCell()
{
comboBox = new ComboBox<>();
}
@Override
public void startEdit()
{
if ( !isEmpty() )
{
super.startEdit();
comboBox.setItems( getTableView().getItems().get( getIndex() ).getColumn1List() );
comboBox.getSelectionModel().select( getItem() );
comboBox.focusedProperty().addListener( new ChangeListener<Boolean>()
{
@Override
public void changed( ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue )
{
if ( !newValue )
{
commitEdit( comboBox.getSelectionModel().getSelectedItem() );
}
}
} );
setText( null );
setGraphic( comboBox );
}
}
@Override
public void cancelEdit()
{
super.cancelEdit();
setText( ( String ) getItem() );
setGraphic( null );
}
@Override
public void updateItem( String item, boolean empty )
{
super.updateItem( item, empty );
if ( empty )
{
setText( null );
setGraphic( null );
}
else
{
if ( isEditing() )
{
setText( null );
setGraphic( comboBox );
}
else
{
setText( getItem() );
setGraphic( null );
}
}
}
}
public static void main( String[] args )
{
launch( args );
}
public static class TabVo
{
private String column1;
private String column2;
private ObservableList<String> column1List;
private TabVo( String column1, String column2, ObservableList<String> column1List )
{
this.column1 = column1;
this.column2 = column2;
this.column1List = column1List;
}
public String getColumn1()
{
return column1;
}
public void setColumn1( String column1 )
{
this.column1 = column1;
}
public String getColumn2()
{
return column2;
}
public void setColumn2( String column2 )
{
this.column2 = column2;
}
public ObservableList<String> getColumn1List()
{
return column1List;
}
public void setColumn1List( ObservableList<String> column1List )
{
this.column1List = column1List;
}
}
}
第一列在编辑模式下使用组合框,而第二列使用文本字段的默认工厂。