0

I am doing a program where I create an Arraylist of an object called City

    City c1 = new City("Miami", "Florida", 33175, -80.4068, 25.7341);
    City c2 = new City("Seattle", "Washington", 98109, -122.3476, 47.6339);
    City c3 = new City("Levittown", "Pennsylvania", 19058, -75.1028, 40.3286);
    City c4 = new City("Tampa", "Florida", 33625, -82.559, 28.0726);
    City c5 = new City("Topeka", "Kansas", 66617, -95.6384, 39.1271);

    ArrayList<City> cities = new ArrayList<City>();

    cities.add(c1);
    cities.add(c2);
    cities.add(c3);
    cities.add(c4);
    cities.add(c5);

I need to display it one by one with next and previous buttons. Currently I have a for loop going through the ArrayList creating the label and text fields and getting the class data from the increment(i) Here is the code for that:

 for (int i = 0; i < cities.size(); i++) {


    GridPane pane = new GridPane();
    pane.setHgap(5);
    pane.setVgap(5);
    pane.setPadding(new Insets(25,25,25,25));


    Label label1 = new Label("City:");
    TextField textField1 = new TextField (cities.get(i).getCity());
    pane.add(label1, 0, 1);
    pane.add(textField1, 1, 1);

    Label label2 = new Label("State:");
    TextField textField2 = new TextField (cities.get(i).getState());
    pane.add(label2, 0, 2);
    pane.add(textField2, 1, 2);

    Label label3 = new Label("Zip Code:");
    TextField textField3 = new TextField (String.valueOf(cities.get(i).getpostalCode()));
    pane.add(label3, 0, 3);
    pane.add(textField3, 1, 3);

    Label label4 = new Label("Longitude:");
    TextField textField4 = new TextField (String.valueOf(cities.get(i).getLongitude()));
    pane.add(label4, 0, 4);
    pane.add(textField4, 1, 4);

    Label label5 = new Label("Longitude:");
    TextField textField5 = new TextField (String.valueOf(cities.get(i).getLatitude()));
    pane.add(label5, 0, 5);
    pane.add(textField5, 1, 5);

    Button prev = new Button("Previous");
    pane.add(prev, 0, 20);

    Button next = new Button("Next");
    pane.add(next, 2, 20); 

    // buttons are work in progress
    next.setOnAction((ActionEvent e) -> {


            cities.get(i).getCity(); 
            textField1.setText(cities.get(i).getCity());



     });

    BorderPane borderPane = new BorderPane();
    borderPane.setCenter(pane);

    Scene scene = new Scene(borderPane, 500, 500);
    primaryStage.setTitle("Cities");
    primaryStage.setScene(scene); 
    primaryStage.show(); 

    }

I can display it without the ForLoop, but I don't know know how to go from here. Also, How do I implement my prev/next buttons setOnActions inside the loop?

Thank you!

5
  • 1
    Please add a minimal, complete & verifiable example, so we can go from there. Check this How to create a Minimal, Complete, and Verifiable example Commented May 16, 2018 at 3:02
  • 1
    The better question is why are you using a for loop in this manner? Commented May 16, 2018 at 4:26
  • I think you have to use iterator and .next in setOnAction . Commented May 16, 2018 at 4:57
  • @Sedrick Im currently completing without the forloop. I think I figured out how to do it. I may post the solution if anyone is interested in it(probably not). Yea I don't know why that was a good idea. Commented May 16, 2018 at 5:00
  • @Yves -> post the solution please... Commented May 16, 2018 at 5:30

2 Answers 2

2

