2013-07-14 2 views
0

Я работаю над контроллером, чтобы сделать игру Судоку. Когда вы запустите файл SudokuMain.java и нажмите «Файл» в верхней части страницы, а затем выберите «Новая игра», я получаю исключение:Почему я получаю исключение NullPointerException, когда я нажимаю «Новая игра»?

Исключение из потока «AWT-EventQueue-0» java.lang .NullPointerException

У меня есть ActionListener для «Новой игры», чтобы создать объект JDialog под названием «Создать совет» и предлагает пользователю ввести «Строки для региона» и «Столбцы для региона» и нажмите «Создать панель» »или нажмите« Отмена »и покончите с этим.

Я не уверен, что я делаю неправильно, но я чувствую, что проблема кроется во внутреннем классе MenuAtTop. Любая помощь приветствуется!

// Allow short name access to following classes 
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import java.util.*; 

public class SudokuMain extends JComponent { 

    public static void main(String[] args) { 
    new SudokuMain(); 
    } 

    private SudokuBase board; 
    private SudokuView view; 

    private JFrame win; 
    private JPanel center; 
    private JPanel west; 
    private JPanel east; 
    private JPanel cells; 

    private final Dialog1 setWin1; 

    public SudokuMain() { 

    // start game 
    view = new SudokuView(makeBoard()); 
    board = makeBoard(); 

    win = new JFrame("Sudoku"); 
    center = new JPanel(); 
    west = new JPanel(); 
    east = new JPanel(); 

    // "player" cells for current Sudoku board 
    cells = new SetSymbols(view); 
    // the 1st set-up window 
    setWin1 = new Dialog1(this, "New Game", true); 

    // create menu bar 
    MenuAtTop menuBar = new MenuAtTop(this); 
    win.setJMenuBar(menuBar); 

    win.setLayout(new BorderLayout()); 
    view.setSelected(1, 1); 
    west.setLayout(new BorderLayout()); 
    east.setLayout(new BorderLayout()); 
    center.setLayout(new FlowLayout()); 

    west.add(cells); 
    east.add(view, BorderLayout.CENTER); 
    center.add(west); 
    center.add(east); 

    win.add(center); 

    win.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    win.pack(); 
    win.setVisible(true); 

} 

class SudokuControlButton extends JPanel { 

    private int row; 
    private int col; 

    // row of selected cell 
    private int selRow; 
    // column of selected cell 
    private int selCol; 

    // the value that corresponds with the desired symbol 
    private int value; 

    /** 
    * Constructs SudokuControlButton object; the graphic "button" 
    * to control the board. 
    */ 
    public SudokuControlButton(final SudokuView view) { 

    setPreferredSize(new Dimension(40, 40)); 
    setBackground(Color.LIGHT_GRAY); 

    //value = 0; 

    addMouseListener(new MouseListener() { 

     public void mouseClicked(MouseEvent e) { 
     selRow = view.getSelectedRow(); 
     selCol = view.getSelectedColumn(); 

     if(!board.isGiven(selRow, selCol)) { 
      board.setValue(selRow, selCol, value); 

     view.repaint(); 
     } else { // have system beep sound 
      getToolkit().beep(); 
     } 

     repaint(); 
     } 

     public void mouseEntered(MouseEvent e){ 
     // set to "highlighted" color 
     setBackground(Color.WHITE); 

     repaint(); 
     } 

     public void mouseExited(MouseEvent e){ 
     // set to default color 
     setBackground(Color.LIGHT_GRAY); 

     repaint(); 
     } 

     public void mousePressed(MouseEvent e){ 
     // set to "active" color 
     setBackground(Color.YELLOW); 

     repaint(); 
     } 

     public void mouseReleased(MouseEvent e){ 
     } 

    }); 
    } 

