2013-04-25 4 views
3

У меня есть ObservableList<MyElement> list = FXCollections.observableArrayList();Как связать позицию в списке с атрибутом этого элемента?

public class MyElement 
{ 
    private IntegerProperty position;//with getter 
    //[...] 

    //somewhere in the constructor taking the list as argument 
    position.bind(list.indexOf(this)); 
} 

Теперь я хотел бы связать MyElement.position с фактическим положением в списке, т.е. если изменения позиции в списке (например, перетаскиванием в GUI или что-нибудь еще) Я хочу, чтобы свойство position обновлялось автоматически.

Возможно ли это? Могу ли я сделать двунаправленную привязку между этими значениями?

+1

Я думаю, вы должны добавить listChangeListener и послушать изменения в списке. Если произойдет какое-то интересное изменение - обновите свою собственность. –

+1

попробуйте этот пример: [listview DnD Example] (http://blog.ngopal.com.np/2012/05/06/javafx-drag-and-drop-cell-in-listview/) – Kalaschni

ответ

2

Я не знаю, правильно ли я понял ваш вопрос, но я постараюсь ответить на него :-).

Дело в том, что если объект ObservableList (javafx.collections) не хранит какое-то «выбранное» состояние индекса, зачем нам связывать с ним другое целое число?

Я думаю, что в этом случае ваш код должен отвечать за сохранение «выбранного» состояния индекса и выставить его на клиентский код. Если это то, что вы ищете, то я предлагаю вам три атрибуты для борьбы с ним:

public class ListSelection<T> { 
    private ObservableList<T> items = FXCollections.observableArrayList(new ArrayList<T>()); 
    private ObjectProperty<T> selectedItem = new SimpleObjectProperty<>(); 
    private IntegerProperty selectedIndex = new SimpleIntegerProperty(0); 
} 

Выбранный элемент можно управлять с помощью атрибута selectedIndex.

Затем создайте привязку к selectedItem, чтобы "автоматически" обновлять при selectedIndex изменения:

selectedItem.bind(
    when(isEmpty(items)) 
     .then(new SimpleObjectProperty<T>()) 
     .otherwise(valueAt(items, selectedIndex)) 
); 

Bindings должны были импортированы статически:

import static javafx.beans.binding.Bindings.*; 

Обратите внимание на использование метода Bindings.valueAt(ObservableList<E> list, ObservableIntegerValue index) , Он создает привязку к элементу list.get(index.getValue()).

Наконец, вы можете использовать его как это:

ListSelection<String> selection = new ListSelection<>(); 
Label label = new Label(); 
List<String> weekDays = Arrays.asList("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"); 

selection.getItems().addAll(weekDays); 
label.textProperty().bind(selection.selectedItemProperty()); 

Я также предлагаю вам взглянуть на javafx.scene.control.SelectionModel класса и его подклассов (например javafx.scene.control.SingleSelectionModel.). Возможно, было бы легче расширить некоторые из них.