2013-07-25 2 views
0

Я создаю игру Судоку, и я пытаюсь предоставить варианты сохранения, сохранения и открытия игр. Я использую JFileChooser для этого. Я могу сохранить (или «сохранить как»), но когда я пытаюсь открыть сохраненный файл, я получаю сообщение об ошибке. Я новичок в программировании, и я надеюсь, что кто-то сможет определить проблему и рассказать мне о том, как читать содержимое доски Sudoku, когда я экономлю (а также как бороться с воссозданием судоку, когда я открываю файл). Я слышал, что есть более простой способ справиться с этим, используя InputStream/OutputStream вместо Reader/Writer ...Судоку игра, проблема сериализации

Вот мой код для внутреннего класса, который реализует это (я не знаю, есть ли способ опубликовать весь мой класс без превышения максимально допустимой для данного текстового поля):.

// this inner class provides a JMenuBar object at the top of 
    // the board 
    class MenuAtTop extends JMenuBar implements ActionListener{ 

    // SudokuMain2 object we are dealing with 
    private SudokuMain2 main; 

    // the "File" menu 
    private JMenu fileMenu; 
    // the "New Game" option 
    private JMenuItem newGame; 
    // the "Open" option 
    private JMenuItem open; 
    // the "Save" option 
    private JMenuItem save; 
    // the "Save As" option 
    private JMenuItem saveAs; 
    // the "Reset" option 
    private JMenuItem reset; 
    // the "Quit" option 
    private JMenuItem quit; 

    // the ability to choose files 
    private JFileChooser choose; 

    // the saved file 
// // compiler would not allow "static" keyword 
    private File fileSaved = null; 

    private Object opener; 

    // JDialog object to create a dialog box to prompt 
    // user for new game information 
    private JDialog createNewWin; 

    /** 
    * Constructs MenuAtTop object. 
    * 
    * @param m The SudokuMain2 object to be referred to. 
    */ 
    public MenuAtTop(final SudokuMain2 m) { 

     main = m; 

     opener = null; 
     choose = new JFileChooser(); 

     // instantiate and bind to reference 
     fileMenu = new JMenu("File"); 
     add(fileMenu); 

     // instantiate and bind to reference 
     newGame = new JMenuItem("New Game"); 
     newGame.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 
                ActionEvent.CTRL_MASK)); 
     fileMenu.add(newGame); 
     newGame.addActionListener(this); 

     open = new JMenuItem("Open"); 
     open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, 
               ActionEvent.CTRL_MASK)); 
     fileMenu.add(open); 
     // add action listener to "Open" option 
     open.addActionListener(this); 

     save = new JMenuItem("Save"); 
     save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, 
               ActionEvent.CTRL_MASK)); 
     fileMenu.add(save); 
