src/main/java/de/uapcore/sudoku/ActionHandler.java

Sat, 25 Jul 2020 15:29:51 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 25 Jul 2020 15:29:51 +0200
changeset 10
369903afbb29
parent 9
576e7a2861ae
child 12
1c62c6009161
permissions
-rw-r--r--

adds more javadoc

     1 /*
     2  * Copyright 2013 Mike Becker. All rights reserved.
     3  *
     4  * Redistribution and use in source and binary forms, with or without
     5  * modification, are permitted provided that the following conditions are met:
     6  *
     7  * 1. Redistributions of source code must retain the above copyright
     8  *    notice, this list of conditions and the following disclaimer.
     9  *
    10  * 2. Redistributions in binary form must reproduce the above copyright
    11  *    notice, this list of conditions and the following disclaimer in the
    12  *    documentation and/or other materials provided with the distribution.
    13  *
    14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    24  * POSSIBILITY OF SUCH DAMAGE.
    25  */
    27 package de.uapcore.sudoku;
    29 import javax.swing.*;
    30 import java.awt.event.ActionEvent;
    31 import java.awt.event.ActionListener;
    32 import java.io.File;
    33 import java.io.IOException;
    35 /**
    36  * Handles all user issued actions in the application.
    37  */
    38 public final class ActionHandler implements ActionListener {
    40     public static final String SAVE = "save";
    41     public static final String CHECK = "check";
    42     public static final String SOLVE = "solve";
    44     public static final String NEW = "new";
    45     public static final String OPEN = "open";
    46     public static final String SAVE_AS = "save as";
    47     public static final String QUIT = "quit";
    48     public static final String ABOUT = "about";
    50     private Field field;
    51     private Solver solver;
    52     private DocumentHandler doc;
    54     /**
    55      * Constructs a new action handler instance.
    56      *
    57      * @param f a reference to the playing field
    58      */
    59     public ActionHandler(Field f) {
    60         field = f;
    61         solver = new Solver();
    62         doc = new DocumentHandler();
    63     }
    65     /**
    66      * Prompts the user for a file name.
    67      * <p>
    68      * If the user chooses an existing file, they are asked whether the file should be overwritten.
    69      *
    70      * @return true if the user approves a chosen file name
    71      */
    72     private boolean chooseSaveFilename() {
    73         JFileChooser fc = new JFileChooser(".");
    74         fc.setMultiSelectionEnabled(false);
    75         if (fc.showSaveDialog(field) == JFileChooser.APPROVE_OPTION) {
    76             File f = fc.getSelectedFile();
    77             if (f.exists()) {
    78                 int result = JOptionPane.showConfirmDialog(field,
    79                         "Bereits existierende Datei überschreiben?", "Sudoku",
    80                         JOptionPane.YES_NO_OPTION);
    81                 if (result == JOptionPane.YES_OPTION) {
    82                     doc.setFilename(f.getAbsolutePath());
    83                     return true;
    84                 } else {
    85                     return false;
    86                 }
    87             } else {
    88                 doc.setFilename(f.getAbsolutePath());
    89                 return true;
    90             }
    91         } else {
    92             return false;
    93         }
    94     }
    96     /**
    97      * Prompts the user for a file to open and, if approved, loads that file.
    98      */
    99     private void open() {
   100         JFileChooser fc = new JFileChooser(".");
   101         fc.setMultiSelectionEnabled(false);
   102         if (fc.showOpenDialog(field) == JFileChooser.APPROVE_OPTION) {
   103             File f = fc.getSelectedFile();
   104             doc.setFilename(f.getAbsolutePath());
   105             try {
   106                 doc.load(field);
   107             } catch (IOException e) {
   108                 JOptionPane.showMessageDialog(field,
   109                         "Datei konnte nicht geladen werden: " + e.getMessage(),
   110                         "Sudoku", JOptionPane.ERROR_MESSAGE);
   111             }
   112         }
   113     }
   115     /**
   116      * Attempts to save the Sudoku field to a file.
   117      * <p>
   118      * If necessary, the user is prompted for a file name.
   119      * <p>
   120      * The field must be solvable, otherwise it cannot be saved.
   121      *
   122      * @param rename true if the user shall always be prompted, even if a file name is already known
   123      * @return true if the user approves the chosen file name
   124      */
   125     private boolean save(boolean rename) {
   126         if (!doc.isFilenameSet() || rename) {
   127             if (!chooseSaveFilename()) {
   128                 return false;
   129             }
   130         }
   131         if (solver.check(field)) {
   132             field.setAllCellsModified(false);
   133             try {
   134                 doc.save(field);
   135             } catch (IOException e) {
   136                 JOptionPane.showMessageDialog(field,
   137                         "Datei konnte nicht gespeichert werden: " + e.getMessage(),
   138                         "Sudoku", JOptionPane.ERROR_MESSAGE);
   139             }
   140             return true;
   141         } else {
   142             JOptionPane.showMessageDialog(field,
   143                     "Das Feld kann mit Fehlern nicht gespeichert werden!",
   144                     "Sudoku", JOptionPane.ERROR_MESSAGE);
   145             return false;
   146         }
   147     }
   149     /**
   150      * Checks the Sudoku field and displays the result as a dialog box.
   151      */
   152     private void check() {
   153         if (solver.check(field)) {
   154             JOptionPane.showMessageDialog(field, "Überprüfung erfolgreich!",
   155                     "Sudoku", JOptionPane.INFORMATION_MESSAGE);
   156         } else {
   157             JOptionPane.showMessageDialog(field, "Das Feld enthält Fehler!",
   158                     "Sudoku", JOptionPane.WARNING_MESSAGE);
   159         }
   160     }
   162     /**
   163      * Solves the field or displays an error dialog if the field is not solvable.
   164      */
   165     private void solve() {
   166         if (!solver.check(field) || !solver.solve(field)) {
   167             JOptionPane.showMessageDialog(field, "Das Feld ist nicht lösbar!",
   168                     "Sudoku", JOptionPane.WARNING_MESSAGE);
   169         }
   170     }
   172     /**
   173      * Checks whether there are unsaved changes and asks the user to save the field.
   174      *
   175      * @return true if there are no unsaved changes or the user actively decides to continue - false, otherwise
   176      */
   177     private boolean saveUnsaved() {
   178         boolean proceed = false;
   179         if (field.isAnyCellModified()) {
   180             int result = JOptionPane.showConfirmDialog(field,
   181                     "Das Feld ist ungespeichert - jetzt speichern?",
   182                     "Sudoku", JOptionPane.YES_NO_CANCEL_OPTION);
   183             if (result == JOptionPane.YES_OPTION) {
   184                 if (save(false)) {
   185                     proceed = true;
   186                 }
   187             } else if (result == JOptionPane.NO_OPTION) {
   188                 proceed = true;
   189             }
   190         } else {
   191             proceed = true;
   192         }
   194         return proceed;
   195     }
   197     @Override
   198     public void actionPerformed(ActionEvent e) {
   199         switch (e.getActionCommand()) {
   200             case NEW:
   201                 if (saveUnsaved()) {
   202                     doc.clearFilename();
   203                     field.clear();
   204                 }
   205                 break;
   206             case OPEN:
   207                 open();
   208                 break;
   209             case SAVE:
   210                 save(false);
   211                 break;
   212             case SAVE_AS:
   213                 save(true);
   214                 break;
   215             case CHECK:
   216                 check();
   217                 break;
   218             case SOLVE:
   219                 solve();
   220                 break;
   221             case QUIT:
   222                 if (saveUnsaved()) {
   223                     System.exit(0);
   224                 }
   225                 break;
   226             case ABOUT:
   227                 JOptionPane.showMessageDialog(field,
   228                         "Sudoku - Copyright (c) 2013 Mike Becker\nwww.uap-core.de" +
   229                                 "\nPublished under the BSD License",
   230                         "Sudoku", JOptionPane.INFORMATION_MESSAGE);
   231                 break;
   232             default:
   233                 throw new UnsupportedOperationException(
   234                         "unknown action: " + e.getActionCommand());
   235         }
   236     }
   238 }

mercurial