Преобразовать 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 — это коллекция, а наблюдаемый список может быть интерфейсом к коллекции, поэтому я думал, что свободен дома. Однако, когда я пытаюсь реализовать конструктор 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 в другую структуру данных?

Большое спасибо, -РАО


person Pete    schedule 14.04.2016    source источник


Ответы (2)


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()));

который создаст новый наблюдаемый список и скопирует в него все элементы из предоставленного вами списка. Таким образом, последующее манипулирование одним списком не изменит другой.

person James_D    schedule 14.04.2016
comment
Оно работает!!! Так круто!!! Я сейчас на седьмом небе от счастья, ты не представляешь. Миллион благодарностей, это действительно здорово. :) - person Pete; 14.04.2016

Чтобы создать 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
}

Надеюсь поможет...

person Marvin Nyalik    schedule 10.10.2017