gpt4 book ai didi

java - 如何正确避免特定的 UITableViewCell 可编辑?

转载 作者:太空宇宙 更新时间:2023-11-04 14:51:19 25 4
gpt4 key购买 nike

以下问题:我需要知道在特定时刻,天气我的TableView当前是否正在编辑。我用了editingCellProperty并将特定的业务逻辑绑定(bind)到它,以便在表切换这些模式时获得通知。

不幸的是,状态并不总是正确显示,因为我有特定的单元格(在同一列内),这些单元格根本不应该被编辑,但当单击不可编辑的单元格时,TablePosition 仍然被设置到 EditingCellProperty 中,因此我得到的信息是,我的 TableView 正在编辑,尽管根据条件被告知,该单元格不可编辑,并且编辑模式从未真正启动。

我创建了一个小示例,其中 ColumnName 的所有偶数行都是可编辑的,而奇数行则不可编辑。

Small Example

示例代码:

public class TableViewEditableStateError extends Application
{
public static void main( final String[] args )
{
launch( args );
}

@Override
public void start( final Stage primaryStage )
{
Item item1 = new Item( 1, "Item1" );
Item item2 = new Item( 2, "Item2" );
Item item3 = new Item( 3, "Item3" );
Item item4 = new Item( 4, "Item4" );

ObservableList<Item> itemList = FXCollections.observableArrayList( item1, item2, item3, item4 );

TableColumn<Item, Integer> columnId = new TableColumn<>( "ColumnId" );
TableColumn<Item, String> columnName = new TableColumn<>( "ColumnName" );

columnId.setCellValueFactory( new PropertyValueFactory<Item, Integer>( "id" ) );
columnName.setCellValueFactory( new PropertyValueFactory<Item, String>( "name" ) );

// columnName.setCellFactory( TextFieldTableCell.forTableColumn() ); -> Using own implementation for editablestate-behaviour

columnName.setCellFactory( new Callback<TableColumn<Item, String>, TableCell<Item, String>>()
{
@Override
public TableCell<Item, String> call( final TableColumn<Item, String> column )
{
TableCell<Item, String> cell = new EditableTableCell<Item>()
{
@Override
public void startEdit()//Business-Rule to deceide, which cell is editable.
{
if ( getTableRow().getIndex() % 2 != 0/* Only Odd Values are editable. -> Any Random Condition */)
{
System.out.println( "Do not initiate Editing." );
return;
}

System.out.println( "initiate Editing." );
super.startEdit();
}
};

return cell;
}
} );

columnName.setOnEditCommit( new EventHandler<CellEditEvent<Item, String>>()
{
@Override
public void handle( final CellEditEvent<Item, String> event )
{
final Item item = event.getRowValue();

System.out.println( "Change Item " + item + " from " + event.getOldValue() + " to new value "
+ event.getNewValue() );

item.setName( event.getNewValue() );
}
} );

final TableView<Item> tableView = new TableView<>( itemList );
tableView.getColumns().add( columnId );
tableView.getColumns().add( columnName );

tableView.setColumnResizePolicy( TableView.CONSTRAINED_RESIZE_POLICY );

tableView.setEditable( true );
columnId.setEditable( false );

Label label = new Label( "Editing-State: is not editing..." );

//Listener to record editing behaviour:
tableView.editingCellProperty().addListener( new ChangeListener<TablePosition<Item, ?>>()
{
@Override
public void changed( final ObservableValue<? extends TablePosition<Item, ?>> observable,
final TablePosition<Item, ?> oldValue, final TablePosition<Item, ?> newValue )
{
System.out.println( "Editstate changed to: " + newValue );

if ( newValue != null )
label.setText( "Editing-State: is editing..." );
else
label.setText( "Editing-State: is not editing..." );
}
} );

BorderPane layout = new BorderPane();
layout.setCenter( tableView );
layout.setTop( label );
Scene scene = new Scene( layout, 400, 400 );
scene.getStylesheets().add( getClass().getResource( "application.css" ).toExternalForm() );
primaryStage.setScene( scene );
primaryStage.show();
}

class EditableTableCell<S> extends TableCell<S, String>
{
protected TextField textField;

@Override
public void startEdit()
{
super.startEdit();

if ( textField == null )
{
createTextField();
}

setGraphic( textField );
setContentDisplay( ContentDisplay.GRAPHIC_ONLY );
Platform.runLater( new Runnable()
{
@Override
public void run()
{
textField.selectAll();
textField.requestFocus();
}
} );
}

@Override
public void cancelEdit()
{
super.cancelEdit();
setText( getItem() == null ? "" : getItem().toString() );
setContentDisplay( ContentDisplay.TEXT_ONLY );
textField = null;
}

@Override
public void updateItem( final String item, final boolean empty )
{
super.updateItem( item, empty );
if ( empty )
{
setText( null );
setGraphic( null );
}
else
{
if ( isEditing() )
{
if ( textField != null )
{
textField.setText( getItem() == null ? "" : getItem().toString() );
}
setGraphic( textField );
setContentDisplay( ContentDisplay.GRAPHIC_ONLY );
}
else
{
setText( getItem() == null ? "" : getItem().toString() );
setContentDisplay( ContentDisplay.TEXT_ONLY );
}
}
}

private void createTextField()
{
textField = new TextField( getItem() == null ? "" : getItem().toString() );

textField.setOnKeyPressed( new EventHandler<KeyEvent>()
{
@Override
public void handle( final KeyEvent keyEvent )
{
if ( keyEvent.getCode() == KeyCode.ENTER )
{
commitEdit( textField.getText() );
}
else if ( keyEvent.getCode() == KeyCode.ESCAPE )
{
cancelEdit();
}
}
} );

textField.focusedProperty().addListener( new ChangeListener<Boolean>()
{
@Override
public void changed( final ObservableValue<? extends Boolean> observable, final Boolean oldValue,
final Boolean newValue )
{
if ( !newValue && textField != null )
{
final String text = textField.getText();
commitEdit( text );
}
}
} );
}
}
}

