Свойство элементов списка привязки javafx

Я настроил поле со списком, чтобы добавлять и удалять элементы в поле со списком. Теперь я бы привязал свой настроенный список со списком, но он не работает, и я не понимаю, что происходит.

Вот мой пример примера:

public class CbbxEditSuppr extends ComboBox<BoxItem> {

private TextField editor = null;
private ObservableList<BoxItem> items = null;



/**
 * 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.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.getBtn());
                        setText(t.getItem());
                    } 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.getItem();
            }
        }
        @Override
        public BoxItem fromString(String id) {
            if (id != null) {
                final BoxItem box = new BoxItem(id, items);
                return box;
            } else {
                return null;
            }

        }
    });
    // 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());
                    editor.clear();
                }
            } else if  (event != null && event.getCode().equals(KeyCode.DOWN)) {
                showPopUpMenu();
            }
        }
    });
    // propriétés editable et selection du premier element
    this.setEditable(true);
    /* 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);
                items.add(hbox);
            }
        }
    }
    this.getSelectionModel().selectFirst();
}

private void showPopUpMenu(){
    if (!this.isShowing()) {
        this.show();
    }
}

/**
 * Ajoute un item à la liste
 * 
 * @param stg String nom de l'item
 */
public void addItem(String stg) {
    if (stg != null) {
        items.add(new BoxItem(stg, items));
    }
}


/**
 * 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.getItem());
                if (!item.equals(lastItem)) {
                    stgBuilder.append(", ");
                }
            }
        }
    }
    stgBuilder.append(" ]");
    return stgBuilder.toString();

}
}

и

public class ComboboxSample extends Application {

    public static void main(String[] args) {
     launch(args);
}


@Override
public void start(Stage stage) {
    stage.setTitle("ComboBoxSample");
    Scene scene = new Scene(new Group(), 450, 250);

    CbbxEditSuppr cbboxLeft = new CbbxEditSuppr(FXCollections.observableArrayList(new ArrayList()), 200);
    CbbxEditSuppr cbboxRight = new CbbxEditSuppr(FXCollections.observableArrayList(new ArrayList()), 200);

    cbboxLeft.itemsProperty().bindBidirectional(cbboxRight.itemsProperty());
    GridPane grid = new GridPane();
    grid.setVgap(4);
    grid.setHgap(10);
    grid.setPadding(new Insets(5, 5, 5, 5));
    grid.add(new Label("To: "), 0, 0);
    grid.add(cbboxLeft, 1, 0);
    grid.add(cbboxRight, 2, 0);

    Group root = (Group) scene.getRoot();
    root.getChildren().add(grid);
    stage.setScene(scene);
    stage.show();

}
}

Когда я добавляю значение в правое поле со списком, оно работает, но не в левом поле со списком. У вас есть какие-нибудь советы, пожалуйста?


person Nono    schedule 13.11.2014    source источник
comment
Что работает, а что не работает? Чего вы ожидали и как оно себя ведет? У вас есть ошибки? Если да, то есть ли у вас трассировка стека?   -  person Lajos Arpad    schedule 13.11.2014
comment
В моем примере показано 2 выпадающих списка: comboboxLeft и comboboxright. Это поле со списком привязано. У меня нет трассировки стека, моя проблема связана с поведением поля со списком. Когда я пишу в правильном поле со списком и нажимаю ENTER, текст добавляется как элемент в поле со списком. Этот элемент добавляется в оба списка. Теперь, когда я делаю то же самое в левом поле со списком, элемент не добавляется в поле со списком. Это моя проблема. привязка работает только в одну сторону :(   -  person Nono    schedule 13.11.2014


Ответы (1)


Проблема в том, что вы «затеняете» поле items. В подклассе вашего поля со списком есть два свойства, называемых items: одно вы определяете, а другое наследуете. Когда вы вызываете itemsProperty(), вы получаете свойство, обертывающее унаследованное items, и вы привязываетесь к нему. Затем в реализации вашего класса вы ссылаетесь на теневое поле items, которое не связано.

Вы должны полностью удалить поле items из своего класса и просто обратиться к унаследованному, вызвав getItems().

Например, сделать

if (addedItems != null && addedItems.size() > 0) {
    for (String stg : addedItems) {
        if (stg != null) {
            final BoxItem hbox = new BoxItem(stg, items);
            getItems().add(hbox);
        }
    }
}
person James_D    schedule 17.11.2014