我想知道是否有可能在每個ListView項目之後添加圖像按鈕。例如:JavaFX - 具有圖像按鈕的ListView項目
其中那些紅色方塊應該有一個按鈕。如果可能,我該如何處理項目按鈕的點擊事件?
編輯:如果有另一個控件可以做到這一點,請讓我知道。我正在測試TableView。
在此先感謝!
我想知道是否有可能在每個ListView項目之後添加圖像按鈕。例如:JavaFX - 具有圖像按鈕的ListView項目
其中那些紅色方塊應該有一個按鈕。如果可能,我該如何處理項目按鈕的點擊事件?
編輯:如果有另一個控件可以做到這一點,請讓我知道。我正在測試TableView。
在此先感謝!
我最近測試了這個。我的解決辦法:
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);
}
}
細胞將是這樣的:
相關部分是XCell.updateItem
方法和setGraphic
通話。通過setGraphic()
通常應爲標籤設置一個圖標,但它同樣適用於設置複雜的節點 - 在這種情況下,帶有標籤和按鈕的HBox。
您需要確保Button的事件處理程序引用了列表中的正確項目。在下面的第一個鏈接中提到,目前選擇的項目可能已經足夠。因此,在處理按鈕的事件時,請取出列表中當前選定的索引。
你可能想看看這些:
以前的解決方案工作得很好,當我的名單並不大,我並沒有增加更多的控制使得節點更復雜。當我添加更多控件時,我發現併發問題,也可能是因爲我繪製的地圖有12000多個對象(線條和多邊形)。問題(我可以看到)是ListView中的一些項目將在內部重複,這意味着cellfactory將被創建兩次和/或未創建。看起來「updateItem」是線程隊列中的最後一個。 所以要解決這個問題,我必須在創建ListView之前創建節點。事情是這樣的:
ObservableList<Node> list = FXCollections.observableArrayList();
for (AisaLayer layer : listLayers) {
mapLayers.put(layer.getLayerName(), layer);
list.add(new AisaNode(layer));
System.out.println("Ordered:" + layer.getLayerName());
}
lv.setItems(list);
lv.setCellFactory(new Callback<ListView<Node>, ListCell<Node>>() {
@Override
public ListCell<Node> call(ListView<Node> param) {
return new DefaultListCell<>();
}
});
我用簡單的DefaultListCell在fxexperience.com
您也可以使用自定義HBox中對象的列表建議。下面的例子展示瞭如何使用這種定製的HBox內部類以及將這些對象的嵌套列表過程用於ListView控件。
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;
public class ListViewDemo extends Application {
public static class HBoxCell extends HBox {
Label label = new Label();
Button button = new Button();
HBoxCell(String labelText, String buttonText) {
super();
label.setText(labelText);
label.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(label, Priority.ALWAYS);
button.setText(buttonText);
this.getChildren().addAll(label, button);
}
}
public Parent createContent() {
BorderPane layout = new BorderPane();
List<HBoxCell> list = new ArrayList<>();
for (int i = 0; i < 12; i++) {
list.add(new HBoxCell("Item " + i, "Button " + i));
}
ListView<HBoxCell> listView = new ListView<HBoxCell>();
ObservableList<HBoxCell> myObservableList = FXCollections.observableList(list);
listView.setItems(myObservableList);
layout.setCenter(listView);
return layout;
}
@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createContent()));
stage.setWidth(300);
stage.setHeight(200);
stage.show();
}
public static void main(String args[]) {
launch(args);
}
}
這個實現的結果是這樣的:
然而,爲了功效管理按鈕事件,你應該增加額外的自定義按鈕對象爲HBoxCustom構造方法考慮,並創建一個適當的方法,這將允許您控制按鈕點擊事件。
優秀!非常感謝編碼!工作得很好! – Leonardo 2013-04-01 15:17:49
沒有必要將當前項存儲在'lastItem'字段中。你可以直接在按鈕處理程序中調用'getItem()'。 – 2016-12-05 16:32:41