我正在创建一个电影系统,借此用户应该能够通过主页中的组合框选择电影。我在FilmController类中创建了一个Array列表,然后将其转换为observableList,并努力在组合框(HomepageController)中填充其内容。
这是具有arraylist和observableList的FilmController
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());
}
}
我看过this question,但是它似乎对我没有用。
我希望组合框仅列出影片名称,最好是当鼠标悬停在影片名称上时,如果可能的话,我希望它显示其余属性。
这是组合框的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>
答案 0 :(得分:2)
您应该设置一个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
值的替代方法,您可以在其中传递默认值。
答案 1 :(得分:2)
您不需要/不想在.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;
}
}
结果: