使用JFrame

时间:2015-05-10 08:11:44

标签: java arrays string swing

我创造了一个简单的轮盘重拍。我正在使用JFrame。关于我的代码的一切工作正常,除了一件事。我在我的代码中标记了它,它是方法ButtonAction。对不起,我可能会发布很多代码,但是这种方法可能是你应该看的唯一方法。我只是发布下面的其余代码以获取更多信息。无论如何,在那个方法下我创建了一个字符串数组,以不同的方式命名每个按起初我这样做了:

  public ButtonAction(int i) {

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

像这样按钮被称为按钮1,按钮2等。这根本没问题,但我希望每个按钮都有一个完全不同的名称,所以我做了一个字符串数组:

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;

不幸的是,我得到了错误。我究竟做错了什么?

如果它有帮助,这是完整的代码:

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();
         }
      });
   }


}

这是我得到的错误代码:

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 个答案:

答案 0 :(得分:2)

您的ButtonNaam数组有8个元素,索引为going from 0 to 7,您尝试访问不存在的元素ButtonNaam[8],这就是ArrayIndexOutOfBoundsException的含义。< / p>

使用实际的按钮数定义一个costant:

 private static final int BUTTON_COUNT = 8;

要解决此问题,您必须更改此行:

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

到此:

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

正如代码目前所示,您正在跳过ButtonNaam的第一个元素并尝试访问索引无效为8的元素。

使用数组时始终注意索引,您所拥有的是 off-by-one 错误的典型示例:

  

一个一个错误(OBOE),通常也称为OBOB(一个一个)   bug),是一个逻辑错误,涉及边界的离散等价物   条件。 它经常发生在迭代的计算机编程中   循环迭代一次太多或太少。

     

可能会出现此问题   当程序员犯错误时,例如使用“小于或等于”   到“哪里”小于“应该用于比较或   没有考虑到序列从零开始而不是   一个(与许多语言中的数组索引一样)。

链接到Wikipedia

答案 1 :(得分:2)

这是问题所在:

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

Java中的数组是0索引的。因此,当您使用数组索引1到8时,有效索引实际上是0到7.所以你的循环应该是:

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

当然,也会更改valueButtonAction的值...所以另一种选择是返回原始循环,但随后使用访问阵列时i - 1

答案 2 :(得分:1)

Java中的

Arrays具有从0开始的索引。所以你的for循环应该是

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

而不是

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