Конвертировать 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);
    }
});
Другие вопросы по тегам