    public void paintComponent(Graphics g) { 
    super.paintComponent(g); 

    switch(value) { 
     case 0: 
     drawSymbol(g, 0); 
     break; 
    case 1: 
     drawSymbol(g, 1); 
     break; 
    case 2: 
     drawSymbol(g, 2); 
     break; 
    case 3: 
     drawSymbol(g, 3); 
     break; 
    case 4: 
     drawSymbol(g, 4); 
     break; 
    case 5: 
     drawSymbol(g, 5); 
     break; 
    case 6: 
     drawSymbol(g, 6); 
     break; 
    case 7: 
     drawSymbol(g, 7); 
     break; 
    case 8: 
     drawSymbol(g, 8); 
     break; 
    case 9: 
     drawSymbol(g, 9); 
     break; 
    case 10: 
     drawSymbol(g, 10); 
     break; 
    case 11: 
     drawSymbol(g, 11); 
     break; 
    case 12: 
     drawSymbol(g, 12); 
     break; 
    } 

} 

/** 
* This method draws the symbol that corresponds with 
* the specified value (0-12). 
* 
* @param g The drawing mechanism. 
* @param value The specified value. 
*/ 
public void drawSymbol(Graphics g, int value) { 

    if(value < 0 || value > 12) { 
    String msg = "Value cannot be less than 1 or greater than 12."; 
    throw new IllegalArgumentException(msg); 
    } 

    // enable drawing with "thick" lines 
    Graphics2D g2 = (Graphics2D) g; 
    g2.setStroke(new BasicStroke(3)); 

    switch(value) { 
    case 0: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     break; 
    case 1: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g2.drawLine(5, 5, 5, 45); 
     break; 
    case 2: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g2.drawLine(5, 5, 5, 45); 
     g2.drawLine(10, 5, 10, 45); 
     break; 
    case 3: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g2.drawLine(5, 5, 5, 45); 
     g2.drawLine(10, 5, 10, 45); 
     g2.drawLine(15, 5, 15, 45); 
     break; 
    case 4: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g2.drawLine(5, 5, 5, 45); 
     g2.drawLine(10, 5, 10, 45); 
     g2.drawLine(15, 5, 15, 45); 
     g2.drawLine(20, 5, 20, 45); 
     break; 
    case 5: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g2.drawLine(5, 5, 5, 45); 
     g2.drawLine(10, 5, 10, 45); 
     g2.drawLine(15, 5, 15, 45); 
     g2.drawLine(20, 5, 20, 45); 
     g2.drawLine(25, 5, 25, 45); 
     break; 
    case 6: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g2.drawLine(5, 5, 5, 45); 
     g2.drawLine(10, 5, 10, 45); 
     g2.drawLine(15, 5, 15, 45); 
     g2.drawLine(20, 5, 20, 45); 
     g2.drawLine(25, 5, 25, 45); 
     g2.drawLine(30, 5, 30, 45); 
     break; 
    case 7: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g2.drawLine(5, 5, 5, 20); 
     g2.drawLine(10, 5, 10, 20); 
     g2.drawLine(15, 5, 15, 20); 
     g2.drawLine(20, 5, 20, 20); 
     g2.drawLine(25, 5, 25, 20); 
     g2.drawLine(30, 5, 30, 20); 
     g2.drawLine(5, 30, 5, 45); 
     break; 
    case 8: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g2.drawLine(5, 5, 5, 20); 
     g2.drawLine(10, 5, 10, 20); 
     g2.drawLine(15, 5, 15, 20); 
     g2.drawLine(20, 5, 20, 20); 
     g2.drawLine(25, 5, 25, 20); 
     g2.drawLine(30, 5, 30, 20); 
     g2.drawLine(5, 30, 5, 45); 
     g2.drawLine(10, 30, 10, 45); 
     break; 
    case 9: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g2.drawLine(5, 5, 5, 20); 
     g2.drawLine(10, 5, 10, 20); 
     g2.drawLine(15, 5, 15, 20); 
     g2.drawLine(20, 5, 20, 20); 
     g2.drawLine(25, 5, 25, 20); 
     g2.drawLine(30, 5, 30, 20); 
     g2.drawLine(5, 30, 5, 45); 
     g2.drawLine(10, 30, 10, 45); 
     g2.drawLine(15, 30, 15, 45); 
     break; 
    case 10: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g.drawLine(5, 5, 5, 20); 
     g.drawLine(10, 5, 10, 20); 
     g.drawLine(15, 5, 15, 20); 
     g.drawLine(20, 5, 20, 20); 
     g.drawLine(25, 5, 25, 20); 
     g.drawLine(30, 5, 30, 20); 
     g.drawLine(5, 30, 5, 45); 
     g.drawLine(10, 30, 10, 45); 
     g.drawLine(15, 30, 15, 45); 
     g.drawLine(20, 30, 20, 45); 
     break; 
    case 11: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g.drawLine(5, 5, 5, 20); 
     g.drawLine(10, 5, 10, 20); 
     g.drawLine(15, 5, 15, 20); 
     g.drawLine(20, 5, 20, 20); 
     g.drawLine(25, 5, 25, 20); 
     g.drawLine(30, 5, 30, 20); 
     g.drawLine(5, 30, 5, 45); 
     g.drawLine(10, 30, 10, 45); 
     g.drawLine(15, 30, 15, 45); 
     g.drawLine(20, 30, 20, 45); 
     g.drawLine(25, 30, 25, 45); 
     break; 
    case 12: 
     // draw borders 
     g.drawRect(0, 0, 50, 50); 
     // draw symbol 
     g.drawLine(5, 5, 5, 20); 
     g.drawLine(10, 5, 10, 20); 
     g.drawLine(15, 5, 15, 20); 
     g.drawLine(20, 5, 20, 20); 
     g.drawLine(25, 5, 25, 20); 
     g.drawLine(30, 5, 30, 20); 
     g.drawLine(5, 30, 5, 45); 
     g.drawLine(10, 30, 10, 45); 
     g.drawLine(15, 30, 15, 45); 
     g.drawLine(20, 30, 20, 45); 
     g.drawLine(25, 30, 25, 45); 
     g.drawLine(30, 30, 30, 45); 
     break; 
    } 

    } 

} 

class MenuAtTop extends JMenuBar implements ActionListener{ 