//  //save.setEnabled(false); 
     // add action listener to "Save" option 
     save.addActionListener(this); 

     saveAs = new JMenuItem("Save As"); 
     saveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, 
                ActionEvent.CTRL_MASK)); 
     fileMenu.add(saveAs); 
     // add action listener to "Save As" option 
     saveAs.addActionListener(this); 

     reset = new JMenuItem("Reset"); 
     reset.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, 
                ActionEvent.CTRL_MASK)); 
     fileMenu.add(reset); 
     // add action listener to "Reset" option 
     reset.addActionListener(this); 

     quit = new JMenuItem("Quit"); 
     quit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 
               ActionEvent.CTRL_MASK)); 
     fileMenu.add(quit); 
     // add action listener to "Quit" option 
     quit.addActionListener(this); 

    } 

    public void actionPerformed(ActionEvent e) { 
     if(e.getSource().equals(quit)) { 
     closePrompt(); 
     //main.win.dispose(); 
     } 
     else if(e.getSource().equals(reset)) { 
     int n = JOptionPane.showConfirmDialog(main.win, 
               "Any player values will" + 
               " be lost. Proceed?", 
               "Warning!", 2); 
     if(n == JOptionPane.OK_OPTION) { 
      main.board.reset(); 

      main.view.repaint(); 
     } 
     } 
     else if(e.getSource().equals(saveAs)) { 
     saveAs(); 
     } 
     else if(e.getSource().equals(save)) { 
     if(fileSaved == null) { 
      saveAs(); 
     } 
     else { 
      try { 
      board.writeToStream(new FileOutputStream(fileSaved)); 
//   main.board.setDirty(false); 
      } catch (Exception ex) { 
      JOptionPane.showMessageDialog(main.win, "Error saving file."); 
      } 
     } 
     } 

     else if(e.getSource().equals(open)) { 

     int returnVal = choose.showOpenDialog(main.win); 
     if(returnVal == JFileChooser.APPROVE_OPTION) { 
      boolean error = false; 
      File openFile = choose.getSelectedFile(); 

      try { 
      FileInputStream fin = new FileInputStream(openFile); 
      ObjectInputStream ois = new ObjectInputStream(fin); 
      opener = ois.readObject(); 
      } catch (Exception ex) { 
      JOptionPane.showMessageDialog(main.win, "Error opening file."); 
      error = true; 
      } 

      if(opener != null && opener instanceof SudokuBase){ 
      main.west.remove(main.symbols); 
      main.east.remove(main.view); 
      //add in state information for new board 
      main.south.remove(main.rowColRegStates); 

      main.view = new SudokuView((SudokuBase) opener); 
      main.symbols = new SetSymbols(main.view); 
      //add in state information for new board 
      main.rowColRegStates = new ShowStates(main.view); 

      main.west.add(main.symbols); 
      main.east.add(main.view); 
      //add in state information for new board 
      main.south.add(main.rowColRegStates); 

      main.win.requestFocus(); 

      fileSaved = openFile; 
//   main.board.setDirty(false); 
      } else { 
      if(error) { 
       JOptionPane.showMessageDialog(main.win, " Incorrect file type!"); 
      } 
      } 
     } 
     // else: user cancelled 
     } 
     else if(e.getSource().equals(newGame)) { 
     setEnabled(false); 
     // create dialog box prompting for the new board information 
     createNewWin = new Dialog1(main, "Create New Board", true); 
     // make it visible 
     createNewWin.setVisible(true); 

     fileSaved = null; 
     } 
    } 

    // This method prompts the user to choose a file to save to, 
    // and then saves the file. 
    private int saveAs() { 
     boolean saveError; 
     int rtn = choose.showSaveDialog(main.win); 

     if(rtn == JFileChooser.APPROVE_OPTION) { 
     saveError = false; 
     File fileSaveAs = choose.getSelectedFile(); 
     try { 
      board.writeToStream(new FileOutputStream(fileSaveAs)); 
     } catch (Exception e) { 
      JOptionPane.showMessageDialog(main.win, "Error saving file."); 
      saveError = true; 
     } 

     if(!saveError) { 
      fileSaved = fileSaveAs; 
//   main.board.setDirty(false); 
     } 
     } 

     return rtn; 

    } 

    /** 
    * Asks the user if they want to save before closing if changes were made. 
    */ 
    private void closePrompt() { 
     if(true) { //board.isDirty()) { 
     int n = JOptionPane.showConfirmDialog(main.win, "Save game?"); 
     if(n == JOptionPane.YES_OPTION) { 
      int saved = saveAs(); 
      if(saved != JFileChooser.CANCEL_OPTION){ 
      main.win.dispose(); 
      } 
     } 
     else if(n == JOptionPane.NO_OPTION) { 
      main.win.dispose(); 
     } 
     } 
     else 
     main.win.dispose(); 
    } 

    } 
+0

Что ошибка вы получаете? – tbodt

+4

* «Я получаю сообщение об ошибке». * Вы собираетесь поделиться с нами ошибкой или нам следует угадать? ОК .. для «TooManyKittensError», desex the tomcat из соседней двери. –

+0

Объект, содержащий информацию для сохранения, является экземпляром класса 'SudokuMain2'? Покажите нам класс ... –

ответ

0

Вот первая часть класса SudokuMain (я случайно положил «SudokuMain2» вместо «SudokuMain» в MenuAtTop, поэтому игнорировать 2):

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

public class SudokuMain extends JComponent { 

