Javafx:无法在表格单元格中正确显示内容

时间:2015-08-22 09:43:09

标签: java javafx

我有以下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>).

1 个答案:

答案 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;
}

我还编辑了上面的过滤器代码。