Combobox javafx2 tableview问题:单元格中的回调和可编辑组合框
我对tableview及其单元格有问题。我想用可编辑的组合框自定义单元格。下面是我的组合框代码:Combobox javafx2 tableview问题:单元格中的回调和可编辑组合框,combobox,callback,javafx,tableview,Combobox,Callback,Javafx,Tableview,我对tableview及其单元格有问题。我想用可编辑的组合框自定义单元格。下面是我的组合框代码: public class CbbxEditSuppr extends ComboBox<BoxItem> { private TextField editor = null; private ObservableList<BoxItem> items = null; private double prefWidth = 0.0; /** * Constructeur
public class CbbxEditSuppr extends ComboBox<BoxItem> {
private TextField editor = null;
private ObservableList<BoxItem> items = null;
private double prefWidth = 0.0;
/**
* Constructeur.
*
* @param addedItems ObservableList<String>
* @param prefWidth double largeur préférée
*/
public CbbxEditSuppr(ObservableList<String> addedItems, final double prefWidth) {
// initialisation des attributs
editor = this.getEditor();
items = this.getItems();
this.prefWidth = prefWidth;
this.setPrefWidth(prefWidth);
// initialisation du contenu de la cellule
this.setCellFactory(new Callback<ListView<BoxItem>, ListCell<BoxItem>>() {
@Override
public ListCell<BoxItem> call(ListView<BoxItem> p) {
final ListCell<BoxItem> cell = new ListCell<BoxItem>() {
@Override
protected void updateItem(BoxItem t, boolean bln) {
super.updateItem(t, bln);
if (t != null) {
setGraphic(t);
} else {
setGraphic(null);
}
}
};
return cell;
}
});
// déininition du converter
this.setConverter(new StringConverter<BoxItem>() {
@Override
public String toString(BoxItem cbbx) {
if (cbbx == null) {
return null;
} else {
return cbbx.getName();
}
}
@Override
public BoxItem fromString(String id) {
if (id != null) {
final BoxItem box = new BoxItem(id, items, prefWidth);
return box;
} else {
return null;
}
}
});
/* ajout des valeurs a la liste d'items */
if (addedItems != null && addedItems.size() > 0) {
for (String stg : addedItems) {
if (stg != null) {
final BoxItem hbox = new BoxItem(stg, items, this.prefWidth);
items.add(hbox);
}
}
}
// permet de prendre en compte la touche ENTER, et ajouter des valeurs a la liste
this.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
public void handle(final KeyEvent event) {
if (event != null && event.getCode().equals(KeyCode.ENTER)) {
if (editor.getText().trim().length() > 0) {
addItem(editor.getText(), prefWidth);
editor.clear();
}
}
}
});
// propriétés editable et selection du premier element
this.setEditable(true);
this.getSelectionModel().selectFirst();
// ajout de l'affichage du menu popup lors du focus du textfield d'edition de la combobox
editor.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
if (arg0 != null && arg2) {
showpopupMenu();
}
}
});
}
/**
* Permet l'affichage du menu popup dans une cellule.
*/
private void showpopupMenu() {
if (!isShowing() && this != null) {
this.show();
}
}
/**
* Ajoute un item à la liste
*
* @param stg String nom de l'item
* @param width double taille préférée
*/
public void addItem(String stg, double width) {
if (stg != null) {
items.add(new BoxItem(stg, items, width));
}
}
/**
* Retourne la description du contenu de la liste
*/
public String toString() {
final StringBuilder stgBuilder = new StringBuilder("[ ");
if (items != null && items.size() > 0) {
final BoxItem lastItem = items.get(items.size() - 1);
for (BoxItem item : items) {
if (item != null) {
stgBuilder.append(item.getName());
if (!item.equals(lastItem)) {
stgBuilder.append(", ");
}
}
}
}
stgBuilder.append(" ]");
return stgBuilder.toString();
}
public class BoxItem extends HBox {
private Label lbl = null;
private Button btn = null;
private ObservableList<BoxItem> listItems;
/**
* Constructeur.
*
* @param stg String nom de la box
* @param items ObservableList<BoxItem> liste d'items de la combobox
* @param prefWidth int largeur de la combobox
*/
public BoxItem(String stg, final ObservableList<BoxItem> items, double prefWidth) {
super();
this.listItems = items;
if (stg != null) {
this.setSpacing(40);
lbl = new Label(stg);
lbl.setPrefWidth(prefWidth);
btn = new Button("x");
this.getChildren().addAll(lbl, btn);
btn.setOnMousePressed(new EventHandler<Event>() {
@Override
public void handle(Event arg0) {
final BoxItem bx = (BoxItem) btn.getParent();
if (bx != null) {
listItems.remove(bx);
}
}
});
}
}
/**
* Retourne le texte inscrit dans le label
*
* @return String
*/
public String getName() {
if (lbl != null) {
return lbl.getText();
}
return null;
}
/**
* retourne le bouton contenu dans une box
*
* @return Button
*/
public Button getBtn() {
return btn;
}
}
}
公共类cbbxeditsupper扩展组合框{
私有文本字段编辑器=null;
私有可观察列表项=空;
专用双预宽=0.0;
/**
*建筑工人。
*
*@param addedItems observeList
*@param prefWidth双倍大的préférée
*/
公共CBBXeditSupper(可观察列表加法器,最终双前缀宽度){
//属性初始化
editor=this.getEditor();
items=this.getItems();
this.prefWidth=prefWidth;
此.setPrefWidth(prefWidth);
//单元内容的初始化
this.setCellFactory(新回调(){
@凌驾
公共ListCell调用(ListView p){
最终ListCell单元格=新ListCell(){
@凌驾
受保护的void updateItem(BoxItem t,布尔bln){
超级更新项(t,bln);
如果(t!=null){
设定图形(t);
}否则{
设置图形(空);
}
}
};
返回单元;
}
});
//déininition du转换器
this.setConverter(新的StringConverter(){
@凌驾
公共字符串到字符串(BoxItem cbbx){
如果(cbbx==null){
返回null;
}否则{
返回cbbx.getName();
}
}
@凌驾
public BoxItem fromString(字符串id){
如果(id!=null){
最终BoxItem框=新的BoxItem(id、项目、宽度);
返回框;
}否则{
返回null;
}
}
});
/*一份物品清单*/
if(addedItems!=null&&addedItems.size()>0){
for(字符串stg:addedItems){
如果(stg!=null){
final BoxItem hbox=新的BoxItem(stg,items,this.prefWidth);
添加项目(hbox);
}
}
}
//你可以进来,也可以出去
this.addEventFilter(按KeyEvent.KEY_,新建EventHandler()){
公共无效句柄(最终KeyEvent事件){
if(event!=null&&event.getCode().equals(KeyCode.ENTER)){
if(editor.getText().trim().length()>0){
addItem(editor.getText(),prefWidth);
编辑器.clear();
}
}
}
});
//propriétés premier元素的可编辑et选择
此.setEditable(true);
这个.getSelectionModel().selectFirst();
//菜单弹出窗口中的文字字段和文本框的编辑
editor.focusedProperty().addListener(新的ChangeListener()){
@凌驾
public void已更改(observeValue我认为出现问题的原因是BoxItem
是一个节点
子类,即您混合了视图类型和数据类型。(在updateItem()方法中有BoxItem t;
和setGraphic(t);
)这对于组合框来说尤其糟糕,因为所选项目最终尝试在场景图中出现两次(一次出现在组合框的下拉列表中,一次出现在显示所选内容的“按钮单元格”中)
请参阅中的“关于将节点插入组合框项目列表的警告”
相反,请使用不同的类来表示正在显示的数据,并使用UI控件来显示这些数据
Callback<TableColumn<DonorData, ObservableList<BoxItem>>, TableCell<DonorData, ObservableList<BoxItem>>> cellFactoryEditingCell = new Callback<TableColumn<DonorData, ObservableList<BoxItem>>, TableCell<DonorData, ObservableList<BoxItem>>>() {
public TableCell<DonorData, ObservableList<BoxItem>> call(TableColumn<DonorData, ObservableList<BoxItem>> data) {
return new CbbxEditingCell<DonorData, ObservableList<BoxItem>>();
}
};
colDonorOtherRef.setCellValueFactory(new PropertyValueFactory<DonorData, ObservableList<BoxItem>>("othersRef"));
colDonorOtherRef.setCellFactory(cellFactoryEditingCell);
colDonorOtherRef.setOnEditCommit(new EventHandler<CellEditEvent<DonorData, ObservableList<BoxItem>>>() {
@Override
public void handle(CellEditEvent<DonorData, ObservableList<BoxItem>> event) {
final DonorData rec = event.getTableView().getItems().get(event.getTablePosition().getRow());
//TODO action
}
});
public class CbbxEditingCell<S, T> extends TableCell<S, T> {
private CbbxEditSuppr cbbx;
private ObservableList<String> listValues = null;
private boolean isSelectFirst = false;
public CbbxEditingCell() {
listValues = FXCollections.observableArrayList(new ArrayList());
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createTextField();
setText(null);
setGraphic(cbbx);
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
try {
if (!getItem().toString().equals("null")) {
setText(cbbx.toString());
}
} catch (Exception e) {
}
setGraphic(null);
}
@Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
setText(null);
setGraphic(cbbx);
} else {
if (getItem() != null && cbbx != null) {
setText(cbbx.toString());
} else {
setText(null);
}
setGraphic(null);
}
}
}
private void createTextField() {
final double width = this.getWidth() - this.getGraphicTextGap() * 2;
cbbx = new CbbxEditSuppr((ObservableList<String>) listValues, width);
if (isSelectFirst) {
cbbx.getSelectionModel().selectFirst();
}
cbbx.setMinWidth(width);
cbbx.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit((T) cbbx.getItems());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
cbbx.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (!newValue) {
commitEdit((T) cbbx.getItems());
}
}
});
}
public void selectFirstItem() {
isSelectFirst = true;
}
}