0

javafx2 で fxml ファイルを作成します。

Person オブジェクトのリストがあります。このリストの名前は ですEntries。ObservableList がありmyObservableListます。この中にラベルを入れたい。各ラベルには、人物の画像と名前のテキストのペアが含まれている必要があります。私はこのコードを書きます:

for (int i=0; i<numberOfEntries; i++){                               
    currentEntry = Entries.get(i);
    name=currentEntry.getName();                                  
    image1 = new Image("file:"+currentEntry.getIcon());                    
    imageView1= new ImageView();
    imageView1.setFitHeight(50);
    imageView1.setFitWidth(70);
    imageView1.setImage(image1);                       
    label = new Label(name, imageView1);
    label.setFont(new Font("serif", 32));                         
    myObservableList.add(label);                   
}

問題なく動作しますが、イメージを数回挿入した後、JVM から次のエラー メッセージが表示されます。

Caused by: java.lang.OutOfMemoryError: Java heap space.

このエラーはコード行から発生します image1 = new Image("file:"+currentEntry.getIcon());

最後に、myObservableList のすべての要素を ComboBox アイテムに入れたいと思います。このため、Java コントローラーの Initialize メソッドで次のように記述します。

    myComboBox.setItems(myObservableList);

    ListCell<Label> buttonCell = new ListCell<Label>() {
         @Override protected void updateItem(Label item, boolean isEmpty) {
         super.updateItem(item, isEmpty);
            setText(item==null ? "" : item.getText());                 
        }
    };

    myComboBox.setButtonCell(buttonCell);

私はjavafxの経験が十分ではないと確信しており、すべてのアイテムの同じセルにアイコンとテキストのペアを含むコンボボックスがあるため、どのように処理すればよいかわかりません。

Peter Duniho と PakkuDon のおかげで、私の文章の英語力が向上しました。

4

1 に答える 1

2

(または他のコントロールの)Nodeデータ型としてクラスを使用することは、ほとんどの場合間違いです。ComboBoxデータのみを表すクラスを使用し、セル ファクトリを登録してデータの表示方法を構成する必要があります。

あなたの場合、データに画像を含めると、メモリの問題が発生する可能性があります。各イメージは、メモリ内で数メガバイトで表される可能性があります。したがって、データ クラスは画像名を保持する必要があり、コンボ ボックスのセルを使用して画像を作成できます。

アイデアを提供するためのサンプルコードを次に示します。

データ クラス (Person.java):

public class Person {
    private final String name ;
    private final String imageFileName ;

    public Person(String name, String imageFileName) {
        this.name = name ;
        this.imageFileName = imageFileName ;
    }

    public String getName() {
        return name ;
    }

    public String getImageFileName() {
        return imageFileName ;
    }
}

ComboBoxから作成するUI コードList<Person>:

List<Person> entries = ... ; // populated from DB

ComboBox<Person> comboBox = new ComboBox<>();
comboBox.getItems().addAll(entries);

comboBox.setCellFactory(new Callback<ListView<Person>, ListCell<Person>>() {
    @Override
    public ListCell<Person> call(ListView<Person> listCell) {

        return new ListCell<Person>() {
            private final ImageView = new ImageView();
            @Override
            public void updateItem(Person person, boolean empty) {
                super.updateItem(person, empty);
                if (empty) {
                    setText(null);
                    setGraphic(null);
                } else {
                    File imageFile = new File(person.getImageFileName());
                    String imageUrl = imageFile.toURI().toURL().toExternalForm();
                    Image image = new Image(imageUrl, 70, 50, 
                        // preserve ratio
                        true, 
                        // smooth resizing
                        true,
                        // load in background
                        true);
                    imageView.setImage(image);
                    setText(person.getName());
                    setGraphic(imageView);
                }
            }
        };
    }
});

のにも同じListCell実装を使用できます。ComboBoxbuttonCell

ここでのポイントは、セルは可視セルに対してのみ作成されるため、セルが表示されるときに画像が「オンデマンド」で読み込まれるということです。Image幅と高さのパラメーターを受け取るコンストラクターを使用すると、Imageオブジェクトが読み込まれるときにサイズを変更できるため、メモリ フットプリントも削減されます。

最後に、フラグを使用してバックグラウンドで画像を読み込むことが重要であることに注意してください。これにより、UI の応答性が維持されます。すばやくスクロールすると、しばらくロードされていない画像が表示される可能性があります。画像が利用可能になると、セルは適切に再描画されます。

于 2015-01-26T13:42:17.427 に答える