2013-07-25 53 views
0

我正在创建数独游戏,我正在尝试提供用于保存,另存为和打开游戏的选项。我正在使用JFileChooser来做到这一点。我可以保存(或“另存为”),但是当我尝试打开保存的文件时,出现错误。我是编程新手,我希望有人能够发现问题并教我如何在储蓄时阅读Sudoku板的内容(以及如何在打开时重新创建Sudoku板文件)。我听到有一种更简单的方法来处理这个使用InputStream/OutputStream而不是读/写器...数独游戏,序列化问题

这里是我的内部类的代码实现了这一点(我不知道是否有办法发布我不超出字符限制该文本框整个班级):

// 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',请从隔壁的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课程。我知道他们不是答案,但我不知道如何发布我的大班。 – adub3