0

I'm creating a simple roulette remake. I'm using JFrame. Everything about my code works fine, except for one thing. I marked it in my code, it's the method ButtonAction. I'm sorry I might be posting a lot of code, but that method is probably the only method you should be looking. I'm just posting the rest of the code below for extra information. Anyway, under that method I made a string array to name each button differently. At first I made it like this:

  public ButtonAction(int i) {

      String name = "Button " + i;
      putValue(NAME, name);
      this.value = i;
  }

Like this each button was called Button 1, Button 2 etc. That was no problem at all, but I wanted each button to have a completely different name, so I made this, a string array:

public ButtonAction(int i) {

        String[] ButtonNaam = {"Chances Simples", "Douzaines", "Colonne", "Transversale simple", "Carré", "Transversale pleine", "Cheval", "Plein"};
        String name1 = ButtonNaam[i];

        putValue(NAME, name1);
        this.value = i;

And then I got the error, unfortunately. What exactly am I doing wrong?

This is the full code if it helps:

import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;

import javax.swing.*;

@SuppressWarnings("serial")
public class RouletteGUI extends JPanel {
   // preferred size dimensions
   private static final int PREF_W = 450;
   private static final int PREF_H = 300;

   // number of buttons displayed
   private static final int BUTTON_COUNT = 8;
   public static final String BLANK_PANEL = "blank";
   public static final String MAIN_PANEL = "main panel";
   private CardLayout cardLayout = new CardLayout();



   public RouletteGUI() {
      // create JPanel to hold our buttons. use a grid layout with 1 column
      JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 5, 5));
      for (int i = 1; i <= BUTTON_COUNT; i++) {
          // create a new JButton and give it a an Action
         JButton button = new JButton(new ButtonAction(i));
         // add it to the buttonPanel
         buttonPanel.add(button); 
      } 
      // main JPanel to hold the buttonPanel
      JPanel mainPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
      mainPanel.add(buttonPanel);

      // set this class's layout
      setLayout(cardLayout);
      add(mainPanel, MAIN_PANEL); // add mainPanel
      add(new JPanel(), BLANK_PANEL);  // add a blank JPanel
   }

   @Override // so JPanel will be at least our desired size
   public Dimension getPreferredSize() {
      Dimension superSz = super.getPreferredSize();
      if (isPreferredSizeSet()) {
         return superSz;
      }
      int prefW = Math.max(superSz.width, PREF_W);
      int prefH = Math.max(superSz.height, PREF_H);
      return new Dimension(prefW, prefH);
   }

   // our AbstractAction class, an ActionListener "on steroids"
   private class ButtonAction extends AbstractAction {
      private int value;

      public ButtonAction(int i) {

            String[] ButtonNaam = {"Chances Simples", "Douzaines", "Colonne", "Transversale simple", "Carré", "Transversale pleine", "Cheval", "Plein"};
            String name1 = ButtonNaam[i];

            putValue(NAME, name1);
            this.value = i;
            //HERE I GET THE ERROR
            //!!!!!!!!!!!!!!!!!!!
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         // TODO: do some number specific action based on value
         // For a trivial example:
         String message = "Button pressed: " + value;
         JOptionPane.showMessageDialog(null, message);

         // swap view to a blank view
         cardLayout.show(RouletteGUI.this, BLANK_PANEL);
      }
   }

   // create and display GUI in a thread-safe manner
   private static void createAndShowGui() {

      RouletteGUI mainPanel = new RouletteGUI();

      JFrame frame = new JFrame("Roulette");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
      frame.setResizable(false);
      Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
      int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
      int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
      frame.setLocation(x, y);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }


}

And this is the error code I get:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 8
    at RouletteGUI$ButtonAction.<init>(RouletteGUI.java:61)
    at RouletteGUI.<init>(RouletteGUI.java:30)
    at RouletteGUI.createAndShowGui(RouletteGUI.java:82)
    at RouletteGUI.access$1(RouletteGUI.java:80)
    at RouletteGUI$1.run(RouletteGUI.java:100)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

3 Answers 3

2

This is the problem:

for (int i = 1; i <= BUTTON_COUNT; i++)

Arrays in Java are 0-indexed. So while you're using array indexes 1 to 8, the valid indexes are actually 0 to 7. So your loop should be:

for (int i = 0; i < BUTTON_COUNT; i++)

Of course, that will also change the value of value in your ButtonAction... so another option is to go back to your original loop, but then use i - 1 when accessing the array.

Sign up to request clarification or add additional context in comments.

Comments

2

Your ButtonNaam array has 8 elements, with index going from 0 to 7, you are trying to access element ButtonNaam[8] that does not exist, this is what that ArrayIndexOutOfBoundsException means.

You define a costant with the actual number of buttons you have:

 private static final int BUTTON_COUNT = 8;

To fix this you have to change this line:

for (int i = 1; i <= BUTTON_COUNT; i++) {

to this:

for (int i = 0; i < BUTTON_COUNT; i++) {

As the code is at the moment, you are skipping the first element of ButtonNaam and trying to access an element with an invalid index of 8.

Always pay attention to indexes when using arrays, what you had there is a typical example of off-by-one error:

An off-by-one error (OBOE), also commonly known as an OBOB (off-by-one bug), is a logic error involving the discrete equivalent of a boundary condition. It often occurs in computer programming when an iterative loop iterates one time too many or too few.

This problem could arise when a programmer makes mistakes such as using "is less than or equal to" where "is less than" should have been used in a comparison or fails to take into account that a sequence starts at zero rather than one (as with array indices in many languages).

Link to Wikipedia.

Comments

1

Arrays in Java have 0-based indexes. So your for loop should read

for (int i = 0; i < BUTTON_COUNT; i++) { ... }

instead of

for (int i = 1; i <= BUTTON_COUNT; i++) { ... }

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.