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

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

mercurial