Ya no necesitas investigar más por todo internet porque llegaste al sitio adecuado, poseemos la respuesta que quieres recibir pero sin complicarte.
Solución:
Entiendo tu pregunta. Hay principalmente dos formas de configurar elementos en una Listview
:
1. Crea el ObservableList
y configurar los elementos del ListView
con el ObservableList
(listView.setItems(observableList)
).
2. Utilizar el setCellFactory()
método del ListView
clase.
Preferiría utilizar el setCellFactory()
método, porque este enfoque simplifica el proceso y ayuda a separar la lógica empresarial y la interfaz de usuario (FXML).
Aquí hay una explicación más detallada:
1. Cree un nuevo archivo FXML con el nombre listview.fxml
para contener el ListView
y establezca el ListViewController
class como su controlador:
Expediente: listview.fxml:
2. Crea el controlador y asígnale un nombre ListViewController
.
El controlador puede cargar el listview.fxml
archivo y acceder al listview
.
Expediente: 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 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, javafx.scene.control.ListCell>()
@Override
public ListCell call(ListView listView)
return new ListViewCell();
);
3. Primero debe establecer el valor de la ObservableList
. Esto es muy importante.
Luego, configure los elementos de la lista usando el ObservableList
y llama al setCellFactory()
método en el ListView
. En el ejemplo dado, solo tomo el String
valores y añádalos al String
selecciona el Set
).
4. Cuando el setCellFactory()
se llama al método en el ListView
, devolverá el ListCell
. Entonces, en aras de la simplicidad, agregué una clase que extiende el ListCell
, y el setGraphic()
El método está presente para el ListCell()
y establecerá los elementos del ListCell
.
Expediente: ListViewCell.java:
package demo;
import javafx.scene.control.ListCell;
public class ListViewCell extends ListCell
@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. Acabo de agregar una clase que cargará el listCellItem.fxml
y devuelve el HBox
, que contendrá los otros componentes como hijos.
los HBox
luego se establece en el ListCell
.
Expediente: listCellItem.fxml:
Expediente: 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;
De esta manera, puede utilizar el setCellFactory()
método para separar las cosas que son lógica empresarial y FXML.
Espero que esto sea de ayuda.
El ejemplo anterior de @Anvay necesita un par de ajustes para funcionar. Estas son cosas sencillas de poner en marcha.
- ListViewController debe ejecutarse en el hilo de la aplicación JavaFX.
- Solo puede llamar a los elementos @FXML inyectados desde JavaFX inicializar() método
- Necesito llamar a setListView ()
- El stringSet del ejemplo debe asignarse con un nuevo antes de llamar a setListView ().
El ListViewController a continuación funciona con estos cambios. Cambié “stringSet“a una lista”,stringList“. El controlador es más o menos el controlador de muestra proporcionado por Constructor de escenas 2
public class ListViewController
@FXML private ResourceBundle resources;
@FXML private URL location;
@FXML private ListView listView;
private List stringList = new ArrayList<>(5);
private ObservableList observableList = FXCollections.observableArrayList();
public void setListView()
stringList.add("String 1");
stringList.add("String 2");
stringList.add("String 3");
stringList.add("String 4");
observableList.setAll(stringList);
listView.setItems(observableList);
listView.setCellFactory(
new Callback, javafx.scene.control.ListCell>()
@Override
public ListCell call(ListView listView)
return new ListViewCell();
);
@FXML
void initialize()
assert listView != null : "fx:id="listView" was not injected: check your FXML file 'CustomList.fxml'.";
setListView();
//ListViewController
La plataforma JavaFX debe iniciarse en el método main () desde una aplicación JavaFX. Netbeans proporciona convenientemente la mayor parte de esta estructura desde la plantilla de aplicación Maven JavaFX.
public class MainApp extends Application
@Override
public void start(Stage stage) throws Exception
Parent root = FXMLLoader.load(getClass().getResource("/fxml/CustomList.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add("/styles/Styles.css");
stage.setTitle("CustomList");
stage.setScene(scene);
stage.show();
/**
* The main() method is ignored in correctly deployed JavaFX application.
*
* @param args the command line arguments
**/
public static void main(String[] args)
launch(args);
La respuesta de Anvay por alguna razón no funcionó para mí, lo que tuve que hacer para solucionarlo fueron solo algunos ajustes muy pequeños:
- eliminar la declaración de datos de importación de listCellItem.fxml
- como dice el comentario debajo de la publicación en Data.java poner hBox = fmxlLoader.load ()
-
También tenía una clase principal (intellij autogenerada).
public class MainMain extends Application { @Override public void start(Stage primaryStage) throws Exception FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("MainController.fxml")); try Parent root = fxmlLoader.load(); Scene scene = new Scene(root); primaryStage.setScene(scene); primaryStage.setTitle("Title"); primaryStage.show(); catch (IOException e) throw new RuntimeException(e); public static void main(String[] args) launch(args);
Sé que esto probablemente era obvio para la mayoría de los expertos aquí, pero estos problemas me dejaron perplejo durante horas mientras depuraba.
Si haces scroll puedes encontrar las explicaciones de otros desarrolladores, tú asimismo tienes el poder mostrar el tuyo si te gusta.