Конвертировать ArrayList в список наблюдаемых для программы JavaFX?
Я начинающий Java-программист, изучаю Java FX из разных источников. В моей программе я хотел бы создать ComboBox и заполнить выборки выводом toString() серии объектов из ArrayList. Здесь начинки пиццы определяются как объект. Они создаются и хранятся в объекте PizzaMgr, в основном прославленной обертке для ArrayList:
public class Topping{
private String name;
public Topping(String a){
this.name=a;
}
public String toString(){
return this.name;
}
}
//=================================================
import java.util.ArrayList;
public class PizzaMgr{
private ArrayList<Topping> OrderedToppings;
public PizzaMgr(){
OrderedToppings = new ArrayList<Topping>();
OrderedToppings.add(new Topping("Pepperoni"));
OrderedToppings.add(new Topping("Mushrooms"));
OrderedToppings.add(new Topping("Onions"));
}
public ArrayList<Topping> getList(){
return OrderedToppings;
}
}
Все идет нормально. Но неприятность возникает, когда я хочу, чтобы ComboBox перечислил все эти элементы в ArrayList от PizzaMgr. В идеале я хотел бы использовать этот конструктор ComboBox:
ComboBox<T>(ObservableList<T> items)
Эта проблема? Как извлечь все элементы ArrayList в список наблюдаемых? Я читал Arraylists, Observable Lists, интерфейсы в целом, но я не могу понять, как заставить это работать. Я читал, что ArrayList является коллекцией, а Observable List может быть интерфейсом к коллекции, поэтому я подумал, что я свободен дома. Тем не менее, когда я пытаюсь реализовать конструктор ComboBox:
import javafx.scene.control.*;
public class Menu{
public static void main(String[] args){
PizzaMgr m = new PizzaMgr();
ComboBox<Topping> topMenu = new ComboBox<Topping>(m.getList());
}
}
Я получаю ошибку компилятора:
Menu.java:18: error: incompatible types: ArrayList<Topping> cannot be converted to ObservableList<Topping>
ComboBox<Topping> topMenu = new ComboBox<Topping>(m.getList());
^
Поэтому очевидно, что мой ArrayList не рассматривается как список наблюдаемых.
Что меня озадачивает: как я могу представить свой ArrayList конструктору ComboBox, чтобы он выглядел как наблюдаемый список? Это слабый синтаксис? Или мне нужно заранее преобразовать ArrayList в другую структуру данных?
Большое спасибо, -RAO
3 ответа
ObservableList
субинтерфейс (специализированная версия) List
, (ObservableList
добавляет функциональность для наблюдения за изменениями в списке.) ArrayList
это конкретная реализация List
, но не является реализацией ObservableList
, Следовательно, вы можете передать ArrayList
где-нибудь List
ожидается, но вы не можете передать ArrayList
если ObservableList
ожидается.
Обратите внимание на то, что на самом деле не рекомендуется раскрывать тип реализации, но вы должны просто указать тип интерфейса:
import java.util.List;
import java.util.ArrayList;
public class PizzaMgr{
private List<Topping> orderedToppings;
public PizzaMgr(){
orderedToppings = new ArrayList<Topping>();
orderedToppings.add(new Topping("Pepperoni"));
orderedToppings.add(new Topping("Mushrooms"));
orderedToppings.add(new Topping("Onions"));
}
public List<Topping> getList(){
return orderedToppings;
}
}
Чтобы создать ObservableList
от обычного List
, ты можешь использовать
ComboBox<Topping> topMenu
= new ComboBox<Topping>(FXCollections.observableList(m.getList()));
который создает новый ObservableList
который "оборачивает" список массивов, который вы предоставляете. Т.е. зовет get(index)
или же add(item)
в наблюдаемом списке просто делегаты в список, который вы предоставляете.
Вы могли бы также сделать
ComboBox<Topping> topMenu
= new ComboBox<Topping>(FXCollections.observableArrayList(m.getList()));
который создаст новый наблюдаемый список и скопирует в него все элементы из списка, который вы предоставляете. Поэтому последующее управление одним списком не изменит другого.
Чтобы создать observableList
Прежде всего, необходимо иметь заранее определенный список, например arrayList
, Передать список экземпляру observableList
как показано ниже...
//Assuming you had this for a list
List<String> list = new ArrayList<String>();
//Pass it over in this manner
ObservableList<String> observableList = FXCollections.observableList(list);
//Then add a listener
observableList.addListener (new ListChangeListener() {
//override the method here
}
Надеюсь, это поможет...
ArrayList<Site> sites = new ArrayList < Site > ();
sites.add(new Site("Google", "http://www.google.com"));
ObservableList<Site> siteList = FXCollections.observableArrayList(sites);
final ComboBox comboBox = new ComboBox(siteList);
Button btn = new Button();
btn.setText("Read comboBox");
btn.setOnAction(new EventHandler < ActionEvent > () {
@Override
public void handle(ActionEvent event) {
label.setText("selected: " + comboBox.getValue());
Site site = (Site) comboBox.getSelectionModel().getSelectedItem();
System.out.println(site.name);
}
});