我正在尝试使用fxml填充列表视图,但在运行我的程序时,方法setCellFactory
以某种方式不会被我的ListView
调用。
是否有人可以帮助我解释如何修复我的代码?
listviewContoller.java - >
public class ListViewController implements Initializable {
@SuppressWarnings("rawtypes")
@FXML
private ListView listView;
private ArrayList<String> arrayList = new ArrayList<>();
@SuppressWarnings("rawtypes")
ObservableList observableList = FXCollections.observableArrayList();
@SuppressWarnings("unchecked")
@Override
public void initialize(URL location, ResourceBundle resources) {
arrayList.add("String 1");
arrayList.add("String 2");
arrayList.add("String 3");
arrayList.add("String 4");
observableList.setAll(arrayList);
listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
@Override
public ListCell<String> call(ListView<String> param) {
return new ListViewCell();
}
});
}
}
ListViewCell.java - &gt;
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());
} else {
Data data = new Data();
data.setInfo("AAAA");
setGraphic(data.getBox());
}
}
}
Data.java - &gt;
public class Data implements Initializable{
@FXML
private HBox hBox;
@FXML
private ImageView imageListCell;
@FXML
private Label labelListCell;
@Override
public void initialize(URL location, ResourceBundle resources) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/Tracker/UI/listCellItem.fxml"));
try {
loader.load();
} catch (IOException e){
throw new RuntimeException(e);
}
}
public void setInfo(String string) {
labelListCell.setText(string);
}
public HBox getBox() {
return hBox;
}
}
答案 0 :(得分:2)
setCellFactory
,但您使用的是不以任何方式显示内容的单元格:
创建Data
的实例不会加载fxml,如果没有加载fxml,getBox()
将始终返回null
。
Data
以避免重新加载fxml是个好主意。
通常在这种情况下,您可以使用从fxml加载的内容创建自定义Node
类型:
public class Data extends HBox {
public Data() {
// load fxml here
FXMLLoader loader = new FXMLLoader(getClass().getResource("/Tracker/UI/listCellItem.fxml"));
loader.setController(this);
loader.setRoot(this);
try {
loader.load();
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
@FXML
private ImageView imageListCell;
@FXML
private Label labelListCell;
public void setInfo(String string) {
labelListCell.setText(string);
}
}
<强> listCellItem.fxml 强>
<!-- no fx:controller attribute allowed here -->
<fx:root type="javafx.scene.layout.HBox" xmlns:fx="http://javafx.com/fxml/1">
<!-- contents of the root tag of the old fxml should be copied here -->
</fx:root>
请注意,您还应复制旧fxml的根元素的所有属性,但要复制fx:controller
属性。
public class ListViewCell extends ListCell<String> {
private final Data data;
public ListViewCell() {
this.data = new Data();
setGraphic(this.data);
}
@Override
public void updateItem(String string, boolean empty) {
super.updateItem(string, empty);
data.setInfo(string == null ? "AAAA" : string);
}
}
此外,您从未设置items
属性的新值:
@Override
public void initialize(URL location, ResourceBundle resources) {
arrayList.add("String 1");
arrayList.add("String 2");
arrayList.add("String 3");
arrayList.add("String 4");
observableList.setAll(arrayList);
listView.setItems(observableList);
...
}
此外,为什么不简单地添加@SuppressWarnings("rawtypes")
作为类型参数???
@SuppressWarnings("unchecked")
和<String>
。
答案 1 :(得分:0)
您可以直接在列表视图中添加对象
在下面的示例中,我在fxml中创建了一个列表项,并使用for循环在列表视图中添加该项
参见示例
的来源ListViewExample FXML代码
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="389.0" prefWidth="471.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="customlistview.ListViewExampleController">
<children>
<ListView fx:id="listView" layoutX="14.0" layoutY="14.0" prefHeight="389.0" prefWidth="517.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
ListViewExampleController代码
package customlistview;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.util.Callback;
import javafx.scene.layout.Pane;
/**
*
* @author hemant-pc
*/
public class ListViewExample implements Initializable {
@FXML
private ListView listView;
@FXML
Pane pane;
public ListViewExample() {
}
@Override
public void initialize(URL url, ResourceBundle rb) {
try {
ObservableList<Pane> list = FXCollections.observableArrayList();
for (int i = 1; i <= 10; i++) {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ListItem.fxml"));
Pane listItem = fxmlLoader.load();
ListItemController controller = fxmlLoader.getController();
controller.setText("List Item " + i);
list.add(listItem);
}
listView.getItems().addAll(list);
} catch (IOException ex) {
Logger.getLogger(ListViewExample.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
ListItem FXML代码
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>
<Pane fx:id="pane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="65.0" prefWidth="317.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="customlistview.ListItemController">
<children>
<Label fx:id="label" layoutX="35.0" layoutY="6.0" prefHeight="50.0" prefWidth="117.0" text="ListItem1" />
<Button fx:id="button" layoutX="201.0" layoutY="19.0" mnemonicParsing="false" onAction="#ButtonClick" text="Button" />
</children>
</Pane>
ListItemController代码
package customlistview;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
import javafx.scene.control.Label;
/**
* FXML Controller class
*
* @author hemant-pc
*/
public class ListItemController implements Initializable {
@FXML
Label label;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
@FXML
public void ButtonClick(ActionEvent event) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setContentText(label.getText());
alert.showAndWait();
}
public void setText(String string) {
label.setText(string);
}
public String getText() {
return label.getText();
}
}
<强>快照强>