Ich habe dies kürzlich getestet. Meine Lösung:
Der relevante Teil ist die XCell.updateItem
Methode und der setGraphic
Aufruf:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class SO extends Application {
static class XCell extends ListCell<String> {
HBox hbox = new HBox();
Label label = new Label("(empty)");
Pane pane = new Pane();
Button button = new Button("(>)");
String lastItem;
public XCell() {
super();
hbox.getChildren().addAll(label, pane, button);
HBox.setHgrow(pane, Priority.ALWAYS);
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println(lastItem + " : " + event);
}
});
}
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setText(null); // No text in label of super class
if (empty) {
lastItem = null;
setGraphic(null);
} else {
lastItem = item;
label.setText(item!=null ? item : "<null>");
setGraphic(hbox);
}
}
}
@Override
public void start(Stage primaryStage) throws Exception {
StackPane pane = new StackPane();
Scene scene = new Scene(pane, 300, 150);
primaryStage.setScene(scene);
ObservableList<String> list = FXCollections.observableArrayList(
"Item 1", "Item 2", "Item 3", "Item 4");
ListView<String> lv = new ListView<>(list);
lv.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
@Override
public ListCell<String> call(ListView<String> param) {
return new XCell();
}
});
pane.getChildren().add(lv);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Die Zellen werden wie folgt aussehen. Mit setGraphic()
sollte normalerweise ein Icon für ein Label gesetzt werden, aber es funktioniert genauso gut einen komplexen Knoten zu setzen - in diesem Fall die HBox mit Label und Button.
Sie müssen sicherstellen, dass der Ereignishandler der Schaltfläche auf das richtige Element in der Liste verweist. Im ersten Link unten wird erwähnt, dass der aktuell ausgewählte Gegenstand vorerst ausreichen könnte. Rufen Sie den aktuell ausgewählten Index in der Liste ab, wenn Sie das Ereignis der Schaltfläche behandeln.
Vielleicht möchten Sie auf diese aussehen:
Ausgezeichnet! Vielen Dank für die Codierung! Arbeitete gut! – Leonardo
Das aktuelle Element muss nicht in einem 'lastItem'-Feld gespeichert werden. Sie können 'getItem()' direkt im Button-Handler aufrufen. –