Search code examples
javabuttonjavafxfxmlscenebuilder

Implementing numerous buttons using an arrayList in javaFX


I am implementing a User Interface for a restaurant menu that involves a large number of increment and decrement buttons as shown below - please note I have used SceneBuilder to create the UI: see image one

I have tried numerous methods to allow looping through each button and updating the text field next to it on mouse click but have failed to implement this via an arrayList - i keep receiving a null pointer error when i know the arraylist is succesfully filling up with the buttons. Here is what I have tried: I have a method which fills up the list by specifying the fxids of the appropriate buttons as so -

    plusButtonList.add(soupPlus);
    plusButtonList.add(guacPlus);
    plusButtonList.add(empanadaPlus);
    plusButtonList.add(jalapenoPlus);
    plusButtonList.add(quesaPlus);

I also then have a method which is supposed to iterate through each of these buttons, setting the onaction to retrieve the current counter value from the textfield (which is also in a list but the corresponding button and text fields will be at the same indexed position) this method is called in 'initialise' in the controller class.

 private void checkIfIncrement() {

  for(int i = 0; i < 20; i++) {
      int counter = i;
      plusButtonList.get(i).setOnAction(e -> {
          int currentCountVal = foodCounterList.get(counter);
          theTextFields.get(counter).setText(Integer.toString(currentCountVal+ 1));
          foodCounterList.set(counter, currentCountVal+1); 
      });
  }

NOTE: foodCounterList is a list of integers containing each text field's current value. 'theTextFields' is the list containing each of the text fields. UPDATE: Here is my Controller Class after attempting to implement the suggested improvement by Matt.

  package customer;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Pagination;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;

/**
 * View for the customer.
 * @author Arslan Nazir
 *
 */
public class CustomerView {


  @FXML
  private ResourceBundle resources;

  @FXML
  private URL location;

  @FXML
  private ImageView imageview;
  Stage stage;

  @FXML
  private Button soupPlus;

  @FXML
  private  Button soupMinus;

  @FXML
  private  TextField soupField;

  @FXML
  private  Button guacMinus;

  @FXML
  private  Button guacPlus;

  @FXML
  private  TextField guacField;

  @FXML
  private Font x11322;

  @FXML
  private  Button empanadaMinus;

  @FXML
  private  TextField empanadaField;

  @FXML
  private  Button empanadaPlus;

  @FXML
  private  Button jalapenoMinus;

  @FXML
  private  Button jalapenoPlus;

  @FXML
  private  TextField jalapenoField;

  @FXML
  private  Button quesaMinus;

  @FXML
  private  Button quesaPlus;

  @FXML
  private  TextField quesaField;

  @FXML
  private  Button choriMinus;

  @FXML
  private  Button choriPlus;

  @FXML
  private  TextField choriField;

  @FXML
  private  Button seafoodMinus;

  @FXML
  private  Button seafoodPlus;

  @FXML
  private  TextField seafoodField;

  @FXML
  private  Button avocadoMinus;

  @FXML
  private  Button avocadoPlus;

  @FXML
  private  TextField avocadoField;

  @FXML
  private  Button burritoMinus;

  @FXML
  private  Button burritoPlus;

  @FXML
  private  TextField burritoField;

  @FXML
  private  Button chilliMinus;

  @FXML
  private  Button chilliPlus;

  @FXML
  private  TextField chilliField;

  @FXML
  private Font x113221;

  @FXML
  private  Button churrosMinus;

  @FXML
  private  Button churrosPlus;

  @FXML
  private  TextField churrosField;

  @FXML
  private  Button pastelMinus;

  @FXML
  private  Button pastelPlus;

  @FXML
  private  TextField pastelField;

  @FXML
  private  Button brownieMinus;

  @FXML
  private  Button browniePlus;

  @FXML
  private  TextField brownieField;

  @FXML
  private  Button strawbMinus;

  @FXML
  private  Button strawbPlus;

  @FXML
  private  TextField strawbField;

  @FXML
  private  Button vanillaMinus;

  @FXML
  private  Button vanillaPlus;

  @FXML
  private  TextField vanillaField;

  @FXML
  private Font x11321;

  @FXML
  private  Button colaPlus;

  @FXML
  private  Button colaMinus;

  @FXML
  private  TextField colaField;

  @FXML
  private  Button dietColaMinus;

  @FXML
  private  Button dietColaPlus;

  @FXML
  private  TextField dietColaField;

  @FXML
  private  Button mojitoMinus;

  @FXML
  private  Button mojitoPlus;

  @FXML
  private  TextField mojitoField;

  @FXML
  private  Button blueMargMinus;

  @FXML
  private  Button blueMargPlus;

  @FXML
  private  TextField blueMargField;

  @FXML
  private  Button redMargMinus;

  @FXML
  private  Button redMargPlus;

  @FXML
  private  TextField redMargField;

  @FXML
  private  Button bottleWaterMinus;

  @FXML
  private  Button bottleWaterPlus;

  @FXML
  private  TextField bottleWaterField;

  @FXML
  private  Button tapWaterMinus;

  @FXML
  private  Button tapWaterPlus;

  @FXML
  private  TextField tapWaterField;

  @FXML
  private  Button closeprogram;

  @FXML
  private  Button minimiseprogram;

  @FXML
  private VBox bgone;

  @FXML
  private  Button callwaiter;

  @FXML
  private  TextField summaryField;

  static List<TextField> theTextFields = new ArrayList<>();
  ArrayList<Button> plusButtonList = new ArrayList<>(Arrays.asList(soupPlus, guacPlus));
  static List<Button> minusButtonList = new ArrayList<>();
  static List<Integer> foodCounterList = new ArrayList<>();



  public void listPopulate() {
        theTextFields.add(soupField);
        theTextFields.add(guacField);
        theTextFields.add(empanadaField);
        theTextFields.add(jalapenoField);
        theTextFields.add(quesaField);
        theTextFields.add(choriField);
        theTextFields.add(seafoodField);
        theTextFields.add(avocadoField);
        theTextFields.add(burritoField);
        theTextFields.add(chilliField);
        theTextFields.add(churrosField);
        theTextFields.add(pastelField);
        theTextFields.add(brownieField);
        theTextFields.add(strawbField);
        theTextFields.add(vanillaField);
        theTextFields.add(colaField);
        theTextFields.add(dietColaField);
        theTextFields.add(mojitoField);
        theTextFields.add(blueMargField);
        theTextFields.add(redMargField);
        theTextFields.add(bottleWaterField);
        theTextFields.add(tapWaterField);

        for (int i = 0; i< theTextFields.size(); i++) {
            theTextFields.get(i).setText("0");
        }

        minusButtonList.add(soupMinus);
        minusButtonList.add(guacMinus);
        minusButtonList.add(empanadaMinus);
        minusButtonList.add(jalapenoMinus);
        minusButtonList.add(quesaMinus);
        minusButtonList.add(choriMinus);
        minusButtonList.add(seafoodMinus);
        minusButtonList.add(avocadoMinus);
        minusButtonList.add(burritoMinus);
        minusButtonList.add(chilliMinus);
        minusButtonList.add(churrosMinus);
        minusButtonList.add(pastelMinus);
        minusButtonList.add(brownieMinus);
        minusButtonList.add(strawbMinus);
        minusButtonList.add(vanillaMinus);
        minusButtonList.add(colaMinus);
        minusButtonList.add(dietColaMinus);
        minusButtonList.add(mojitoMinus);
        minusButtonList.add(blueMargMinus);
        minusButtonList.add(redMargMinus);
        minusButtonList.add(bottleWaterMinus);
        minusButtonList.add(tapWaterMinus);

        /**
        plusButtonList[0] = soupPlus;
        plusButtonList[1] = guacPlus;
        plusButtonList[2] = empanadaPlus;
        plusButtonList[3] = soupPlus;
        plusButtonList[4] = soupPlus;
        plusButtonList[5] = soupPlus;
        plusButtonList[6] = soupPlus;
        plusButtonList[7] = soupPlus;
        plusButtonList[8] = soupPlus;
        plusButtonList[9] = soupPlus;
        plusButtonList[10] = soupPlus;
        plusButtonList[11] = soupPlus;
        plusButtonList[12] = soupPlus;
        plusButtonList[13] = soupPlus;
        plusButtonList[14] = soupPlus;
        plusButtonList[15] = soupPlus;
        plusButtonList[16] = soupPlus;
        plusButtonList[17] = soupPlus;
        plusButtonList[18] = soupPlus;
        plusButtonList[19] = soupPlus;
        plusButtonList[20] = soupPlus;
        plusButtonList[21] = soupPlus;
        plusButtonList[22] = soupPlus;



        plusButtonList.add(soupPlus);
        plusButtonList.add(guacPlus);
        plusButtonList.add(empanadaPlus);
        plusButtonList.add(jalapenoPlus);
        plusButtonList.add(quesaPlus);
        plusButtonList.add(choriPlus);
        plusButtonList.add(seafoodPlus);
        plusButtonList.add(avocadoPlus);
        plusButtonList.add(burritoPlus);
        plusButtonList.add(chilliPlus);
        plusButtonList.add(churrosPlus);
        plusButtonList.add(pastelPlus);
        plusButtonList.add(browniePlus);
        plusButtonList.add(strawbPlus);
        plusButtonList.add(vanillaPlus);
        plusButtonList.add(colaPlus);
        plusButtonList.add(dietColaPlus);
        plusButtonList.add(mojitoPlus);
        plusButtonList.add(blueMargPlus);
        plusButtonList.add(redMargPlus);
        plusButtonList.add(bottleWaterPlus);
        plusButtonList.add(tapWaterPlus);
        **/

        foodCounterList.add(Integer.parseInt(soupField.getText()));
        foodCounterList.add(Integer.parseInt(guacField.getText()));
        foodCounterList.add(Integer.parseInt(empanadaField.getText()));
        foodCounterList.add(Integer.parseInt(jalapenoField.getText()));
        foodCounterList.add(Integer.parseInt(quesaField.getText()));
        foodCounterList.add(Integer.parseInt(choriField.getText()));
        foodCounterList.add(Integer.parseInt(seafoodField.getText()));
        foodCounterList.add(Integer.parseInt(avocadoField.getText()));
        foodCounterList.add(Integer.parseInt(burritoField.getText()));
        foodCounterList.add(Integer.parseInt(chilliField.getText()));
        foodCounterList.add(Integer.parseInt(churrosField.getText()));
        foodCounterList.add(Integer.parseInt(pastelField.getText()));
        foodCounterList.add(Integer.parseInt(brownieField.getText()));
        foodCounterList.add(Integer.parseInt(strawbField.getText()));
        foodCounterList.add(Integer.parseInt(vanillaField.getText()));
        foodCounterList.add(Integer.parseInt(colaField.getText()));
        foodCounterList.add(Integer.parseInt(dietColaField.getText()));
        foodCounterList.add(Integer.parseInt(mojitoField.getText()));
        foodCounterList.add(Integer.parseInt(blueMargField.getText()));
        foodCounterList.add(Integer.parseInt(redMargField.getText()));
        foodCounterList.add(Integer.parseInt(bottleWaterField.getText()));
        foodCounterList.add(Integer.parseInt(tapWaterField.getText()));


    }
    private void checkIfIncrement() {

      for (int i = 0; i < theTextFields.size(); i++) {
        setButtonActionsForFoodItem(plusButtonList.get(i), theTextFields.get(i));
      }
    }

      private void setButtonActionsForFoodItem(Button plusButton, TextField textField) {
          plusButton.setOnAction(event -> {
                int currentValue = Integer.parseInt(textField.getText());
                textField.setText(String.valueOf(++currentValue));
            });
      }


    /**for(int i =0; i < plusButtonList.size(); i++) {
          int counter = i;
          plusButtonList.get(i).setOnMouseClicked(new EventHandler<MouseEvent>() {

                @Override
                public void handle(MouseEvent t) {
                    int currentCountVal = foodCounterList.get(counter);
                      theTextFields.get(counter).setText(Integer.toString(currentCountVal+ 1));
                      foodCounterList.set(counter, currentCountVal+1); 
                }
            });

      }**/


    @FXML
    private void handleCloseProgram(ActionEvent event) {
        stage = (Stage)((Button)event.getSource()).getScene().getWindow();
        stage.close();
        System.exit(1);
    }



  @FXML
  private void handleMinimiseProgram(ActionEvent event) {
    stage = (Stage)((Button)event.getSource()).getScene().getWindow();
    stage.setIconified(true);
  }

  @FXML
  public void handle(ActionEvent event) {

  }




  @FXML
  void initialize() {
      //ButtonAndCountLists.setCounters();
      listPopulate();
      //System.out.println(plusButtonList.get(21));
      System.out.println(foodCounterList.get(1));
      checkIfIncrement();
  }


}

Solution

  • So I had a similar issue. I was trying to get a specific button to trigger a specific event depending on which button was clicked out of the array list. Here was my solution, I tried using .isPressed() first but that always returned false, so I changed it to isArmed() and that worked. Maybe you can try that? My code is written below.

    serveButtons was the arrayList that contained all of the different buttons. orderContentsList was the arrayList that contained the textAreas to be changed.

    int which = 0;
    for (int i = 0; i < serveButtons.size(); i++) {
      if (serveButtons.get(i).isArmed()) {
        which = i;
        break;
      }
    }
    orderContentsList.get(which).setText(null);
    

    If you need any more information about the arrayLists then let me know.