我理解你的问题。在 Listview
中有主要两种设置项的方式:
1. 创建 ObservableList
并使用 ObservableList
来设置 ListView
的项 (listView.setItems(observableList)
)。
2. 使用 ListView
类的 setCellFactory()
方法。
你会更倾向于使用 setCellFactory()
方法,因为这种方法简化了过程并帮助将业务逻辑和 UI(FXML)分离。
以下是更详细的说明:
1. 创建一个名为listview.fxml
的新FXML文件以包含 ListView
,并将 ListViewController
类设置为其控制器:
文件:listview.fxml:
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.ListView?>
<?import demo.ListViewController?>
<GridPane xmlns:fx="http://javafx.com/fxml" alignment="CENTER">
<ListView fx:id="listView"/>
</GridPane>
2. 创建控制器并将其命名为 ListViewController
。
控制器可以加载 listview.fxml
文件并访问 listview
。
文件: ListViewController.java:
package demo;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.util.Callback;
import java.io.IOException;
import java.util.Set;
public class ListViewController
{
@FXML
private ListView listView;
private Set<String> stringSet;
ObservableList observableList = FXCollections.observableArrayList();
public ListViewController()
{
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/listview.fxml"));
fxmlLoader.setController(this);
try
{
Parent parent = (Parent)fxmlLoader.load();
Scene scene = new Scene(parent, 400.0 ,500.0);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
public void setListView()
{
stringSet.add("String 1");
stringSet.add("String 2");
stringSet.add("String 3");
stringSet.add("String 4");
observableList.setAll(stringSet);
listView.setItems(observableList);
listView.setCellFactory(new Callback<ListView<String>, javafx.scene.control.ListCell<String>>()
{
@Override
public ListCell<String> call(ListView<String> listView)
{
return new ListViewCell();
}
});
}
}
3. 首先,您需要设置ObservableList
的值。这非常重要。
然后,使用ObservableList
设置列表项,并在ListView
上调用setCellFactory()
方法。在给定的示例中,我只是将String
值添加到String
集合中(Set<String> stringSet
)。
4. 当在ListView
上调用setCellFactory()
方法时,它将返回ListCell
。为了简单起见,我添加了一个扩展ListCell
的类,并且ListCell()
中有setGraphic()
方法,将为ListCell
设置项目。
文件:ListViewCell.java
package demo;
import javafx.scene.control.ListCell;
public class ListViewCell extends ListCell<String>
{
@Override
public void updateItem(String string, boolean empty)
{
super.updateItem(string,empty);
if(string != null)
{
Data data = new Data();
data.setInfo(string);
setGraphic(data.getBox());
}
}
}
5. 我刚刚添加了一个类,它将加载listCellItem.fxml
并返回HBox
,该HBox
将包含其他组件作为子项。
然后将HBox
设置为ListCell
。
文件:listCellItem.fxml:
<?import demo.Data?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Label?>
<HBox xmlns:fx="http://javafx.com/fxml" fx:id="hBox">
<children>
<Label fx:id="label1"/>
<Label fx:id="label2"/>
</children>
</HBox>
文件:Data.java:
package demo;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import java.io.IOException;
public class Data
{
@FXML
private HBox hBox;
@FXML
private Label label1;
@FXML
private Label label2;
public Data()
{
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/listCellItem.fxml"));
fxmlLoader.setController(this);
try
{
fxmlLoader.load();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
public void setInfo(String string)
{
label1.setText(string);
label2.setText(string);
}
public HBox getBox()
{
return hBox;
}
}
使用这种方式,您可以使用setCellFactory()
方法分离业务逻辑和FXML。
希望这对您有所帮助。