0

編集 --- Object クラスを表示し、initialize メソッド内にコードを追加し、以前のフィルター メソッドを削除し、FXML から TextField の OnAction を削除しました。---

これを理解しようとする私の最初の試みは、多くの Android の問題を引き起こしたので、ここにいます。

JavaFX、Scenebuilder、FXML を使用して簡単な GUI を作成しました。この GUI は、プラント ショップの在庫をシミュレートし、ファイルに追加/削除/表示/保存することができますObservableListStringまた、ユーザーが に入力したパーシャル に基づいてオブジェクトをフィルタリングすることも想定されていますTextField

これは、すべてコマンドライン経由だったので、このプログラムの以前の化身では簡単でした。しかし、今まで見たことのない新しい問題に遭遇しました。

各オブジェクトは、疑似乱数の ID 番号とユーザー指定の接頭辞 (花の場合は F、雑草の場合は W、ハーブの場合は H、真菌の場合は Fn)、名前、色、および「棘」、「香り」などのブール属性を使用して印刷されます。 、「食用」など。それらはラジオボタンによって決定されます。たとえば、ユーザーが新しい花のすべての値を入力すると、次のように出力されます。

これが私の最初の ObservableList と FilteredList です。

ObservableList<Plant> observablePlantList = FXCollections.observableArrayList();
FilteredList<Plant> filteredList = new FilteredList<Plant>(observablePlantList);

以下は、Plant クラスと 1 つのサブクラス (まったく同じものが 4 つあります) で、それらがリストにどのように表示されるかを示しています (ブール値はラジオ ボタンです)。

    public class Plant {
public String ID;
public String name;
public String color;
public boolean smell;
public boolean thorns;
public boolean edible;
public boolean poisonous;
public boolean flavor;
public boolean medicine;
public boolean seasonal;
public int idNum;

public Plant(String ID, int idNum, String name, String color, boolean smell, boolean thorns, boolean edible, boolean poisonous, boolean flavor, boolean medicine, boolean seasonal) {
    this.ID = ID;
    this.idNum = randomID(idNum);
    this.name = name;
    this.color = color;
    this.smell = false;
    this.thorns = false;
    this.edible = false;
    this.poisonous = false;
    this.flavor = false;
    this.medicine = false;
    this.seasonal = false;
}

public void setColor(String color) {this.color = color;}
public void setID(String ID) {this.ID = ID;}
public void setName(String name) {this.name = name;}

public String getID() {return ID;}
public String getName() {return name;}

public int randomID(int idNum) {
    Random randomNum = new Random();
    idNum = randomNum.nextInt(50);
    return idNum;
}

public String toString() {

    return "ID: " + this.ID + "-" + this.idNum + ", Name: " + this.name + ", Color: " + this.color;
}

}

サブクラス

    public class Flower extends Plant {

public Flower(String ID, int idNum, String name, String color, boolean smell, boolean thorns, boolean edible, boolean poisonous, boolean flavor, boolean medicine, boolean seasonal) {

    super(ID, idNum, name, color, smell, thorns, edible, poisonous, flavor, medicine, seasonal);
}
public void setSmell(boolean smell) {
    this.smell = smell;
}
public void setThorns(boolean thorns) {
    this.thorns = thorns;
}
public String toString() {

    return super.toString() + ", Scent? " + this.smell + ", Thorns? " + this.thorns;
}

}

これは、以下の回答の提案のおかげで、初期化メソッド内にあるものです。問題は、何も変わらないことです:

    @Override
public void initialize(URL fxmlFileLocation, ResourceBundle rb) {

    plantList.setItems(filteredList);

    //binding filterInput text entries
    filteredList.predicateProperty().bind(Bindings.createObjectBinding(() -> {
        String filterText = filterInput.getText();
        if(filterText == null || filterText.isEmpty()) {
            return null;
        }
        else {
            final String uppercase = filterText.toUpperCase();
            return (plant) -> plant.getName().toUpperCase().contains(uppercase);
        }
    }, filterInput.textProperty()));

これに関する私の目標は、新しいシーンでアイテムをフィルタリングして表示するボタンを使用するのではなく、ObservableArrayList をリアルタイムでフィルタリングすることです。私はこれが実装されているのを見てきましたが、その機能が本当に気に入っています。

提供されたヘルプに感謝します。

4

2 に答える 2

0

新しいバージョンの JavaFX に導入された新しい方法を学ぶ必要があります。私は実際にやりたいことを考え、それを紙に書き、私の能力/現在の知識を最大限に発揮して書きました.

初期化メソッドに ChangeListener がまだあり、OnAction が FXML ファイルから削除されている作業コードを次に示します。これで、文字を入力すると、それぞれの植物が表示され、バックスペースを押すと元の植物が表示されます。

ご提案いただいた内容を利用できなかったことを深くお詫び申し上げます。述語とバインディングを完全に理解するにはまだ十分な経験がありませんが、調査する必要があることは間違いありません。

     public void filterPlantList(String oldValue, String newValue) {

    ObservableList<Plant> filteredList = FXCollections.observableArrayList();
    if(filterInput == null || (newValue.length() < oldValue.length()) || newValue == null) {
        plantList.setItems(observablePlantList);
    }
    else {
        newValue = newValue.toUpperCase();
        for(Plant plants : plantList.getItems()) {
            String filterText = plants.getName();
            if(filterText.toUpperCase().contains(newValue)) {
                filteredList.add(plants);
            }
        }
        plantList.setItems(filteredList);
    }
}
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle rb) {

    //add Listener to filterInput TextField
    filterInput.textProperty().addListener(new ChangeListener() {
        public void changed(ObservableValue observable, Object oldValue, Object newValue) {
            filterPlantList((String) oldValue, (String) newValue);
        }
    });
于 2015-11-26T00:25:42.923 に答える