    /** 
    * The application method. 
    * 
    * @param args The command-line arguments. 
    */ 
    public static void main(String[] args) { 
    new SudokuMain(); 
    } 

    // this field refers to the SudokuBase class to access information 
    // of the board. 
    private SudokuBase board; 
    // this field refers to SudokuView object to access its information 
    // and provide output 
    private SudokuView view; 

    // the window all the components are contained in 
    private JFrame win; 
    // center JPanel object in window 
    private JPanel center; 
    // left JPanel object in window 
    private JPanel west; 
    // right JPanel object in window 
    private JPanel east; 
    // bottom JPanel object in window 
    private JPanel south; 

    // JPanel object to hold graphic "buttons" 
    private JPanel symbols; 
    // JPanel object to show "states" of Sudoku board 
    private JPanel rowColRegStates; 

    // the first set-up window (cannot be changed once 
    // instantiated) 
    private final Dialog1 setWin1; 

    /** 
    * Constructs SudokuMain object. 
    */ 
    public SudokuMain() { 

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

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

    // graphic "buttons" for current Sudoku board 
    symbols = new SetSymbols(view); 
    // "states" of current Sudoku board 
    rowColRegStates = new ShowStates(view); 

    // the first set-up window 
    setWin1 = new Dialog1(this, "New Game", true); 

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

    // display game mode 
    JLabel mode = new JLabel("Normal Play Mode"); 
    mode.setHorizontalAlignment(JLabel.CENTER); 
    Font modeFont = new Font("Arial", Font.BOLD, 14); 
    mode.setFont(modeFont); 

// // set selected cell at (0, 0) 
// view.setSelected(0, 0); 

    // add window focus listener 
    win.addWindowFocusListener(new WindowFocusListener() { 

     public void windowGainedFocus(WindowEvent e) { 
     win.pack(); 
     // set selected cell at (0, 0) 
     view.setSelected(0, 0); 
     } 

     public void windowLostFocus(WindowEvent e) { 
     } 
    }); 

    // add window listener 
    win.addWindowListener(new WindowAdapter() { 
     public void windowClosing(WindowEvent e) { 
     menuBar.closePrompt(); 
     } 
    }); 

    win.setLayout(new BorderLayout()); 
    west.setLayout(new BorderLayout()); 
    east.setLayout(new BorderLayout()); 
    center.setLayout(new FlowLayout()); 

    west.add(symbols); 
    east.add(view, BorderLayout.CENTER); 
    south.add(rowColRegStates); 
    center.add(west); 
    center.add(east); 

    win.add(south, BorderLayout.NORTH); 
    win.add(center, BorderLayout.CENTER); 
    win.add(mode, BorderLayout.SOUTH); 

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

    } 

    // this inner class constructs graphic "buttons" to set desired 
    // cells of board 
    class SudokuControlButton extends JPanel { 

    // 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. 
    * 
    * @param view The SudokuView object to be controlled. 
    * @param v The value that corresponds to the desired symbol. 
    */ 
    public SudokuControlButton(final SudokuView view, int v) { 
     // set characteristics of graphic "button" 
     setPreferredSize(new Dimension(50, 50)); 
     setBackground(Color.LIGHT_GRAY); 

     value = v; 

     addMouseListener(new MouseListener() { 

     /** 
     * This method selects a "button" and puts it in focus when the mouse 
     * is clicked on it. 
     * 
     * @param event Captures information on the mouse button being 
     *    clicked (pressed and released) on a component. 
     */ 
     public void mouseClicked(MouseEvent e) { 
      selRow = view.getSelectedRow(); 
      selCol = view.getSelectedColumn(); 

      if(!board.isGiven(selRow, selCol)) { 
      board.setValue(selRow, selCol, value); 
      view.new SudokuCell(selRow, selCol, board); 
      // set to "highlighted" color 
      setBackground(Color.WHITE); 
      view.repaint(); 
      } 
      else { // have system beep sound 
      getToolkit().beep(); 
      } 

      repaint(); 
     } 

     /** 
     * This method handles behavior when the mouse enters a graphic 
     * "button". 
     * 
     * @param event Captures information on the mouse button being 
     *    entered over a component. 
     */ 
     public void mouseEntered(MouseEvent e){ 
      // set to "highlighted" color 
      setBackground(Color.WHITE); 

      repaint(); 
     } 

     /** 
     * This method handles behavior when the mouse exits a graphic 
     * "button". 
     * 
     * @param event Captures information on the mouse button being 
     *    exited from a component. 
     */ 
     public void mouseExited(MouseEvent e){ 
      // set to default color 
      SudokuControlButton button = (SudokuControlButton) e.getSource(); 

      setBackground(Color.LIGHT_GRAY); 

      repaint(); 
     } 

     /** 
     * This method handles behavior when the mouse is pressed on a 
     * graphic "button". 
     * 
     * @param event Captures information on the mouse button being 
     *    pressed on a component. 
     */ 
     public void mousePressed(MouseEvent e){ 
      // set to "active" color 
      setBackground(Color.YELLOW); 

      repaint(); 
     } 

     /** 
     * This method handles behavior when the mouse is released on a 
     * graphic "button". 
     * 
     * @param e Captures information on the mouse button being 
     *    released on a component. 
     */ 
     public void mouseReleased(MouseEvent e){ 
     } 

     }); 

    } 

