This discussion is archived
8 Replies Latest reply: Dec 10, 2012 2:49 PM by edward17 RSS

Wonky ChoiceBox runs out of memory

edward17 Newbie
Currently Being Moderated
So I opened a ticket for this, but wanted some feedback...



I have a choicebox with 1000 items.
I call setItems with the observablelist of items.
Everything is fine
I call setItems on same component (with smaller ObservableList)
Everything is fine(?)
I call setItems on same component with the original list of 1000

The JVM goes wild and runs out of memory.

Code below.

Why the switcharoo? The long list in my app is shared by multiple components. At some point in one scene I want a subset of the list (a filtered list) so I switch the choicebox to the filtered content. When done, I switch it back.

SO trying to figure out an alternative method to achieve switching lists in a choicebox without affecting the "master" list.

This behavior does NOT occur in a Listview by the way.
package javafxapplication2;

import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ListView;

public class SampleController implements Initializable {
    
    @FXML private Button reloadButton;
    @FXML private ListView mylist;
    @FXML private ChoiceBox mychoices;
    
    ObservableList<String> dummy = FXCollections.observableArrayList(new ArrayList<String>());
    ObservableList<String> real = FXCollections.observableArrayList(new ArrayList<String>());
    
    
    @FXML
    private void handleButtonAction(ActionEvent event) {
        mychoices.setItems(dummy);
        mychoices.setItems(real);
        //mylist.setItems(dummy);
        //mylist.setItems(real);
    }
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        reloadButton.setOnAction(new EventHandler<ActionEvent>(){
            @Override
            public void handle(ActionEvent t) {
                handleButtonAction(t);
            }
        });
        for(int i = 0; i < 1000; i++) {
            real.add("Entry #" + i);
        }
        mychoices.setItems(real);
        mylist.setItems(real);
    }    
}
<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="338.0" prefWidth="320.0" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication2.SampleController">
  <children>
    <ChoiceBox fx:id="mychoices" layoutX="76.0" layoutY="74.0" prefWidth="169.0">
      <items>
      </items>
    </ChoiceBox>
    <ListView fx:id="mylist" layoutX="59.0" layoutY="169.0" prefHeight="147.0" prefWidth="200.0" />
    <Button fx:id="reloadButton" layoutX="130.0" layoutY="127.0" mnemonicParsing="false" text="Reload" />
  </children>
</AnchorPane>
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javafxapplication2;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class JavaFXApplication2 extends Application {
    
    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
        
        Scene scene = new Scene(root);
        
        stage.setScene(scene);
        stage.show();
    }

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

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points