JavaFX的8,用的ListView复选框 [英] JavaFX 8, ListView with Checkboxes

查看:1320
本文介绍了JavaFX的8,用的ListView复选框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个简单的ListView。我已经想通了,我可以使用的方法setCellFactory(),但我不明白如何正确地使用它们。到目前为止,我有:

I want to create a simple ListView. I have figured out I can use the method setCellFactory() but I don't understand how to use them correctly. So far I have:

myListView.setCellFactory(CheckBoxListCell.forListView(property));

通过调用的回调财产是什么 - 我认为回调是与双向边界。所以,我创建了一个

With "property" being something called a Callback--I think Callback has something to do with bidirectional bounding. So I created a

property = new CallBack<String, ObservableValue<Boolean>>();

我的编译器告诉我,如果我创建一个新的回调,我需要覆盖的方法调用。

My compiler is telling me if I create a new Callback, I need to overwrite the method call.

和我在这里卡住了。我怎么与方法调用呢?我可以实现它,但是我应该回来,或者用它呢?我想点击任何的listItem我的复选框,并把它显示喜,在控制台中。

And here I am stuck. What do I do with that method call? I can implement it, but what should I return, or use it for? I want to click my checkbox on any listItem and have it display "hi" in console.

推荐答案

如果你有一个的ListView&LT;弦乐&GT; ,然后在每个项目的ListView 字符串和<一个href=\"http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/cell/CheckBoxListCell.html#forListView-javafx.util.Callback-\"><$c$c>CheckBoxListCell.forListView(...)方法需要一个回调&LT;弦乐,ObservableValue&LT;布尔&GT;方式&gt;

If you have a ListView<String>, then each item in the ListView is a String, and the CheckBoxListCell.forListView(...) method expects a Callback<String, ObservableValue<Boolean>>.

在物联网中,<一个有思想的pre-Java的8路href=\"http://docs.oracle.com/javase/8/javafx/api/javafx/util/Callback.html\"><$c$c>Callback<String, ObservableValue&LT;布尔&GT;&GT; 是定义一个方法的接口,

In the pre-Java 8 way of thinking of things, a Callback<String, ObservableValue<Boolean>> is an interface that defines a single method,

public ObservableValue<Boolean> call(String s) ;

所以,你需要的东西,实现该接口,并且在该类型的对象传递。

So you need something that implements that interface, and you pass in an object of that type.

的<一个href=\"http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/cell/CheckBoxListCell.html#forListView-javafx.util.Callback-\">documentation还告诉大家,回调的使用方式:

The documentation also tells you how that callback is used:

有一个回调,考虑到T类型的对象(这是取出来的值
  在ListView.items清单),将返回
  ObservableValue那些重新presents给定的项目是否为
  选定的或没有。这ObservableValue将双向约束
  (即在细胞中复选框将设置/取消该属性
  基于用户的互动,和该复选框会反映的状态
  在ObservableValue,如果外部变化)。

A Callback that, given an object of type T (which is a value taken out of the ListView.items list), will return an ObservableValue that represents whether the given item is selected or not. This ObservableValue will be bound bidirectionally (meaning that the CheckBox in the cell will set/unset this property based on user interactions, and the CheckBox will reflect the state of the ObservableValue, if it changes externally).

(因为你有一个的ListView&LT;弦乐&GT; ,这里 T 字符串)。因此,在列表视图中的每个元素(每个元素都是一个字符串),回调是用来确定一个 ObservableValue&LT;布尔&GT; 这是双向绑定到复选框的状态。即如果复选框被选中,该属性设置为真正,并且如果不加以控制设置为。相反,如果属性设置为真正(或)编程,复选框被选中(或取消选中)。

(Since you have a ListView<String>, here T is String.) So, for each element in the list view (each element is a String), the callback is used to determine an ObservableValue<Boolean> which is bidirectionally bound to the state of the checkbox. I.e. if the checkbox is checked, that property is set to true, and if unchecked it is set to false. Conversely, if the property is set to true (or false) programmatically, the checkbox is checked (or unchecked).

在这里典型的用例是该项目中的 ListView控件类型将有一个 BooleanProperty 作为其一部分其状态。所以,你通常会以某种自定义的类重presenting数据的使用,与内项目类,如下所示:

The typical use case here is that the type of item in the ListView would have a BooleanProperty as part of its state. So you would typically use this with some kind of custom class representing your data, as follows with the inner Item class:

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.CheckBoxListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;

public class ListViewWithCheckBox extends Application {

    @Override
    public void start(Stage primaryStage) {
        ListView<Item> listView = new ListView<>();
        for (int i=1; i<=20; i++) {
            Item item = new Item("Item "+i, false);

            // observe item's on property and display message if it changes:
            item.onProperty().addListener((obs, wasOn, isNowOn) -> {
                System.out.println(item.getName() + " changed on state from "+wasOn+" to "+isNowOn);
            });

            listView.getItems().add(item);
        }

        listView.setCellFactory(CheckBoxListCell.forListView(new Callback<Item, ObservableValue<Boolean>>() {
            @Override
            public ObservableValue<Boolean> call(Item item) {
                return item.onProperty();
            }
        }));

        BorderPane root = new BorderPane(listView);
        Scene scene = new Scene(root, 250, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static class Item {
        private final StringProperty name = new SimpleStringProperty();
        private final BooleanProperty on = new SimpleBooleanProperty();

        public Item(String name, boolean on) {
            setName(name);
            setOn(on);
        }

        public final StringProperty nameProperty() {
            return this.name;
        }

        public final String getName() {
            return this.nameProperty().get();
        }

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

        public final BooleanProperty onProperty() {
            return this.on;
        }

        public final boolean isOn() {
            return this.onProperty().get();
        }

        public final void setOn(final boolean on) {
            this.onProperty().set(on);
        }

        @Override
        public String toString() {
            return getName();
        }

    }

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

如果你真的有一个的ListView&LT;弦乐&GT; ,它不是真正清楚你通过点击复选框,设置该属性将是什么。但没有什么可以阻止你只是结合的复选框的选中状态而创建一个在回调:

If you genuinely have a ListView<String>, it's not really clear what the property you are setting by clicking on the check box would be. But there's nothing to stop you creating one in the callback just for the purpose of binding to the check box's selected state:

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.CheckBoxListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;

public class ListViewWithStringAndCheckBox extends Application {

    @Override
    public void start(Stage primaryStage) {
        ListView<String> listView = new ListView<>();
        for (int i = 1; i <= 20 ; i++) {
            String item = "Item "+i ;
            listView.getItems().add(item);
        }

        listView.setCellFactory(CheckBoxListCell.forListView(new Callback<String, ObservableValue<Boolean>>() {
            @Override
            public ObservableValue<Boolean> call(String item) {
                BooleanProperty observable = new SimpleBooleanProperty();
                observable.addListener((obs, wasSelected, isNowSelected) -> 
                    System.out.println("Check box for "+item+" changed from "+wasSelected+" to "+isNowSelected)
                );
                return observable ;
            }
        }));

        BorderPane root = new BorderPane(listView);
        Scene scene = new Scene(root, 250, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

注意,在这种情况下,有可能被创建并经常弃去 BooleanProperty 秒。这可能是在实践中没有问题,但它确实意味着第一个版本,通过专用模型类,可以有更好的表现。

Notice that in this case, the BooleanPropertys are potentially being created and discarded frequently. This probably isn't a problem in practice, but it does mean the first version, with the dedicated model class, may perform better.

在Java 8中,可以简化code。因为回调接口只有一个抽象方法(使它成为一个的功能接口的),你可以把回调&LT的;项目,ObservableValue&LT;布尔&GT;&GT; 作为一个函数,它接受一个项目并生成一个 ObservableValue&LT;布尔&GT; 。因此,在第一示例中的细胞工厂可以用一个拉姆达前$ P $写入pssion

In Java 8, you can simplify the code. Because the Callback interface has only one abstract method (making it a Functional Interface), you can think of a Callback<Item, ObservableValue<Boolean>> as a function which takes a Item and generates an ObservableValue<Boolean>. So the cell factory in the first example could be written with a lambda expression:

    listView.setCellFactory(CheckBoxListCell.forListView(item -> item.onProperty()));

或者,更简洁的使用方法引用的:

    listView.setCellFactory(CheckBoxListCell.forListView(Item::onProperty));

这篇关于JavaFX的8,用的ListView复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