It would be better to move the nodes for displaying the city to a new class. This way you can more easily seperate the concerns. (You don't need to consider the city display when implementing the navigation and the other way round.)

public class CityView extends GridPane {

    public CityView() {
        setHgap(5);
        setVgap(5);
        setPadding(new Insets(25, 25, 25, 25));

        Label label1 = new Label("City:");
        TextField cityText = new TextField();

        Label label2 = new Label("State:");
        TextField stateText = new TextField();

        Label label3 = new Label("Zip Code:");
        TextField zipCodeText = new TextField();

        Label label4 = new Label("Longitude:");
        TextField longitudeText = new TextField();

        Label label5 = new Label("Longitude:");
        TextField latitudeText = new TextField();

        addColumn(0, label1, label2, label3, label4, label5);
        addColumn(1, cityText, stateText, zipCodeText, longitudeText, latitudeText);

        this.city.addListener((o, oldValue, newValue) -> {
            // fill TextFields with new city values
            String name = null;
            String state = null;
            String zipCode = null;
            String longitude = null;
            String latitude = null;

            if (city != null) {
                name = newValue.getCity();
                state = newValue.getState();
                zipCode = String.valueOf(newValue.getpostalCode());
                longitude = String.valueOf(newValue.getLongitude());
                latitude = String.valueOf(newValue.getLatitude());
            }

            cityText.setText(name);
            stateText.setText(state);
            zipCodeText.setText(zipCode);
            longitudeText.setText(longitude);
            latitudeText.setText(latitude);
        });
    }

    private final ObjectProperty<City> city = new SimpleObjectProperty<>(this, "city");

    public ObjectProperty<City> cityProperty() {
        return city;
    }

    public City getCity() {
        return cityProperty().get();
    }

    public void setCity(City city) {
        cityProperty().set(city);
    }

}
@Override
public void start(Stage primaryStage) {
    ObservableList<City> cities = FXCollections.observableArrayList(
            new City("Miami", "Florida", 33175, -80.4068, 25.7341),
            new City("Seattle", "Washington", 98109, -122.3476, 47.6339),
            new City("Levittown", "Pennsylvania", 19058, -75.1028, 40.3286),
            new City("Tampa", "Florida", 33625, -82.559, 28.0726),
            new City("Topeka", "Kansas", 66617, -95.6384, 39.1271));

    IntegerProperty index = new SimpleIntegerProperty();
    IntegerBinding displayIndex = index.add(1);
    IntegerBinding size = Bindings.size(cities);
    size.addListener((o, oldValue, newValue) -> {
        // keep index valid when cities are removed (not necessary for lists that are not modified)
        int newSize = newValue.intValue();
        int i = index.get();
        if (i+1 >= newSize) {
            index.set(Math.max(0, newSize - 1));
        }
    });

    CityView cityView = new CityView();
    cityView.cityProperty().bind(Bindings.valueAt(cities, index));

    Button last = new Button("<");
    last.setOnAction(evt -> {
        index.set(index.get() - 1);
    });
    last.disableProperty().bind(index.lessThanOrEqualTo(0));

    Button next = new Button(">");
    next.setOnAction(evt -> {
        index.set(index.get() + 1);
    });
    next.disableProperty().bind(displayIndex.greaterThanOrEqualTo(size));

    Label indexLabel = new Label();
    indexLabel.setMaxSize(Region.USE_PREF_SIZE, Double.MAX_VALUE);
    indexLabel.setAlignment(Pos.CENTER_RIGHT);
    indexLabel.setPrefWidth(20);
    indexLabel.textProperty().bind(displayIndex.asString());

    HBox navigation = new HBox(10, last, indexLabel, next);
    navigation.setFillHeight(true);

    VBox root = new VBox(cityView, navigation);

    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.setResizable(false);
    primaryStage.show();
}
Sign up to request clarification or add additional context in comments.

Comments

1

a complete minimal sample would help to answer, but as you did not provide this i just describe what you have to do:

  • get rid of the for loop,
  • create a method that accepts a City and has access to ArrayList cities (static? or as parameter for this method
  • assign the values of city to the Nodes form the UI

this code is written out of my mind, so it might not compile, but it is only intended to give you a direction anyway

// Note that you could also do this by using the index, instead of city...
public void set(final City city) {
    // assign values to the Nodes of the UI
    // ...
    // update the onAction Event for the NextButton
    getNextButton().setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            //getNextIndexOf returns the index of the City+1 (if possible)
            set(cities.get(getNextIndexOf(city));
        }
    });
    // update the onAction Event for the PreviousButton
    // do the equivalend as for the NextButton but decreasing the index
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.