当前位置: 首页 > 知识库问答 >
问题:

通过ListView获取ListCell

海岳
2023-03-14

我有一个列表视图和我自己的列表单元格

在<代码>列表视图上。getItems()。获取(索引) 访问模型没有问题,但我想用收到的索引对列表单元格进行布局更改,用索引1对列表单元格进行布局更改

如何通过ListView访问ListCell?

我寻找这样一种方法:

listView.getListCell(index);

共有3个答案

贲绪
2023-03-14

cell有一个名为“. cell”的样式类

public Cell getListCell(ListView list, int index){
    Object[]cells = list.lookupAll(".cell").toArray();
    return (Cell)cells[index];
}
闾丘山
2023-03-14

这是一种相对简单的方法,其中只有一个“选定”索引。在这里,我创建一个属性来保存选定的索引,单元格工厂只需观察它,以及单元格的项目属性和索引属性,并通过绑定设置文本。如果需要,您可以做类似的事情来设置图形。

import java.util.concurrent.Callable;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
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.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Callback;

public class ListViewStyleAroundSelection extends Application {

    @Override
    public void start(Stage primaryStage) {
        final ListView<String> listView = new ListView<>();
        for (int i=1; i<=20; i++) {
            listView.getItems().add("Item "+i);
        }
        final HBox controls = new HBox(5);
        final Button button = new Button("Set selection");
        final TextField indexField = new TextField();

        final IntegerProperty selectionIndex = new SimpleIntegerProperty();
        button.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                try {
                    selectionIndex.set(Integer.parseInt(indexField.getText()));
                } catch (NumberFormatException nfe) {
                    indexField.setText("");
                }
            }

        });

        controls.getChildren().addAll(new Label("Enter selection index:"), indexField, button);
        final BorderPane root = new BorderPane();
        root.setCenter(listView);
        root.setBottom(controls);

        listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {

            @Override
            public ListCell<String> call(ListView<String> lv) {
                final ListCell<String> cell = new ListCell<>();
                cell.textProperty().bind(Bindings.createStringBinding(new Callable<String>() {

                    @Override
                    public String call() throws Exception {
                        if (cell.getItem() == null) {
                            return null ;
                        } else {
                            switch (cell.getIndex() - selectionIndex.get()) {
                              case -1: return cell.getItem() + " (selected item below)"; 
                              case 0: return cell.getItem() + " (selected)";
                              case 1: return cell.getItem() + " (selected item above)";
                              default: return cell.getItem();
                            }
                        }
                    }

                }, cell.itemProperty(), cell.indexProperty(), selectionIndex));
                return cell;
            }

        });

        final Scene scene = new Scene(root, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这是一个稍微复杂的版本。这里我有一个自定义数据类型,其中包括一个布尔属性。更新将指定项目的布尔属性设置为true。单元格工厂创建一个单元格,并观察当前项目和前一个项目的选定属性。然后,像以前一样,它使用绑定来更新单元格的文本。

import java.util.concurrent.Callable;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.binding.IntegerBinding;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
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.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Callback;

public class ListViewStyleAroundSelection extends Application {

    @Override
    public void start(Stage primaryStage) {
        final ListView<MyDataType> listView = new ListView<>();
        for (int i=0; i<=20; i++) {
            listView.getItems().add(new MyDataType("Item "+i, false));
        }
        final HBox controls = new HBox(5);
        controls.setPadding(new Insets(5));
        final Button button = new Button("Set selection");
        final TextField indexField = new TextField();

        button.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                try {
                    int index = Integer.parseInt(indexField.getText());
                    if (index >= 0 && index < listView.getItems().size()) {
                        final MyDataType item = listView.getItems().get(index);
                        item.setSelected( ! item.isSelected() );
                    }
                } catch (NumberFormatException nfe) {
                    indexField.setText("");
                }
            }

        });

        controls.getChildren().addAll(new Label("Enter selection index:"), indexField, button);
        final BorderPane root = new BorderPane();
        root.setCenter(listView);
        root.setBottom(controls);

        listView.setCellFactory(new Callback<ListView<MyDataType>, ListCell<MyDataType>>() {

            @Override
            public ListCell<MyDataType> call(ListView<MyDataType> lv) {
                final ListCell<MyDataType> cell = new ListCell<>();
                final IntegerBinding previousIndex = cell.indexProperty().subtract(1);
                final ObjectBinding<MyDataType> previousItem = Bindings.valueAt(listView.getItems(), previousIndex);
                final BooleanBinding previousItemSelected = Bindings.selectBoolean(previousItem, "selected");
                final StringBinding thisItemName = Bindings.selectString(cell.itemProperty(), "name");
                final BooleanBinding thisItemSelected = Bindings.selectBoolean(cell.itemProperty(), "selected");
                cell.textProperty().bind(Bindings.createStringBinding(new Callable<String>() {

                    @Override
                    public String call() throws Exception {
                        if (cell.getItem() == null) {
                            return null ;
                        } else {
                            String value = cell.getItem().getName();
                            if (thisItemSelected.get()) {
                                value = value + " (selected) " ;
                            } else if (previousItemSelected.get()) {
                                value = value + " (selected item is above)";
                            }
                            return value ;
                        }
                    }

                }, thisItemName, thisItemSelected, previousItemSelected));
                return cell;
            }

        });

        final Scene scene = new Scene(root, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static class MyDataType {
        private final BooleanProperty selected ;
        private final StringProperty name ;
        public MyDataType(String name, boolean selected) {
            this.name = new SimpleStringProperty(this, "name", name);
            this.selected = new SimpleBooleanProperty(this, "selected", selected);
        }
        public final String getName() {
            return name.get();
        }
        public final void setName(String name) {
            this.name.set(name);
        }
        public final StringProperty nameProperty() {
            return name ;
        }
        public final boolean isSelected() {
            return selected.get();
        }
        public final void setSelected(boolean selected) {
            this.selected.set(selected);
        }
        public final BooleanProperty selectedProperty() {
            return selected;
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
黄昊
2023-03-14

不幸的是,目前还没有API来按索引获取列表单元格或获取ListView的所有子项(listcells)。一种解决方案是,在MyObject类中定义一个新的StringProperty specialIndicator。

 class MyObject {

        ....//u r properties
        private StringProperty specialIndicator;

当您从网络信号获取索引时,请设置对象的这个specialIndicator属性,并执行ListView的forcerefresh

public void onReceivedNetWorkSignalIndex() {
 listView.getItems().get(indexFromService).setSpecialIndicator("selected");
 listView.getItems().get(indexFromService+1).setSpecialIndicator("selectedplusone");
//force refresh listview (it will trigger cellFactory again so that you can manipulate layout)
 listView.setItems(null);
 listView.setItems(allObjects);

}

由于您已经有了自定义对象ListView,我假设您已经有了自定义cellFactory(如果没有的话,您必须创建一个),请修改您的自定义cellFactory以处理这个特殊的指示器

         listView.setCellFactory(new Callback<ListView<MyObject>, ListCell<MyObject>>() {
                    @Override
                    public ListCell<MyObject> call(ListView<MyObject> myObjectListView) {
                        ListCell<MyObject> cell = new ListCell<MyObject>(){
                            @Override
                            protected void updateItem(MyObject myObject, boolean b) {
                                super.updateItem(myObject, b);
                                if(myObject != null) {
                                    setText(myObject.getName());
                                    if("selected".equalsIgnoreCase(myObject.getSpecialIndicator())) {
                                        System.out.println("Setting new CSS/graphics for index retun from service." + myObject.getName());
                                    } else if("selectedplusone".equalsIgnoreCase(myObject.getSpecialIndicator())) {
                                        System.out.println("Setting new CSS/Graphics for index+1 returned from service" + myObject.getName());
                                    }
                              myObject.setSpecialIndicator(""); // reset it back to empty
                                }
                            }
                        };

                        return cell;
                    }
                });
public class ListViewTest extends Application {


    @Override
    public void start(Stage stage) throws Exception {

        VBox root = new VBox();
        final ObservableList<MyObject> allObjects = FXCollections.observableArrayList(new MyObject("object0"), new MyObject("object1"),new MyObject("object2"),new MyObject("object3"),new MyObject("object4"));
       final  ListView<MyObject> listView = new ListView<>(allObjects);
        listView.setCellFactory(new Callback<ListView<MyObject>, ListCell<MyObject>>() {
            @Override
            public ListCell<MyObject> call(ListView<MyObject> myObjectListView) {
                ListCell<MyObject> cell = new ListCell<MyObject>(){
                    @Override
                    protected void updateItem(MyObject myObject, boolean b) {
                        super.updateItem(myObject, b);
                        if(myObject != null) {
                            setText(myObject.getName());
                            if("selected".equalsIgnoreCase(myObject.getSpecialIndicator())) {
                                System.out.println("Setting new CSS/graphics for index retun from service." + myObject.getName());
                                setText("I am selected Index from Service");
                            } else if("selectedplusone".equalsIgnoreCase(myObject.getSpecialIndicator())) {
                                System.out.println("Setting new CSS/Graphics for index+1 returned from service" + myObject.getName());
                                setText("I am selected Index +1  from Service");
                            }
                            myObject.setSpecialIndicator(""); // reset it back to empty
                        }
                    }
                };

                return cell;
            }
        });
        Button serviceIndex2 = new Button("ServiceIndex2");
        serviceIndex2.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent actionEvent) {
                int indexFromService =2;
                listView.getItems().get(indexFromService).setSpecialIndicator("selected");
                listView.getItems().get(indexFromService+1).setSpecialIndicator("selectedplusone");
                listView.setItems(null);
                listView.setItems(allObjects);
            }
        });
        root.getChildren().addAll(listView,serviceIndex2);
        Scene scene = new Scene(root,500,500);
        stage.setScene(scene);
        stage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }

    class MyObject {

        private StringProperty name;
        private StringProperty specialIndicator;

        MyObject(String name) {
            this.name = new SimpleStringProperty(name);
            this.specialIndicator = new SimpleStringProperty();
        }

        public String getName() {
            return name.get();
        }

        public StringProperty nameProperty() {
            return name;
        }

        public void setName(String name) {
            this.name.set(name);
        }

        public String getSpecialIndicator() {
            return specialIndicator.get();
        }

        public StringProperty specialIndicatorProperty() {
            return specialIndicator;
        }

        public void setSpecialIndicator(String specialIndicator) {
            this.specialIndicator.set(specialIndicator);
        }
    }
}
 类似资料:
  • 问题内容: 我需要知道我的用户是否已连接。为此,我想读取在服务器端通过express-session设置的cookie: 我尝试使用react-cookie,但是它不起作用,但是我复制/粘贴了npm react-cookie doc: 这很奇怪,因为可以呈现正确的结果,但是我不知道如何处理: 问题答案: 您可以使用软件包,也可以使用命令进行安装。 文档:https : //github.com/j

  • 我必须从自定义帖子类型返回所有帖子,由'start_date'从'ACF字段'。 我有一些有日期的帖子,还有一些没有日期的帖子。当我添加“orderby”时= 这是我的代码: 如果我删掉 我所有的帖子都被退回,但它们不是按开始日期排序的 有什么想法吗? 谢谢。

  • 问题内容: 如何使用SQLAlchemy从表中选择一个或多个随机行? 问题答案: 这在很大程度上是特定于数据库的问题。 我知道PostgreSQL,SQLite,MySQL和Oracle可以通过随机函数进行排序,因此可以在SQLAlchemy中使用它: 接下来,您需要通过所需的记录数来限制查询(例如使用)。 请记住,至少在PostgreSQL中,选择随机记录会带来严重的性能问题。这是一篇很好的文章

  • 本文向大家介绍magento 通过SKU获取产品,包括了magento 通过SKU获取产品的使用技巧和注意事项,需要的朋友参考一下 示例            

  • 嗨,我一直在到处寻找一个非常简单的解释,如何通过xPath找到一个元素。 我想要的只是一种简单的方法来寻找一个元素,但是我想要找到的所有帮助都需要一个。这对我不管用。以下是我想做的: 加载URL 这是我的代码: 当我执行 我得到未定义时,我做 有没有更简单的方法来获取元素?也许是。。。。

  • 我已经通过Mac(OS-Yosemite)终端手动安装了maven。命令 给出以下输出: 但是当我做时,我得到了以下信息: [错误]无法在/Users/shilpa_rajendran/创建本地存储库。m2/仓库-