    private SudokuMain main; 

    private JMenu fileMenu; 
    private JMenuItem newGame; 

    private JDialog createNewWin; 

    public MenuAtTop(final SudokuMain m) { 

    fileMenu = new JMenu("File"); 
    add(fileMenu); 

    newGame = new JMenuItem("New Game"); 
    newGame.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 
                ActionEvent.CTRL_MASK)); 
    fileMenu.add(newGame); 
    newGame.addActionListener(this); 

    } 

    public void actionPerformed(ActionEvent e) { 
    setEnabled(false); 
    createNewWin = new Dialog1(main, "Create New Board", true); 
    } 

} 

class Dialog1 extends JDialog { 

    private JTextField rows; 
    private JTextField cols; 
    private JButton createBoard; 
    private JButton cancel; 
    private JLabel rowLabel; 
    private JLabel colLabel; 
    private JLabel errorMes; 


    private JPanel center; 
    private JPanel north; 
    private JDialog setUpWin2; 

    /** 
    * Constructs Dialog1 object. 
    * 
    * @param win The window containing the dialog box. 
    * @param header The title of dialog box. 
    * @param modal Whether dialog box is modal or not. 
    */ 
    public Dialog1(final SudokuMain win, String header, boolean modal) { 
    // call superclass constructor 
    super(); 

    // instantiate and bind to references 
    rows = new JTextField(2); 
    cols = new JTextField(2); 
    createBoard = new JButton("Create Board"); 
    cancel = new JButton("Cancel"); 
    rowLabel = new JLabel("Rows per region: "); 
    colLabel = new JLabel("Columns per region: "); 
    errorMes = new JLabel(); 

    north = new JPanel(new FlowLayout()); 
    center = new JPanel(new FlowLayout()); 

    // set characteristics 
    setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); 
    setTitle(header); 
    setModal(modal); 
    setLayout(new BorderLayout()); 

    // set characteristics of error message 
    errorMes.setForeground(Color.RED); 
    errorMes.setFont(new Font("Arial", Font.ITALIC, 12)); 
    errorMes.setVisible(false); 

    cancel.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
     setVisible(false); 
     } 
    }); 

    createBoard.addActionListener(new ActionListener() { 

     public void actionPerformed(ActionEvent e) { 
     int newRows; 
     int newCols; 
     int newSize; 

     try{ 
      newRows = Integer.parseInt(rows.getText()); 
      newCols = Integer.parseInt(cols.getText()); 
     } catch (NumberFormatException exc) { 
      newRows = 0; 
      newCols = 0; 
     } 

     newSize = newRows * newCols; 
     // input validation 
     if(newSize <= 0 && newSize > 12) { 
      errorMes.setText("Rows times columns cannot be greater than 12!"); 
      errorMes.setVisible(true); 
      pack(); 

     } else{ // valid input 
      errorMes.setVisible(false); 
      setVisible(false); 
      setUpWin2 = new Dialog2(win, "New Sudoku", newRows, newCols, true); 
     } 
     }}); 


    // place error message in the center 
    center.add(errorMes); 

    // place labels for rows and columns at the top 
    north.add(rowLabel); 
    north.add(rows); 
    north.add(colLabel); 
    north.add(cols); 

    add(center, BorderLayout.CENTER); 
    add(north, BorderLayout.NORTH); 

    pack(); 

    if(!win.win.isVisible()) { 
     dispose(); 
    } 

    } 
} 

