3

看看下面的工作代码:

    class MyType{
       SimpleStringProperty myname;
       SimpleObjectProperty<Color> mycolor;
    }

    TableColumn col;
    arr = FXCollections.observableArrayList(new ArrayList<MyType>());
    tblColName.setCellValueFactory(new PropertyValueFactory("myname"));
    // Use the cell-factory provided by TextFieldTableCell.
    tblColName.setCellFactory(TextFieldTableCell.forTableColumn());
    tblColName.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent>() {
        @Override
        public void handle(TableColumn.CellEditEvent cellEditEvent) {
            ((MyType) cellEditEvent.getRowValue()).myname.set((String) cellEditEvent.getNewValue());
        }
    });

但是,一旦我使用自定义 TableCell,setOnEditCommit就不再调用其中的代码:

public class ColorPickerTableCell<S> extends TableCell<S, Color>{
private ColorPicker cp;

public ColorPickerTableCell(){        
    cp = new ColorPicker(Color.BLACK);        
    cp.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            commitEdit(cp.getValue());
            updateItem(cp.getValue(), isEmpty());
        }            
    });                
    setGraphic(cp);
    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    setEditable(true);        
}     
@Override
protected void updateItem(Color item, boolean empty) {
    super.updateItem(item, empty);
    cp.setVisible(!empty);
    this.setItem(item);
}

public static <T> Callback<TableColumn<Color, T>, TableCell<Color, T>> forTableColumn(){
    return new Callback<TableColumn<Color, T>, TableCell<Color, T>>() {
        @Override
        public TableCell<Color, T> call(TableColumn<Color, T> colorTTableColumn) {
            return new ColorPickerTableCell();
        }
    };

}

}

对上面的代码稍作改动...

    TableColumn col;
    arr = FXCollections.observableArrayList(new ArrayList<MyType>());
    tblColName.setCellValueFactory(new PropertyValueFactory("myname"));
    // Use the cell-factory provided by TextFieldTableCell.
    tblColName.setCellFactory(ColorPickerTableCell.forTableColumn());
    tblColName.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent>() {
        @Override
        public void handle(TableColumn.CellEditEvent cellEditEvent) {
            throw new NotImplementedException(); // is never thrown.
        }
    });

...使代码不再工作。永远不会抛出异常。我认为我在设计中做错了什么ColorPickerTableCell,但我无法想象是什么。如何让 JavaFX 调用我的OnEditCommit

4

4 回答 4

2

You need first to go to edit state with statEdit(); , if you now commit an event will be fired

于 2015-02-24T22:41:20.480 回答
1

我对 CheckBoxTableCell 和 DatePickerTableCell 和 ColorPickerTableCells 有同样的问题 :-(

我是这样处理的:在控件的事件上,我取回“ ((Inputs)getTableView().getItems().get(getTableRow().getIndex() ”使用的 POJO 对象,并且我更新类似是否在 OnEditCommit 方法中完成...

所以对我来说它看起来像这样(更新颜色):

 ((Inputs) getTableView().getItems().get(
                    getTableRow().getIndex())
                    ).setColor(cp.getValue());

这是 ColorPickerCell 的示例:

public class ColorPickerTableCell<Inputs> extends TableCell<Inputs, Color>{
private ColorPicker cp;

public ColorPickerTableCell(){        
    cp = new ColorPicker(); 
    cp.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            commitEdit(cp.getValue());
            updateItem(cp.getValue(), isEmpty());
            ((Inputs) getTableView().getItems().get(
                    getTableRow().getIndex())
                    ).setColor(cp.getValue());
        }            
    });                
    setGraphic(cp);
    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    setEditable(true);        
}     
@Override
protected void updateItem(Color item, boolean empty) {
    super.updateItem(item, empty);
    cp.setVisible(!empty);
    this.setItem(item);
    cp.setValue(item);
}
}

使用这个简单的 JavaFX 的 POJO:

    public ObjectProperty<Color> color = new SimpleObjectProperty<Color>();

    this.color = new SimpleObjectProperty(color);

    public ObjectProperty<Color> colorProperty() {
    return color;
 }

public void setColor(Color color2) {
    color.set(color2);
}

我不知道这是否是实现这一目标的好方法,但它对我有用......请注意,JavaFX 的 POJO 只能在“ActionEvent”请求(组合框、日期选择器、颜色选择器等)中访问。

问候,

于 2014-04-10T18:15:02.670 回答
1

我最近遇到了同样的问题。不幸的是,我还没有找到任何从ColorPicker控件触发该事件的方法。但是,我想出了以下解决方法。

首先,我创建了一个颜色包装类:

public class ColorWrapper {

 private Color color;

 ....
}

我用Color模型类中的包装器实例替换了该实例M。接下来,我setCellFactory通过以下方式实现方法:

myColumn.setCellFactory(new Callback<TableColumn<M, ColorWrapper>, TableCell<M, ColorWrapper>>() {          

        @Override
        public TableCell<M, ColorWrapper> call(TableColumn<M,ColorWrapper> arg0) {
            return new TableCell<M, ColorWrapper>(){

                private ColorPicker colorPicker;

                private ColorPicker createPicker(){
                    colorPicker = new ColorPicker();

                    colorPicker.setOnAction(new EventHandler<ActionEvent>() {
                        @Override
                        public void handle(ActionEvent evt) {
                            ColorPicker cp = (ColorPicker)evt.getSource();
                            ColorWrapper cw = (ColorWrapper)cp.getUserData();
                            cw.setColor(cp.getValue());
                        }

                    });
                    return colorPicker;
                }


                @Override
                protected void updateItem(ColorWrapper value, boolean empty) {                      
                    super.updateItem(value, empty);
                    if(empty){
                        return;
                    }

                    if(colorPicker == null){
                        colorPicker = createPicker();
                        colorPicker.setUserData(value);
                    }

                    colorPicker.setValue(value.getColor());
                    setGraphic(colorPicker);
                }

            };

        }            

    });

如您所见,我只是利用setUserData/getUserData了类的方法,仅ColorPicker此而已。有用。

于 2013-10-06T23:13:01.437 回答
0

为了详细说明justcode的答案,这是我遇到问题并解决它的课程:

public class DeleteButtonCell extends TableCell<Menu, Menu> {

  private Button deleteButton;

  public DeleteButtonCell() {
    deleteButton = new Button();
    deleteButton.setId("trash-button");
    deleteButton.setOnAction((e) -> {
      startEdit();
      commitEdit((Menu) this.getTableView().getItems().get(this.getIndex()));
    });
  }

  @Override
  protected void updateItem(Menu t, boolean empty) {
    super.updateItem(t, empty);
    if (empty) {
      setGraphic(null);
    } else {
      setGraphic(deleteButton);
    }
  }

}
于 2015-06-04T10:37:33.170 回答