我有以下Trade
对象类。
public class Trade implements Comparable<Trade>{
// attributes of each trade that go into the tableViewTransaction log
// properties
private StringProperty itemID;
public Trade(int itemID){
this.itemID = new SimpleStringProperty(String.format("%04d",itemID));
}
public String getItemID(){
return this.itemID.get();
}
public StringProperty itemIDProperty(){
return this.itemID;
}
public void setItemID(String itemID){
int id = Integer.parseInt(itemID);
this.itemID.set(String.format("%04d",id));
}
}
现在在我的Controller
课程中,我有一个tableView TransactionLog
和一个itemID
的表格列。
public TableView<Trade> fxTransactionLog;
public TableColumn<Trade, String> fxTransactionLogItemID;
tableView是可编辑的,使用以下代码的表列也是可编辑的。
问题出在哪里:tableView能够完美地显示itemID。例如,当我创建一个itemID = 1的新Trade
对象时,表格单元格将显示0001
,然后我决定编辑一个Trade对象的itemID
并输入到新ID 为13,它将显示为0013
,如下所示。
0001 -> 0013 // This works fine, if I edit the cell and assign a DIFFERENT value to the cell.
但是,如果我点击编辑itemID
并指定它已经拥有的相同值,在这种情况下为1。它显示1
,这不是我想要的,因为它缺少前导零。我查看了我的代码,然后无法弄清楚为什么会发生这种情况。这更像是一个审美问题。
0001 -> 1 // edit and reassign same value to the cell
即使我将SAME值分配给单元格,如何才能显示0001
而不仅仅1
?
其次,我应该编写什么代码以及在哪里阻止用户输入String
for itemID?
更新:所以我按照link示例12-11进行了操作。我为EditingItemIDCell
创建了一个单独的类。
导入javafx.scene.control.TableCell; import javafx.scene.control.TextField; 公共类EditingItemIDCell扩展TableCell { private TextField textField;
public EditingItemIDCell() {
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(String.format("%04d",Integer.parseInt(getString())));
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(null);
}
}
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
在我的Controller
课程中,我做了以下更改。
但我收到一个错误说:
The method setCellFactory(Callback<TableColumn<Trade,String>,TableCell<Trade,String>>) in the type TableColumn<Trade,String> is not applicable for the arguments (Callback<TableColumn,TableCell>).
答案 0 :(得分:1)
将cellfactory定义为;
Callback<TableColumn<Trade, String>, TableCell<Trade, String>> cellFactory
= new Callback<TableColumn<Trade, String>, TableCell<Trade, String>>()
{
public TableCell call( TableColumn<Trade, String> p )
{
return new EditingItemIDCell();
}
};
在创建文本字段时在EditingItemIDCell中执行
private void createTextField()
{
NumberFormat nf = NumberFormat.getIntegerInstance();
textField = new TextField();
// add filter to allow for typing only integer
textField.setTextFormatter( new TextFormatter<>( c ->
{
if (c.getControlNewText().isEmpty()) {
return c;
} // for the No.2 issue in the comment
ParsePosition parsePosition = new ParsePosition( 0 );
Object object = nf.parse( c.getControlNewText(), parsePosition );
if ( object == null || parsePosition.getIndex() < c.getControlNewText().length() )
{
return null;
}
else
{
return c;
}
} ) );
textField.setText( getString() );
textField.setMinWidth( this.getWidth() - this.getGraphicTextGap() * 2 );
// commit on Enter
textField.setOnAction( new EventHandler<ActionEvent>()
{
@Override
public void handle( ActionEvent event )
{
commitEdit( textField.getText() );
}
} );
textField.focusedProperty().addListener( new ChangeListener<Boolean>()
{
@Override
public void changed( ObservableValue<? extends Boolean> arg0,
Boolean arg1, Boolean arg2 )
{
if ( !arg2 )
{
commitEdit( textField.getText() );
}
}
} );
}
最后,你的实际问题,因为你决定格式化Trade类设置器中的输入值,当用户提交相同的值时,tableview确定原始值没有改变,并且不更新单元格中的渲染值,所以当用户提交&#34; 1&#34;同样,Trade实例的基础值是&#34; 0001&#34;,但渲染的值仍然是&#34; 1&#34;。肮脏的解决方法可能是将值更改为某个任意中间值:
public void setItemID( String itemID )
{
this.itemID.set( "0" );
int id = Integer.parseInt( itemID );
this.itemID.set( String.format( "%04d", id ) );
}
<小时/> 的修改
1)我仍然希望tableCell中的现有textfield 0001 突出显示,当我双击要编辑的单元格时?
将startEdit更改为:
@Override
public void startEdit()
{
if ( !isEmpty() )
{
super.startEdit();
createTextField();
setText( null );
setGraphic( textField );
textField.requestFocus();
// textField.selectAll(); commenting out this because
// JavaFX confuses the caret position described in the comment
// as OP has observed. Seems to be a bug.
}
}
2)另外,使用现有代码,我永远不会删除整数 编辑时的第一个索引。
在文本字段过滤器中,使用以下命令检查空白:
if (c.getControlNewText().isEmpty()) {
return c;
}
我还编辑了上面的过滤器代码。