简体   繁体   中英

“Prev” button not cycling through array, “Next” button works fine

I am trying to get "Next" and "Previous" buttons working in my program. The next button works as expected, but I can't get the logic right for the previous button. I am getting the error:

"Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1 at Bookstore8$3.actionPerformed(Bookstore8.java:257)"

This is my Bookstore class, maybe someone can give me some advice on how to get the logic right for the "Previous" button? The other three buttons work fine. I just can't get that last button figured-out.

/* Declare Bookstore Class */
public class Bookstore8 extends JFrame
{
  /* Declare Index and Assign to First Part of the Array */
 private static int bookstoreIndex = 0;

 private static Book[] bookInventory = new Book[5]; 

     public static JTextArea prepareDisplay(Book myBook, JTextArea myTextArea){

     myTextArea.setText("");

     myTextArea.append(myBook.toString());

     return myTextArea;
    }

     /* Method to Sort Books */
  public static Book [] sortArray(Book[] books) {

   String[] titles = new String[books.length];

   Book[] sortedBooks = new Book [books.length];

   for (int i = 0; i < books.length; i++){
    titles[i] = books[i].getBookTitle();
   }

   Arrays.sort(titles, String.CASE_INSENSITIVE_ORDER);

   for (int i = 0; i < books.length; i++){
        for (int j = 0; j < titles.length; j++){
             if (books[i].getBookTitle().equalsIgnoreCase(titles[j])) {
                        sortedBooks[j] = books[i];
                        break;
             }
        }
   }

   return sortedBooks;
  }

  /* Method to Calculate Inventory */
  public static double calculateInventoryTotal(Book[] books){
   double total = 0;

   for (int i = 0; i < books.length; i++) {

    total += books[i].getBookPrice();
   }
   return total;
  }


   /* Main Method */
  public static void main (String[] args){

       /* Create Book Objects */
       Book one = new Book ("TD45454545", "My First Java Stuff", "Dan Zaleski", 2014, "UPX", 19.99);
       Book two = new Book ("KY67676767", "Hello From Boston", "Joe Smith", 1999, "Random House", 19.99);
       Book three = new Book ("NCC7890987", "I Hate Onions", "John Cooper", 1990, "Random House", 9.99);
       Book four = new Ebook ("YY00000000", "Yo Dawg", "Jim Fix", 1980, "Penguin", 29.99, "http://amazon.com", 2.99);
       Book five = new Ebook ("HB12345678", "Lottsa Books", "Wille Sargent", 2010, "Wherever", 129.99, "http://amazon.com", 12.99);

       bookInventory[0] = two;
       bookInventory[1] = three;
       bookInventory[2] = five;
       bookInventory[3] = one;
       bookInventory[4] = four;

    /* Declare Number Format */ 
  NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);

     /* Sort Items
   bookInventory = sortArray(bookInventory);*/

     /* Declare JText Class */
    final JTextArea textArea = new JTextArea(10,20);
    textArea.setText("");
    textArea.setEditable(false);


    /* Making Buttons */
    JPanel  buttonPanel = new JPanel();
    buttonPanel.setLayout(new GridLayout(1, 3));

    JButton firstButton = new JButton("First");
    buttonPanel.add(firstButton);
    firstButton.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
        bookstoreIndex = 0;
        prepareDisplay(bookInventory[bookstoreIndex], textArea);
       }
  });

    JButton lastButton = new JButton("Last");
    buttonPanel.add(lastButton);
    lastButton.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
            bookstoreIndex = (bookInventory.length - 1);
            prepareDisplay(bookInventory[bookstoreIndex], textArea);
           }
  });

    JButton prevButton = new JButton("Previous");
    buttonPanel.add(prevButton);
    prevButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        bookstoreIndex--;
        if (bookstoreIndex == bookInventory.length - 1) {
            bookstoreIndex=0;
        }
        prepareDisplay(bookInventory[bookstoreIndex], textArea);
      }
    });

    JButton nextButton = new JButton("Next");
    buttonPanel.add(nextButton);
    nextButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        bookstoreIndex++;
        if (bookstoreIndex == bookInventory.length) {
            bookstoreIndex=0;
        }
        prepareDisplay(bookInventory[bookstoreIndex], textArea);
      }
    });

    /* Total Value */
    String totalValue = "Total Value = " + nf.format(calculateInventoryTotal(bookInventory));
    JLabel valuePanel = new JLabel(totalValue);

  /* Add Logo */
    JLabel logoLabel = new JLabel (new ImageIcon("cmdroundlogo600.png"));
    JPanel logoPanel = new JPanel();
    logoPanel.add(logoLabel);

    JPanel centerPanel = new JPanel();
    centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));
    centerPanel.add(prepareDisplay(bookInventory[bookstoreIndex], textArea));

    /* Assemble the GUI */
    JFrame frame = new JFrame();
    frame.setLayout(new BorderLayout());
    frame.add(logoPanel, BorderLayout.NORTH);
    frame.add(buttonPanel, BorderLayout.SOUTH);
    frame.add(centerPanel, BorderLayout.CENTER);
    frame.add(valuePanel, BorderLayout.LINE_END);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

     }

}

You're checking the wrong boundary, the top boundary, in your prev's ActionListener as noted in comments below:

  public void actionPerformed(ActionEvent e) {
    bookstoreIndex--;

    // this checks if the index is **ABOVE** the range of acceptable
    if (bookstoreIndex == bookInventory.length - 1) {
        bookstoreIndex=0;
    }
    prepareDisplay(bookInventory[bookstoreIndex], textArea);
  }

Instead, since your decrementing the index, you need to check if it is below the bottom boundary, to check if it's < 0. For example:

  public void actionPerformed(ActionEvent e) {
    bookstoreIndex--;

    // You want to check if the index is **BELOW** the range of acceptable
    if (bookstoreIndex < 0) {
        bookstoreIndex = bookInventory.length - 1;
    }
    prepareDisplay(bookInventory[bookstoreIndex], textArea);
  }

Or another way that can work with either prev or next:

  public void actionPerformed(ActionEvent e) {
    bookstoreIndex--; // ++ for the next button's listener

    bookstoreIndex += bookInventory.length; // in case it's < 0
    bokstoreIndex %= bookInventory.length; // put it in correct range

    prepareDisplay(bookInventory[bookstoreIndex], textArea);
  }

As an aside, your code is grossly over-using the static modifier, and is putting too much code and responsibility in the main method. I strongly urge you to OOP-ify your code quite a bit, make it more OOP compliant and well behaved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM