【问题标题】:Battleship using JButtons使用 JButtons 的战舰
【发布时间】:2013-12-14 08:21:15
【问题描述】:

开始使用 JButtons 制作战舰游戏,知道这比简单地绘制图表要困难一些,但我觉得在给定选项下完成这一壮举更有必要。无论如何,我被抛出错误,而 Eclipse 并没有宣布这些错误是什么。谁能破译这些,或者至少让我接近弄清楚我的问题?编辑:已发布更新代码

import java.awt.event.*;
import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;

public class TestDemo extends JPanel implements ActionListener{
    private JPanel lButton, rButton, textPan, turnPan;
    private JRadioButton turnC, turnP;
    private JTextArea jta;
    private static JMenuBar menuBar;
    private JRadioButton jrb;
    private static int SIZE = 10;
    private JButton[][] left, right;
    private int rand1, rand2;
    private int turnIndicator; //Allows the swap method to switch between player turn and computer turn 0 = player turn, 1 = computer turn
    public TestDemo(){
        setLayout(new FlowLayout(FlowLayout.CENTER));

        /** Buttons + Button Panels */
        lButton = new JPanel();
        lButton.setLayout(new GridLayout(SIZE,SIZE));
        rButton = new JPanel();
        rButton.setLayout(new GridLayout(SIZE,SIZE));
        left = new JButton[SIZE][SIZE];
        right = new JButton[SIZE][SIZE];
        turnIndicator = 0; 
        for (char row = 'A'; row <= 'J'; row++) 
            for (int col = 1, i = 0, j = 0; col <= 10 && i < SIZE && j < SIZE; col++, i++, j++) {
                left[i][j] = new JButton("" + row + col);
                right[i][j] = new JButton(""+row+col);
                left[i][j].setMargin(new Insets(0, 0, 0, 0));
                left[i][j].setPreferredSize(new Dimension(40, 40));
                right[i][j].setMargin(new Insets(0, 0, 0, 0));
                right[i][j].setPreferredSize(new Dimension(40, 40));
                left[i][j].addActionListener(this);
                right[i][j].addActionListener(this);
                lButton.add(left[i][j]);
                rButton.add(right[i][j]);
            }//end for
        /** End of Buttons + Button panels */

        /** Text Area */
        jta = new JTextArea(5,25);
        jta.setLineWrap(true);
        jta.setWrapStyleWord(true);
        jta.setEditable(false);
        jta.setVisible(true);
        textPan = new JPanel();
        textPan.setLayout(new FlowLayout(FlowLayout.CENTER));
        textPan.add(new JScrollPane(jta));
        /** End of Text Area */

        /** Turn radio button */
        turnC = new JRadioButton("Computer");
        turnC.addActionListener(this);
        turnC.setEnabled(false);
        turnP = new JRadioButton("Player");
        turnP.addActionListener(this);
        turnP.setEnabled(false);
        ButtonGroup group = new ButtonGroup();
        group.add(turnC);
        group.add(turnP);
        turnP.setSelected(true);
        turnPan = new JPanel();
        turnPan.setLayout(new BorderLayout());
        turnPan.add(turnC, BorderLayout.LINE_START);
        turnPan.add(turnP, BorderLayout.LINE_END);
        /** End turn radio button and label */

        /** Menu setup */
        menuBar = new JMenuBar();
        JMenu file = new JMenu("File");
        file.setMnemonic(KeyEvent.VK_F);
        JMenuItem newGame = new JMenuItem("New Game"); newGame.addActionListener(this);
        JMenuItem exit = new JMenuItem("Exit"); exit.addActionListener(new exitApp());
        newGame.setMnemonic(KeyEvent.VK_N); exit.setMnemonic(KeyEvent.VK_E);
        newGame.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.ALT_MASK));
        exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, ActionEvent.ALT_MASK));
        menuBar.add(file);
        file.add(newGame); file.add(exit);
        /** End Menu setup */

        JPanel gameTest = new JPanel();
        gameTest.setLayout(new BorderLayout());
        gameTest.add(lButton, BorderLayout.LINE_START);
        gameTest.add(rButton, BorderLayout.LINE_END);
        gameTest.add(textPan, BorderLayout.PAGE_END);
        gameTest.add(turnPan, BorderLayout.CENTER);
        add(gameTest);  
    }//end TestDemo

