Как мне заполнить комбинированный список наблюдаемым массивом? - PullRequest
0 голосов
/ 14 марта 2019

Я создаю систему кинематографа, в которой пользователь должен иметь возможность выбирать фильм через выпадающий список на главной странице. Я создал список Array в классе FilmController, а затем преобразовал его в observableList и пытаюсь заполнить его содержимое в выпадающем списке (HomepageController).

Это FilmController с arraylist & observableList

public class FilmController {

private ArrayList<Film> films = new ArrayList<>();

public FilmController() {
    Film f1 = new Film("Avatar", "James Cameron", "James Cameron",
            "Sam Wortherington" + "Zoe Saldana", "162", "Sci-Fi", 8.50);

    Film f2 = new Film("Black Panther", "Kevin Feige", "Ryan Coogler",
            "Chadwick Boseman" + "Lupita Nyong'o", "135", "Sci-Fi Fantasy", 10.00);

    Film f3 = new Film("Creed 2", "Sylvester Stallone", "Steven Caple Jr",
            "Michael B Jordan" + "Tessa Thompson", "130", "Drama", 10.00);

    Film f4 = new Film("Deadpool", "Simon Kinberg", "Tim Miller",
            "Ryan Reynolds" + "Morena Baccarin", "109", "Sci-Fi", 7.50);

    Film f5 = new Film("A Quiet Place", "Michel Bay", "John Krasinski",
            "Emily Blunt" + "John Krasinski", "91", "Thriller", 8.00);

    films.add(f1);
    films.add(f2);
    films.add(f3);
    films.add(f4);
    films.add(f5);
}

public ArrayList<Film> getFilms() {
    return films;
}

public ObservableList<Film> getOlFilms() {
    return FXCollections.observableArrayList(films);

   }
}

Я пытался реализовать это в HomepageController, но, похоже, выдает ошибку:

  public class HomepageController {

        public ComboBox cbFilms;

public void initialize() { 
cbFilms.setButtonCell((ListCell) cbFilms.getCellFactory().call(null)); 
}

public void cbListFilms(ActionEvent actionEvent) {
        FilmController f = new FilmController();
        cbFilms.setItems(f.getOlFilms().toArray());
    } 
}

Я посмотрел на этот вопрос , но, похоже, он мне не подходит.

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

Это содержимое fxml для выпадающего списка:

    <ComboBox fx:id="cbFilms" layoutX="291.0" layoutY="138.0" onAction="#cbListFilms" prefHeight="31.0" prefWidth="230.0"
          promptText="Please select film by name" style="-fx-background-color: tan;">
    <items>
        <FXCollections fx:factory="observableArrayList"/>
    </items>
    <effect>
        <SepiaTone/>
    </effect>
</ComboBox>

Ответы [ 2 ]

2 голосов
/ 14 марта 2019

Вам не нужно / не нужно вызывать метод .toArray() для ObservableList.Метод ComboBox.setItems() требует ObservableList очень хорошо:

cbFilms.setItems(f.getOlFilms());

Затем, чтобы ComboBox отображал только название фильма, вам нужно установить StringConverter на ComboBox.StringConverter в основном берет объект и возвращает его String представление:

cbFilms.setConverter(new StringConverter<Film>() {
    @Override
    public String toString(Film film) {
        return film.getTitle();
    }

    @Override
    public Film fromString(String string) {
        return null;
    }
});

Вот полный пример, который вы можете проверить:

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class SimpleComboBoxExample extends Application {

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

    @Override
    public void start(Stage primaryStage) {

        // Simple interface
        VBox root = new VBox(5);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);

        // Create some sample data
        ObservableList<Film> filmsList = FXCollections.observableArrayList();
        filmsList.add(new Film("Titanic", "James Cameron"));
        filmsList.add(new Film("Jaws", "Steven Spielberg"));
        filmsList.add(new Film("The Last Samurai", "Edward Zwick"));

        // Define our ComboBox with our data model as its type
        ComboBox<Film> cboFilms = new ComboBox<>();

        // Use a StringConverter to configure our ComboBox to display only the film's title
        cboFilms.setConverter(new StringConverter<Film>() {
            @Override
            public String toString(Film film) {
                return film.getTitle();
            }

            @Override
            public Film fromString(String string) {
                return null;
            }
        });

        // Finally, set our ComboBox's items to our sample list
        cboFilms.setItems(filmsList);

        root.getChildren().add(cboFilms);

        // Show the Stage
        primaryStage.setWidth(300);
        primaryStage.setHeight(300);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}

// Our data model class
class Film {

    private StringProperty title = new SimpleStringProperty();
    private StringProperty director = new SimpleStringProperty();

    public Film(String title, String director) {
        this.title.set(title);
        this.director.set(director);
    }

    public String getTitle() {
        return title.get();
    }

    public StringProperty titleProperty() {
        return title;
    }

    public String getDirector() {
        return director.get();
    }

    public StringProperty directorProperty() {
        return director;
    }
}

Результат:

screenshot

2 голосов
/ 14 марта 2019

Вы должны установить CellFactory, который обрабатывает все элементы в вашем ComboBox:

ComboBox<Film> comboBox = new ComboBox<>();
comboBox.setItems(f.getOlFilms());
comboBox.setCellFactory(param -> new ListCell<Film>() {
    @Override
    protected void updateItem(Film item, boolean empty) {
        super.updateItem(item, empty);
        if (item != null) {
            setText(item.getName());
        } else {
            // handle null object
        }
    }
});

Дополнительно вы должны установить ButtonCell для выбранного элемента.Вы можете либо создать собственный ListCell для этого, чтобы добавить больше данных в представление, либо использовать то же, что и для элементов:

comboBox.setButtonCell(comboBox.getCellFactory().call(null));

В качестве альтернативы значению nullвы можете передать значение по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...