我创造了一个简单的轮盘重拍。我正在使用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)
答案 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++)
当然,也会更改value
中ButtonAction
的值...所以另一种选择是返回原始循环,但随后使用访问阵列时i - 1
。
答案 2 :(得分:1)
Arrays具有从0开始的索引。所以你的for
循环应该是
for (int i = 0; i < BUTTON_COUNT; i++) { ... }
而不是
for (int i = 1; i <= BUTTON_COUNT; i++) { ... }