# HG changeset patch # User Mike Becker # Date 1359221892 -3600 # Node ID ed931970b4ac142d11cd71456d9cd4741dfb2b74 # Parent 5179eff8a9b69c7de03a6a4e0b7d69580e40fb25 added license and main menu diff -r 5179eff8a9b6 -r ed931970b4ac LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENSE Sat Jan 26 18:38:12 2013 +0100 @@ -0,0 +1,25 @@ +Copyright 2013 Mike Becker. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + diff -r 5179eff8a9b6 -r ed931970b4ac src/de/uapcore/sudoku/ActionHandler.java --- a/src/de/uapcore/sudoku/ActionHandler.java Sat Jan 26 17:42:07 2013 +0100 +++ b/src/de/uapcore/sudoku/ActionHandler.java Sat Jan 26 18:38:12 2013 +0100 @@ -1,3 +1,29 @@ +/* + * Copyright 2013 Mike Becker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + package de.uapcore.sudoku; import java.awt.event.ActionEvent; @@ -14,6 +40,12 @@ public static final String CHECK = "check"; public static final String SOLVE = "solve"; + public static final String NEW = "new"; + public static final String OPEN = "open"; + public static final String SAVE_AS = "save as"; + public static final String QUIT = "quit"; + public static final String ABOUT = "about"; + private Field field; private Solver solver; @@ -22,14 +54,16 @@ solver = new Solver(); } - private void save() { + private boolean save() { if (solver.check(field)) { field.setAllCellsModified(false); // TODO: save to file + return true; } else { JOptionPane.showMessageDialog(field, "Das Feld kann mit Fehlern nicht gespeichert werden!", "Sudoku", JOptionPane.ERROR_MESSAGE); + return false; } } @@ -50,15 +84,37 @@ @Override public void actionPerformed(ActionEvent e) { switch (e.getActionCommand()) { - case "save": + case SAVE: save(); break; - case "check": + case CHECK: check(); break; - case "solve": + case SOLVE: solve(); break; + case QUIT: + if (field.isAnyCellModified()) { + int result = JOptionPane.showConfirmDialog(field, + "Das Feld ist ungespeichert - jetzt speichern?", + "Sudoku", JOptionPane.YES_NO_CANCEL_OPTION); + if (result == JOptionPane.YES_OPTION) { + if (save()) { + System.exit(0); + } + } else if (result == JOptionPane.NO_OPTION) { + System.exit(0); + } + } else { + System.exit(0); + } + break; + case ABOUT: + JOptionPane.showMessageDialog(field, + "Sudoku - Copyright (c) 2013 Mike Becker\nwww.uap-core.de"+ + "\nPublished under the BSD License", + "Sudoku", JOptionPane.INFORMATION_MESSAGE); + break; default: throw new UnsupportedOperationException( "unknown action: "+e.getActionCommand()); diff -r 5179eff8a9b6 -r ed931970b4ac src/de/uapcore/sudoku/ButtonPanel.java --- a/src/de/uapcore/sudoku/ButtonPanel.java Sat Jan 26 17:42:07 2013 +0100 +++ b/src/de/uapcore/sudoku/ButtonPanel.java Sat Jan 26 18:38:12 2013 +0100 @@ -1,3 +1,29 @@ +/* + * Copyright 2013 Mike Becker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + package de.uapcore.sudoku; import java.awt.Color; diff -r 5179eff8a9b6 -r ed931970b4ac src/de/uapcore/sudoku/Field.java --- a/src/de/uapcore/sudoku/Field.java Sat Jan 26 17:42:07 2013 +0100 +++ b/src/de/uapcore/sudoku/Field.java Sat Jan 26 18:38:12 2013 +0100 @@ -1,3 +1,29 @@ +/* + * Copyright 2013 Mike Becker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + package de.uapcore.sudoku; import java.awt.Color; diff -r 5179eff8a9b6 -r ed931970b4ac src/de/uapcore/sudoku/MainMenu.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/de/uapcore/sudoku/MainMenu.java Sat Jan 26 18:38:12 2013 +0100 @@ -0,0 +1,101 @@ +/* + * Copyright 2013 Mike Becker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package de.uapcore.sudoku; + +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; + +/** + * + * @author mike + */ +public class MainMenu { + + private ActionHandler handler; + private JMenuBar menuBar; + + public MainMenu(ActionHandler h) { + handler = h; + menuBar = new JMenuBar(); + menuBar.add(createMenu("Datei", 'd', + createMenuItem("Neu", 'n', "control N", ActionHandler.NEW), + createMenuItem("Öffnen", 'f', "control O", ActionHandler.OPEN), + createMenuItem("Speichern", 's', "control S", ActionHandler.SAVE), + createMenuItem("Speichern als...", 'a', ActionHandler.SAVE_AS), + createSeparator(), + createMenuItem("Prüfen", 'p', "control P", ActionHandler.CHECK), + createMenuItem("Lösen", 'l', "control L", ActionHandler.SOLVE), + createSeparator(), + createMenuItem("Beenden", 'e', ActionHandler.QUIT) + )); + menuBar.add(createMenu("Help", 'h', + createMenuItem("Über...", 'b', "F1", ActionHandler.ABOUT) + )); + } + + private JMenuItem createSeparator() { + // Return null, the createMenu method knows how to handle it + return null; + } + + private JMenu createMenu(String caption, char mnemonic, JMenuItem...items) { + JMenu menu = new JMenu(caption); + menu.setMnemonic(mnemonic); + for (JMenuItem item : items) { + if (item == null) { + menu.addSeparator(); + } else { + menu.add(item); + } + } + return menu; + } + + private JMenuItem createMenuItem(String caption, char mnemonic, + String command) { + return createMenuItem(caption, mnemonic, null, command); + } + + private JMenuItem createMenuItem(String caption, char mnemonic, + String stroke, String command) { + JMenuItem item = new JMenuItem(caption); + item.setMnemonic(mnemonic); + if (stroke != null) { + item.setAccelerator(KeyStroke.getKeyStroke(stroke)); + } + item.setActionCommand(command); + item.addActionListener(handler); + + return item; + } + + public JMenuBar getMenuBar() { + return menuBar; + } +} diff -r 5179eff8a9b6 -r ed931970b4ac src/de/uapcore/sudoku/Solver.java --- a/src/de/uapcore/sudoku/Solver.java Sat Jan 26 17:42:07 2013 +0100 +++ b/src/de/uapcore/sudoku/Solver.java Sat Jan 26 18:38:12 2013 +0100 @@ -1,3 +1,29 @@ +/* + * Copyright 2013 Mike Becker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + package de.uapcore.sudoku; /** diff -r 5179eff8a9b6 -r ed931970b4ac src/de/uapcore/sudoku/Sudoku.java --- a/src/de/uapcore/sudoku/Sudoku.java Sat Jan 26 17:42:07 2013 +0100 +++ b/src/de/uapcore/sudoku/Sudoku.java Sat Jan 26 18:38:12 2013 +0100 @@ -1,11 +1,37 @@ +/* + * Copyright 2013 Mike Becker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + package de.uapcore.sudoku; import java.awt.Color; +import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JFrame; -import javax.swing.JRootPane; /** * @@ -18,21 +44,22 @@ Field f = new Field(); ActionHandler h = new ActionHandler(f); + setJMenuBar(new MainMenu(h).getMenuBar()); - JRootPane root = getRootPane(); + Container content = getContentPane(); - root.setLayout(new GridBagLayout()); + content.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(20, 20, 20, 20); c.fill = GridBagConstraints.HORIZONTAL; c.gridx = 0; c.gridy = 0; - root.add(f, c); + content.add(f, c); c.gridy++; - root.add(new ButtonPanel(h), c); + content.add(new ButtonPanel(h), c); pack(); - root.setBackground(Color.WHITE); + content.setBackground(Color.WHITE); setLocationByPlatform(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } diff -r 5179eff8a9b6 -r ed931970b4ac src/de/uapcore/sudoku/SudokuTextField.java --- a/src/de/uapcore/sudoku/SudokuTextField.java Sat Jan 26 17:42:07 2013 +0100 +++ b/src/de/uapcore/sudoku/SudokuTextField.java Sat Jan 26 18:38:12 2013 +0100 @@ -1,3 +1,29 @@ +/* + * Copyright 2013 Mike Becker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + package de.uapcore.sudoku; import java.awt.Color; @@ -31,19 +57,23 @@ addKeyListener(new KeyAdapter() { private void handle(KeyEvent e) { - if (getText().length() > 0 && getSelectedText() == null) { - int c = e.getKeyCode(); - if (c != KeyEvent.VK_DELETE && - c != KeyEvent.VK_BACK_SPACE && - !e.isActionKey()) { + char c = e.getKeyChar(); + if (!e.isAltDown() && !e.isControlDown() && + Character.isLetterOrDigit(c)) { + // Perform clean input check + if (getText().length() > 0 && getSelectedText() == null) { e.consume(); + } else { + if (c < '1' || c > '9') { + e.consume(); + } else { + setModified(true); + } } } else { - char c = e.getKeyChar(); - if (c < '0' || c > '9') { - e.consume(); - } else { - setModified(true); + // We can still be tricked by hotkeys, so do it the hard way + if (!getText().matches("^[1-9]$")) { + setText(""); } } }