JavaFX-带有图像按钮的ListView项
我想知道是否有可能在每个ListView项目之后添加一个图像按钮。例如: 这些红色方块应该有一个按钮。如果可能,我如何处理项目按钮的单击事件 编辑:如果有其他控件可以这样做,请告诉我。我正在测试TableViewJavaFX-带有图像按钮的ListView项,listview,javafx,Listview,Javafx,我想知道是否有可能在每个ListView项目之后添加一个图像按钮。例如: 这些红色方块应该有一个按钮。如果可能,我如何处理项目按钮的单击事件 编辑:如果有其他控件可以这样做,请告诉我。我正在测试TableView 提前谢谢 我最近在测试这个。我的解决方案: import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList;
提前谢谢 我最近在测试这个。我的解决方案:
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);
}
}
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.Label;
导入javafx.scene.control.ListCell;
导入javafx.scene.control.ListView;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.Pane;
导入javafx.scene.layout.Priority;
导入javafx.scene.layout.StackPane;
导入javafx.stage.stage;
导入javafx.util.Callback;
公共类因此扩展了应用程序{
静态类XCell扩展了ListCell{
HBox HBox=新的HBox();
标签标签=新标签(“(空)”);
窗格=新窗格();
按钮按钮=新按钮(“(>)”);
字符串最后一项;
公共XCell(){
超级();
hbox.getChildren().addAll(标签、窗格、按钮);
HBox.setHgrow(窗格,Priority.ALWAYS);
setOnAction(新的EventHandler
当我的列表不大时,上一个解决方案运行良好,我没有添加更多控件使节点更复杂。当我添加更多控件时,我发现并发性存在问题,可能也是因为我正在绘制包含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<>();
}
});
observeList=FXCollections.observearraylist();
对于(AisLayer图层:listLayers){
放置(layer.getLayerName(),layer);
增加(新阳极(层));
System.out.println(“有序:“+layer.getLayerName());
}
lv.设置项目(列表);
lv.setCellFactory(新回调(){
@凌驾
公共ListCell调用(ListView参数){
返回新的DefaultListCell();
}
});
我使用了fxexperience.com中推荐的简单DefaultListCell,您也可以使用自定义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);
}
}
import java.util.ArrayList;
导入java.util.List;
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.scene.Parent;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.Label;
导入javafx.scene.control.ListView;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.Priority;
导入javafx.stage.stage;
公共类ListViewDemo扩展了应用程序{
公共静态类HBoxCell扩展HBox{
标签=新标签();
按钮按钮=新按钮();
HBoxCell(字符串标签文本、字符串按钮文本){
超级();
label.setText(labelText);
label.setMaxWidth(双倍最大值);
HBox.setHgrow(标签、优先级、始终);
button.setText(buttonText);
this.getChildren().addAll(标签、按钮);
}
}
公共父级createContent(){
BorderPane布局=新建BorderPane();
列表=新的ArrayList();
对于(int i=0;i<12;i++){
添加(新的HBoxCell(“项目”+i,“按钮”+i));
}
ListView ListView=新建ListView();
ObservableList myObservableList=FXCollections.ObservableList(列表);
setItems(myObservableList);
布局。设置中心(listView);
返回布局;
}
@凌驾
public void start(Stage)引发异常{
stage.setScene(新场景(createContent());
舞台设置宽度(300);
舞台设置高度(200);
stage.show();
}
公共静态void main(字符串参数[]){
发射(args);
}
}
此实施的结果如下所示:
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<>();
}
});
但是,为了有效地管理按钮事件,您应该考虑在HBOXXECUTE构造器方法中添加附加自定义按钮对象,并创建一个适当的方法,这将允许您控制按钮单击事件。
极好!非常感谢编码!工作得很好!不需要将当前项存储在<代码> L中。astItem
字段。您可以直接在按钮处理程序中调用getItem()
。它不适用于@FXML初始化的ListView:(@CarlosLópezMarí这确实适用于FXML初始化的ListView我没有深入研究过这一点,但表面上看,这似乎是一个糟糕的想法。