class Dialog2 extends JDialog { 

    private SudokuView view; 

    private JPanel panel; 
    private JPanel northPanel; 
    private JPanel cells; 

    private JButton setGivens; 
    private JButton cancel; 

    /** 
    * Constructs Dialog2 object. 
    * 
    * @param win The window containing the dialog box. 
    * @param header The title of the dialog box. 
    * @param rows the rows to the new SudokuBoard to be constructed in the dialog box 
    * @param cols the columns to the new SudokuBoard to be constructed in the dialog box 
    * @param modal boolean value for whether the box is modal or not 
    */ 
    public Dialog2(final SudokuMain mainWin, String header, int rows, int cols, 
       boolean modal) { 
    // call superclass constructor 
    super(); 

    // instantiate and bind to references 
    view = new SudokuView(new SudokuBoard(rows, cols)); 
    panel = new JPanel(); 
    northPanel = new JPanel(); 
    setGivens = new JButton("Set Givens"); 
    cancel = new JButton("Cancel"); 
    cells = new SetSymbols(view); 

    // set up characteristics 
    setTitle(header); 
    setModal(modal); 
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    setLayout(new FlowLayout()); 
    panel.setLayout(new BorderLayout()); 
    northPanel.setLayout(new FlowLayout()); 


    setGivens.addActionListener(new ActionListener() { 

     public void actionPerformed(ActionEvent e) { 
     // set "given" cells 
     makeBoard().fixGivens(); 

     // have window refer to new board 
     west.remove(mainWin.view); 
     mainWin.east.remove(mainWin.cells); 

     mainWin.view = view; 
     mainWin.cells = cells; 

     mainWin.west.add(mainWin.view); 
     mainWin.east.add(mainWin.cells); 

     setVisible(false); 

     }}); 

    cancel.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     setVisible(false); 
    }}); 

    // place buttons at the top 
    northPanel.add(setGivens); 
    northPanel.add(cancel); 

    panel.add(view, BorderLayout.CENTER); 
    panel.add(northPanel, BorderLayout.NORTH); 

    add(panel); 
    add(cells); 

    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    pack(); 
    setVisible(true); 

    } 

} 