    /** 
    * This method draws the graphic "button" associated with 
    * each numeric value, 0 to 12. 
    * 
    * @param g The drawing mechanism. 
    */ 
    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 0 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; 
     } 

    } 

    } 

    // this inner class provides a JMenuBar object at the top of 
    // the board 
    class MenuAtTop extends JMenuBar implements ActionListener{ 

    // SudokuMain object we are dealing with 
    private SudokuMain main; 

    // the "File" menu 
    private JMenu fileMenu; 
    // the "New Game" option 
    private JMenuItem newGame; 
    // the "Open" option 
    private JMenuItem open; 
    // the "Save" option 
    private JMenuItem save; 
    // the "Save As" option 
    private JMenuItem saveAs; 
    // the "Reset" option 
    private JMenuItem reset; 
    // the "Quit" option 
    private JMenuItem quit; 

    // the ability to choose files 
    private JFileChooser choose; 

    // the saved file 
// // compiler would not allow "static" keyword 
    private File fileSaved = null; 

    private Object opener; 

    // JDialog object to create a dialog box to prompt 
    // user for new game information 
    private JDialog createNewWin; 

    /** 
    * Constructs MenuAtTop object. 
    * 
    * @param m The SudokuMain object to be referred to. 
    */ 
    public MenuAtTop(final SudokuMain m) { 

     main = m; 

     opener = null; 
     choose = new JFileChooser(); 

     // instantiate and bind to reference 
     fileMenu = new JMenu("File"); 
     add(fileMenu); 

     // instantiate and bind to reference 
     newGame = new JMenuItem("New Game"); 
     newGame.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 
                ActionEvent.CTRL_MASK)); 
     fileMenu.add(newGame); 
     newGame.addActionListener(this); 

     open = new JMenuItem("Open"); 
     open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, 
               ActionEvent.CTRL_MASK)); 
     fileMenu.add(open); 
     // add action listener to "Open" option 
     open.addActionListener(this); 

     save = new JMenuItem("Save"); 
     save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, 
               ActionEvent.CTRL_MASK)); 
     fileMenu.add(save); 
     // add action listener to "Save" option 
     save.addActionListener(this); 

     saveAs = new JMenuItem("Save As"); 
     saveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, 
                ActionEvent.CTRL_MASK)); 
     fileMenu.add(saveAs); 
     // add action listener to "Save As" option 
     saveAs.addActionListener(this); 

     reset = new JMenuItem("Reset"); 
     reset.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, 
                ActionEvent.CTRL_MASK)); 
     fileMenu.add(reset); 
     // add action listener to "Reset" option 
     reset.addActionListener(this); 

     quit = new JMenuItem("Quit"); 
     quit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 
               ActionEvent.CTRL_MASK)); 
     fileMenu.add(quit); 
     // add action listener to "Quit" option 
     quit.addActionListener(this); 

    } 

    public void actionPerformed(ActionEvent e) { 

     if(e.getSource().equals(newGame)) { 

     setEnabled(false); 
     // create dialog box prompting for the new board information 
     createNewWin = new Dialog1(main, "Create New Board", true); 
     // make it visible 
     createNewWin.setVisible(true); 

     fileSaved = null; 

     } else if(e.getSource().equals(open)) { 

     int returnVal = choose.showOpenDialog(main.win); 
     if(returnVal == JFileChooser.APPROVE_OPTION) { 
      boolean error = false; 
      File openFile = choose.getSelectedFile(); 

      try { 
      FileInputStream fin = new FileInputStream(openFile); 
      ObjectInputStream ois = new ObjectInputStream(fin); 
      opener = ois.readObject(); 
      } catch (Exception exc) { 
      JOptionPane.showMessageDialog(main.win, "Error opening file."); 
      error = true; 
      } 

      // "opener" reads something and it is of type SudokuBase 
      if(opener != null && opener instanceof SudokuBase){ 
      main.west.remove(main.symbols); 
      main.east.remove(main.view); 
      main.south.remove(main.rowColRegStates); 

      main.view = new SudokuView((SudokuBase) opener); 
      main.symbols = new SetSymbols(main.view); 
      main.rowColRegStates = new ShowStates(main.view); 

      main.west.add(main.symbols); 
      main.east.add(main.view); 
      main.south.add(main.rowColRegStates); 

      main.win.requestFocus(); 

      fileSaved = openFile; 
      } else { 
      if(error) { 
       JOptionPane.showMessageDialog(main.win, "Incorrect file type."); 
      } 
      } 
     } 

     } else if(e.getSource().equals(save)) { 

     if(fileSaved == null) { 
      saveAsPrompt(); 
     } else { 
      try { 
      board.writeToStream(new FileOutputStream(fileSaved)); 
      } catch (Exception exc) { 
      JOptionPane.showMessageDialog(main.win, "Error saving file."); 
      } 
     } 

     } else if(e.getSource().equals(saveAs)) { 
     saveAsPrompt(); 
     } else if(e.getSource().equals(reset)) { 

     int n = JOptionPane.showConfirmDialog(main.win, 
               "Any player values will" + 
               " be lost. Proceed?", 
               "Warning!", 2); 
     if(n == JOptionPane.OK_OPTION) { 
      main.board.reset(); 
      main.view.repaint(); 
     } 

     } else if(e.getSource().equals(quit)) { 
     closePrompt(); 
     } 

    } 

    // This method prompts the user to choose a file to save to, 
    // and then saves the file. 
    private int saveAsPrompt() { 
     boolean saveError; 
     int rtn = choose.showSaveDialog(main.win); 

     if(rtn == JFileChooser.APPROVE_OPTION) { 
     saveError = false; 
     File fileSaveAs = choose.getSelectedFile(); 
     try { 
      board.writeToStream(new FileOutputStream(fileSaveAs)); 
     } catch (Exception e) { 
      JOptionPane.showMessageDialog(main.win, "Error saving file."); 
      saveError = true; 
     } 

     if(!saveError) { 
      fileSaved = fileSaveAs; 
     } 
     } 

     return rtn; 

    } 

    // This method prompts the user whether they want to save before 
    // closing, only if changes occurred. 
    private void closePrompt() { 
     if(true) { 
     int n = JOptionPane.showConfirmDialog(main.win, "Save game?"); 
     if(n == JOptionPane.YES_OPTION) { 
      int saved = saveAsPrompt(); 
      if(saved != JFileChooser.CANCEL_OPTION){ 
      main.win.dispose(); 
      } 
     } else if(n == JOptionPane.NO_OPTION) { 
      main.win.dispose(); 
     } 
     } 
     else { // no changes were made 
     main.win.dispose(); 
     } 
    } 

    } 