数据类项目:

public class Item
{
private final IntegerProperty id = new SimpleIntegerProperty();
private final StringProperty name = new SimpleStringProperty();

public Item( final int id, final String name )
{
this.id.set( id );
this.name.set( name );
}

public int getId()
{
return id.get();
}

public String getName()
{
return name.get();
}

public void setId( final int id )
{
this.id.set( id );
}

public void setName( final String name )
{
this.name.set( name );
}

public IntegerProperty idProperty()
{
return id;
}

public StringProperty nameProperty()
{
return name;
}
}

我将问题范围缩小到 editCell TableView 的方法,因为它不对特定于单元格的可编辑状态使用react:

/**
* Causes the cell at the given row/column view indexes to switch into
* its editing state, if it is not already in it, and assuming that the
* TableView and column are also editable.
*/
public void edit(int row, TableColumn<S,?> column) {
if (!isEditable() || (column != null && ! column.isEditable())) {
return;
}

if (row < 0 && column == null) {
setEditingCell(null);
} else {
setEditingCell(new TablePosition<>(this, row, column));
}
}

但是由于 setEditingCell() 是一个私有(private)方法,我无法按照我希望的方式重写 edit-Method 。所以我很好奇:谁能告诉我在同一列中实现动态可编辑表格单元格的正确方法,同时TableView的editingCell-State将始终保持正确?

最佳答案

在监听器中类似这样的东西可以忽略编辑你不想要的单元格更改

    editingCellProperty().addListener((obs,ov,nv) -> {
if (nv!=null && nv.getRow() % 2 != 0/* Only Odd Values are editable. -> Any Random Condition */)
{
System.out.println( "Pretend this never happened" );
}
else
System.out.println("Editstate changed to: " + nv);
});

即使我在 EditableCell 构造函数中为某些单元格 setEditable(false) ,监听器仍然会触发。它认为它不会发生在 TableCell 编辑方法中,因为它会检查 !isEditable() 。发生的情况是 editorialCell 发生变化,从正在编辑的最后一个单元格到未编辑的新单元格。我想这有点道理,但是您不会得到空值,但单元格的 TablePosition 未被编辑。即使没有正在编辑的单元格,尝试编​​辑不可编辑的单元格仍然会触发监听器。

我认为这需要一个错误报告。

关于java - 如何正确避免特定的 UITableViewCell 可编辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23740462/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com