public static void main(String[] args) {
    JFrame frame = new JFrame();
    TestDemo td = new TestDemo();
    frame.add(td);
    frame.setVisible(true);
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setJMenuBar(menuBar);
}//end main

public void actionPerformed(ActionEvent e)
{
    JButton pressed = (JButton) e.getSource();
    if(turnIndicator == 0)
    {

    turnP.setSelected(true);
    (pressed).setEnabled(false);
    jta.append("Shot fired at : " + (pressed).getActionCommand() + '\n' );
    turnIndicator = 1;
    } 
    turnC.setSelected(true);
    swap(); //Throwing an error

}//end actionPerformed

public void compAttk()
{
    ArrayList<Integer> key1 = new ArrayList<Integer>(100);
    ArrayList<Integer> key2 = new ArrayList<Integer>(100);
    rand1 = (int) ((Math.random() * 10) + 1);
    rand2 = (int) ((Math.random() * 10) + 1);
    if(key1.contains(rand1) || key2.contains(rand2))/** Checks if the coords are already pressed*/
    {
        rand1 = (int) ((Math.random() * 10) + 1);
        rand2 = (int) ((Math.random() * 10) + 1);
        right[rand1][rand2].setEnabled(false); //I'm sure will also throw an error
    }
    right[rand1][rand2].setEnabled(false); //Throwing an error
    key1.add(rand1);
    key2.add(rand2);
    turnIndicator = 0;
}//end compAttk

public void swap() //Once user presses a button, turnIndicator will initialize to 1, then this method handles what happens afterwards.
{
    if(turnIndicator == 1)
    {
        compAttk(); //Throwing an error
        turnIndicator = 0;
    }
    else
       JOptionPane.showMessageDialog(null, "Your turn");
}//end swap
static class exitApp implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        System.exit(0);
    }
}//end exitApp
}//end TestDemo class


Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 10
at TestDemo.compAttk(TestDemo.java:91)
at TestDemo.swap(TestDemo.java:103)
at TestDemo.actionPerformed(TestDemo.java:70)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at     javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

【问题讨论】:

    标签: java arrays swing


    【解决方案1】:

    看来您应该将 rand1 = (int) (Math.random() + 10); 替换为 rand1 = (int) (Math.random() * 10);

    我想,按照现在的写法,你总是得到一个随机数 10,这不是你所期望的。

    这里的另一件事是,如果你的 ArrayList 包含 10 个元素,它的最后一个索引是 9,而不是 10。这就是 ArrayIndexOutOfBoundsException 的来源。

    【讨论】:

    • 太晚了(我的随机数生成器中有一个 + 而不是 * 的借口)。关于数组列表的事情。不,我不希望只有 10 个,我希望按钮的行和列在 1-10 之间的随机整数。
    • @jeffreyzachary,用* 替换+ 应该可以修复异常,除非您的代码有更多问题。使用 + 而不是 * 会使您的随机生成器始终返回 10,这超出了数组的范围。
    • 对,是的,它消除了这些错误。我最大的 3 个问题是我收到的 swap(); 方法的错误、我如何调用 right[rand1][rand2].setEnabled(false); 以及我在 swap(); 方法中调用 compAttk(); 时的错误。我完全不确定关于 java.awt 等的其他错误是否会在这 3 个之后消失,但至少这会给我一些喘息的空间,因为我知道我已经解决了我的方法错误。
    • 好吧,仍然没有运气解决这个问题,但是,作为唯一至少尝试解决我的问题的回答者,我会给你最好的答案。谢谢芽!仍然是一个初学者程序员,所以我学习的越来越多。
    • @jeffreyzachary,这个问题指的是已经解决的错误。如果您有其他问题,您应该为他们提出新的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多