...

0

... // вторая и заключительная часть класса SudokuMain

// this inner class provides a dialog box to prompt the user 
    // for new board information 
    class Dialog1 extends JDialog { 

    // rows for new game 
    private JTextField rows; 
    // cols for new game 
    private JTextField cols; 
    // button to create a new board 
    private JButton createBoard; 
    // button to cancel new board and return to 
    // previous game 
    private JButton cancel; 
    // labels for rows per region 
    private JLabel rowLabel; 
    // label for columns per region 
    private JLabel colLabel; 
    // label dislayed when error occurs 
    private JLabel errorMes; 

    // JPanel object to house error message 
    private JPanel center; 
    // JPanel object to house rows and columns prompt 
    private JPanel north; 
    // JPanel object to house create new board and cancel buttons 
    private JPanel south; 
    // JDialog object to create window for new game 
    private JDialog createWin2; 

    /** 
    * Constructs Dialog1 object. 
    * 
    * @param win The window containing the dialog box. 
    * @param header The title of the 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 New 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()); 
     south = 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); 

     // keep track of "old" board 
     final SudokuBase oldBoard = board; 

     // add action listener for "Cancel" button 
     cancel.addActionListener(new ActionListener() { 

     /** 
     * This method handles the action of activating the 
     * "Cancel" button to make the dialog box "invisible". 
     * 
     * @param e Captures information about the event that occurred. 
     */ 
     public void actionPerformed(ActionEvent e) { 
      setVisible(false); 
     } 
     }); 

     // add action listener for "Create Board" button 
     createBoard.addActionListener(new ActionListener() { 

     /** 
     * This method handles the action of activating the 
     * "Cancel" button to make the dialog box "invisible". 
     * 
     * @param e Captures information about the event that occurred. 
     */ 
     public void actionPerformed(ActionEvent e) { 
      int newRows; 
      int newCols; 
      int newSize; 

      // handles potential exception when converting String input 
      // to int 
      try{ 
      newRows = Integer.parseInt(rows.getText()); 
      newCols = Integer.parseInt(cols.getText()); 
      } catch (NumberFormatException nfe) { 
      newRows = 0; 
      newCols = 0; 
      } 

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

      } else { 
      errorMes.setVisible(false); 
      setVisible(false); 

      // update board to new board 
      board = new SudokuBoard(newRows, newCols); 
      createWin2 = new Dialog2(win, oldBoard, view, symbols, newRows, 
            newCols, "New Sudoku Game", 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); 
     // place both buttons at bottom 
     south.add(createBoard); 
     south.add(cancel); 

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

     pack(); 

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

    } 
    } 

    // this inner class a dialog box to house a new game 
    class Dialog2 extends JDialog { 

    // view to be used 
    private SudokuView view; 

    // the panel to house the board (view) and both the 
    // "Set givens" and "Cancel" buttons 
    private JPanel panel; 
    // panel placed within "panel" that houses both the "Set givens" 
    // and "Cancel" buttons 
    private JPanel northPanel; 
    // panel to house the graphic "buttons" 
    private JPanel symbols; 

    // "Set givens" button 
    private JButton setGivenCells; 
    // "Cancel" button 
    private JButton cancel; 

    /** 
    * Constructs Dialog2 object. 
    * 
    * @param win The window containing the dialog box. 
    * @param oldBoard The "old" SudokuBoard to keep track of. 
    * @param oldView The "old" SudokuView to keep track of. 
    * @param oldSymbols The "old" graphic "buttons" to keep track of. 
    * @param rows The rows of the new Sudoku board to be created. 
    * @param cols The columns of the new Sudoku board to be created. 
    * @param header The title of the dialog box. 
    * @param modal Whether the dialog box is modal or not. 
    */ 
    public Dialog2(final SudokuMain mainWin, final SudokuBase oldBoard, 
        final SudokuView oldView, final JPanel oldSymbols, 
        int rows, int cols, String header, boolean modal) { 
     // call superclass constructor 
     super(); 

     // instantiate and bind to references 
     view = new SudokuView(board); 
     panel = new JPanel(); 
     northPanel = new JPanel(); 
     setGivenCells = new JButton("Set givens"); 
     cancel = new JButton("Cancel"); 
     symbols = new SetSymbols(view); 

     // create menu bar 
     final MenuAtTop menuBar = new MenuAtTop(mainWin); 
     setJMenuBar(menuBar); 

     // display "Set-Up Mode" 
     final JLabel setupMode = new JLabel("Set-Up Mode"); 
     setupMode.setHorizontalAlignment(JLabel.CENTER); 
     Font setupModeFont = new Font("Comic Sans MS", Font.BOLD, 18); 
     setupMode.setFont(setupModeFont); 
     setupMode.setForeground(Color.RED); 

     // display "Normal Play Mode" 
     final JLabel mode = new JLabel("Normal Play Mode"); 
     mode.setHorizontalAlignment(JLabel.CENTER); 
     Font modeFont = new Font("Arial", Font.BOLD, 14); 
     mode.setFont(modeFont); 

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

     // add action listener to "Set givens" button 
     setGivenCells.addActionListener(new ActionListener() { 

     /** 
     * This method handles the action of activating the 
     * "Set givens" button. 
     * 
     * @param e Captures information about the event that occurred. 
     */ 
     public void actionPerformed(ActionEvent e) { 
      // set "given" cells 
      board.fixGivens(); 

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

      // remove "Set-Up Mode" label and replace with 
      // "Normal Play Mode" label 
      panel.remove(setupMode); 
      panel.add(mode, BorderLayout.SOUTH); 

      // disable both buttons 
      setGivenCells.setEnabled(false); 
      cancel.setEnabled(false); 

      validate(); 
      repaint(); 

     } 
     }); 

     // add action listener to "Cancel" button 
     cancel.addActionListener(new ActionListener() { 

     /** 
     * This method handles the action of activating the 
     * "Cancel" button. 
     * 
     * @param e Captures information about the event that occurred. 
     */ 
     public void actionPerformed(ActionEvent e) { 
      // have window refer to "old" board 
      board = oldBoard; 

      mainWin.west.remove(mainWin.symbols); 
      mainWin.east.remove(mainWin.view); 

      mainWin.view = oldView; 
      mainWin.symbols = oldSymbols; 

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

      // disable both buttons 
      setGivenCells.setEnabled(false); 
      cancel.setEnabled(false); 

      setVisible(false); 

      repaint(); 

     } 
     }); 

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

     // place board to fill remainder of space not 
     // occupied by buttons at the top 
     panel.add(view, BorderLayout.CENTER); 
     panel.add(northPanel, BorderLayout.NORTH); 
     panel.add(setupMode, BorderLayout.SOUTH); 

     // place graphic "buttons" to left of board 
     add(symbols); 
     add(panel); 

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

    } 

    } 



// this inner class creates the graphic "buttons" to set the selected cell 
    // to the desired "button" 
    class SetSymbols extends JPanel { 

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

    private int value; 

    /** 
    * 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 colSymbol = 0; colSymbol < tempBd.getBoardSize(); colSymbol++) { 
     // keep track of value of graphic "button" 
     value = colSymbol; 

     final JPanel symPanel = new JPanel(); 

     // set value for each graphic "button" 
     tempBd.setValue(0, colSymbol, colSymbol); 
     // add the appropriate symbol to each graphic "button" 
     symPanel.add(new SudokuControlButton(view, value)); 

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

     } 

    } 

    /** 
    * Draws the symbol associated with each 
    * numeric value (0 to 12) on the non-given 
    * selected cell. 
    * 
    * @param g The drawing mechanism. 
    */ 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     // get selected cell information from SudokuView reference 
     int row = view.getSelectedRow(); 
     int col = view.getSelectedColumn(); 

     switch(value) { 
     case 0: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 1: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 2: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 3: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 4: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 5: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 6: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 7: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 8: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 9: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 10: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 11: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     case 12: 
      view.new SudokuCell(row, col, board).drawSymbol(g, row, col); 
      break; 
     } 

    } 

    } 

    // this inner class displays the state information for each row, column, and region 
    class ShowStates extends JPanel{ 

    // the SudokuView object to be used 
    private SudokuView view; 

    // JPanel for row state 
    private JPanel rowSt; 
    // JPanel for column state 
    private JPanel columnSt; 
    // JPanel for region state 
    private JPanel regionSt; 
    // displays row state 
    private JPanel[] rowStColor; 
    // displays column state 
    private JPanel[] columnStColor; 
    // displays region state 
    private JPanel[] regionStColor; 

    // number of rows per region 
    private int rows; 
    // number of columns per region 
    private int columns; 
    // size per region (rows * columns) 
    private int size; 

    /** 
    * Constructs the ShowStates object. 
    * 
    * @param view The SudokuView object for ShowStates. 
    */ 
    public ShowStates(SudokuView v) { 

     // bind to references 
     rows = board.getRowsPerRegion(); 
     columns = board.getColumnsPerRegion(); 
     size = rows * columns; 

     // bind to reference 
     view = v; 

     // row characteristics 
     rowSt = new JPanel(); 
     rowSt.setLayout(new GridLayout(size, 1)); 
     rowStColor = new JPanel[size]; 
     rowSt.setPreferredSize(new Dimension(50, 50)); 
     rowSt.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

     // column characteristics 
     columnSt = new JPanel(); 
     columnSt.setLayout(new GridLayout(1, size)); 
     columnStColor = new JPanel[size]; 
     columnSt.setPreferredSize(new Dimension(50, 50)); 
     columnSt.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

     // region characteristics 
     regionSt = new JPanel(); 
     regionSt.setLayout(new GridLayout(rows, columns)); 
     regionStColor = new JPanel[size]; 
     regionSt.setPreferredSize(new Dimension(50, 50)); 
     regionSt.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

     for(int i = 0; i < size; i++) { 
     // instantiate and bind to references 
     JPanel rowPanel = new JPanel(); 
     JPanel columnPanel = new JPanel(); 
     JPanel regionPanel = new JPanel(); 

     rowStColor[i] = rowPanel; 
     columnStColor[i] = columnPanel; 
     regionStColor[i] = regionPanel; 

     // add to respective JPanel objects 
     rowSt.add(rowPanel); 
     columnSt.add(columnPanel); 
     regionSt.add(regionPanel); 
     } 

     // add each state to "this" JPanel 
     add(rowSt); 
     add(columnSt); 
     add(regionSt); 

    } 

    /** 
    * This method draws the appropriate color to display the state information. 
    * 
    * @param g The drawing mechanism. 
    */ 
    public void paintComponent(java.awt.Graphics g) { 
     super.paintComponent(g); 

     for(int i = 0; i < rows * columns; i++) { 

     // check the state of each row 
     if(board.getRowState(i) == SudokuBase.State.ERROR){ 
      rowStColor[i].setBackground(Color.RED); 
     } 
     else if(board.getRowState(i) == SudokuBase.State.INCOMPLETE) { 
      rowStColor[i].setBackground(Color.YELLOW); 
     } 
     else { // board.getRowState(i) == SudokuBase.State.COMPLETE 
      rowStColor[i].setBackground(Color.GREEN); 
     } 

     // check the state of each column 
     if(board.getColumnState(i) == SudokuBase.State.ERROR){ 
      columnStColor[i].setBackground(Color.RED); 
     } 
     else if(board.getColumnState(i) == SudokuBase.State.INCOMPLETE) { 
      columnStColor[i].setBackground(Color.YELLOW); 
     } 
     else { // board.getColumnState(i) == SudokuBase.State.COMPLETE 
      columnStColor[i].setBackground(Color.GREEN); 
     } 

     // check the state of each region 
     if(board.getRegionState(i) == SudokuBase.State.ERROR){ 
      regionStColor[i].setBackground(Color.RED); 
     } 
     else if(board.getRegionState(i) == SudokuBase.State.INCOMPLETE) { 
      regionStColor[i].setBackground(Color.YELLOW); 
     } 
     else { // board.getRegionState(i) == SudokuBase.State.COMPLETE 
      regionStColor[i].setBackground(Color.GREEN); 
     } 

     } 

    } 

    } 

    /** 
    * This method provides a pre-set board to start with in 
    * "Normal Play" mode. 
    * 
    * @return The board with the "givens" already set. 
    */ 
    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; 
    } 

} 
+0

Вот класс SudokuMain в 2 взноса. Я знаю, что они не ответы, но я не знал, как еще опубликовать мой огромный класс. – adub3

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