class SetSymbols extends JPanel { 

// temporary board to help create graphic "buttons" 
private SudokuBoard tempBd; 

/** 
* Constructs SetSymbols object. 
* @param view The SudokuView object for SetSymbols. 
*/ 
public SetSymbols(final SudokuView view) { 
    // instantiate and bind to reference 
    tempBd = new SudokuBoard(1, board.getBoardSize() + 1); 

    setLayout(new GridLayout((tempBd.getBoardSize())/2 + 1, 2)); 

    for(int colCell = 0; colCell < tempBd.getBoardSize(); colCell++) { 

    // cannot be changed after set/instantiated 
    final int value = colCell; 
    final JPanel cell = new JPanel(); 
    final Color defaultColor = cell.getBackground(); 

    // set characteristics 
    cell.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 
    // set value for each graphic "button" 
    tempBd.setValue(0, colCell, colCell); 
    // add the appropriate symbol to each graphic "button" 
    cell.add(view.new SudokuCell(0, colCell, tempBd)); 

    cell.addMouseListener(new MouseListener() { 
     // whether inside graphic "button" or not 
     boolean insideCell; 

     public void mouseClicked(MouseEvent e) { 
     int selRow = view.getSelectedRow(); 
     int selCol = view.getSelectedColumn(); 

     if(!board.isGiven(selRow, selCol)) { 
      board.setValue(selRow, selCol, value); 

      view.repaint(); 
     } 
     else { // have system beep sound 
      cell.getToolkit().beep(); 
     } 

     } 

     public void mouseEntered(MouseEvent e) { 
     insideCell = true; 
     // set to "highlighted" color 
     cell.setBackground(Color.WHITE); 

     view.repaint(); 
     } 

     public void mouseExited(MouseEvent e) { 
     insideCell = false; 
     // set to default color 
     cell.setBackground(defaultColor); 

     view.repaint(); 
     } 

     public void mousePressed(MouseEvent e) { 
     // set to "active" color 
     cell.setBackground(Color.YELLOW); 

     view.repaint(); 
     } 

     public void mouseReleased(MouseEvent e) { 
     if(insideCell) { 
      cell.setBackground(Color.YELLOW); 
     } 
     else { // outside of symbol's cell 
      cell.setBackground(defaultColor); 
     } 

     view.repaint(); 
     } 
    }); 

    // add graphic "button" 
    add(cell); 

    } 

    // handle possible "empty" graphic "button" 
    if(tempBd.getBoardSize() % 2 != 0) { 
    JPanel empty = new JPanel(); 
    empty.setBackground(Color.LIGHT_GRAY); 
    empty.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 
    add(empty); 
    } 

    } 

    } 

    public static SudokuBase makeBoard() { 
    SudokuBase board = new SudokuBoard(2, 3); 
    board.setValue(0, 3, 6); 
    board.setValue(0, 5, 1); 
    board.setValue(1, 2, 4); 
    board.setValue(1, 4, 5); 
    board.setValue(1, 5, 3); 
    board.setValue(2, 3, 3); 
    board.setValue(3, 2, 6); 
    board.setValue(4, 0, 2); 
    board.setValue(4, 1, 3); 
    board.setValue(4, 3, 1); 
    board.setValue(5, 0, 6); 
    board.setValue(5, 2, 1); 
    board.fixGivens(); 
    return board; 
    } 

} 
+5

В: «Я не уверен, что я делаю неправильно ...» A: Вы не используете отладчик. Eclipse, Netbeans и даже в командной строке JDK есть отладчики, которые позволяют вам отслеживать ваш код, устанавливать контрольные точки, проверять переменные ... и получать трассировки стека, показывающие точную строку (и, как правило, точную переменную), которая терпит неудачу. СИЛЬНОЕ ПРЕДЛОЖЕНИЕ: используйте IDE (например, Eclipse) и ознакомьтесь с его отладчиком! ИМХО ... – paulsm4

+1

Какая линия вызывает NPE? Пожалуйста, разместите * full * stacktrace, чтобы мы могли вам помочь. Я также согласен с @ paulsm4 в том, что вы должны научиться использовать среду IDE (например, Netbeans, Eclipse или IntelliJ) и встроенный отладчик. Изучение того, как отлаживать код, является важным инструментом для каждого программиста. –

+1

Вы должны отправить что-нибудь еще немного. Это слишком краткий ... Серьезно, хотя, добро пожаловать в SO. Здесь возьмите [тур] (http://stackoverflow.com/about). Вы захотите опубликовать гораздо более краткий пример. Если вы когда-либо имели ошибку, распечатайте трассировку стека. Кроме того, SO не является услугой отладки, вы должны попробовать это самостоятельно. Если вы все еще застряли, что вы пробовали, и мы постараемся помочь. –

ответ

2

Передано значение переменной main, перед тем как получить значение. Возможно, вы хотели инициализировать его параметру в конструкторе MenuAtTop, например main = m;?

+0

Вы должны отметить его как правильный ответ для будущих посетителей. Рад, что проблема исправлена. – kevinsa5

+0

спасибо, что удалил исключение NullPointerException. теперь, когда я нажимаю «Новая игра» в разделе «Файл», ничего не происходит. это должно создать экземпляр объекта «Dialog1» (в основном JDialog) под названием «Create Board» и предлагает пользователю ввести «Строки для региона» и «Столбцы для региона», а затем нажать «Создать панель» или нажать «Отмена» »и покончить с этим. Мне не хватает поля SudokuMain в разделах «Dialog1»? ... – adub3

+0

Попробуйте вызвать метод 'setVisible (boolean)' вашего диалога, как в 'createNewWin.setVisible (true);' после того, как вы его создадите. JDialog наследуется от [Dialog] (http://docs.oracle.com/javase/6/docs/api/java/awt/Dialog.html#setVisible%28boolean%29). – kevinsa5

Смежные вопросы