converts to maven project

Sat, 25 Jul 2020 14:01:28 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 25 Jul 2020 14:01:28 +0200
changeset 9
576e7a2861ae
parent 8
e70a0e3555fb
child 10
369903afbb29

converts to maven project

.hgignore file | annotate | diff | comparison | revisions
build.xml file | annotate | diff | comparison | revisions
nbproject/build-impl.xml file | annotate | diff | comparison | revisions
nbproject/genfiles.properties file | annotate | diff | comparison | revisions
nbproject/project.properties file | annotate | diff | comparison | revisions
nbproject/project.xml file | annotate | diff | comparison | revisions
pom.xml file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/ActionHandler.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/ButtonPanel.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/DocumentHandler.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/Field.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/MainMenu.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/Solver.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/Sudoku.java file | annotate | diff | comparison | revisions
src/de/uapcore/sudoku/SudokuTextField.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/sudoku/ActionHandler.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/sudoku/ButtonPanel.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/sudoku/DocumentHandler.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/sudoku/Field.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/sudoku/MainMenu.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/sudoku/Solver.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/sudoku/Sudoku.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/sudoku/SudokuTextField.java file | annotate | diff | comparison | revisions
     1.1 --- a/.hgignore	Fri Feb 01 10:18:47 2013 +0100
     1.2 +++ b/.hgignore	Sat Jul 25 14:01:28 2020 +0200
     1.3 @@ -3,3 +3,5 @@
     1.4  \.chg\..*$
     1.5  \.rej$
     1.6  \.conflict\~$
     1.7 +.iml$
     1.8 +.idea/
     2.1 --- a/build.xml	Fri Feb 01 10:18:47 2013 +0100
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,74 +0,0 @@
     2.4 -<?xml version="1.0" encoding="UTF-8"?>
     2.5 -<!-- You may freely edit this file. See commented blocks below for -->
     2.6 -<!-- some examples of how to customize the build. -->
     2.7 -<!-- (If you delete it and reopen the project it will be recreated.) -->
     2.8 -<!-- By default, only the Clean and Build commands use this build script. -->
     2.9 -<!-- Commands such as Run, Debug, and Test only use this build script if -->
    2.10 -<!-- the Compile on Save feature is turned off for the project. -->
    2.11 -<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
    2.12 -<!-- in the project's Project Properties dialog box.-->
    2.13 -<project name="Sudoku" default="default" basedir=".">
    2.14 -    <description>Builds, tests, and runs the project Sudoku.</description>
    2.15 -    <import file="nbproject/build-impl.xml"/>
    2.16 -    <!--
    2.17 -
    2.18 -    There exist several targets which are by default empty and which can be 
    2.19 -    used for execution of your tasks. These targets are usually executed 
    2.20 -    before and after some main targets. They are: 
    2.21 -
    2.22 -      -pre-init:                 called before initialization of project properties
    2.23 -      -post-init:                called after initialization of project properties
    2.24 -      -pre-compile:              called before javac compilation
    2.25 -      -post-compile:             called after javac compilation
    2.26 -      -pre-compile-single:       called before javac compilation of single file
    2.27 -      -post-compile-single:      called after javac compilation of single file
    2.28 -      -pre-compile-test:         called before javac compilation of JUnit tests
    2.29 -      -post-compile-test:        called after javac compilation of JUnit tests
    2.30 -      -pre-compile-test-single:  called before javac compilation of single JUnit test
    2.31 -      -post-compile-test-single: called after javac compilation of single JUunit test
    2.32 -      -pre-jar:                  called before JAR building
    2.33 -      -post-jar:                 called after JAR building
    2.34 -      -post-clean:               called after cleaning build products
    2.35 -
    2.36 -    (Targets beginning with '-' are not intended to be called on their own.)
    2.37 -
    2.38 -    Example of inserting an obfuscator after compilation could look like this:
    2.39 -
    2.40 -        <target name="-post-compile">
    2.41 -            <obfuscate>
    2.42 -                <fileset dir="${build.classes.dir}"/>
    2.43 -            </obfuscate>
    2.44 -        </target>
    2.45 -
    2.46 -    For list of available properties check the imported 
    2.47 -    nbproject/build-impl.xml file. 
    2.48 -
    2.49 -
    2.50 -    Another way to customize the build is by overriding existing main targets.
    2.51 -    The targets of interest are: 
    2.52 -
    2.53 -      -init-macrodef-javac:     defines macro for javac compilation
    2.54 -      -init-macrodef-junit:     defines macro for junit execution
    2.55 -      -init-macrodef-debug:     defines macro for class debugging
    2.56 -      -init-macrodef-java:      defines macro for class execution
    2.57 -      -do-jar-with-manifest:    JAR building (if you are using a manifest)
    2.58 -      -do-jar-without-manifest: JAR building (if you are not using a manifest)
    2.59 -      run:                      execution of project 
    2.60 -      -javadoc-build:           Javadoc generation
    2.61 -      test-report:              JUnit report generation
    2.62 -
    2.63 -    An example of overriding the target for project execution could look like this:
    2.64 -
    2.65 -        <target name="run" depends="Sudoku-impl.jar">
    2.66 -            <exec dir="bin" executable="launcher.exe">
    2.67 -                <arg file="${dist.jar}"/>
    2.68 -            </exec>
    2.69 -        </target>
    2.70 -
    2.71 -    Notice that the overridden target depends on the jar target and not only on 
    2.72 -    the compile target as the regular run target does. Again, for a list of available 
    2.73 -    properties which you can use, check the target you are overriding in the
    2.74 -    nbproject/build-impl.xml file. 
    2.75 -
    2.76 -    -->
    2.77 -</project>
     3.1 --- a/nbproject/build-impl.xml	Fri Feb 01 10:18:47 2013 +0100
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,1400 +0,0 @@
     3.4 -<?xml version="1.0" encoding="UTF-8"?>
     3.5 -<!--
     3.6 -*** GENERATED FROM project.xml - DO NOT EDIT  ***
     3.7 -***         EDIT ../build.xml INSTEAD         ***
     3.8 -
     3.9 -For the purpose of easier reading the script
    3.10 -is divided into following sections:
    3.11 -
    3.12 -  - initialization
    3.13 -  - compilation
    3.14 -  - jar
    3.15 -  - execution
    3.16 -  - debugging
    3.17 -  - javadoc
    3.18 -  - test compilation
    3.19 -  - test execution
    3.20 -  - test debugging
    3.21 -  - applet
    3.22 -  - cleanup
    3.23 -
    3.24 -        -->
    3.25 -<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="Sudoku-impl">
    3.26 -    <fail message="Please build using Ant 1.8.0 or higher.">
    3.27 -        <condition>
    3.28 -            <not>
    3.29 -                <antversion atleast="1.8.0"/>
    3.30 -            </not>
    3.31 -        </condition>
    3.32 -    </fail>
    3.33 -    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
    3.34 -    <!-- 
    3.35 -                ======================
    3.36 -                INITIALIZATION SECTION 
    3.37 -                ======================
    3.38 -            -->
    3.39 -    <target name="-pre-init">
    3.40 -        <!-- Empty placeholder for easier customization. -->
    3.41 -        <!-- You can override this target in the ../build.xml file. -->
    3.42 -    </target>
    3.43 -    <target depends="-pre-init" name="-init-private">
    3.44 -        <property file="nbproject/private/config.properties"/>
    3.45 -        <property file="nbproject/private/configs/${config}.properties"/>
    3.46 -        <property file="nbproject/private/private.properties"/>
    3.47 -    </target>
    3.48 -    <target depends="-pre-init,-init-private" name="-init-user">
    3.49 -        <property file="${user.properties.file}"/>
    3.50 -        <!-- The two properties below are usually overridden -->
    3.51 -        <!-- by the active platform. Just a fallback. -->
    3.52 -        <property name="default.javac.source" value="1.4"/>
    3.53 -        <property name="default.javac.target" value="1.4"/>
    3.54 -    </target>
    3.55 -    <target depends="-pre-init,-init-private,-init-user" name="-init-project">
    3.56 -        <property file="nbproject/configs/${config}.properties"/>
    3.57 -        <property file="nbproject/project.properties"/>
    3.58 -    </target>
    3.59 -    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
    3.60 -        <available file="${manifest.file}" property="manifest.available"/>
    3.61 -        <condition property="splashscreen.available">
    3.62 -            <and>
    3.63 -                <not>
    3.64 -                    <equals arg1="${application.splash}" arg2="" trim="true"/>
    3.65 -                </not>
    3.66 -                <available file="${application.splash}"/>
    3.67 -            </and>
    3.68 -        </condition>
    3.69 -        <condition property="main.class.available">
    3.70 -            <and>
    3.71 -                <isset property="main.class"/>
    3.72 -                <not>
    3.73 -                    <equals arg1="${main.class}" arg2="" trim="true"/>
    3.74 -                </not>
    3.75 -            </and>
    3.76 -        </condition>
    3.77 -        <condition property="manifest.available+main.class">
    3.78 -            <and>
    3.79 -                <isset property="manifest.available"/>
    3.80 -                <isset property="main.class.available"/>
    3.81 -            </and>
    3.82 -        </condition>
    3.83 -        <condition property="do.archive">
    3.84 -            <not>
    3.85 -                <istrue value="${jar.archive.disabled}"/>
    3.86 -            </not>
    3.87 -        </condition>
    3.88 -        <condition property="do.mkdist">
    3.89 -            <and>
    3.90 -                <isset property="do.archive"/>
    3.91 -                <isset property="libs.CopyLibs.classpath"/>
    3.92 -                <not>
    3.93 -                    <istrue value="${mkdist.disabled}"/>
    3.94 -                </not>
    3.95 -            </and>
    3.96 -        </condition>
    3.97 -        <condition property="manifest.available+main.class+mkdist.available">
    3.98 -            <and>
    3.99 -                <istrue value="${manifest.available+main.class}"/>
   3.100 -                <isset property="do.mkdist"/>
   3.101 -            </and>
   3.102 -        </condition>
   3.103 -        <condition property="do.archive+manifest.available">
   3.104 -            <and>
   3.105 -                <isset property="manifest.available"/>
   3.106 -                <istrue value="${do.archive}"/>
   3.107 -            </and>
   3.108 -        </condition>
   3.109 -        <condition property="do.archive+main.class.available">
   3.110 -            <and>
   3.111 -                <isset property="main.class.available"/>
   3.112 -                <istrue value="${do.archive}"/>
   3.113 -            </and>
   3.114 -        </condition>
   3.115 -        <condition property="do.archive+splashscreen.available">
   3.116 -            <and>
   3.117 -                <isset property="splashscreen.available"/>
   3.118 -                <istrue value="${do.archive}"/>
   3.119 -            </and>
   3.120 -        </condition>
   3.121 -        <condition property="do.archive+manifest.available+main.class">
   3.122 -            <and>
   3.123 -                <istrue value="${manifest.available+main.class}"/>
   3.124 -                <istrue value="${do.archive}"/>
   3.125 -            </and>
   3.126 -        </condition>
   3.127 -        <condition property="manifest.available-mkdist.available">
   3.128 -            <or>
   3.129 -                <istrue value="${manifest.available}"/>
   3.130 -                <isset property="do.mkdist"/>
   3.131 -            </or>
   3.132 -        </condition>
   3.133 -        <condition property="manifest.available+main.class-mkdist.available">
   3.134 -            <or>
   3.135 -                <istrue value="${manifest.available+main.class}"/>
   3.136 -                <isset property="do.mkdist"/>
   3.137 -            </or>
   3.138 -        </condition>
   3.139 -        <condition property="have.tests">
   3.140 -            <or>
   3.141 -                <available file="${test.src.dir}"/>
   3.142 -            </or>
   3.143 -        </condition>
   3.144 -        <condition property="have.sources">
   3.145 -            <or>
   3.146 -                <available file="${src.dir}"/>
   3.147 -            </or>
   3.148 -        </condition>
   3.149 -        <condition property="netbeans.home+have.tests">
   3.150 -            <and>
   3.151 -                <isset property="netbeans.home"/>
   3.152 -                <isset property="have.tests"/>
   3.153 -            </and>
   3.154 -        </condition>
   3.155 -        <condition property="no.javadoc.preview">
   3.156 -            <and>
   3.157 -                <isset property="javadoc.preview"/>
   3.158 -                <isfalse value="${javadoc.preview}"/>
   3.159 -            </and>
   3.160 -        </condition>
   3.161 -        <property name="run.jvmargs" value=""/>
   3.162 -        <property name="run.jvmargs.ide" value=""/>
   3.163 -        <property name="javac.compilerargs" value=""/>
   3.164 -        <property name="work.dir" value="${basedir}"/>
   3.165 -        <condition property="no.deps">
   3.166 -            <and>
   3.167 -                <istrue value="${no.dependencies}"/>
   3.168 -            </and>
   3.169 -        </condition>
   3.170 -        <property name="javac.debug" value="true"/>
   3.171 -        <property name="javadoc.preview" value="true"/>
   3.172 -        <property name="application.args" value=""/>
   3.173 -        <property name="source.encoding" value="${file.encoding}"/>
   3.174 -        <property name="runtime.encoding" value="${source.encoding}"/>
   3.175 -        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
   3.176 -            <and>
   3.177 -                <isset property="javadoc.encoding"/>
   3.178 -                <not>
   3.179 -                    <equals arg1="${javadoc.encoding}" arg2=""/>
   3.180 -                </not>
   3.181 -            </and>
   3.182 -        </condition>
   3.183 -        <property name="javadoc.encoding.used" value="${source.encoding}"/>
   3.184 -        <property name="includes" value="**"/>
   3.185 -        <property name="excludes" value=""/>
   3.186 -        <property name="do.depend" value="false"/>
   3.187 -        <condition property="do.depend.true">
   3.188 -            <istrue value="${do.depend}"/>
   3.189 -        </condition>
   3.190 -        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
   3.191 -        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
   3.192 -            <length length="0" string="${endorsed.classpath}" when="greater"/>
   3.193 -        </condition>
   3.194 -        <condition else="false" property="jdkBug6558476">
   3.195 -            <and>
   3.196 -                <matches pattern="1\.[56]" string="${java.specification.version}"/>
   3.197 -                <not>
   3.198 -                    <os family="unix"/>
   3.199 -                </not>
   3.200 -            </and>
   3.201 -        </condition>
   3.202 -        <property name="javac.fork" value="${jdkBug6558476}"/>
   3.203 -        <property name="jar.index" value="false"/>
   3.204 -        <property name="jar.index.metainf" value="${jar.index}"/>
   3.205 -        <property name="copylibs.rebase" value="true"/>
   3.206 -        <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
   3.207 -        <condition property="junit.available">
   3.208 -            <or>
   3.209 -                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
   3.210 -                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
   3.211 -            </or>
   3.212 -        </condition>
   3.213 -        <condition property="testng.available">
   3.214 -            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
   3.215 -        </condition>
   3.216 -        <condition property="junit+testng.available">
   3.217 -            <and>
   3.218 -                <istrue value="${junit.available}"/>
   3.219 -                <istrue value="${testng.available}"/>
   3.220 -            </and>
   3.221 -        </condition>
   3.222 -        <condition else="testng" property="testng.mode" value="mixed">
   3.223 -            <istrue value="${junit+testng.available}"/>
   3.224 -        </condition>
   3.225 -        <condition else="" property="testng.debug.mode" value="-mixed">
   3.226 -            <istrue value="${junit+testng.available}"/>
   3.227 -        </condition>
   3.228 -    </target>
   3.229 -    <target name="-post-init">
   3.230 -        <!-- Empty placeholder for easier customization. -->
   3.231 -        <!-- You can override this target in the ../build.xml file. -->
   3.232 -    </target>
   3.233 -    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
   3.234 -        <fail unless="src.dir">Must set src.dir</fail>
   3.235 -        <fail unless="test.src.dir">Must set test.src.dir</fail>
   3.236 -        <fail unless="build.dir">Must set build.dir</fail>
   3.237 -        <fail unless="dist.dir">Must set dist.dir</fail>
   3.238 -        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
   3.239 -        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
   3.240 -        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
   3.241 -        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
   3.242 -        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
   3.243 -        <fail unless="dist.jar">Must set dist.jar</fail>
   3.244 -    </target>
   3.245 -    <target name="-init-macrodef-property">
   3.246 -        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
   3.247 -            <attribute name="name"/>
   3.248 -            <attribute name="value"/>
   3.249 -            <sequential>
   3.250 -                <property name="@{name}" value="${@{value}}"/>
   3.251 -            </sequential>
   3.252 -        </macrodef>
   3.253 -    </target>
   3.254 -    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
   3.255 -        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.256 -            <attribute default="${src.dir}" name="srcdir"/>
   3.257 -            <attribute default="${build.classes.dir}" name="destdir"/>
   3.258 -            <attribute default="${javac.classpath}" name="classpath"/>
   3.259 -            <attribute default="${javac.processorpath}" name="processorpath"/>
   3.260 -            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
   3.261 -            <attribute default="${includes}" name="includes"/>
   3.262 -            <attribute default="${excludes}" name="excludes"/>
   3.263 -            <attribute default="${javac.debug}" name="debug"/>
   3.264 -            <attribute default="${empty.dir}" name="sourcepath"/>
   3.265 -            <attribute default="${empty.dir}" name="gensrcdir"/>
   3.266 -            <element name="customize" optional="true"/>
   3.267 -            <sequential>
   3.268 -                <property location="${build.dir}/empty" name="empty.dir"/>
   3.269 -                <mkdir dir="${empty.dir}"/>
   3.270 -                <mkdir dir="@{apgeneratedsrcdir}"/>
   3.271 -                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
   3.272 -                    <src>
   3.273 -                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
   3.274 -                            <include name="*"/>
   3.275 -                        </dirset>
   3.276 -                    </src>
   3.277 -                    <classpath>
   3.278 -                        <path path="@{classpath}"/>
   3.279 -                    </classpath>
   3.280 -                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
   3.281 -                    <compilerarg line="${javac.compilerargs}"/>
   3.282 -                    <compilerarg value="-processorpath"/>
   3.283 -                    <compilerarg path="@{processorpath}:${empty.dir}"/>
   3.284 -                    <compilerarg line="${ap.processors.internal}"/>
   3.285 -                    <compilerarg line="${annotation.processing.processor.options}"/>
   3.286 -                    <compilerarg value="-s"/>
   3.287 -                    <compilerarg path="@{apgeneratedsrcdir}"/>
   3.288 -                    <compilerarg line="${ap.proc.none.internal}"/>
   3.289 -                    <customize/>
   3.290 -                </javac>
   3.291 -            </sequential>
   3.292 -        </macrodef>
   3.293 -    </target>
   3.294 -    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
   3.295 -        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.296 -            <attribute default="${src.dir}" name="srcdir"/>
   3.297 -            <attribute default="${build.classes.dir}" name="destdir"/>
   3.298 -            <attribute default="${javac.classpath}" name="classpath"/>
   3.299 -            <attribute default="${javac.processorpath}" name="processorpath"/>
   3.300 -            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
   3.301 -            <attribute default="${includes}" name="includes"/>
   3.302 -            <attribute default="${excludes}" name="excludes"/>
   3.303 -            <attribute default="${javac.debug}" name="debug"/>
   3.304 -            <attribute default="${empty.dir}" name="sourcepath"/>
   3.305 -            <attribute default="${empty.dir}" name="gensrcdir"/>
   3.306 -            <element name="customize" optional="true"/>
   3.307 -            <sequential>
   3.308 -                <property location="${build.dir}/empty" name="empty.dir"/>
   3.309 -                <mkdir dir="${empty.dir}"/>
   3.310 -                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
   3.311 -                    <src>
   3.312 -                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
   3.313 -                            <include name="*"/>
   3.314 -                        </dirset>
   3.315 -                    </src>
   3.316 -                    <classpath>
   3.317 -                        <path path="@{classpath}"/>
   3.318 -                    </classpath>
   3.319 -                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
   3.320 -                    <compilerarg line="${javac.compilerargs}"/>
   3.321 -                    <customize/>
   3.322 -                </javac>
   3.323 -            </sequential>
   3.324 -        </macrodef>
   3.325 -    </target>
   3.326 -    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
   3.327 -        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.328 -            <attribute default="${src.dir}" name="srcdir"/>
   3.329 -            <attribute default="${build.classes.dir}" name="destdir"/>
   3.330 -            <attribute default="${javac.classpath}" name="classpath"/>
   3.331 -            <sequential>
   3.332 -                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
   3.333 -                    <classpath>
   3.334 -                        <path path="@{classpath}"/>
   3.335 -                    </classpath>
   3.336 -                </depend>
   3.337 -            </sequential>
   3.338 -        </macrodef>
   3.339 -        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.340 -            <attribute default="${build.classes.dir}" name="destdir"/>
   3.341 -            <sequential>
   3.342 -                <fail unless="javac.includes">Must set javac.includes</fail>
   3.343 -                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
   3.344 -                    <path>
   3.345 -                        <filelist dir="@{destdir}" files="${javac.includes}"/>
   3.346 -                    </path>
   3.347 -                    <globmapper from="*.java" to="*.class"/>
   3.348 -                </pathconvert>
   3.349 -                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
   3.350 -                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
   3.351 -                <delete>
   3.352 -                    <files includesfile="${javac.includesfile.binary}"/>
   3.353 -                </delete>
   3.354 -                <delete>
   3.355 -                    <fileset file="${javac.includesfile.binary}"/>
   3.356 -                </delete>
   3.357 -            </sequential>
   3.358 -        </macrodef>
   3.359 -    </target>
   3.360 -    <target if="${junit.available}" name="-init-macrodef-junit-init">
   3.361 -        <condition else="false" property="nb.junit.batch" value="true">
   3.362 -            <and>
   3.363 -                <istrue value="${junit.available}"/>
   3.364 -                <not>
   3.365 -                    <isset property="test.method"/>
   3.366 -                </not>
   3.367 -            </and>
   3.368 -        </condition>
   3.369 -        <condition else="false" property="nb.junit.single" value="true">
   3.370 -            <and>
   3.371 -                <istrue value="${junit.available}"/>
   3.372 -                <isset property="test.method"/>
   3.373 -            </and>
   3.374 -        </condition>
   3.375 -    </target>
   3.376 -    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
   3.377 -        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.378 -            <attribute default="${includes}" name="includes"/>
   3.379 -            <attribute default="${excludes}" name="excludes"/>
   3.380 -            <attribute default="**" name="testincludes"/>
   3.381 -            <attribute default="" name="testmethods"/>
   3.382 -            <element name="customize" optional="true"/>
   3.383 -            <sequential>
   3.384 -                <property name="junit.forkmode" value="perTest"/>
   3.385 -                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
   3.386 -                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
   3.387 -                    <syspropertyset>
   3.388 -                        <propertyref prefix="test-sys-prop."/>
   3.389 -                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
   3.390 -                    </syspropertyset>
   3.391 -                    <formatter type="brief" usefile="false"/>
   3.392 -                    <formatter type="xml"/>
   3.393 -                    <jvmarg value="-ea"/>
   3.394 -                    <customize/>
   3.395 -                </junit>
   3.396 -            </sequential>
   3.397 -        </macrodef>
   3.398 -    </target>
   3.399 -    <target if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
   3.400 -        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.401 -            <attribute default="${includes}" name="includes"/>
   3.402 -            <attribute default="${excludes}" name="excludes"/>
   3.403 -            <attribute default="**" name="testincludes"/>
   3.404 -            <attribute default="" name="testmethods"/>
   3.405 -            <element name="customize" optional="true"/>
   3.406 -            <sequential>
   3.407 -                <property name="junit.forkmode" value="perTest"/>
   3.408 -                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
   3.409 -                    <batchtest todir="${build.test.results.dir}">
   3.410 -                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
   3.411 -                            <filename name="@{testincludes}"/>
   3.412 -                        </fileset>
   3.413 -                    </batchtest>
   3.414 -                    <syspropertyset>
   3.415 -                        <propertyref prefix="test-sys-prop."/>
   3.416 -                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
   3.417 -                    </syspropertyset>
   3.418 -                    <formatter type="brief" usefile="false"/>
   3.419 -                    <formatter type="xml"/>
   3.420 -                    <jvmarg value="-ea"/>
   3.421 -                    <customize/>
   3.422 -                </junit>
   3.423 -            </sequential>
   3.424 -        </macrodef>
   3.425 -    </target>
   3.426 -    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
   3.427 -    <target if="${testng.available}" name="-init-macrodef-testng">
   3.428 -        <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.429 -            <attribute default="${includes}" name="includes"/>
   3.430 -            <attribute default="${excludes}" name="excludes"/>
   3.431 -            <attribute default="**" name="testincludes"/>
   3.432 -            <attribute default="" name="testmethods"/>
   3.433 -            <element name="customize" optional="true"/>
   3.434 -            <sequential>
   3.435 -                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
   3.436 -                    <isset property="test.method"/>
   3.437 -                </condition>
   3.438 -                <union id="test.set">
   3.439 -                    <fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">
   3.440 -                        <filename name="@{testincludes}"/>
   3.441 -                    </fileset>
   3.442 -                </union>
   3.443 -                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
   3.444 -                <testng classfilesetref="test.set" failureProperty="tests.failed" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="Sudoku" testname="TestNG tests" workingDir="${work.dir}">
   3.445 -                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
   3.446 -                    <propertyset>
   3.447 -                        <propertyref prefix="test-sys-prop."/>
   3.448 -                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
   3.449 -                    </propertyset>
   3.450 -                    <customize/>
   3.451 -                </testng>
   3.452 -            </sequential>
   3.453 -        </macrodef>
   3.454 -    </target>
   3.455 -    <target name="-init-macrodef-test-impl">
   3.456 -        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.457 -            <attribute default="${includes}" name="includes"/>
   3.458 -            <attribute default="${excludes}" name="excludes"/>
   3.459 -            <attribute default="**" name="testincludes"/>
   3.460 -            <attribute default="" name="testmethods"/>
   3.461 -            <element implicit="true" name="customize" optional="true"/>
   3.462 -            <sequential>
   3.463 -                <echo>No tests executed.</echo>
   3.464 -            </sequential>
   3.465 -        </macrodef>
   3.466 -    </target>
   3.467 -    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
   3.468 -        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.469 -            <attribute default="${includes}" name="includes"/>
   3.470 -            <attribute default="${excludes}" name="excludes"/>
   3.471 -            <attribute default="**" name="testincludes"/>
   3.472 -            <attribute default="" name="testmethods"/>
   3.473 -            <element implicit="true" name="customize" optional="true"/>
   3.474 -            <sequential>
   3.475 -                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
   3.476 -                    <customize/>
   3.477 -                </j2seproject3:junit>
   3.478 -            </sequential>
   3.479 -        </macrodef>
   3.480 -    </target>
   3.481 -    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
   3.482 -        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.483 -            <attribute default="${includes}" name="includes"/>
   3.484 -            <attribute default="${excludes}" name="excludes"/>
   3.485 -            <attribute default="**" name="testincludes"/>
   3.486 -            <attribute default="" name="testmethods"/>
   3.487 -            <element implicit="true" name="customize" optional="true"/>
   3.488 -            <sequential>
   3.489 -                <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
   3.490 -                    <customize/>
   3.491 -                </j2seproject3:testng>
   3.492 -            </sequential>
   3.493 -        </macrodef>
   3.494 -    </target>
   3.495 -    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
   3.496 -        <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.497 -            <attribute default="${includes}" name="includes"/>
   3.498 -            <attribute default="${excludes}" name="excludes"/>
   3.499 -            <attribute default="**" name="testincludes"/>
   3.500 -            <attribute default="" name="testmethods"/>
   3.501 -            <sequential>
   3.502 -                <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
   3.503 -                    <customize>
   3.504 -                        <classpath>
   3.505 -                            <path path="${run.test.classpath}"/>
   3.506 -                        </classpath>
   3.507 -                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
   3.508 -                        <jvmarg line="${run.jvmargs}"/>
   3.509 -                        <jvmarg line="${run.jvmargs.ide}"/>
   3.510 -                    </customize>
   3.511 -                </j2seproject3:test-impl>
   3.512 -            </sequential>
   3.513 -        </macrodef>
   3.514 -    </target>
   3.515 -    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
   3.516 -        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.517 -            <attribute default="${includes}" name="includes"/>
   3.518 -            <attribute default="${excludes}" name="excludes"/>
   3.519 -            <attribute default="**" name="testincludes"/>
   3.520 -            <attribute default="" name="testmethods"/>
   3.521 -            <element name="customize" optional="true"/>
   3.522 -            <sequential>
   3.523 -                <property name="junit.forkmode" value="perTest"/>
   3.524 -                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
   3.525 -                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
   3.526 -                    <syspropertyset>
   3.527 -                        <propertyref prefix="test-sys-prop."/>
   3.528 -                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
   3.529 -                    </syspropertyset>
   3.530 -                    <formatter type="brief" usefile="false"/>
   3.531 -                    <formatter type="xml"/>
   3.532 -                    <jvmarg value="-ea"/>
   3.533 -                    <jvmarg line="${debug-args-line}"/>
   3.534 -                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
   3.535 -                    <customize/>
   3.536 -                </junit>
   3.537 -            </sequential>
   3.538 -        </macrodef>
   3.539 -    </target>
   3.540 -    <target if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
   3.541 -        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.542 -            <attribute default="${includes}" name="includes"/>
   3.543 -            <attribute default="${excludes}" name="excludes"/>
   3.544 -            <attribute default="**" name="testincludes"/>
   3.545 -            <attribute default="" name="testmethods"/>
   3.546 -            <element name="customize" optional="true"/>
   3.547 -            <sequential>
   3.548 -                <property name="junit.forkmode" value="perTest"/>
   3.549 -                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
   3.550 -                    <batchtest todir="${build.test.results.dir}">
   3.551 -                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
   3.552 -                            <filename name="@{testincludes}"/>
   3.553 -                        </fileset>
   3.554 -                    </batchtest>
   3.555 -                    <syspropertyset>
   3.556 -                        <propertyref prefix="test-sys-prop."/>
   3.557 -                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
   3.558 -                    </syspropertyset>
   3.559 -                    <formatter type="brief" usefile="false"/>
   3.560 -                    <formatter type="xml"/>
   3.561 -                    <jvmarg value="-ea"/>
   3.562 -                    <jvmarg line="${debug-args-line}"/>
   3.563 -                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
   3.564 -                    <customize/>
   3.565 -                </junit>
   3.566 -            </sequential>
   3.567 -        </macrodef>
   3.568 -    </target>
   3.569 -    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
   3.570 -        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.571 -            <attribute default="${includes}" name="includes"/>
   3.572 -            <attribute default="${excludes}" name="excludes"/>
   3.573 -            <attribute default="**" name="testincludes"/>
   3.574 -            <attribute default="" name="testmethods"/>
   3.575 -            <element implicit="true" name="customize" optional="true"/>
   3.576 -            <sequential>
   3.577 -                <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
   3.578 -                    <customize/>
   3.579 -                </j2seproject3:junit-debug>
   3.580 -            </sequential>
   3.581 -        </macrodef>
   3.582 -    </target>
   3.583 -    <target if="${testng.available}" name="-init-macrodef-testng-debug">
   3.584 -        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.585 -            <attribute default="${main.class}" name="testClass"/>
   3.586 -            <attribute default="" name="testMethod"/>
   3.587 -            <element name="customize2" optional="true"/>
   3.588 -            <sequential>
   3.589 -                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
   3.590 -                    <isset property="test.method"/>
   3.591 -                </condition>
   3.592 -                <condition else="-suitename Sudoku -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
   3.593 -                    <matches pattern=".*\.xml" string="@{testClass}"/>
   3.594 -                </condition>
   3.595 -                <delete dir="${build.test.results.dir}" quiet="true"/>
   3.596 -                <mkdir dir="${build.test.results.dir}"/>
   3.597 -                <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">
   3.598 -                    <customize>
   3.599 -                        <customize2/>
   3.600 -                        <jvmarg value="-ea"/>
   3.601 -                        <arg line="${testng.debug.mode}"/>
   3.602 -                        <arg line="-d ${build.test.results.dir}"/>
   3.603 -                        <arg line="-listener org.testng.reporters.VerboseReporter"/>
   3.604 -                        <arg line="${testng.cmd.args}"/>
   3.605 -                    </customize>
   3.606 -                </j2seproject3:debug>
   3.607 -            </sequential>
   3.608 -        </macrodef>
   3.609 -    </target>
   3.610 -    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
   3.611 -        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.612 -            <attribute default="${main.class}" name="testClass"/>
   3.613 -            <attribute default="" name="testMethod"/>
   3.614 -            <element implicit="true" name="customize2" optional="true"/>
   3.615 -            <sequential>
   3.616 -                <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
   3.617 -                    <customize2/>
   3.618 -                </j2seproject3:testng-debug>
   3.619 -            </sequential>
   3.620 -        </macrodef>
   3.621 -    </target>
   3.622 -    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
   3.623 -        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.624 -            <attribute default="${includes}" name="includes"/>
   3.625 -            <attribute default="${excludes}" name="excludes"/>
   3.626 -            <attribute default="**" name="testincludes"/>
   3.627 -            <attribute default="" name="testmethods"/>
   3.628 -            <attribute default="${main.class}" name="testClass"/>
   3.629 -            <attribute default="" name="testMethod"/>
   3.630 -            <sequential>
   3.631 -                <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
   3.632 -                    <customize>
   3.633 -                        <classpath>
   3.634 -                            <path path="${run.test.classpath}"/>
   3.635 -                        </classpath>
   3.636 -                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
   3.637 -                        <jvmarg line="${run.jvmargs}"/>
   3.638 -                        <jvmarg line="${run.jvmargs.ide}"/>
   3.639 -                    </customize>
   3.640 -                </j2seproject3:test-debug-impl>
   3.641 -            </sequential>
   3.642 -        </macrodef>
   3.643 -    </target>
   3.644 -    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
   3.645 -        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.646 -            <attribute default="${includes}" name="includes"/>
   3.647 -            <attribute default="${excludes}" name="excludes"/>
   3.648 -            <attribute default="**" name="testincludes"/>
   3.649 -            <attribute default="" name="testmethods"/>
   3.650 -            <attribute default="${main.class}" name="testClass"/>
   3.651 -            <attribute default="" name="testMethod"/>
   3.652 -            <sequential>
   3.653 -                <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
   3.654 -                    <customize2>
   3.655 -                        <syspropertyset>
   3.656 -                            <propertyref prefix="test-sys-prop."/>
   3.657 -                            <mapper from="test-sys-prop.*" to="*" type="glob"/>
   3.658 -                        </syspropertyset>
   3.659 -                    </customize2>
   3.660 -                </j2seproject3:testng-debug-impl>
   3.661 -            </sequential>
   3.662 -        </macrodef>
   3.663 -    </target>
   3.664 -    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
   3.665 -    <!--
   3.666 -                pre NB7.2 profiling section; consider it deprecated
   3.667 -            -->
   3.668 -    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
   3.669 -    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
   3.670 -        <!-- Empty placeholder for easier customization. -->
   3.671 -        <!-- You can override this target in the ../build.xml file. -->
   3.672 -    </target>
   3.673 -    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
   3.674 -        <!-- Empty placeholder for easier customization. -->
   3.675 -        <!-- You can override this target in the ../build.xml file. -->
   3.676 -    </target>
   3.677 -    <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile">
   3.678 -        <macrodef name="resolve">
   3.679 -            <attribute name="name"/>
   3.680 -            <attribute name="value"/>
   3.681 -            <sequential>
   3.682 -                <property name="@{name}" value="${env.@{value}}"/>
   3.683 -            </sequential>
   3.684 -        </macrodef>
   3.685 -        <macrodef name="profile">
   3.686 -            <attribute default="${main.class}" name="classname"/>
   3.687 -            <element name="customize" optional="true"/>
   3.688 -            <sequential>
   3.689 -                <property environment="env"/>
   3.690 -                <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
   3.691 -                <java classname="@{classname}" dir="${profiler.info.dir}" fork="true" jvm="${profiler.info.jvm}">
   3.692 -                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
   3.693 -                    <jvmarg value="${profiler.info.jvmargs.agent}"/>
   3.694 -                    <jvmarg line="${profiler.info.jvmargs}"/>
   3.695 -                    <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
   3.696 -                    <arg line="${application.args}"/>
   3.697 -                    <classpath>
   3.698 -                        <path path="${run.classpath}"/>
   3.699 -                    </classpath>
   3.700 -                    <syspropertyset>
   3.701 -                        <propertyref prefix="run-sys-prop."/>
   3.702 -                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
   3.703 -                    </syspropertyset>
   3.704 -                    <customize/>
   3.705 -                </java>
   3.706 -            </sequential>
   3.707 -        </macrodef>
   3.708 -    </target>
   3.709 -    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check">
   3.710 -        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
   3.711 -        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
   3.712 -    </target>
   3.713 -    <!--
   3.714 -                end of pre NB7.2 profiling section
   3.715 -            -->
   3.716 -    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
   3.717 -        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
   3.718 -            <attribute default="${main.class}" name="name"/>
   3.719 -            <attribute default="${debug.classpath}" name="classpath"/>
   3.720 -            <attribute default="" name="stopclassname"/>
   3.721 -            <sequential>
   3.722 -                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
   3.723 -                    <classpath>
   3.724 -                        <path path="@{classpath}"/>
   3.725 -                    </classpath>
   3.726 -                </nbjpdastart>
   3.727 -            </sequential>
   3.728 -        </macrodef>
   3.729 -        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
   3.730 -            <attribute default="${build.classes.dir}" name="dir"/>
   3.731 -            <sequential>
   3.732 -                <nbjpdareload>
   3.733 -                    <fileset dir="@{dir}" includes="${fix.classes}">
   3.734 -                        <include name="${fix.includes}*.class"/>
   3.735 -                    </fileset>
   3.736 -                </nbjpdareload>
   3.737 -            </sequential>
   3.738 -        </macrodef>
   3.739 -    </target>
   3.740 -    <target name="-init-debug-args">
   3.741 -        <property name="version-output" value="java version &quot;${ant.java.version}"/>
   3.742 -        <condition property="have-jdk-older-than-1.4">
   3.743 -            <or>
   3.744 -                <contains string="${version-output}" substring="java version &quot;1.0"/>
   3.745 -                <contains string="${version-output}" substring="java version &quot;1.1"/>
   3.746 -                <contains string="${version-output}" substring="java version &quot;1.2"/>
   3.747 -                <contains string="${version-output}" substring="java version &quot;1.3"/>
   3.748 -            </or>
   3.749 -        </condition>
   3.750 -        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
   3.751 -            <istrue value="${have-jdk-older-than-1.4}"/>
   3.752 -        </condition>
   3.753 -        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
   3.754 -            <os family="windows"/>
   3.755 -        </condition>
   3.756 -        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
   3.757 -            <isset property="debug.transport"/>
   3.758 -        </condition>
   3.759 -    </target>
   3.760 -    <target depends="-init-debug-args" name="-init-macrodef-debug">
   3.761 -        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.762 -            <attribute default="${main.class}" name="classname"/>
   3.763 -            <attribute default="${debug.classpath}" name="classpath"/>
   3.764 -            <element name="customize" optional="true"/>
   3.765 -            <sequential>
   3.766 -                <java classname="@{classname}" dir="${work.dir}" fork="true">
   3.767 -                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
   3.768 -                    <jvmarg line="${debug-args-line}"/>
   3.769 -                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
   3.770 -                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
   3.771 -                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
   3.772 -                    <jvmarg line="${run.jvmargs}"/>
   3.773 -                    <jvmarg line="${run.jvmargs.ide}"/>
   3.774 -                    <classpath>
   3.775 -                        <path path="@{classpath}"/>
   3.776 -                    </classpath>
   3.777 -                    <syspropertyset>
   3.778 -                        <propertyref prefix="run-sys-prop."/>
   3.779 -                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
   3.780 -                    </syspropertyset>
   3.781 -                    <customize/>
   3.782 -                </java>
   3.783 -            </sequential>
   3.784 -        </macrodef>
   3.785 -    </target>
   3.786 -    <target name="-init-macrodef-java">
   3.787 -        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
   3.788 -            <attribute default="${main.class}" name="classname"/>
   3.789 -            <attribute default="${run.classpath}" name="classpath"/>
   3.790 -            <attribute default="jvm" name="jvm"/>
   3.791 -            <element name="customize" optional="true"/>
   3.792 -            <sequential>
   3.793 -                <java classname="@{classname}" dir="${work.dir}" fork="true">
   3.794 -                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
   3.795 -                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
   3.796 -                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
   3.797 -                    <jvmarg line="${run.jvmargs}"/>
   3.798 -                    <jvmarg line="${run.jvmargs.ide}"/>
   3.799 -                    <classpath>
   3.800 -                        <path path="@{classpath}"/>
   3.801 -                    </classpath>
   3.802 -                    <syspropertyset>
   3.803 -                        <propertyref prefix="run-sys-prop."/>
   3.804 -                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
   3.805 -                    </syspropertyset>
   3.806 -                    <customize/>
   3.807 -                </java>
   3.808 -            </sequential>
   3.809 -        </macrodef>
   3.810 -    </target>
   3.811 -    <target name="-init-macrodef-copylibs">
   3.812 -        <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
   3.813 -            <attribute default="${manifest.file}" name="manifest"/>
   3.814 -            <element name="customize" optional="true"/>
   3.815 -            <sequential>
   3.816 -                <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
   3.817 -                <pathconvert property="run.classpath.without.build.classes.dir">
   3.818 -                    <path path="${run.classpath}"/>
   3.819 -                    <map from="${build.classes.dir.resolved}" to=""/>
   3.820 -                </pathconvert>
   3.821 -                <pathconvert pathsep=" " property="jar.classpath">
   3.822 -                    <path path="${run.classpath.without.build.classes.dir}"/>
   3.823 -                    <chainedmapper>
   3.824 -                        <flattenmapper/>
   3.825 -                        <filtermapper>
   3.826 -                            <replacestring from=" " to="%20"/>
   3.827 -                        </filtermapper>
   3.828 -                        <globmapper from="*" to="lib/*"/>
   3.829 -                    </chainedmapper>
   3.830 -                </pathconvert>
   3.831 -                <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
   3.832 -                <copylibs compress="${jar.compress}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
   3.833 -                    <fileset dir="${build.classes.dir}"/>
   3.834 -                    <manifest>
   3.835 -                        <attribute name="Class-Path" value="${jar.classpath}"/>
   3.836 -                        <customize/>
   3.837 -                    </manifest>
   3.838 -                </copylibs>
   3.839 -            </sequential>
   3.840 -        </macrodef>
   3.841 -    </target>
   3.842 -    <target name="-init-presetdef-jar">
   3.843 -        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
   3.844 -            <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">
   3.845 -                <j2seproject1:fileset dir="${build.classes.dir}"/>
   3.846 -            </jar>
   3.847 -        </presetdef>
   3.848 -    </target>
   3.849 -    <target name="-init-ap-cmdline-properties">
   3.850 -        <property name="annotation.processing.enabled" value="true"/>
   3.851 -        <property name="annotation.processing.processors.list" value=""/>
   3.852 -        <property name="annotation.processing.processor.options" value=""/>
   3.853 -        <property name="annotation.processing.run.all.processors" value="true"/>
   3.854 -        <property name="javac.processorpath" value="${javac.classpath}"/>
   3.855 -        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
   3.856 -        <condition property="ap.supported.internal" value="true">
   3.857 -            <not>
   3.858 -                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
   3.859 -            </not>
   3.860 -        </condition>
   3.861 -    </target>
   3.862 -    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
   3.863 -        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
   3.864 -            <isfalse value="${annotation.processing.run.all.processors}"/>
   3.865 -        </condition>
   3.866 -        <condition else="" property="ap.proc.none.internal" value="-proc:none">
   3.867 -            <isfalse value="${annotation.processing.enabled}"/>
   3.868 -        </condition>
   3.869 -    </target>
   3.870 -    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
   3.871 -        <property name="ap.cmd.line.internal" value=""/>
   3.872 -    </target>
   3.873 -    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
   3.874 -    <!--
   3.875 -                ===================
   3.876 -                COMPILATION SECTION
   3.877 -                ===================
   3.878 -            -->
   3.879 -    <target name="-deps-jar-init" unless="built-jar.properties">
   3.880 -        <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
   3.881 -        <delete file="${built-jar.properties}" quiet="true"/>
   3.882 -    </target>
   3.883 -    <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
   3.884 -        <echo level="warn" message="Cycle detected: Sudoku was already built"/>
   3.885 -    </target>
   3.886 -    <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
   3.887 -        <mkdir dir="${build.dir}"/>
   3.888 -        <touch file="${built-jar.properties}" verbose="false"/>
   3.889 -        <property file="${built-jar.properties}" prefix="already.built.jar."/>
   3.890 -        <antcall target="-warn-already-built-jar"/>
   3.891 -        <propertyfile file="${built-jar.properties}">
   3.892 -            <entry key="${basedir}" value=""/>
   3.893 -        </propertyfile>
   3.894 -    </target>
   3.895 -    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
   3.896 -    <target depends="init" name="-check-automatic-build">
   3.897 -        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
   3.898 -    </target>
   3.899 -    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
   3.900 -        <antcall target="clean"/>
   3.901 -    </target>
   3.902 -    <target depends="init,deps-jar" name="-pre-pre-compile">
   3.903 -        <mkdir dir="${build.classes.dir}"/>
   3.904 -    </target>
   3.905 -    <target name="-pre-compile">
   3.906 -        <!-- Empty placeholder for easier customization. -->
   3.907 -        <!-- You can override this target in the ../build.xml file. -->
   3.908 -    </target>
   3.909 -    <target if="do.depend.true" name="-compile-depend">
   3.910 -        <pathconvert property="build.generated.subdirs">
   3.911 -            <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
   3.912 -                <include name="*"/>
   3.913 -            </dirset>
   3.914 -        </pathconvert>
   3.915 -        <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
   3.916 -    </target>
   3.917 -    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
   3.918 -        <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
   3.919 -        <copy todir="${build.classes.dir}">
   3.920 -            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
   3.921 -        </copy>
   3.922 -    </target>
   3.923 -    <target if="has.persistence.xml" name="-copy-persistence-xml">
   3.924 -        <mkdir dir="${build.classes.dir}/META-INF"/>
   3.925 -        <copy todir="${build.classes.dir}/META-INF">
   3.926 -            <fileset dir="${meta.inf.dir}" includes="persistence.xml"/>
   3.927 -        </copy>
   3.928 -    </target>
   3.929 -    <target name="-post-compile">
   3.930 -        <!-- Empty placeholder for easier customization. -->
   3.931 -        <!-- You can override this target in the ../build.xml file. -->
   3.932 -    </target>
   3.933 -    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
   3.934 -    <target name="-pre-compile-single">
   3.935 -        <!-- Empty placeholder for easier customization. -->
   3.936 -        <!-- You can override this target in the ../build.xml file. -->
   3.937 -    </target>
   3.938 -    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
   3.939 -        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
   3.940 -        <j2seproject3:force-recompile/>
   3.941 -        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
   3.942 -    </target>
   3.943 -    <target name="-post-compile-single">
   3.944 -        <!-- Empty placeholder for easier customization. -->
   3.945 -        <!-- You can override this target in the ../build.xml file. -->
   3.946 -    </target>
   3.947 -    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
   3.948 -    <!--
   3.949 -                ====================
   3.950 -                JAR BUILDING SECTION
   3.951 -                ====================
   3.952 -            -->
   3.953 -    <target depends="init" name="-pre-pre-jar">
   3.954 -        <dirname file="${dist.jar}" property="dist.jar.dir"/>
   3.955 -        <mkdir dir="${dist.jar.dir}"/>
   3.956 -    </target>
   3.957 -    <target name="-pre-jar">
   3.958 -        <!-- Empty placeholder for easier customization. -->
   3.959 -        <!-- You can override this target in the ../build.xml file. -->
   3.960 -    </target>
   3.961 -    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive" name="-do-jar-without-manifest" unless="manifest.available-mkdist.available">
   3.962 -        <j2seproject1:jar/>
   3.963 -    </target>
   3.964 -    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class-mkdist.available">
   3.965 -        <j2seproject1:jar manifest="${manifest.file}"/>
   3.966 -    </target>
   3.967 -    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
   3.968 -        <j2seproject1:jar manifest="${manifest.file}">
   3.969 -            <j2seproject1:manifest>
   3.970 -                <j2seproject1:attribute name="Main-Class" value="${main.class}"/>
   3.971 -            </j2seproject1:manifest>
   3.972 -        </j2seproject1:jar>
   3.973 -        <echo level="info">To run this application from the command line without Ant, try:</echo>
   3.974 -        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
   3.975 -        <property location="${dist.jar}" name="dist.jar.resolved"/>
   3.976 -        <pathconvert property="run.classpath.with.dist.jar">
   3.977 -            <path path="${run.classpath}"/>
   3.978 -            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
   3.979 -        </pathconvert>
   3.980 -        <echo level="info">java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
   3.981 -    </target>
   3.982 -    <target depends="init" if="do.archive" name="-do-jar-with-libraries-create-manifest" unless="manifest.available">
   3.983 -        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
   3.984 -        <touch file="${tmp.manifest.file}" verbose="false"/>
   3.985 -    </target>
   3.986 -    <target depends="init" if="do.archive+manifest.available" name="-do-jar-with-libraries-copy-manifest">
   3.987 -        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
   3.988 -        <copy file="${manifest.file}" tofile="${tmp.manifest.file}"/>
   3.989 -    </target>
   3.990 -    <target depends="init,-do-jar-with-libraries-create-manifest,-do-jar-with-libraries-copy-manifest" if="do.archive+main.class.available" name="-do-jar-with-libraries-set-main">
   3.991 -        <manifest file="${tmp.manifest.file}" mode="update">
   3.992 -            <attribute name="Main-Class" value="${main.class}"/>
   3.993 -        </manifest>
   3.994 -    </target>
   3.995 -    <target depends="init,-do-jar-with-libraries-create-manifest,-do-jar-with-libraries-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-with-libraries-set-splashscreen">
   3.996 -        <basename file="${application.splash}" property="splashscreen.basename"/>
   3.997 -        <mkdir dir="${build.classes.dir}/META-INF"/>
   3.998 -        <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
   3.999 -        <manifest file="${tmp.manifest.file}" mode="update">
  3.1000 -            <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
  3.1001 -        </manifest>
  3.1002 -    </target>
  3.1003 -    <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-with-libraries-create-manifest,-do-jar-with-libraries-copy-manifest,-do-jar-with-libraries-set-main,-do-jar-with-libraries-set-splashscreen" if="do.mkdist" name="-do-jar-with-libraries-pack">
  3.1004 -        <j2seproject3:copylibs manifest="${tmp.manifest.file}"/>
  3.1005 -        <echo level="info">To run this application from the command line without Ant, try:</echo>
  3.1006 -        <property location="${dist.jar}" name="dist.jar.resolved"/>
  3.1007 -        <echo level="info">java -jar "${dist.jar.resolved}"</echo>
  3.1008 -    </target>
  3.1009 -    <target depends="-do-jar-with-libraries-pack" if="do.archive" name="-do-jar-with-libraries-delete-manifest">
  3.1010 -        <delete>
  3.1011 -            <fileset file="${tmp.manifest.file}"/>
  3.1012 -        </delete>
  3.1013 -    </target>
  3.1014 -    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-with-libraries-create-manifest,-do-jar-with-libraries-copy-manifest,-do-jar-with-libraries-set-main,-do-jar-with-libraries-set-splashscreen,-do-jar-with-libraries-pack,-do-jar-with-libraries-delete-manifest" name="-do-jar-with-libraries"/>
  3.1015 -    <target name="-post-jar">
  3.1016 -        <!-- Empty placeholder for easier customization. -->
  3.1017 -        <!-- You can override this target in the ../build.xml file. -->
  3.1018 -    </target>
  3.1019 -    <target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
  3.1020 -    <!--
  3.1021 -                =================
  3.1022 -                EXECUTION SECTION
  3.1023 -                =================
  3.1024 -            -->
  3.1025 -    <target depends="init,compile" description="Run a main class." name="run">
  3.1026 -        <j2seproject1:java>
  3.1027 -            <customize>
  3.1028 -                <arg line="${application.args}"/>
  3.1029 -            </customize>
  3.1030 -        </j2seproject1:java>
  3.1031 -    </target>
  3.1032 -    <target name="-do-not-recompile">
  3.1033 -        <property name="javac.includes.binary" value=""/>
  3.1034 -    </target>
  3.1035 -    <target depends="init,compile-single" name="run-single">
  3.1036 -        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
  3.1037 -        <j2seproject1:java classname="${run.class}"/>
  3.1038 -    </target>
  3.1039 -    <target depends="init,compile-test-single" name="run-test-with-main">
  3.1040 -        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
  3.1041 -        <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
  3.1042 -    </target>
  3.1043 -    <!--
  3.1044 -                =================
  3.1045 -                DEBUGGING SECTION
  3.1046 -                =================
  3.1047 -            -->
  3.1048 -    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
  3.1049 -        <j2seproject1:nbjpdastart name="${debug.class}"/>
  3.1050 -    </target>
  3.1051 -    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
  3.1052 -        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
  3.1053 -    </target>
  3.1054 -    <target depends="init,compile" name="-debug-start-debuggee">
  3.1055 -        <j2seproject3:debug>
  3.1056 -            <customize>
  3.1057 -                <arg line="${application.args}"/>
  3.1058 -            </customize>
  3.1059 -        </j2seproject3:debug>
  3.1060 -    </target>
  3.1061 -    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
  3.1062 -    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
  3.1063 -        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>
  3.1064 -    </target>
  3.1065 -    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
  3.1066 -    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
  3.1067 -        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
  3.1068 -        <j2seproject3:debug classname="${debug.class}"/>
  3.1069 -    </target>
  3.1070 -    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
  3.1071 -    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
  3.1072 -        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
  3.1073 -        <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
  3.1074 -    </target>
  3.1075 -    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
  3.1076 -    <target depends="init" name="-pre-debug-fix">
  3.1077 -        <fail unless="fix.includes">Must set fix.includes</fail>
  3.1078 -        <property name="javac.includes" value="${fix.includes}.java"/>
  3.1079 -    </target>
  3.1080 -    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
  3.1081 -        <j2seproject1:nbjpdareload/>
  3.1082 -    </target>
  3.1083 -    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
  3.1084 -    <!--
  3.1085 -                =================
  3.1086 -                PROFILING SECTION
  3.1087 -                =================
  3.1088 -            -->
  3.1089 -    <!--
  3.1090 -                pre NB7.2 profiler integration
  3.1091 -            -->
  3.1092 -    <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
  3.1093 -        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
  3.1094 -        <nbprofiledirect>
  3.1095 -            <classpath>
  3.1096 -                <path path="${run.classpath}"/>
  3.1097 -            </classpath>
  3.1098 -        </nbprofiledirect>
  3.1099 -        <profile/>
  3.1100 -    </target>
  3.1101 -    <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72">
  3.1102 -        <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
  3.1103 -        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
  3.1104 -        <nbprofiledirect>
  3.1105 -            <classpath>
  3.1106 -                <path path="${run.classpath}"/>
  3.1107 -            </classpath>
  3.1108 -        </nbprofiledirect>
  3.1109 -        <profile classname="${profile.class}"/>
  3.1110 -    </target>
  3.1111 -    <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72">
  3.1112 -        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
  3.1113 -        <nbprofiledirect>
  3.1114 -            <classpath>
  3.1115 -                <path path="${run.classpath}"/>
  3.1116 -            </classpath>
  3.1117 -        </nbprofiledirect>
  3.1118 -        <profile classname="sun.applet.AppletViewer">
  3.1119 -            <customize>
  3.1120 -                <arg value="${applet.url}"/>
  3.1121 -            </customize>
  3.1122 -        </profile>
  3.1123 -    </target>
  3.1124 -    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
  3.1125 -        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
  3.1126 -        <nbprofiledirect>
  3.1127 -            <classpath>
  3.1128 -                <path path="${run.test.classpath}"/>
  3.1129 -            </classpath>
  3.1130 -        </nbprofiledirect>
  3.1131 -        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
  3.1132 -            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
  3.1133 -            <jvmarg value="${profiler.info.jvmargs.agent}"/>
  3.1134 -            <jvmarg line="${profiler.info.jvmargs}"/>
  3.1135 -            <test name="${profile.class}"/>
  3.1136 -            <classpath>
  3.1137 -                <path path="${run.test.classpath}"/>
  3.1138 -            </classpath>
  3.1139 -            <syspropertyset>
  3.1140 -                <propertyref prefix="test-sys-prop."/>
  3.1141 -                <mapper from="test-sys-prop.*" to="*" type="glob"/>
  3.1142 -            </syspropertyset>
  3.1143 -            <formatter type="brief" usefile="false"/>
  3.1144 -            <formatter type="xml"/>
  3.1145 -        </junit>
  3.1146 -    </target>
  3.1147 -    <!--
  3.1148 -                end of pre NB72 profiling section
  3.1149 -            -->
  3.1150 -    <target if="netbeans.home" name="-profile-check">
  3.1151 -        <condition property="profiler.configured">
  3.1152 -            <or>
  3.1153 -                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
  3.1154 -                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
  3.1155 -            </or>
  3.1156 -        </condition>
  3.1157 -    </target>
  3.1158 -    <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
  3.1159 -        <startprofiler/>
  3.1160 -        <antcall target="run"/>
  3.1161 -    </target>
  3.1162 -    <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent">
  3.1163 -        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
  3.1164 -        <startprofiler/>
  3.1165 -        <antcall target="run-single"/>
  3.1166 -    </target>
  3.1167 -    <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/>
  3.1168 -    <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs">
  3.1169 -        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
  3.1170 -        <startprofiler/>
  3.1171 -        <antcall target="test-single"/>
  3.1172 -    </target>
  3.1173 -    <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">
  3.1174 -        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
  3.1175 -        <startprofiler/>
  3.1176 -        <antcal target="run-test-with-main"/>
  3.1177 -    </target>
  3.1178 -    <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">
  3.1179 -        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
  3.1180 -        <startprofiler/>
  3.1181 -        <antcall target="run-applet"/>
  3.1182 -    </target>
  3.1183 -    <!--
  3.1184 -                ===============
  3.1185 -                JAVADOC SECTION
  3.1186 -                ===============
  3.1187 -            -->
  3.1188 -    <target depends="init" if="have.sources" name="-javadoc-build">
  3.1189 -        <mkdir dir="${dist.javadoc.dir}"/>
  3.1190 -        <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}">
  3.1191 -            <and>
  3.1192 -                <isset property="endorsed.classpath.cmd.line.arg"/>
  3.1193 -                <not>
  3.1194 -                    <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/>
  3.1195 -                </not>
  3.1196 -            </and>
  3.1197 -        </condition>
  3.1198 -        <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
  3.1199 -            <classpath>
  3.1200 -                <path path="${javac.classpath}"/>
  3.1201 -            </classpath>
  3.1202 -            <fileset dir="${src.dir}" excludes="*.java,${excludes}" includes="${includes}">
  3.1203 -                <filename name="**/*.java"/>
  3.1204 -            </fileset>
  3.1205 -            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
  3.1206 -                <include name="**/*.java"/>
  3.1207 -                <exclude name="*.java"/>
  3.1208 -            </fileset>
  3.1209 -            <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
  3.1210 -        </javadoc>
  3.1211 -        <copy todir="${dist.javadoc.dir}">
  3.1212 -            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
  3.1213 -                <filename name="**/doc-files/**"/>
  3.1214 -            </fileset>
  3.1215 -            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
  3.1216 -                <include name="**/doc-files/**"/>
  3.1217 -            </fileset>
  3.1218 -        </copy>
  3.1219 -    </target>
  3.1220 -    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
  3.1221 -        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
  3.1222 -    </target>
  3.1223 -    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
  3.1224 -    <!--
  3.1225 -                =========================
  3.1226 -                TEST COMPILATION SECTION
  3.1227 -                =========================
  3.1228 -            -->
  3.1229 -    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
  3.1230 -        <mkdir dir="${build.test.classes.dir}"/>
  3.1231 -    </target>
  3.1232 -    <target name="-pre-compile-test">
  3.1233 -        <!-- Empty placeholder for easier customization. -->
  3.1234 -        <!-- You can override this target in the ../build.xml file. -->
  3.1235 -    </target>
  3.1236 -    <target if="do.depend.true" name="-compile-test-depend">
  3.1237 -        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
  3.1238 -    </target>
  3.1239 -    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
  3.1240 -        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir="${test.src.dir}"/>
  3.1241 -        <copy todir="${build.test.classes.dir}">
  3.1242 -            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
  3.1243 -        </copy>
  3.1244 -    </target>
  3.1245 -    <target name="-post-compile-test">
  3.1246 -        <!-- Empty placeholder for easier customization. -->
  3.1247 -        <!-- You can override this target in the ../build.xml file. -->
  3.1248 -    </target>
  3.1249 -    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
  3.1250 -    <target name="-pre-compile-test-single">
  3.1251 -        <!-- Empty placeholder for easier customization. -->
  3.1252 -        <!-- You can override this target in the ../build.xml file. -->
  3.1253 -    </target>
  3.1254 -    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
  3.1255 -        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
  3.1256 -        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
  3.1257 -        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
  3.1258 -        <copy todir="${build.test.classes.dir}">
  3.1259 -            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
  3.1260 -        </copy>
  3.1261 -    </target>
  3.1262 -    <target name="-post-compile-test-single">
  3.1263 -        <!-- Empty placeholder for easier customization. -->
  3.1264 -        <!-- You can override this target in the ../build.xml file. -->
  3.1265 -    </target>
  3.1266 -    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
  3.1267 -    <!--
  3.1268 -                =======================
  3.1269 -                TEST EXECUTION SECTION
  3.1270 -                =======================
  3.1271 -            -->
  3.1272 -    <target depends="init" if="have.tests" name="-pre-test-run">
  3.1273 -        <mkdir dir="${build.test.results.dir}"/>
  3.1274 -    </target>
  3.1275 -    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
  3.1276 -        <j2seproject3:test testincludes="**/*Test.java"/>
  3.1277 -    </target>
  3.1278 -    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
  3.1279 -        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
  3.1280 -    </target>
  3.1281 -    <target depends="init" if="have.tests" name="test-report"/>
  3.1282 -    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
  3.1283 -    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
  3.1284 -    <target depends="init" if="have.tests" name="-pre-test-run-single">
  3.1285 -        <mkdir dir="${build.test.results.dir}"/>
  3.1286 -    </target>
  3.1287 -    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
  3.1288 -        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
  3.1289 -        <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
  3.1290 -    </target>
  3.1291 -    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
  3.1292 -        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
  3.1293 -    </target>
  3.1294 -    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
  3.1295 -    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
  3.1296 -        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
  3.1297 -        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
  3.1298 -        <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
  3.1299 -    </target>
  3.1300 -    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
  3.1301 -        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
  3.1302 -    </target>
  3.1303 -    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
  3.1304 -    <!--
  3.1305 -                =======================
  3.1306 -                TEST DEBUGGING SECTION
  3.1307 -                =======================
  3.1308 -            -->
  3.1309 -    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
  3.1310 -        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
  3.1311 -        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
  3.1312 -    </target>
  3.1313 -    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
  3.1314 -        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
  3.1315 -        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
  3.1316 -        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
  3.1317 -    </target>
  3.1318 -    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
  3.1319 -        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
  3.1320 -    </target>
  3.1321 -    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
  3.1322 -    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
  3.1323 -    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
  3.1324 -        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
  3.1325 -    </target>
  3.1326 -    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
  3.1327 -    <!--
  3.1328 -                =========================
  3.1329 -                APPLET EXECUTION SECTION
  3.1330 -                =========================
  3.1331 -            -->
  3.1332 -    <target depends="init,compile-single" name="run-applet">
  3.1333 -        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
  3.1334 -        <j2seproject1:java classname="sun.applet.AppletViewer">
  3.1335 -            <customize>
  3.1336 -                <arg value="${applet.url}"/>
  3.1337 -            </customize>
  3.1338 -        </j2seproject1:java>
  3.1339 -    </target>
  3.1340 -    <!--
  3.1341 -                =========================
  3.1342 -                APPLET DEBUGGING  SECTION
  3.1343 -                =========================
  3.1344 -            -->
  3.1345 -    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
  3.1346 -        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
  3.1347 -        <j2seproject3:debug classname="sun.applet.AppletViewer">
  3.1348 -            <customize>
  3.1349 -                <arg value="${applet.url}"/>
  3.1350 -            </customize>
  3.1351 -        </j2seproject3:debug>
  3.1352 -    </target>
  3.1353 -    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
  3.1354 -    <!--
  3.1355 -                ===============
  3.1356 -                CLEANUP SECTION
  3.1357 -                ===============
  3.1358 -            -->
  3.1359 -    <target name="-deps-clean-init" unless="built-clean.properties">
  3.1360 -        <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
  3.1361 -        <delete file="${built-clean.properties}" quiet="true"/>
  3.1362 -    </target>
  3.1363 -    <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
  3.1364 -        <echo level="warn" message="Cycle detected: Sudoku was already built"/>
  3.1365 -    </target>
  3.1366 -    <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
  3.1367 -        <mkdir dir="${build.dir}"/>
  3.1368 -        <touch file="${built-clean.properties}" verbose="false"/>
  3.1369 -        <property file="${built-clean.properties}" prefix="already.built.clean."/>
  3.1370 -        <antcall target="-warn-already-built-clean"/>
  3.1371 -        <propertyfile file="${built-clean.properties}">
  3.1372 -            <entry key="${basedir}" value=""/>
  3.1373 -        </propertyfile>
  3.1374 -    </target>
  3.1375 -    <target depends="init" name="-do-clean">
  3.1376 -        <delete dir="${build.dir}"/>
  3.1377 -        <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
  3.1378 -    </target>
  3.1379 -    <target name="-post-clean">
  3.1380 -        <!-- Empty placeholder for easier customization. -->
  3.1381 -        <!-- You can override this target in the ../build.xml file. -->
  3.1382 -    </target>
  3.1383 -    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
  3.1384 -    <target name="-check-call-dep">
  3.1385 -        <property file="${call.built.properties}" prefix="already.built."/>
  3.1386 -        <condition property="should.call.dep">
  3.1387 -            <and>
  3.1388 -                <not>
  3.1389 -                    <isset property="already.built.${call.subproject}"/>
  3.1390 -                </not>
  3.1391 -                <available file="${call.script}"/>
  3.1392 -            </and>
  3.1393 -        </condition>
  3.1394 -    </target>
  3.1395 -    <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
  3.1396 -        <ant antfile="${call.script}" inheritall="false" target="${call.target}">
  3.1397 -            <propertyset>
  3.1398 -                <propertyref prefix="transfer."/>
  3.1399 -                <mapper from="transfer.*" to="*" type="glob"/>
  3.1400 -            </propertyset>
  3.1401 -        </ant>
  3.1402 -    </target>
  3.1403 -</project>
     4.1 --- a/nbproject/genfiles.properties	Fri Feb 01 10:18:47 2013 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,8 +0,0 @@
     4.4 -build.xml.data.CRC32=7c7a460d
     4.5 -build.xml.script.CRC32=0dfebe00
     4.6 -build.xml.stylesheet.CRC32=28e38971@1.53.1.46
     4.7 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
     4.8 -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
     4.9 -nbproject/build-impl.xml.data.CRC32=7c7a460d
    4.10 -nbproject/build-impl.xml.script.CRC32=2bd010ed
    4.11 -nbproject/build-impl.xml.stylesheet.CRC32=6ddba6b6@1.53.1.46
     5.1 --- a/nbproject/project.properties	Fri Feb 01 10:18:47 2013 +0100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,71 +0,0 @@
     5.4 -annotation.processing.enabled=true
     5.5 -annotation.processing.enabled.in.editor=false
     5.6 -annotation.processing.processor.options=
     5.7 -annotation.processing.processors.list=
     5.8 -annotation.processing.run.all.processors=true
     5.9 -annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
    5.10 -build.classes.dir=${build.dir}/classes
    5.11 -build.classes.excludes=**/*.java,**/*.form
    5.12 -# This directory is removed when the project is cleaned:
    5.13 -build.dir=build
    5.14 -build.generated.dir=${build.dir}/generated
    5.15 -build.generated.sources.dir=${build.dir}/generated-sources
    5.16 -# Only compile against the classpath explicitly listed here:
    5.17 -build.sysclasspath=ignore
    5.18 -build.test.classes.dir=${build.dir}/test/classes
    5.19 -build.test.results.dir=${build.dir}/test/results
    5.20 -# Uncomment to specify the preferred debugger connection transport:
    5.21 -#debug.transport=dt_socket
    5.22 -debug.classpath=\
    5.23 -    ${run.classpath}
    5.24 -debug.test.classpath=\
    5.25 -    ${run.test.classpath}
    5.26 -# This directory is removed when the project is cleaned:
    5.27 -dist.dir=dist
    5.28 -dist.jar=${dist.dir}/Sudoku.jar
    5.29 -dist.javadoc.dir=${dist.dir}/javadoc
    5.30 -excludes=
    5.31 -includes=**
    5.32 -jar.compress=false
    5.33 -javac.classpath=
    5.34 -# Space-separated list of extra javac options
    5.35 -javac.compilerargs=
    5.36 -javac.deprecation=false
    5.37 -javac.processorpath=\
    5.38 -    ${javac.classpath}
    5.39 -javac.source=1.7
    5.40 -javac.target=1.7
    5.41 -javac.test.classpath=\
    5.42 -    ${javac.classpath}:\
    5.43 -    ${build.classes.dir}
    5.44 -javac.test.processorpath=\
    5.45 -    ${javac.test.classpath}
    5.46 -javadoc.additionalparam=
    5.47 -javadoc.author=false
    5.48 -javadoc.encoding=${source.encoding}
    5.49 -javadoc.noindex=false
    5.50 -javadoc.nonavbar=false
    5.51 -javadoc.notree=false
    5.52 -javadoc.private=false
    5.53 -javadoc.splitindex=true
    5.54 -javadoc.use=true
    5.55 -javadoc.version=false
    5.56 -javadoc.windowtitle=
    5.57 -main.class=de.uapcore.sudoku.Sudoku
    5.58 -manifest.file=manifest.mf
    5.59 -meta.inf.dir=${src.dir}/META-INF
    5.60 -mkdist.disabled=false
    5.61 -platform.active=default_platform
    5.62 -run.classpath=\
    5.63 -    ${javac.classpath}:\
    5.64 -    ${build.classes.dir}
    5.65 -# Space-separated list of JVM arguments used when running the project.
    5.66 -# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
    5.67 -# To set system properties for unit tests define test-sys-prop.name=value:
    5.68 -run.jvmargs=
    5.69 -run.test.classpath=\
    5.70 -    ${javac.test.classpath}:\
    5.71 -    ${build.test.classes.dir}
    5.72 -source.encoding=UTF-8
    5.73 -src.dir=src
    5.74 -test.src.dir=test
     6.1 --- a/nbproject/project.xml	Fri Feb 01 10:18:47 2013 +0100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,15 +0,0 @@
     6.4 -<?xml version="1.0" encoding="UTF-8"?>
     6.5 -<project xmlns="http://www.netbeans.org/ns/project/1">
     6.6 -    <type>org.netbeans.modules.java.j2seproject</type>
     6.7 -    <configuration>
     6.8 -        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
     6.9 -            <name>Sudoku</name>
    6.10 -            <source-roots>
    6.11 -                <root id="src.dir"/>
    6.12 -            </source-roots>
    6.13 -            <test-roots>
    6.14 -                <root id="test.src.dir"/>
    6.15 -            </test-roots>
    6.16 -        </data>
    6.17 -    </configuration>
    6.18 -</project>
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/pom.xml	Sat Jul 25 14:01:28 2020 +0200
     7.3 @@ -0,0 +1,35 @@
     7.4 +<project>
     7.5 +    <modelVersion>4.0.0</modelVersion>
     7.6 +
     7.7 +    <groupId>de.uapcore</groupId>
     7.8 +    <artifactId>sudoku</artifactId>
     7.9 +    <version>1.0</version>
    7.10 +
    7.11 +    <build>
    7.12 +        <plugins>
    7.13 +            <plugin>
    7.14 +                <artifactId>maven-compiler-plugin</artifactId>
    7.15 +                <version>3.8.1</version>
    7.16 +                <configuration>
    7.17 +                    <source>1.8</source>
    7.18 +                    <target>1.8</target>
    7.19 +                </configuration>
    7.20 +            </plugin>
    7.21 +            <plugin>
    7.22 +                <groupId>org.apache.maven.plugins</groupId>
    7.23 +                <artifactId>maven-jar-plugin</artifactId>
    7.24 +                <version>3.0.2</version>
    7.25 +                <configuration>
    7.26 +                    <archive>
    7.27 +                        <manifest>
    7.28 +                            <mainClass>
    7.29 +                                de.uapcore.sudoku.Sudoku
    7.30 +                            </mainClass>
    7.31 +                        </manifest>
    7.32 +                    </archive>
    7.33 +                </configuration>
    7.34 +            </plugin>
    7.35 +        </plugins>
    7.36 +    </build>
    7.37 +</project>
    7.38 +
     8.1 --- a/src/de/uapcore/sudoku/ActionHandler.java	Fri Feb 01 10:18:47 2013 +0100
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,204 +0,0 @@
     8.4 -/*
     8.5 - * Copyright 2013 Mike Becker. All rights reserved.
     8.6 - * 
     8.7 - * Redistribution and use in source and binary forms, with or without
     8.8 - * modification, are permitted provided that the following conditions are met:
     8.9 - * 
    8.10 - * 1. Redistributions of source code must retain the above copyright
    8.11 - *    notice, this list of conditions and the following disclaimer.
    8.12 - * 
    8.13 - * 2. Redistributions in binary form must reproduce the above copyright
    8.14 - *    notice, this list of conditions and the following disclaimer in the
    8.15 - *    documentation and/or other materials provided with the distribution.
    8.16 - * 
    8.17 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    8.18 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    8.19 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    8.20 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    8.21 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    8.22 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    8.23 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    8.24 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    8.25 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    8.26 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    8.27 - * POSSIBILITY OF SUCH DAMAGE.
    8.28 - */
    8.29 -
    8.30 -package de.uapcore.sudoku;
    8.31 -
    8.32 -import java.awt.event.ActionEvent;
    8.33 -import java.awt.event.ActionListener;
    8.34 -import java.io.File;
    8.35 -import java.io.IOException;
    8.36 -import javax.swing.JFileChooser;
    8.37 -import javax.swing.JOptionPane;
    8.38 -
    8.39 -/**
    8.40 - *
    8.41 - * @author mike
    8.42 - */
    8.43 -public final class ActionHandler implements ActionListener {
    8.44 -    
    8.45 -    public static final String SAVE = "save";
    8.46 -    public static final String CHECK = "check";
    8.47 -    public static final String SOLVE = "solve";
    8.48 -    
    8.49 -    public static final String NEW = "new";
    8.50 -    public static final String OPEN = "open";
    8.51 -    public static final String SAVE_AS = "save as";
    8.52 -    public static final String QUIT = "quit";
    8.53 -    public static final String ABOUT = "about";
    8.54 -    
    8.55 -    private Field field;
    8.56 -    private Solver solver;
    8.57 -    private DocumentHandler doc;
    8.58 -    
    8.59 -    public ActionHandler(Field f) {
    8.60 -        field = f;
    8.61 -        solver = new Solver();
    8.62 -        doc = new DocumentHandler();
    8.63 -    }
    8.64 -    
    8.65 -    private boolean chooseSaveFilename() {
    8.66 -        JFileChooser fc = new JFileChooser(".");
    8.67 -        fc.setMultiSelectionEnabled(false);
    8.68 -        if (fc.showSaveDialog(field) == JFileChooser.APPROVE_OPTION) {
    8.69 -            File f = fc.getSelectedFile();
    8.70 -            if (f.exists()) {
    8.71 -                int result = JOptionPane.showConfirmDialog(field,
    8.72 -                        "Bereits existierende Datei überschreiben?", "Sudoku",
    8.73 -                        JOptionPane.YES_NO_OPTION);
    8.74 -                if (result == JOptionPane.YES_OPTION) {
    8.75 -                    doc.setFilename(f.getAbsolutePath());
    8.76 -                    return true;
    8.77 -                } else {
    8.78 -                    return false;
    8.79 -                }
    8.80 -            } else {
    8.81 -                doc.setFilename(f.getAbsolutePath());
    8.82 -                return true;
    8.83 -            }
    8.84 -        } else {
    8.85 -            return false;
    8.86 -        }
    8.87 -    }
    8.88 -    
    8.89 -    private void open() {
    8.90 -        JFileChooser fc = new JFileChooser(".");
    8.91 -        fc.setMultiSelectionEnabled(false);
    8.92 -        if (fc.showOpenDialog(field) == JFileChooser.APPROVE_OPTION) {
    8.93 -            File f = fc.getSelectedFile();
    8.94 -            doc.setFilename(f.getAbsolutePath());
    8.95 -            try {
    8.96 -                doc.load(field);
    8.97 -            } catch (IOException e) {
    8.98 -                JOptionPane.showMessageDialog(field,
    8.99 -                    "Datei konnte nicht geladen werden: "+e.getMessage(),
   8.100 -                    "Sudoku", JOptionPane.ERROR_MESSAGE);
   8.101 -            }
   8.102 -        }
   8.103 -    }
   8.104 -    
   8.105 -    private boolean save(boolean rename) {
   8.106 -        if (!doc.isFilenameSet() || rename) {
   8.107 -            if (!chooseSaveFilename()) {
   8.108 -                return false;
   8.109 -            }
   8.110 -        }
   8.111 -        if (solver.check(field)) {
   8.112 -            field.setAllCellsModified(false);
   8.113 -            try {
   8.114 -                doc.save(field);
   8.115 -            } catch (IOException e) {
   8.116 -                JOptionPane.showMessageDialog(field,
   8.117 -                    "Datei konnte nicht gespeichert werden: "+e.getMessage(),
   8.118 -                    "Sudoku", JOptionPane.ERROR_MESSAGE);
   8.119 -            }
   8.120 -            return true;
   8.121 -        } else {
   8.122 -            JOptionPane.showMessageDialog(field,
   8.123 -                    "Das Feld kann mit Fehlern nicht gespeichert werden!",
   8.124 -                    "Sudoku", JOptionPane.ERROR_MESSAGE);
   8.125 -            return false;
   8.126 -        }
   8.127 -    }
   8.128 -    
   8.129 -    private void check() {
   8.130 -        if (solver.check(field)) {
   8.131 -            JOptionPane.showMessageDialog(field, "Überprüfung erfolgreich!",
   8.132 -                    "Sudoku", JOptionPane.INFORMATION_MESSAGE);
   8.133 -        } else {
   8.134 -            JOptionPane.showMessageDialog(field, "Das Feld enthält Fehler!",
   8.135 -                    "Sudoku", JOptionPane.WARNING_MESSAGE);
   8.136 -        }
   8.137 -    }
   8.138 -    
   8.139 -    private void solve() {
   8.140 -        if (!solver.check(field) || !solver.solve(field)) {
   8.141 -            JOptionPane.showMessageDialog(field, "Das Feld ist nicht lösbar!",
   8.142 -                    "Sudoku", JOptionPane.WARNING_MESSAGE);
   8.143 -        }
   8.144 -    }
   8.145 -    
   8.146 -    private boolean saveUnsaved() {
   8.147 -        boolean proceed = false;
   8.148 -        if (field.isAnyCellModified()) {
   8.149 -            int result = JOptionPane.showConfirmDialog(field,
   8.150 -                    "Das Feld ist ungespeichert - jetzt speichern?",
   8.151 -                    "Sudoku", JOptionPane.YES_NO_CANCEL_OPTION);
   8.152 -            if (result == JOptionPane.YES_OPTION) {
   8.153 -                if (save(false)) {
   8.154 -                    proceed = true;
   8.155 -                }
   8.156 -            } else if (result == JOptionPane.NO_OPTION) {
   8.157 -                proceed = true;
   8.158 -            }
   8.159 -        } else {
   8.160 -            proceed = true;
   8.161 -        }
   8.162 -        
   8.163 -        return proceed;
   8.164 -    }
   8.165 -
   8.166 -    @Override
   8.167 -    public void actionPerformed(ActionEvent e) {
   8.168 -        switch (e.getActionCommand()) {
   8.169 -        case NEW:
   8.170 -            if (saveUnsaved()) {
   8.171 -                doc.clearFilename();
   8.172 -                field.clear();
   8.173 -            }
   8.174 -            break;
   8.175 -        case OPEN:
   8.176 -            open();
   8.177 -            break;
   8.178 -        case SAVE:
   8.179 -            save(false);
   8.180 -            break;
   8.181 -        case SAVE_AS:
   8.182 -            save(true);
   8.183 -            break;
   8.184 -        case CHECK:
   8.185 -            check();
   8.186 -            break;
   8.187 -        case SOLVE:
   8.188 -            solve();
   8.189 -            break;
   8.190 -        case QUIT:
   8.191 -            if (saveUnsaved()) {
   8.192 -                System.exit(0);
   8.193 -            }
   8.194 -            break;
   8.195 -        case ABOUT:
   8.196 -            JOptionPane.showMessageDialog(field,
   8.197 -                    "Sudoku - Copyright (c) 2013 Mike Becker\nwww.uap-core.de"+
   8.198 -                    "\nPublished under the BSD License",
   8.199 -                    "Sudoku", JOptionPane.INFORMATION_MESSAGE);
   8.200 -            break;
   8.201 -        default:
   8.202 -            throw new UnsupportedOperationException(
   8.203 -                    "unknown action: "+e.getActionCommand());
   8.204 -        }
   8.205 -    }
   8.206 -    
   8.207 -}
     9.1 --- a/src/de/uapcore/sudoku/ButtonPanel.java	Fri Feb 01 10:18:47 2013 +0100
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,72 +0,0 @@
     9.4 -/*
     9.5 - * Copyright 2013 Mike Becker. All rights reserved.
     9.6 - * 
     9.7 - * Redistribution and use in source and binary forms, with or without
     9.8 - * modification, are permitted provided that the following conditions are met:
     9.9 - * 
    9.10 - * 1. Redistributions of source code must retain the above copyright
    9.11 - *    notice, this list of conditions and the following disclaimer.
    9.12 - * 
    9.13 - * 2. Redistributions in binary form must reproduce the above copyright
    9.14 - *    notice, this list of conditions and the following disclaimer in the
    9.15 - *    documentation and/or other materials provided with the distribution.
    9.16 - * 
    9.17 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    9.18 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    9.19 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    9.20 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    9.21 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    9.22 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    9.23 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    9.24 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    9.25 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    9.26 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    9.27 - * POSSIBILITY OF SUCH DAMAGE.
    9.28 - */
    9.29 -
    9.30 -package de.uapcore.sudoku;
    9.31 -
    9.32 -import java.awt.Color;
    9.33 -import java.awt.GridBagConstraints;
    9.34 -import java.awt.GridBagLayout;
    9.35 -import java.awt.Insets;
    9.36 -import javax.swing.JButton;
    9.37 -import javax.swing.JPanel;
    9.38 -
    9.39 -/**
    9.40 - *
    9.41 - * @author mike
    9.42 - */
    9.43 -public final class ButtonPanel extends JPanel {
    9.44 -    
    9.45 -    private JButton save, check, solve;
    9.46 -
    9.47 -    public ButtonPanel(ActionHandler l) {
    9.48 -        setLayout(new GridBagLayout());
    9.49 -        
    9.50 -        GridBagConstraints c = new GridBagConstraints();
    9.51 -        c.insets = new Insets(10, 10, 10, 10);
    9.52 -        c.fill = GridBagConstraints.HORIZONTAL;
    9.53 -        c.weightx = 1;
    9.54 -        
    9.55 -        c.gridx = 0;
    9.56 -        c.gridy = 0;
    9.57 -        save = new JButton("Speichern");
    9.58 -        add(save, c);
    9.59 -        c.gridx++;
    9.60 -        check = new JButton("Prüfen");
    9.61 -        add(check, c);
    9.62 -        solve = new JButton("Lösen");
    9.63 -        c.gridx++;
    9.64 -        add(solve, c);
    9.65 -        
    9.66 -        save.setActionCommand(ActionHandler.SAVE);
    9.67 -        save.addActionListener(l);
    9.68 -        check.setActionCommand(ActionHandler.CHECK);
    9.69 -        check.addActionListener(l);
    9.70 -        solve.setActionCommand(ActionHandler.SOLVE);
    9.71 -        solve.addActionListener(l);
    9.72 -        
    9.73 -        setBackground(Color.WHITE);
    9.74 -    }
    9.75 -}
    10.1 --- a/src/de/uapcore/sudoku/DocumentHandler.java	Fri Feb 01 10:18:47 2013 +0100
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,110 +0,0 @@
    10.4 -/*
    10.5 - * Copyright 2013 Mike Becker. All rights reserved.
    10.6 - * 
    10.7 - * Redistribution and use in source and binary forms, with or without
    10.8 - * modification, are permitted provided that the following conditions are met:
    10.9 - * 
   10.10 - * 1. Redistributions of source code must retain the above copyright
   10.11 - *    notice, this list of conditions and the following disclaimer.
   10.12 - * 
   10.13 - * 2. Redistributions in binary form must reproduce the above copyright
   10.14 - *    notice, this list of conditions and the following disclaimer in the
   10.15 - *    documentation and/or other materials provided with the distribution.
   10.16 - * 
   10.17 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   10.18 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   10.19 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   10.20 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   10.21 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   10.22 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   10.23 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   10.24 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   10.25 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   10.26 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   10.27 - * POSSIBILITY OF SUCH DAMAGE.
   10.28 - */
   10.29 -
   10.30 -package de.uapcore.sudoku;
   10.31 -
   10.32 -import java.io.BufferedReader;
   10.33 -import java.io.BufferedWriter;
   10.34 -import java.io.FileInputStream;
   10.35 -import java.io.FileOutputStream;
   10.36 -import java.io.IOException;
   10.37 -import java.io.InputStreamReader;
   10.38 -import java.io.OutputStreamWriter;
   10.39 -import java.util.regex.Matcher;
   10.40 -import java.util.regex.Pattern;
   10.41 -
   10.42 -/**
   10.43 - *
   10.44 - * @author mike
   10.45 - */
   10.46 -public class DocumentHandler {
   10.47 -    
   10.48 -    private String filename;
   10.49 -    
   10.50 -    public void load(Field field) throws IOException {
   10.51 -        if (!isFilenameSet()) {
   10.52 -            throw new IOException("no filename supplied");
   10.53 -        }
   10.54 -        int row = 0;
   10.55 -        try (BufferedReader in = new BufferedReader(
   10.56 -                new InputStreamReader(new FileInputStream(filename)))) {
   10.57 -            Pattern pat = Pattern.compile("^\\s*(?:[1-9_] ){8}[1-9_]\\s*$");
   10.58 -            String line;
   10.59 -            while ((line = in.readLine()) != null) {
   10.60 -                if (line.matches("^\\s*$")) {
   10.61 -                    continue;
   10.62 -                }
   10.63 -                Matcher m = pat.matcher(line);
   10.64 -                if (m.matches()) {
   10.65 -                    String c[] = line.trim().split(" ");
   10.66 -                    if (c.length != 9) {
   10.67 -                        break;
   10.68 -                    }
   10.69 -                    for (int i = 0 ; i < 9 ; i++) {
   10.70 -                        field.setCellValue(i, row,
   10.71 -                                c[i].equals("_") ? 0 : Integer.valueOf(c[i]));
   10.72 -                    }
   10.73 -                    row++;
   10.74 -                } else {
   10.75 -                    break;
   10.76 -                }
   10.77 -            }
   10.78 -            if (row != 9) {
   10.79 -                throw new IOException("Kein Sudoku-Feld enthalten!");
   10.80 -            }
   10.81 -        }
   10.82 -        field.setAllCellsModified(false);
   10.83 -    }
   10.84 -    
   10.85 -    public void save(Field field) throws IOException {
   10.86 -        if (!isFilenameSet()) {
   10.87 -            throw new IOException("no filename supplied");
   10.88 -        }
   10.89 -        
   10.90 -        try (BufferedWriter out = new BufferedWriter(
   10.91 -                new OutputStreamWriter(new FileOutputStream(filename)))) {
   10.92 -            for (int i = 0 ; i < 9 ; i++) {
   10.93 -                int[] row = field.getRow(i);
   10.94 -                for (int j = 0 ; j < 9 ; j++) {
   10.95 -                    out.append(row[j] > 0 ? Character.forDigit(row[j], 10):'_');
   10.96 -                    out.append(j == 8 ? '\n': ' ');
   10.97 -                }
   10.98 -            }
   10.99 -        }
  10.100 -    }
  10.101 -    
  10.102 -    public void setFilename(String filename) {
  10.103 -        this.filename = filename;
  10.104 -    }
  10.105 -    
  10.106 -    public void clearFilename() {
  10.107 -        filename = null;
  10.108 -    }
  10.109 -    
  10.110 -    public boolean isFilenameSet() {
  10.111 -        return filename != null;
  10.112 -    }
  10.113 -}
    11.1 --- a/src/de/uapcore/sudoku/Field.java	Fri Feb 01 10:18:47 2013 +0100
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,182 +0,0 @@
    11.4 -/*
    11.5 - * Copyright 2013 Mike Becker. All rights reserved.
    11.6 - * 
    11.7 - * Redistribution and use in source and binary forms, with or without
    11.8 - * modification, are permitted provided that the following conditions are met:
    11.9 - * 
   11.10 - * 1. Redistributions of source code must retain the above copyright
   11.11 - *    notice, this list of conditions and the following disclaimer.
   11.12 - * 
   11.13 - * 2. Redistributions in binary form must reproduce the above copyright
   11.14 - *    notice, this list of conditions and the following disclaimer in the
   11.15 - *    documentation and/or other materials provided with the distribution.
   11.16 - * 
   11.17 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   11.18 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   11.19 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   11.20 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   11.21 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   11.22 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   11.23 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   11.24 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   11.25 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   11.26 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   11.27 - * POSSIBILITY OF SUCH DAMAGE.
   11.28 - */
   11.29 -
   11.30 -package de.uapcore.sudoku;
   11.31 -
   11.32 -import java.awt.Color;
   11.33 -import java.awt.Graphics;
   11.34 -import java.awt.Graphics2D;
   11.35 -import java.awt.GridBagConstraints;
   11.36 -import java.awt.GridBagLayout;
   11.37 -import java.awt.Insets;
   11.38 -import java.awt.image.BufferedImage;
   11.39 -import javax.swing.JPanel;
   11.40 -
   11.41 -/**
   11.42 - *
   11.43 - * @author mike
   11.44 - */
   11.45 -public final class Field extends JPanel {
   11.46 -    private SudokuTextField[][] cells;
   11.47 -    
   11.48 -    public Field() {
   11.49 -        setBackground(Color.WHITE);
   11.50 -        
   11.51 -        setLayout(new GridBagLayout());
   11.52 -        GridBagConstraints c = new GridBagConstraints();
   11.53 -        c.insets = new Insets(5, 5, 5, 5);
   11.54 -        
   11.55 -        cells = new SudokuTextField[9][9];
   11.56 -        for (int x = 0 ; x < 9 ; x++) {
   11.57 -            for (int y = 0 ; y < 9 ; y++) {
   11.58 -                cells[x][y] = new SudokuTextField();
   11.59 -                c.gridx = x;
   11.60 -                c.gridy = y;
   11.61 -                add(cells[x][y], c);
   11.62 -            }
   11.63 -        }
   11.64 -    }
   11.65 -
   11.66 -    @Override
   11.67 -    public void paint(Graphics graphics) {
   11.68 -        final int w = getWidth();
   11.69 -        final int h = getHeight();
   11.70 -        final int cw = w / 9;
   11.71 -        final int ch = h / 9;
   11.72 -        
   11.73 -        BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
   11.74 -        Graphics2D g = img.createGraphics();
   11.75 -        g.setBackground(Color.WHITE);
   11.76 -        g.clearRect(0, 0, w, h);
   11.77 -        
   11.78 -        g.setColor(Color.BLACK);
   11.79 -        g.drawRect(1, 1, w-2, h-2);
   11.80 -        g.drawRect(2, 2, w-4, h-4);
   11.81 -        for (int x = cw ; x < w ; x += cw) {
   11.82 -            for (int y = ch ; y < h ; y += ch) {
   11.83 -                g.drawLine(x, 2, x, h-2);
   11.84 -                g.drawLine(2, y, w-2, y);
   11.85 -                if ((x / cw) % 3 == 0) {
   11.86 -                    g.drawLine(x+1, 2, x+1, h-2);
   11.87 -                }
   11.88 -                if ((y / ch) % 3 == 0) {
   11.89 -                    g.drawLine(2, y+1, w-2, y+1);
   11.90 -                }
   11.91 -            }
   11.92 -        }
   11.93 -        
   11.94 -        graphics.drawImage(img, 0, 0, this);
   11.95 -        super.paintChildren(graphics);
   11.96 -    }
   11.97 -    
   11.98 -    public boolean isCellEmpty(int x, int y) {
   11.99 -        return getCellValue(x, y) == 0;
  11.100 -    }
  11.101 -    
  11.102 -    public int getCellValue(int x, int y) {
  11.103 -        return cells[x][y].getValue();
  11.104 -    }
  11.105 -    
  11.106 -    public void setCellValue(int x, int y, int v) {
  11.107 -        cells[x][y].setValue(v);
  11.108 -    }
  11.109 -    
  11.110 -    public void clearCellValue(int x, int y) {
  11.111 -        setCellValue(x, y, 0);
  11.112 -    }
  11.113 -    
  11.114 -    public void setCellModified(int x, int y, boolean modified) {
  11.115 -        cells[x][y].setModified(modified);
  11.116 -    }
  11.117 -    
  11.118 -    public void setAllCellsModified(boolean modified) {
  11.119 -        for (int x = 0 ; x < 9 ; x++) {
  11.120 -            for (int y = 0 ; y < 9 ; y++) {
  11.121 -                cells[x][y].setModified(modified);
  11.122 -            }
  11.123 -        }
  11.124 -    }
  11.125 -    
  11.126 -    public boolean isAnyCellModified() {
  11.127 -        for (int x = 0 ; x < 9 ; x++) {
  11.128 -            for (int y = 0 ; y < 9 ; y++) {
  11.129 -                if (cells[x][y].isModified()) {
  11.130 -                    return true;
  11.131 -                }
  11.132 -            }
  11.133 -        }
  11.134 -        return false;
  11.135 -    }
  11.136 -    
  11.137 -    public void clear() {
  11.138 -        for (int x = 0 ; x < 9 ; x++) {
  11.139 -            for (int y = 0 ; y < 9 ; y++) {
  11.140 -                cells[x][y].setValue(0);
  11.141 -            }
  11.142 -        }
  11.143 -    }
  11.144 -    
  11.145 -    public int[][] getSquare(int x, int y) {
  11.146 -        if (x < 0 || x > 2 || y < 0 || y > 2) {
  11.147 -            throw new IllegalArgumentException("Invalid square coordinates");
  11.148 -        }
  11.149 -        int[][] square = new int[3][3];
  11.150 -        
  11.151 -        for (int u = 0 ; u < 3 ; u++) {
  11.152 -            for (int v = 0 ; v < 3 ; v++) {
  11.153 -                square[u][v] = getCellValue(3*x+u, 3*y+v);
  11.154 -            }
  11.155 -        }
  11.156 -        
  11.157 -        return square;
  11.158 -    }
  11.159 -    
  11.160 -    public int[] getRow(int y) {
  11.161 -        if (y < 0 || y > 8) {
  11.162 -            throw new IllegalArgumentException("Invalid row number");
  11.163 -        }
  11.164 -        int row[] = new int[9];
  11.165 -        
  11.166 -        for (int x = 0 ; x < 9 ; x++) {
  11.167 -            row[x] = getCellValue(x, y);
  11.168 -        }
  11.169 -        
  11.170 -        return row;
  11.171 -    }
  11.172 -    
  11.173 -    public int[] getColumn(int x) {
  11.174 -        if (x < 0 || x > 8) {
  11.175 -            throw new IllegalArgumentException("Invalid column number");
  11.176 -        }
  11.177 -        int column[] = new int[9];
  11.178 -        
  11.179 -        for (int y = 0 ; y < 9 ; y++) {
  11.180 -            column[y] = getCellValue(x, y);
  11.181 -        }
  11.182 -        
  11.183 -        return column;
  11.184 -    }
  11.185 -}
    12.1 --- a/src/de/uapcore/sudoku/MainMenu.java	Fri Feb 01 10:18:47 2013 +0100
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,101 +0,0 @@
    12.4 -/*
    12.5 - * Copyright 2013 Mike Becker. All rights reserved.
    12.6 - * 
    12.7 - * Redistribution and use in source and binary forms, with or without
    12.8 - * modification, are permitted provided that the following conditions are met:
    12.9 - * 
   12.10 - * 1. Redistributions of source code must retain the above copyright
   12.11 - *    notice, this list of conditions and the following disclaimer.
   12.12 - * 
   12.13 - * 2. Redistributions in binary form must reproduce the above copyright
   12.14 - *    notice, this list of conditions and the following disclaimer in the
   12.15 - *    documentation and/or other materials provided with the distribution.
   12.16 - * 
   12.17 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   12.18 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   12.19 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   12.20 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   12.21 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   12.22 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   12.23 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   12.24 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   12.25 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   12.26 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   12.27 - * POSSIBILITY OF SUCH DAMAGE.
   12.28 - */
   12.29 -
   12.30 -package de.uapcore.sudoku;
   12.31 -
   12.32 -import javax.swing.JMenu;
   12.33 -import javax.swing.JMenuBar;
   12.34 -import javax.swing.JMenuItem;
   12.35 -import javax.swing.KeyStroke;
   12.36 -
   12.37 -/**
   12.38 - *
   12.39 - * @author mike
   12.40 - */
   12.41 -public class MainMenu {
   12.42 -    
   12.43 -    private ActionHandler handler;
   12.44 -    private JMenuBar menuBar;
   12.45 -    
   12.46 -    public MainMenu(ActionHandler h) {
   12.47 -        handler = h;
   12.48 -        menuBar = new JMenuBar();
   12.49 -        menuBar.add(createMenu("Datei", 'd',
   12.50 -            createMenuItem("Neu", 'n', "control N", ActionHandler.NEW),
   12.51 -            createMenuItem("Öffnen", 'f', "control O", ActionHandler.OPEN),
   12.52 -            createMenuItem("Speichern", 's', "control S", ActionHandler.SAVE),
   12.53 -            createMenuItem("Speichern als...", 'a', ActionHandler.SAVE_AS),
   12.54 -            createSeparator(),
   12.55 -            createMenuItem("Prüfen", 'p', "control P", ActionHandler.CHECK),
   12.56 -            createMenuItem("Lösen", 'l', "control L", ActionHandler.SOLVE),
   12.57 -            createSeparator(),
   12.58 -            createMenuItem("Beenden", 'e', ActionHandler.QUIT)
   12.59 -        ));
   12.60 -        menuBar.add(createMenu("Help", 'h',
   12.61 -            createMenuItem("Über...", 'b', "F1", ActionHandler.ABOUT)
   12.62 -        ));
   12.63 -    }
   12.64 -    
   12.65 -    private JMenuItem createSeparator() {
   12.66 -        // Return null, the createMenu method knows how to handle it
   12.67 -        return null;
   12.68 -    }
   12.69 -    
   12.70 -    private JMenu createMenu(String caption, char mnemonic, JMenuItem...items) {
   12.71 -        JMenu menu = new JMenu(caption);
   12.72 -        menu.setMnemonic(mnemonic);
   12.73 -        for (JMenuItem item : items) {
   12.74 -            if (item == null) {
   12.75 -                menu.addSeparator();
   12.76 -            } else {
   12.77 -                menu.add(item);
   12.78 -            }
   12.79 -        }
   12.80 -        return menu;
   12.81 -    }
   12.82 -    
   12.83 -    private JMenuItem createMenuItem(String caption, char mnemonic,
   12.84 -            String command) {
   12.85 -        return createMenuItem(caption, mnemonic, null, command);
   12.86 -    }
   12.87 -    
   12.88 -    private JMenuItem createMenuItem(String caption, char mnemonic,
   12.89 -            String stroke, String command) {
   12.90 -        JMenuItem item = new JMenuItem(caption);
   12.91 -        item.setMnemonic(mnemonic);
   12.92 -        if (stroke != null) {
   12.93 -            item.setAccelerator(KeyStroke.getKeyStroke(stroke));
   12.94 -        }
   12.95 -        item.setActionCommand(command);
   12.96 -        item.addActionListener(handler);
   12.97 -        
   12.98 -        return item;
   12.99 -    }
  12.100 -    
  12.101 -    public JMenuBar getMenuBar() {
  12.102 -        return menuBar;
  12.103 -    }
  12.104 -}
    13.1 --- a/src/de/uapcore/sudoku/Solver.java	Fri Feb 01 10:18:47 2013 +0100
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,227 +0,0 @@
    13.4 -/*
    13.5 - * Copyright 2013 Mike Becker. All rights reserved.
    13.6 - * 
    13.7 - * Redistribution and use in source and binary forms, with or without
    13.8 - * modification, are permitted provided that the following conditions are met:
    13.9 - * 
   13.10 - * 1. Redistributions of source code must retain the above copyright
   13.11 - *    notice, this list of conditions and the following disclaimer.
   13.12 - * 
   13.13 - * 2. Redistributions in binary form must reproduce the above copyright
   13.14 - *    notice, this list of conditions and the following disclaimer in the
   13.15 - *    documentation and/or other materials provided with the distribution.
   13.16 - * 
   13.17 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   13.18 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   13.19 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   13.20 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   13.21 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   13.22 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   13.23 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   13.24 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   13.25 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   13.26 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   13.27 - * POSSIBILITY OF SUCH DAMAGE.
   13.28 - */
   13.29 -
   13.30 -package de.uapcore.sudoku;
   13.31 -
   13.32 -import java.util.ArrayList;
   13.33 -import java.util.List;
   13.34 -
   13.35 -/**
   13.36 - *
   13.37 - * @author mike
   13.38 - */
   13.39 -public final class Solver {
   13.40 -    
   13.41 -    public Solver() {
   13.42 -    }
   13.43 -    
   13.44 -    private Integer fillInCandidate(Field f, List<Integer>[][] candidates, int x, int y) {
   13.45 -        Integer c = candidates[x][y].remove(0);
   13.46 -        f.setCellValue(x, y, c);
   13.47 -        f.setCellModified(x, y, true);
   13.48 -        for (int i = 0 ; i < 9 ; i++) {
   13.49 -            candidates[x][i].remove(c);
   13.50 -            candidates[i][y].remove(c);
   13.51 -        }
   13.52 -        for (int i = 0 ; i < 3 ; i++) {
   13.53 -            for (int j = 0 ; j < 3 ; j++) {
   13.54 -                candidates[x-x%3+i][y-y%3+j].remove(c);
   13.55 -            }
   13.56 -        }
   13.57 -        return c;
   13.58 -    }
   13.59 -    
   13.60 -    private void makeBackup(List<Integer>[][] candidates, List<Integer>[][] candidatesBackup) {
   13.61 -        for (int x = 0 ; x < 9 ; x++) {
   13.62 -            for (int y = 0 ; y < 9 ; y++) {
   13.63 -                candidatesBackup[x][y] = new ArrayList<>(9);
   13.64 -                candidatesBackup[x][y].addAll(candidates[x][y]);
   13.65 -            }
   13.66 -        }
   13.67 -    }
   13.68 -    
   13.69 -    private void makeBackup(Field f, int[][] fieldBackup) {
   13.70 -        for (int x = 0 ; x < 9 ; x++) {
   13.71 -            for (int y = 0 ; y < 9 ; y++) {
   13.72 -                fieldBackup[x][y] = f.getCellValue(x, y);
   13.73 -            }
   13.74 -        }
   13.75 -    }
   13.76 -    
   13.77 -    private void restoreBackup(Field f, int[][] fieldBackup) {
   13.78 -        for (int x = 0 ; x < 9 ; x++) {
   13.79 -            for (int y = 0 ; y < 9 ; y++) {
   13.80 -                f.setCellValue(x, y, fieldBackup[x][y]);
   13.81 -            }
   13.82 -        }
   13.83 -    }
   13.84 -    
   13.85 -    private void restoreBackup(List<Integer>[][] candidates, List<Integer>[][] candidatesBackup) {
   13.86 -        for (int x = 0 ; x < 9 ; x++) {
   13.87 -            for (int y = 0 ; y < 9 ; y++) {
   13.88 -                candidates[x][y].clear();
   13.89 -                candidates[x][y].addAll(candidatesBackup[x][y]);
   13.90 -            }
   13.91 -        }
   13.92 -    }
   13.93 -    
   13.94 -    private boolean solve(Field f, List<Integer>[][] candidates) {
   13.95 -        
   13.96 -        // Make backup
   13.97 -        List<Integer>[][] candidatesBackup = new List[9][9];
   13.98 -        int[][] fieldBackup = new int[9][9];
   13.99 -        makeBackup(candidates, candidatesBackup);
  13.100 -        makeBackup(f, fieldBackup);
  13.101 -        
  13.102 -        // Fill in distinct solutions
  13.103 -        boolean fillDistinct;
  13.104 -        do {
  13.105 -            fillDistinct = false;
  13.106 -            for (int x = 0 ; x < 9 ; x++) {
  13.107 -                for (int y = 0 ; y < 9 ; y++) {
  13.108 -                    if (f.isCellEmpty(x, y) && candidates[x][y].size() == 1) {
  13.109 -                        fillInCandidate(f, candidates, x, y);
  13.110 -                        fillDistinct = true;
  13.111 -                    }
  13.112 -                }
  13.113 -            }
  13.114 -        } while (fillDistinct);
  13.115 -        
  13.116 -        // Try out remaining candidates
  13.117 -        for (int x = 0 ; x < 9 ; x++) {
  13.118 -            for (int y = 0 ; y < 9 ; y++) {
  13.119 -                if (f.isCellEmpty(x, y)) {
  13.120 -                    while (candidates[x][y].size() > 0) {
  13.121 -                        List<Integer>[][] cb = new List[9][9];
  13.122 -                        makeBackup(candidates, cb);
  13.123 -                        Integer c = fillInCandidate(f, candidates, x, y);
  13.124 -                        if (solve(f, candidates)) {
  13.125 -                            break;
  13.126 -                        } else {
  13.127 -                            f.clearCellValue(x, y);
  13.128 -                            restoreBackup(candidates, cb);
  13.129 -                            // Remove current candidate anyway
  13.130 -                            candidates[x][y].remove(c);
  13.131 -                        }
  13.132 -                    }
  13.133 -                }
  13.134 -                if (f.isCellEmpty(x, y)) {
  13.135 -                    restoreBackup(f, fieldBackup);
  13.136 -                    restoreBackup(candidates, candidatesBackup);
  13.137 -                    return false;
  13.138 -                }
  13.139 -            }
  13.140 -        }
  13.141 -        
  13.142 -        return true;
  13.143 -    }
  13.144 -    
  13.145 -    public boolean solve(Field f) {
  13.146 -        
  13.147 -        // Calculate initial candidates
  13.148 -        List<Integer> candidates[][] = new List[9][9];
  13.149 -        for (int x = 0 ; x < 9 ; x++) {
  13.150 -            for (int y = 0 ; y < 9 ; y++) {
  13.151 -                candidates[x][y] = new ArrayList<>(9);
  13.152 -                if (f.getCellValue(x, y) == 0) {
  13.153 -                    // All numbers are candidates
  13.154 -                    for (int c = 1 ; c <= 9 ; c++) {
  13.155 -                        candidates[x][y].add(c);
  13.156 -                    }
  13.157 -                    // Remove row duplicates
  13.158 -                    int[] line = f.getRow(y);
  13.159 -                    for (Integer c : line) {
  13.160 -                        candidates[x][y].remove(c);
  13.161 -                    }
  13.162 -                    // Remove column duplicates
  13.163 -                    line = f.getColumn(x);
  13.164 -                    for (Integer c : line) {
  13.165 -                        candidates[x][y].remove(c);
  13.166 -                    }
  13.167 -                    // Remove square duplicates
  13.168 -                    int[][] square = f.getSquare(x/3, y/3);
  13.169 -                    for (int[] sq : square) {
  13.170 -                        for (Integer c : sq) {
  13.171 -                            candidates[x][y].remove(c);
  13.172 -                        }
  13.173 -                    }
  13.174 -                }
  13.175 -            }
  13.176 -        }
  13.177 -        
  13.178 -        // Backtrack
  13.179 -        return solve(f, candidates);
  13.180 -    }
  13.181 -    
  13.182 -    public boolean check(Field f) {
  13.183 -        int line[];
  13.184 -        for (int i = 0 ; i < 9 ; i++) {
  13.185 -            line = f.getRow(i);
  13.186 -            if (!valid(line)) {
  13.187 -                return false;
  13.188 -            }
  13.189 -            line = f.getColumn(i);
  13.190 -            if (!valid(line)) {
  13.191 -                return false;
  13.192 -            }
  13.193 -        }
  13.194 -        
  13.195 -        int square[][];
  13.196 -        for (int x = 0 ; x < 3 ; x++) {
  13.197 -            for (int y = 0 ; y < 3 ; y++) {
  13.198 -                square = f.getSquare(x, y);
  13.199 -                if (!valid(square)) {
  13.200 -                    return false;
  13.201 -                }
  13.202 -            }
  13.203 -        }
  13.204 -        
  13.205 -        return true;
  13.206 -    }
  13.207 -    
  13.208 -    private boolean valid(int[] line) {
  13.209 -        int numbers[];
  13.210 -        numbers = new int[9];
  13.211 -        for (int i = 0 ; i < 9 ; i++) {
  13.212 -            int l = line[i]-1;
  13.213 -            if (l >= 0) {
  13.214 -                if ((++numbers[l]) > 1) {
  13.215 -                    return false;
  13.216 -                }
  13.217 -            }
  13.218 -        }
  13.219 -        
  13.220 -        return true;
  13.221 -    }
  13.222 -    
  13.223 -    private boolean valid(int[][] square) {
  13.224 -        int[] line = new int[9];
  13.225 -        for (int x = 0 ; x < 3 ; x++) {
  13.226 -            System.arraycopy(square[x], 0, line, 3*x, 3);
  13.227 -        }
  13.228 -        return valid(line);
  13.229 -    }
  13.230 -}
    14.1 --- a/src/de/uapcore/sudoku/Sudoku.java	Fri Feb 01 10:18:47 2013 +0100
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,73 +0,0 @@
    14.4 -/*
    14.5 - * Copyright 2013 Mike Becker. All rights reserved.
    14.6 - * 
    14.7 - * Redistribution and use in source and binary forms, with or without
    14.8 - * modification, are permitted provided that the following conditions are met:
    14.9 - * 
   14.10 - * 1. Redistributions of source code must retain the above copyright
   14.11 - *    notice, this list of conditions and the following disclaimer.
   14.12 - * 
   14.13 - * 2. Redistributions in binary form must reproduce the above copyright
   14.14 - *    notice, this list of conditions and the following disclaimer in the
   14.15 - *    documentation and/or other materials provided with the distribution.
   14.16 - * 
   14.17 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   14.18 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   14.19 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   14.20 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   14.21 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   14.22 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   14.23 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   14.24 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   14.25 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   14.26 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   14.27 - * POSSIBILITY OF SUCH DAMAGE.
   14.28 - */
   14.29 -
   14.30 -package de.uapcore.sudoku;
   14.31 -
   14.32 -import java.awt.Color;
   14.33 -import java.awt.Container;
   14.34 -import java.awt.GridBagConstraints;
   14.35 -import java.awt.GridBagLayout;
   14.36 -import java.awt.Insets;
   14.37 -import javax.swing.JFrame;
   14.38 -
   14.39 -/**
   14.40 - *
   14.41 - * @author mike
   14.42 - */
   14.43 -public final class Sudoku extends JFrame {
   14.44 -    
   14.45 -    public Sudoku() {
   14.46 -        super("Sudoku");
   14.47 -        
   14.48 -        Field f = new Field();
   14.49 -        ActionHandler h = new ActionHandler(f);
   14.50 -        setJMenuBar(new MainMenu(h).getMenuBar());
   14.51 -        
   14.52 -        Container content = getContentPane();
   14.53 -        
   14.54 -        content.setLayout(new GridBagLayout());
   14.55 -        GridBagConstraints c = new GridBagConstraints();
   14.56 -        c.insets = new Insets(20, 20, 20, 20);
   14.57 -        c.fill = GridBagConstraints.HORIZONTAL;
   14.58 -        
   14.59 -        c.gridx = 0; c.gridy = 0;
   14.60 -        content.add(f, c);
   14.61 -        c.gridy++;
   14.62 -        content.add(new ButtonPanel(h), c);
   14.63 -        
   14.64 -        pack();
   14.65 -        content.setBackground(Color.WHITE);
   14.66 -        setLocationByPlatform(true);
   14.67 -        setDefaultCloseOperation(EXIT_ON_CLOSE);
   14.68 -    }
   14.69 -
   14.70 -    /**
   14.71 -     * @param args the command line arguments
   14.72 -     */
   14.73 -    public static void main(String[] args) {
   14.74 -        new Sudoku().setVisible(true);
   14.75 -    }
   14.76 -}
    15.1 --- a/src/de/uapcore/sudoku/SudokuTextField.java	Fri Feb 01 10:18:47 2013 +0100
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,138 +0,0 @@
    15.4 -/*
    15.5 - * Copyright 2013 Mike Becker. All rights reserved.
    15.6 - * 
    15.7 - * Redistribution and use in source and binary forms, with or without
    15.8 - * modification, are permitted provided that the following conditions are met:
    15.9 - * 
   15.10 - * 1. Redistributions of source code must retain the above copyright
   15.11 - *    notice, this list of conditions and the following disclaimer.
   15.12 - * 
   15.13 - * 2. Redistributions in binary form must reproduce the above copyright
   15.14 - *    notice, this list of conditions and the following disclaimer in the
   15.15 - *    documentation and/or other materials provided with the distribution.
   15.16 - * 
   15.17 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   15.18 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15.19 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   15.20 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   15.21 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   15.22 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   15.23 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   15.24 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   15.25 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   15.26 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   15.27 - * POSSIBILITY OF SUCH DAMAGE.
   15.28 - */
   15.29 -
   15.30 -package de.uapcore.sudoku;
   15.31 -
   15.32 -import java.awt.Color;
   15.33 -import java.awt.Dimension;
   15.34 -import java.awt.Font;
   15.35 -import java.awt.event.FocusAdapter;
   15.36 -import java.awt.event.FocusEvent;
   15.37 -import java.awt.event.KeyAdapter;
   15.38 -import java.awt.event.KeyEvent;
   15.39 -import javax.swing.JTextField;
   15.40 -
   15.41 -/**
   15.42 - *
   15.43 - * @author mike
   15.44 - */
   15.45 -public final class SudokuTextField extends JTextField {
   15.46 -    
   15.47 -    private boolean modified;
   15.48 -    
   15.49 -    public SudokuTextField() {
   15.50 -        setBorder(null);
   15.51 -        setBackground(Color.WHITE);
   15.52 -        
   15.53 -        setFont(new Font("Dialog", Font.PLAIN, 18));
   15.54 -        setHorizontalAlignment(JTextField.CENTER);
   15.55 -        
   15.56 -        Dimension dim = new Dimension(40,40);
   15.57 -        setPreferredSize(dim);
   15.58 -        setMinimumSize(dim);
   15.59 -        setMaximumSize(dim);
   15.60 -        
   15.61 -        addKeyListener(new KeyAdapter() {
   15.62 -            private void handle(KeyEvent e) {
   15.63 -                char c = e.getKeyChar();
   15.64 -                if (!e.isAltDown() && !e.isControlDown() &&
   15.65 -                        !Character.isISOControl(c)) {
   15.66 -                    // Perform clean input check
   15.67 -                    if (getText().length() > 0 && getSelectedText() == null) {
   15.68 -                        if (c != KeyEvent.CHAR_UNDEFINED) {
   15.69 -                            e.consume();
   15.70 -                        }
   15.71 -                    } else {
   15.72 -                        if (c < '1' || c > '9') {
   15.73 -                            e.consume();
   15.74 -                        } else {
   15.75 -                            setModified(true);
   15.76 -                        }
   15.77 -                    }
   15.78 -                } else {
   15.79 -                    // We can still be tricked by hotkeys, so do it the hard way
   15.80 -                    if (!getText().matches("^[1-9]$")) {
   15.81 -                        setText("");
   15.82 -                    }
   15.83 -                }
   15.84 -            }
   15.85 -            
   15.86 -            @Override
   15.87 -            public void keyPressed(KeyEvent e) {
   15.88 -                handle(e);
   15.89 -            }
   15.90 -
   15.91 -            @Override
   15.92 -            public void keyTyped(KeyEvent e) {
   15.93 -                handle(e);
   15.94 -            }
   15.95 -
   15.96 -            @Override
   15.97 -            public void keyReleased(KeyEvent e) {
   15.98 -                handle(e);
   15.99 -            }
  15.100 -            
  15.101 -        });
  15.102 -        addFocusListener(new FocusAdapter() {
  15.103 -            @Override
  15.104 -            public void focusGained(FocusEvent e) {
  15.105 -                selectAll();
  15.106 -            }
  15.107 -            @Override
  15.108 -            public void focusLost(FocusEvent e) {
  15.109 -                select(0, 0);
  15.110 -            }
  15.111 -        });
  15.112 -    }
  15.113 -    
  15.114 -    public int getValue() {
  15.115 -        if (getText().length() > 0) {
  15.116 -            return Integer.valueOf(getText());
  15.117 -        } else {
  15.118 -            return 0;
  15.119 -        }
  15.120 -    }
  15.121 -    
  15.122 -    public void setValue(int v) {
  15.123 -        if (v == 0) {
  15.124 -            setText("");
  15.125 -        } else if (v < 10) {
  15.126 -            setText(String.valueOf(v));
  15.127 -        } else {
  15.128 -            throw new IllegalArgumentException(
  15.129 -                    "Sudoku numbers must be in range 0-9 (0 means 'not set')");
  15.130 -        }
  15.131 -    }
  15.132 -    
  15.133 -    public void setModified(boolean modified) {
  15.134 -        this.modified = modified;
  15.135 -        setForeground(modified?Color.BLUE:Color.BLACK);
  15.136 -    }
  15.137 -    
  15.138 -    public boolean isModified() {
  15.139 -        return modified;
  15.140 -    }
  15.141 -}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/main/java/de/uapcore/sudoku/ActionHandler.java	Sat Jul 25 14:01:28 2020 +0200
    16.3 @@ -0,0 +1,203 @@
    16.4 +/*
    16.5 + * Copyright 2013 Mike Becker. All rights reserved.
    16.6 + * 
    16.7 + * Redistribution and use in source and binary forms, with or without
    16.8 + * modification, are permitted provided that the following conditions are met:
    16.9 + * 
   16.10 + * 1. Redistributions of source code must retain the above copyright
   16.11 + *    notice, this list of conditions and the following disclaimer.
   16.12 + * 
   16.13 + * 2. Redistributions in binary form must reproduce the above copyright
   16.14 + *    notice, this list of conditions and the following disclaimer in the
   16.15 + *    documentation and/or other materials provided with the distribution.
   16.16 + * 
   16.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   16.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16.20 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   16.21 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   16.22 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   16.23 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   16.24 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   16.25 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   16.26 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   16.27 + * POSSIBILITY OF SUCH DAMAGE.
   16.28 + */
   16.29 +
   16.30 +package de.uapcore.sudoku;
   16.31 +
   16.32 +import javax.swing.*;
   16.33 +import java.awt.event.ActionEvent;
   16.34 +import java.awt.event.ActionListener;
   16.35 +import java.io.File;
   16.36 +import java.io.IOException;
   16.37 +
   16.38 +/**
   16.39 + *
   16.40 + * @author mike
   16.41 + */
   16.42 +public final class ActionHandler implements ActionListener {
   16.43 +    
   16.44 +    public static final String SAVE = "save";
   16.45 +    public static final String CHECK = "check";
   16.46 +    public static final String SOLVE = "solve";
   16.47 +    
   16.48 +    public static final String NEW = "new";
   16.49 +    public static final String OPEN = "open";
   16.50 +    public static final String SAVE_AS = "save as";
   16.51 +    public static final String QUIT = "quit";
   16.52 +    public static final String ABOUT = "about";
   16.53 +    
   16.54 +    private Field field;
   16.55 +    private Solver solver;
   16.56 +    private DocumentHandler doc;
   16.57 +    
   16.58 +    public ActionHandler(Field f) {
   16.59 +        field = f;
   16.60 +        solver = new Solver();
   16.61 +        doc = new DocumentHandler();
   16.62 +    }
   16.63 +    
   16.64 +    private boolean chooseSaveFilename() {
   16.65 +        JFileChooser fc = new JFileChooser(".");
   16.66 +        fc.setMultiSelectionEnabled(false);
   16.67 +        if (fc.showSaveDialog(field) == JFileChooser.APPROVE_OPTION) {
   16.68 +            File f = fc.getSelectedFile();
   16.69 +            if (f.exists()) {
   16.70 +                int result = JOptionPane.showConfirmDialog(field,
   16.71 +                        "Bereits existierende Datei überschreiben?", "Sudoku",
   16.72 +                        JOptionPane.YES_NO_OPTION);
   16.73 +                if (result == JOptionPane.YES_OPTION) {
   16.74 +                    doc.setFilename(f.getAbsolutePath());
   16.75 +                    return true;
   16.76 +                } else {
   16.77 +                    return false;
   16.78 +                }
   16.79 +            } else {
   16.80 +                doc.setFilename(f.getAbsolutePath());
   16.81 +                return true;
   16.82 +            }
   16.83 +        } else {
   16.84 +            return false;
   16.85 +        }
   16.86 +    }
   16.87 +    
   16.88 +    private void open() {
   16.89 +        JFileChooser fc = new JFileChooser(".");
   16.90 +        fc.setMultiSelectionEnabled(false);
   16.91 +        if (fc.showOpenDialog(field) == JFileChooser.APPROVE_OPTION) {
   16.92 +            File f = fc.getSelectedFile();
   16.93 +            doc.setFilename(f.getAbsolutePath());
   16.94 +            try {
   16.95 +                doc.load(field);
   16.96 +            } catch (IOException e) {
   16.97 +                JOptionPane.showMessageDialog(field,
   16.98 +                    "Datei konnte nicht geladen werden: "+e.getMessage(),
   16.99 +                    "Sudoku", JOptionPane.ERROR_MESSAGE);
  16.100 +            }
  16.101 +        }
  16.102 +    }
  16.103 +    
  16.104 +    private boolean save(boolean rename) {
  16.105 +        if (!doc.isFilenameSet() || rename) {
  16.106 +            if (!chooseSaveFilename()) {
  16.107 +                return false;
  16.108 +            }
  16.109 +        }
  16.110 +        if (solver.check(field)) {
  16.111 +            field.setAllCellsModified(false);
  16.112 +            try {
  16.113 +                doc.save(field);
  16.114 +            } catch (IOException e) {
  16.115 +                JOptionPane.showMessageDialog(field,
  16.116 +                    "Datei konnte nicht gespeichert werden: "+e.getMessage(),
  16.117 +                    "Sudoku", JOptionPane.ERROR_MESSAGE);
  16.118 +            }
  16.119 +            return true;
  16.120 +        } else {
  16.121 +            JOptionPane.showMessageDialog(field,
  16.122 +                    "Das Feld kann mit Fehlern nicht gespeichert werden!",
  16.123 +                    "Sudoku", JOptionPane.ERROR_MESSAGE);
  16.124 +            return false;
  16.125 +        }
  16.126 +    }
  16.127 +    
  16.128 +    private void check() {
  16.129 +        if (solver.check(field)) {
  16.130 +            JOptionPane.showMessageDialog(field, "Überprüfung erfolgreich!",
  16.131 +                    "Sudoku", JOptionPane.INFORMATION_MESSAGE);
  16.132 +        } else {
  16.133 +            JOptionPane.showMessageDialog(field, "Das Feld enthält Fehler!",
  16.134 +                    "Sudoku", JOptionPane.WARNING_MESSAGE);
  16.135 +        }
  16.136 +    }
  16.137 +    
  16.138 +    private void solve() {
  16.139 +        if (!solver.check(field) || !solver.solve(field)) {
  16.140 +            JOptionPane.showMessageDialog(field, "Das Feld ist nicht lösbar!",
  16.141 +                    "Sudoku", JOptionPane.WARNING_MESSAGE);
  16.142 +        }
  16.143 +    }
  16.144 +    
  16.145 +    private boolean saveUnsaved() {
  16.146 +        boolean proceed = false;
  16.147 +        if (field.isAnyCellModified()) {
  16.148 +            int result = JOptionPane.showConfirmDialog(field,
  16.149 +                    "Das Feld ist ungespeichert - jetzt speichern?",
  16.150 +                    "Sudoku", JOptionPane.YES_NO_CANCEL_OPTION);
  16.151 +            if (result == JOptionPane.YES_OPTION) {
  16.152 +                if (save(false)) {
  16.153 +                    proceed = true;
  16.154 +                }
  16.155 +            } else if (result == JOptionPane.NO_OPTION) {
  16.156 +                proceed = true;
  16.157 +            }
  16.158 +        } else {
  16.159 +            proceed = true;
  16.160 +        }
  16.161 +        
  16.162 +        return proceed;
  16.163 +    }
  16.164 +
  16.165 +    @Override
  16.166 +    public void actionPerformed(ActionEvent e) {
  16.167 +        switch (e.getActionCommand()) {
  16.168 +        case NEW:
  16.169 +            if (saveUnsaved()) {
  16.170 +                doc.clearFilename();
  16.171 +                field.clear();
  16.172 +            }
  16.173 +            break;
  16.174 +        case OPEN:
  16.175 +            open();
  16.176 +            break;
  16.177 +        case SAVE:
  16.178 +            save(false);
  16.179 +            break;
  16.180 +        case SAVE_AS:
  16.181 +            save(true);
  16.182 +            break;
  16.183 +        case CHECK:
  16.184 +            check();
  16.185 +            break;
  16.186 +        case SOLVE:
  16.187 +            solve();
  16.188 +            break;
  16.189 +        case QUIT:
  16.190 +            if (saveUnsaved()) {
  16.191 +                System.exit(0);
  16.192 +            }
  16.193 +            break;
  16.194 +        case ABOUT:
  16.195 +            JOptionPane.showMessageDialog(field,
  16.196 +                    "Sudoku - Copyright (c) 2013 Mike Becker\nwww.uap-core.de"+
  16.197 +                    "\nPublished under the BSD License",
  16.198 +                    "Sudoku", JOptionPane.INFORMATION_MESSAGE);
  16.199 +            break;
  16.200 +        default:
  16.201 +            throw new UnsupportedOperationException(
  16.202 +                    "unknown action: "+e.getActionCommand());
  16.203 +        }
  16.204 +    }
  16.205 +    
  16.206 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/main/java/de/uapcore/sudoku/ButtonPanel.java	Sat Jul 25 14:01:28 2020 +0200
    17.3 @@ -0,0 +1,68 @@
    17.4 +/*
    17.5 + * Copyright 2013 Mike Becker. All rights reserved.
    17.6 + * 
    17.7 + * Redistribution and use in source and binary forms, with or without
    17.8 + * modification, are permitted provided that the following conditions are met:
    17.9 + * 
   17.10 + * 1. Redistributions of source code must retain the above copyright
   17.11 + *    notice, this list of conditions and the following disclaimer.
   17.12 + * 
   17.13 + * 2. Redistributions in binary form must reproduce the above copyright
   17.14 + *    notice, this list of conditions and the following disclaimer in the
   17.15 + *    documentation and/or other materials provided with the distribution.
   17.16 + * 
   17.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   17.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17.20 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   17.21 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   17.22 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   17.23 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   17.24 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   17.25 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   17.26 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   17.27 + * POSSIBILITY OF SUCH DAMAGE.
   17.28 + */
   17.29 +
   17.30 +package de.uapcore.sudoku;
   17.31 +
   17.32 +import javax.swing.*;
   17.33 +import java.awt.*;
   17.34 +
   17.35 +/**
   17.36 + *
   17.37 + * @author mike
   17.38 + */
   17.39 +public final class ButtonPanel extends JPanel {
   17.40 +    
   17.41 +    private JButton save, check, solve;
   17.42 +
   17.43 +    public ButtonPanel(ActionHandler l) {
   17.44 +        setLayout(new GridBagLayout());
   17.45 +        
   17.46 +        GridBagConstraints c = new GridBagConstraints();
   17.47 +        c.insets = new Insets(10, 10, 10, 10);
   17.48 +        c.fill = GridBagConstraints.HORIZONTAL;
   17.49 +        c.weightx = 1;
   17.50 +        
   17.51 +        c.gridx = 0;
   17.52 +        c.gridy = 0;
   17.53 +        save = new JButton("Speichern");
   17.54 +        add(save, c);
   17.55 +        c.gridx++;
   17.56 +        check = new JButton("Prüfen");
   17.57 +        add(check, c);
   17.58 +        solve = new JButton("Lösen");
   17.59 +        c.gridx++;
   17.60 +        add(solve, c);
   17.61 +        
   17.62 +        save.setActionCommand(ActionHandler.SAVE);
   17.63 +        save.addActionListener(l);
   17.64 +        check.setActionCommand(ActionHandler.CHECK);
   17.65 +        check.addActionListener(l);
   17.66 +        solve.setActionCommand(ActionHandler.SOLVE);
   17.67 +        solve.addActionListener(l);
   17.68 +        
   17.69 +        setBackground(Color.WHITE);
   17.70 +    }
   17.71 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/src/main/java/de/uapcore/sudoku/DocumentHandler.java	Sat Jul 25 14:01:28 2020 +0200
    18.3 @@ -0,0 +1,104 @@
    18.4 +/*
    18.5 + * Copyright 2013 Mike Becker. All rights reserved.
    18.6 + * 
    18.7 + * Redistribution and use in source and binary forms, with or without
    18.8 + * modification, are permitted provided that the following conditions are met:
    18.9 + * 
   18.10 + * 1. Redistributions of source code must retain the above copyright
   18.11 + *    notice, this list of conditions and the following disclaimer.
   18.12 + * 
   18.13 + * 2. Redistributions in binary form must reproduce the above copyright
   18.14 + *    notice, this list of conditions and the following disclaimer in the
   18.15 + *    documentation and/or other materials provided with the distribution.
   18.16 + * 
   18.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   18.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18.20 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   18.21 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   18.22 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   18.23 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   18.24 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   18.25 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   18.26 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   18.27 + * POSSIBILITY OF SUCH DAMAGE.
   18.28 + */
   18.29 +
   18.30 +package de.uapcore.sudoku;
   18.31 +
   18.32 +import java.io.*;
   18.33 +import java.util.regex.Matcher;
   18.34 +import java.util.regex.Pattern;
   18.35 +
   18.36 +/**
   18.37 + *
   18.38 + * @author mike
   18.39 + */
   18.40 +public class DocumentHandler {
   18.41 +    
   18.42 +    private String filename;
   18.43 +    
   18.44 +    public void load(Field field) throws IOException {
   18.45 +        if (!isFilenameSet()) {
   18.46 +            throw new IOException("no filename supplied");
   18.47 +        }
   18.48 +        int row = 0;
   18.49 +        try (BufferedReader in = new BufferedReader(
   18.50 +                new InputStreamReader(new FileInputStream(filename)))) {
   18.51 +            Pattern pat = Pattern.compile("^\\s*(?:[1-9_] ){8}[1-9_]\\s*$");
   18.52 +            String line;
   18.53 +            while ((line = in.readLine()) != null) {
   18.54 +                if (line.matches("^\\s*$")) {
   18.55 +                    continue;
   18.56 +                }
   18.57 +                Matcher m = pat.matcher(line);
   18.58 +                if (m.matches()) {
   18.59 +                    String c[] = line.trim().split(" ");
   18.60 +                    if (c.length != 9) {
   18.61 +                        break;
   18.62 +                    }
   18.63 +                    for (int i = 0 ; i < 9 ; i++) {
   18.64 +                        field.setCellValue(i, row,
   18.65 +                                c[i].equals("_") ? 0 : Integer.valueOf(c[i]));
   18.66 +                    }
   18.67 +                    row++;
   18.68 +                } else {
   18.69 +                    break;
   18.70 +                }
   18.71 +            }
   18.72 +            if (row != 9) {
   18.73 +                throw new IOException("Kein Sudoku-Feld enthalten!");
   18.74 +            }
   18.75 +        }
   18.76 +        field.setAllCellsModified(false);
   18.77 +    }
   18.78 +    
   18.79 +    public void save(Field field) throws IOException {
   18.80 +        if (!isFilenameSet()) {
   18.81 +            throw new IOException("no filename supplied");
   18.82 +        }
   18.83 +        
   18.84 +        try (BufferedWriter out = new BufferedWriter(
   18.85 +                new OutputStreamWriter(new FileOutputStream(filename)))) {
   18.86 +            for (int i = 0 ; i < 9 ; i++) {
   18.87 +                int[] row = field.getRow(i);
   18.88 +                for (int j = 0 ; j < 9 ; j++) {
   18.89 +                    out.append(row[j] > 0 ? Character.forDigit(row[j], 10):'_');
   18.90 +                    out.append(j == 8 ? '\n': ' ');
   18.91 +                }
   18.92 +            }
   18.93 +        }
   18.94 +    }
   18.95 +    
   18.96 +    public void setFilename(String filename) {
   18.97 +        this.filename = filename;
   18.98 +    }
   18.99 +    
  18.100 +    public void clearFilename() {
  18.101 +        filename = null;
  18.102 +    }
  18.103 +    
  18.104 +    public boolean isFilenameSet() {
  18.105 +        return filename != null;
  18.106 +    }
  18.107 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/src/main/java/de/uapcore/sudoku/Field.java	Sat Jul 25 14:01:28 2020 +0200
    19.3 @@ -0,0 +1,177 @@
    19.4 +/*
    19.5 + * Copyright 2013 Mike Becker. All rights reserved.
    19.6 + * 
    19.7 + * Redistribution and use in source and binary forms, with or without
    19.8 + * modification, are permitted provided that the following conditions are met:
    19.9 + * 
   19.10 + * 1. Redistributions of source code must retain the above copyright
   19.11 + *    notice, this list of conditions and the following disclaimer.
   19.12 + * 
   19.13 + * 2. Redistributions in binary form must reproduce the above copyright
   19.14 + *    notice, this list of conditions and the following disclaimer in the
   19.15 + *    documentation and/or other materials provided with the distribution.
   19.16 + * 
   19.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   19.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19.20 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   19.21 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   19.22 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   19.23 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   19.24 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   19.25 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   19.26 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   19.27 + * POSSIBILITY OF SUCH DAMAGE.
   19.28 + */
   19.29 +
   19.30 +package de.uapcore.sudoku;
   19.31 +
   19.32 +import javax.swing.*;
   19.33 +import java.awt.*;
   19.34 +import java.awt.image.BufferedImage;
   19.35 +
   19.36 +/**
   19.37 + *
   19.38 + * @author mike
   19.39 + */
   19.40 +public final class Field extends JPanel {
   19.41 +    private SudokuTextField[][] cells;
   19.42 +    
   19.43 +    public Field() {
   19.44 +        setBackground(Color.WHITE);
   19.45 +        
   19.46 +        setLayout(new GridBagLayout());
   19.47 +        GridBagConstraints c = new GridBagConstraints();
   19.48 +        c.insets = new Insets(5, 5, 5, 5);
   19.49 +        
   19.50 +        cells = new SudokuTextField[9][9];
   19.51 +        for (int x = 0 ; x < 9 ; x++) {
   19.52 +            for (int y = 0 ; y < 9 ; y++) {
   19.53 +                cells[x][y] = new SudokuTextField();
   19.54 +                c.gridx = x;
   19.55 +                c.gridy = y;
   19.56 +                add(cells[x][y], c);
   19.57 +            }
   19.58 +        }
   19.59 +    }
   19.60 +
   19.61 +    @Override
   19.62 +    public void paint(Graphics graphics) {
   19.63 +        final int w = getWidth();
   19.64 +        final int h = getHeight();
   19.65 +        final int cw = w / 9;
   19.66 +        final int ch = h / 9;
   19.67 +        
   19.68 +        BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
   19.69 +        Graphics2D g = img.createGraphics();
   19.70 +        g.setBackground(Color.WHITE);
   19.71 +        g.clearRect(0, 0, w, h);
   19.72 +        
   19.73 +        g.setColor(Color.BLACK);
   19.74 +        g.drawRect(1, 1, w-2, h-2);
   19.75 +        g.drawRect(2, 2, w-4, h-4);
   19.76 +        for (int x = cw ; x < w ; x += cw) {
   19.77 +            for (int y = ch ; y < h ; y += ch) {
   19.78 +                g.drawLine(x, 2, x, h-2);
   19.79 +                g.drawLine(2, y, w-2, y);
   19.80 +                if ((x / cw) % 3 == 0) {
   19.81 +                    g.drawLine(x+1, 2, x+1, h-2);
   19.82 +                }
   19.83 +                if ((y / ch) % 3 == 0) {
   19.84 +                    g.drawLine(2, y+1, w-2, y+1);
   19.85 +                }
   19.86 +            }
   19.87 +        }
   19.88 +        
   19.89 +        graphics.drawImage(img, 0, 0, this);
   19.90 +        super.paintChildren(graphics);
   19.91 +    }
   19.92 +    
   19.93 +    public boolean isCellEmpty(int x, int y) {
   19.94 +        return getCellValue(x, y) == 0;
   19.95 +    }
   19.96 +    
   19.97 +    public int getCellValue(int x, int y) {
   19.98 +        return cells[x][y].getValue();
   19.99 +    }
  19.100 +    
  19.101 +    public void setCellValue(int x, int y, int v) {
  19.102 +        cells[x][y].setValue(v);
  19.103 +    }
  19.104 +    
  19.105 +    public void clearCellValue(int x, int y) {
  19.106 +        setCellValue(x, y, 0);
  19.107 +    }
  19.108 +    
  19.109 +    public void setCellModified(int x, int y, boolean modified) {
  19.110 +        cells[x][y].setModified(modified);
  19.111 +    }
  19.112 +    
  19.113 +    public void setAllCellsModified(boolean modified) {
  19.114 +        for (int x = 0 ; x < 9 ; x++) {
  19.115 +            for (int y = 0 ; y < 9 ; y++) {
  19.116 +                cells[x][y].setModified(modified);
  19.117 +            }
  19.118 +        }
  19.119 +    }
  19.120 +    
  19.121 +    public boolean isAnyCellModified() {
  19.122 +        for (int x = 0 ; x < 9 ; x++) {
  19.123 +            for (int y = 0 ; y < 9 ; y++) {
  19.124 +                if (cells[x][y].isModified()) {
  19.125 +                    return true;
  19.126 +                }
  19.127 +            }
  19.128 +        }
  19.129 +        return false;
  19.130 +    }
  19.131 +    
  19.132 +    public void clear() {
  19.133 +        for (int x = 0 ; x < 9 ; x++) {
  19.134 +            for (int y = 0 ; y < 9 ; y++) {
  19.135 +                cells[x][y].setValue(0);
  19.136 +            }
  19.137 +        }
  19.138 +    }
  19.139 +    
  19.140 +    public int[][] getSquare(int x, int y) {
  19.141 +        if (x < 0 || x > 2 || y < 0 || y > 2) {
  19.142 +            throw new IllegalArgumentException("Invalid square coordinates");
  19.143 +        }
  19.144 +        int[][] square = new int[3][3];
  19.145 +        
  19.146 +        for (int u = 0 ; u < 3 ; u++) {
  19.147 +            for (int v = 0 ; v < 3 ; v++) {
  19.148 +                square[u][v] = getCellValue(3*x+u, 3*y+v);
  19.149 +            }
  19.150 +        }
  19.151 +        
  19.152 +        return square;
  19.153 +    }
  19.154 +    
  19.155 +    public int[] getRow(int y) {
  19.156 +        if (y < 0 || y > 8) {
  19.157 +            throw new IllegalArgumentException("Invalid row number");
  19.158 +        }
  19.159 +        int row[] = new int[9];
  19.160 +        
  19.161 +        for (int x = 0 ; x < 9 ; x++) {
  19.162 +            row[x] = getCellValue(x, y);
  19.163 +        }
  19.164 +        
  19.165 +        return row;
  19.166 +    }
  19.167 +    
  19.168 +    public int[] getColumn(int x) {
  19.169 +        if (x < 0 || x > 8) {
  19.170 +            throw new IllegalArgumentException("Invalid column number");
  19.171 +        }
  19.172 +        int column[] = new int[9];
  19.173 +        
  19.174 +        for (int y = 0 ; y < 9 ; y++) {
  19.175 +            column[y] = getCellValue(x, y);
  19.176 +        }
  19.177 +        
  19.178 +        return column;
  19.179 +    }
  19.180 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/main/java/de/uapcore/sudoku/MainMenu.java	Sat Jul 25 14:01:28 2020 +0200
    20.3 @@ -0,0 +1,98 @@
    20.4 +/*
    20.5 + * Copyright 2013 Mike Becker. All rights reserved.
    20.6 + * 
    20.7 + * Redistribution and use in source and binary forms, with or without
    20.8 + * modification, are permitted provided that the following conditions are met:
    20.9 + * 
   20.10 + * 1. Redistributions of source code must retain the above copyright
   20.11 + *    notice, this list of conditions and the following disclaimer.
   20.12 + * 
   20.13 + * 2. Redistributions in binary form must reproduce the above copyright
   20.14 + *    notice, this list of conditions and the following disclaimer in the
   20.15 + *    documentation and/or other materials provided with the distribution.
   20.16 + * 
   20.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   20.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20.20 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   20.21 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   20.22 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   20.23 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   20.24 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   20.25 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   20.26 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   20.27 + * POSSIBILITY OF SUCH DAMAGE.
   20.28 + */
   20.29 +
   20.30 +package de.uapcore.sudoku;
   20.31 +
   20.32 +import javax.swing.*;
   20.33 +
   20.34 +/**
   20.35 + *
   20.36 + * @author mike
   20.37 + */
   20.38 +public class MainMenu {
   20.39 +    
   20.40 +    private ActionHandler handler;
   20.41 +    private JMenuBar menuBar;
   20.42 +    
   20.43 +    public MainMenu(ActionHandler h) {
   20.44 +        handler = h;
   20.45 +        menuBar = new JMenuBar();
   20.46 +        menuBar.add(createMenu("Datei", 'd',
   20.47 +            createMenuItem("Neu", 'n', "control N", ActionHandler.NEW),
   20.48 +            createMenuItem("Öffnen", 'f', "control O", ActionHandler.OPEN),
   20.49 +            createMenuItem("Speichern", 's', "control S", ActionHandler.SAVE),
   20.50 +            createMenuItem("Speichern als...", 'a', ActionHandler.SAVE_AS),
   20.51 +            createSeparator(),
   20.52 +            createMenuItem("Prüfen", 'p', "control P", ActionHandler.CHECK),
   20.53 +            createMenuItem("Lösen", 'l', "control L", ActionHandler.SOLVE),
   20.54 +            createSeparator(),
   20.55 +            createMenuItem("Beenden", 'e', ActionHandler.QUIT)
   20.56 +        ));
   20.57 +        menuBar.add(createMenu("Help", 'h',
   20.58 +            createMenuItem("Über...", 'b', "F1", ActionHandler.ABOUT)
   20.59 +        ));
   20.60 +    }
   20.61 +    
   20.62 +    private JMenuItem createSeparator() {
   20.63 +        // Return null, the createMenu method knows how to handle it
   20.64 +        return null;
   20.65 +    }
   20.66 +    
   20.67 +    private JMenu createMenu(String caption, char mnemonic, JMenuItem...items) {
   20.68 +        JMenu menu = new JMenu(caption);
   20.69 +        menu.setMnemonic(mnemonic);
   20.70 +        for (JMenuItem item : items) {
   20.71 +            if (item == null) {
   20.72 +                menu.addSeparator();
   20.73 +            } else {
   20.74 +                menu.add(item);
   20.75 +            }
   20.76 +        }
   20.77 +        return menu;
   20.78 +    }
   20.79 +    
   20.80 +    private JMenuItem createMenuItem(String caption, char mnemonic,
   20.81 +            String command) {
   20.82 +        return createMenuItem(caption, mnemonic, null, command);
   20.83 +    }
   20.84 +    
   20.85 +    private JMenuItem createMenuItem(String caption, char mnemonic,
   20.86 +            String stroke, String command) {
   20.87 +        JMenuItem item = new JMenuItem(caption);
   20.88 +        item.setMnemonic(mnemonic);
   20.89 +        if (stroke != null) {
   20.90 +            item.setAccelerator(KeyStroke.getKeyStroke(stroke));
   20.91 +        }
   20.92 +        item.setActionCommand(command);
   20.93 +        item.addActionListener(handler);
   20.94 +        
   20.95 +        return item;
   20.96 +    }
   20.97 +    
   20.98 +    public JMenuBar getMenuBar() {
   20.99 +        return menuBar;
  20.100 +    }
  20.101 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/src/main/java/de/uapcore/sudoku/Solver.java	Sat Jul 25 14:01:28 2020 +0200
    21.3 @@ -0,0 +1,227 @@
    21.4 +/*
    21.5 + * Copyright 2013 Mike Becker. All rights reserved.
    21.6 + * 
    21.7 + * Redistribution and use in source and binary forms, with or without
    21.8 + * modification, are permitted provided that the following conditions are met:
    21.9 + * 
   21.10 + * 1. Redistributions of source code must retain the above copyright
   21.11 + *    notice, this list of conditions and the following disclaimer.
   21.12 + * 
   21.13 + * 2. Redistributions in binary form must reproduce the above copyright
   21.14 + *    notice, this list of conditions and the following disclaimer in the
   21.15 + *    documentation and/or other materials provided with the distribution.
   21.16 + * 
   21.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   21.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21.20 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   21.21 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   21.22 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   21.23 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   21.24 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   21.25 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   21.26 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   21.27 + * POSSIBILITY OF SUCH DAMAGE.
   21.28 + */
   21.29 +
   21.30 +package de.uapcore.sudoku;
   21.31 +
   21.32 +import java.util.ArrayList;
   21.33 +import java.util.List;
   21.34 +
   21.35 +/**
   21.36 + *
   21.37 + * @author mike
   21.38 + */
   21.39 +public final class Solver {
   21.40 +    
   21.41 +    public Solver() {
   21.42 +    }
   21.43 +    
   21.44 +    private Integer fillInCandidate(Field f, List<Integer>[][] candidates, int x, int y) {
   21.45 +        Integer c = candidates[x][y].remove(0);
   21.46 +        f.setCellValue(x, y, c);
   21.47 +        f.setCellModified(x, y, true);
   21.48 +        for (int i = 0 ; i < 9 ; i++) {
   21.49 +            candidates[x][i].remove(c);
   21.50 +            candidates[i][y].remove(c);
   21.51 +        }
   21.52 +        for (int i = 0 ; i < 3 ; i++) {
   21.53 +            for (int j = 0 ; j < 3 ; j++) {
   21.54 +                candidates[x-x%3+i][y-y%3+j].remove(c);
   21.55 +            }
   21.56 +        }
   21.57 +        return c;
   21.58 +    }
   21.59 +    
   21.60 +    private void makeBackup(List<Integer>[][] candidates, List<Integer>[][] candidatesBackup) {
   21.61 +        for (int x = 0 ; x < 9 ; x++) {
   21.62 +            for (int y = 0 ; y < 9 ; y++) {
   21.63 +                candidatesBackup[x][y] = new ArrayList<>(9);
   21.64 +                candidatesBackup[x][y].addAll(candidates[x][y]);
   21.65 +            }
   21.66 +        }
   21.67 +    }
   21.68 +    
   21.69 +    private void makeBackup(Field f, int[][] fieldBackup) {
   21.70 +        for (int x = 0 ; x < 9 ; x++) {
   21.71 +            for (int y = 0 ; y < 9 ; y++) {
   21.72 +                fieldBackup[x][y] = f.getCellValue(x, y);
   21.73 +            }
   21.74 +        }
   21.75 +    }
   21.76 +    
   21.77 +    private void restoreBackup(Field f, int[][] fieldBackup) {
   21.78 +        for (int x = 0 ; x < 9 ; x++) {
   21.79 +            for (int y = 0 ; y < 9 ; y++) {
   21.80 +                f.setCellValue(x, y, fieldBackup[x][y]);
   21.81 +            }
   21.82 +        }
   21.83 +    }
   21.84 +    
   21.85 +    private void restoreBackup(List<Integer>[][] candidates, List<Integer>[][] candidatesBackup) {
   21.86 +        for (int x = 0 ; x < 9 ; x++) {
   21.87 +            for (int y = 0 ; y < 9 ; y++) {
   21.88 +                candidates[x][y].clear();
   21.89 +                candidates[x][y].addAll(candidatesBackup[x][y]);
   21.90 +            }
   21.91 +        }
   21.92 +    }
   21.93 +    
   21.94 +    private boolean solve(Field f, List<Integer>[][] candidates) {
   21.95 +        
   21.96 +        // Make backup
   21.97 +        List<Integer>[][] candidatesBackup = new List[9][9];
   21.98 +        int[][] fieldBackup = new int[9][9];
   21.99 +        makeBackup(candidates, candidatesBackup);
  21.100 +        makeBackup(f, fieldBackup);
  21.101 +        
  21.102 +        // Fill in distinct solutions
  21.103 +        boolean fillDistinct;
  21.104 +        do {
  21.105 +            fillDistinct = false;
  21.106 +            for (int x = 0 ; x < 9 ; x++) {
  21.107 +                for (int y = 0 ; y < 9 ; y++) {
  21.108 +                    if (f.isCellEmpty(x, y) && candidates[x][y].size() == 1) {
  21.109 +                        fillInCandidate(f, candidates, x, y);
  21.110 +                        fillDistinct = true;
  21.111 +                    }
  21.112 +                }
  21.113 +            }
  21.114 +        } while (fillDistinct);
  21.115 +        
  21.116 +        // Try out remaining candidates
  21.117 +        for (int x = 0 ; x < 9 ; x++) {
  21.118 +            for (int y = 0 ; y < 9 ; y++) {
  21.119 +                if (f.isCellEmpty(x, y)) {
  21.120 +                    while (candidates[x][y].size() > 0) {
  21.121 +                        List<Integer>[][] cb = new List[9][9];
  21.122 +                        makeBackup(candidates, cb);
  21.123 +                        Integer c = fillInCandidate(f, candidates, x, y);
  21.124 +                        if (solve(f, candidates)) {
  21.125 +                            break;
  21.126 +                        } else {
  21.127 +                            f.clearCellValue(x, y);
  21.128 +                            restoreBackup(candidates, cb);
  21.129 +                            // Remove current candidate anyway
  21.130 +                            candidates[x][y].remove(c);
  21.131 +                        }
  21.132 +                    }
  21.133 +                }
  21.134 +                if (f.isCellEmpty(x, y)) {
  21.135 +                    restoreBackup(f, fieldBackup);
  21.136 +                    restoreBackup(candidates, candidatesBackup);
  21.137 +                    return false;
  21.138 +                }
  21.139 +            }
  21.140 +        }
  21.141 +        
  21.142 +        return true;
  21.143 +    }
  21.144 +    
  21.145 +    public boolean solve(Field f) {
  21.146 +        
  21.147 +        // Calculate initial candidates
  21.148 +        List<Integer> candidates[][] = new List[9][9];
  21.149 +        for (int x = 0 ; x < 9 ; x++) {
  21.150 +            for (int y = 0 ; y < 9 ; y++) {
  21.151 +                candidates[x][y] = new ArrayList<>(9);
  21.152 +                if (f.getCellValue(x, y) == 0) {
  21.153 +                    // All numbers are candidates
  21.154 +                    for (int c = 1 ; c <= 9 ; c++) {
  21.155 +                        candidates[x][y].add(c);
  21.156 +                    }
  21.157 +                    // Remove row duplicates
  21.158 +                    int[] line = f.getRow(y);
  21.159 +                    for (Integer c : line) {
  21.160 +                        candidates[x][y].remove(c);
  21.161 +                    }
  21.162 +                    // Remove column duplicates
  21.163 +                    line = f.getColumn(x);
  21.164 +                    for (Integer c : line) {
  21.165 +                        candidates[x][y].remove(c);
  21.166 +                    }
  21.167 +                    // Remove square duplicates
  21.168 +                    int[][] square = f.getSquare(x/3, y/3);
  21.169 +                    for (int[] sq : square) {
  21.170 +                        for (Integer c : sq) {
  21.171 +                            candidates[x][y].remove(c);
  21.172 +                        }
  21.173 +                    }
  21.174 +                }
  21.175 +            }
  21.176 +        }
  21.177 +        
  21.178 +        // Backtrack
  21.179 +        return solve(f, candidates);
  21.180 +    }
  21.181 +    
  21.182 +    public boolean check(Field f) {
  21.183 +        int line[];
  21.184 +        for (int i = 0 ; i < 9 ; i++) {
  21.185 +            line = f.getRow(i);
  21.186 +            if (!valid(line)) {
  21.187 +                return false;
  21.188 +            }
  21.189 +            line = f.getColumn(i);
  21.190 +            if (!valid(line)) {
  21.191 +                return false;
  21.192 +            }
  21.193 +        }
  21.194 +        
  21.195 +        int square[][];
  21.196 +        for (int x = 0 ; x < 3 ; x++) {
  21.197 +            for (int y = 0 ; y < 3 ; y++) {
  21.198 +                square = f.getSquare(x, y);
  21.199 +                if (!valid(square)) {
  21.200 +                    return false;
  21.201 +                }
  21.202 +            }
  21.203 +        }
  21.204 +        
  21.205 +        return true;
  21.206 +    }
  21.207 +    
  21.208 +    private boolean valid(int[] line) {
  21.209 +        int numbers[];
  21.210 +        numbers = new int[9];
  21.211 +        for (int i = 0 ; i < 9 ; i++) {
  21.212 +            int l = line[i]-1;
  21.213 +            if (l >= 0) {
  21.214 +                if ((++numbers[l]) > 1) {
  21.215 +                    return false;
  21.216 +                }
  21.217 +            }
  21.218 +        }
  21.219 +        
  21.220 +        return true;
  21.221 +    }
  21.222 +    
  21.223 +    private boolean valid(int[][] square) {
  21.224 +        int[] line = new int[9];
  21.225 +        for (int x = 0 ; x < 3 ; x++) {
  21.226 +            System.arraycopy(square[x], 0, line, 3*x, 3);
  21.227 +        }
  21.228 +        return valid(line);
  21.229 +    }
  21.230 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/src/main/java/de/uapcore/sudoku/Sudoku.java	Sat Jul 25 14:01:28 2020 +0200
    22.3 @@ -0,0 +1,69 @@
    22.4 +/*
    22.5 + * Copyright 2013 Mike Becker. All rights reserved.
    22.6 + * 
    22.7 + * Redistribution and use in source and binary forms, with or without
    22.8 + * modification, are permitted provided that the following conditions are met:
    22.9 + * 
   22.10 + * 1. Redistributions of source code must retain the above copyright
   22.11 + *    notice, this list of conditions and the following disclaimer.
   22.12 + * 
   22.13 + * 2. Redistributions in binary form must reproduce the above copyright
   22.14 + *    notice, this list of conditions and the following disclaimer in the
   22.15 + *    documentation and/or other materials provided with the distribution.
   22.16 + * 
   22.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   22.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22.20 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   22.21 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   22.22 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   22.23 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   22.24 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   22.25 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   22.26 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   22.27 + * POSSIBILITY OF SUCH DAMAGE.
   22.28 + */
   22.29 +
   22.30 +package de.uapcore.sudoku;
   22.31 +
   22.32 +import javax.swing.*;
   22.33 +import java.awt.*;
   22.34 +
   22.35 +/**
   22.36 + *
   22.37 + * @author mike
   22.38 + */
   22.39 +public final class Sudoku extends JFrame {
   22.40 +    
   22.41 +    public Sudoku() {
   22.42 +        super("Sudoku");
   22.43 +        
   22.44 +        Field f = new Field();
   22.45 +        ActionHandler h = new ActionHandler(f);
   22.46 +        setJMenuBar(new MainMenu(h).getMenuBar());
   22.47 +        
   22.48 +        Container content = getContentPane();
   22.49 +        
   22.50 +        content.setLayout(new GridBagLayout());
   22.51 +        GridBagConstraints c = new GridBagConstraints();
   22.52 +        c.insets = new Insets(20, 20, 20, 20);
   22.53 +        c.fill = GridBagConstraints.HORIZONTAL;
   22.54 +        
   22.55 +        c.gridx = 0; c.gridy = 0;
   22.56 +        content.add(f, c);
   22.57 +        c.gridy++;
   22.58 +        content.add(new ButtonPanel(h), c);
   22.59 +        
   22.60 +        pack();
   22.61 +        content.setBackground(Color.WHITE);
   22.62 +        setLocationByPlatform(true);
   22.63 +        setDefaultCloseOperation(EXIT_ON_CLOSE);
   22.64 +    }
   22.65 +
   22.66 +    /**
   22.67 +     * @param args the command line arguments
   22.68 +     */
   22.69 +    public static void main(String[] args) {
   22.70 +        new Sudoku().setVisible(true);
   22.71 +    }
   22.72 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/src/main/java/de/uapcore/sudoku/SudokuTextField.java	Sat Jul 25 14:01:28 2020 +0200
    23.3 @@ -0,0 +1,136 @@
    23.4 +/*
    23.5 + * Copyright 2013 Mike Becker. All rights reserved.
    23.6 + * 
    23.7 + * Redistribution and use in source and binary forms, with or without
    23.8 + * modification, are permitted provided that the following conditions are met:
    23.9 + * 
   23.10 + * 1. Redistributions of source code must retain the above copyright
   23.11 + *    notice, this list of conditions and the following disclaimer.
   23.12 + * 
   23.13 + * 2. Redistributions in binary form must reproduce the above copyright
   23.14 + *    notice, this list of conditions and the following disclaimer in the
   23.15 + *    documentation and/or other materials provided with the distribution.
   23.16 + * 
   23.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   23.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23.20 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   23.21 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   23.22 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   23.23 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   23.24 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   23.25 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   23.26 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   23.27 + * POSSIBILITY OF SUCH DAMAGE.
   23.28 + */
   23.29 +
   23.30 +package de.uapcore.sudoku;
   23.31 +
   23.32 +import javax.swing.*;
   23.33 +import java.awt.*;
   23.34 +import java.awt.event.FocusAdapter;
   23.35 +import java.awt.event.FocusEvent;
   23.36 +import java.awt.event.KeyAdapter;
   23.37 +import java.awt.event.KeyEvent;
   23.38 +
   23.39 +/**
   23.40 + *
   23.41 + * @author mike
   23.42 + */
   23.43 +public final class SudokuTextField extends JTextField {
   23.44 +    
   23.45 +    private boolean modified;
   23.46 +    
   23.47 +    public SudokuTextField() {
   23.48 +        setBorder(null);
   23.49 +        setBackground(Color.WHITE);
   23.50 +        
   23.51 +        setFont(new Font("Dialog", Font.PLAIN, 18));
   23.52 +        setHorizontalAlignment(JTextField.CENTER);
   23.53 +        
   23.54 +        Dimension dim = new Dimension(40,40);
   23.55 +        setPreferredSize(dim);
   23.56 +        setMinimumSize(dim);
   23.57 +        setMaximumSize(dim);
   23.58 +        
   23.59 +        addKeyListener(new KeyAdapter() {
   23.60 +            private void handle(KeyEvent e) {
   23.61 +                char c = e.getKeyChar();
   23.62 +                if (!e.isAltDown() && !e.isControlDown() &&
   23.63 +                        !Character.isISOControl(c)) {
   23.64 +                    // Perform clean input check
   23.65 +                    if (getText().length() > 0 && getSelectedText() == null) {
   23.66 +                        if (c != KeyEvent.CHAR_UNDEFINED) {
   23.67 +                            e.consume();
   23.68 +                        }
   23.69 +                    } else {
   23.70 +                        if (c < '1' || c > '9') {
   23.71 +                            e.consume();
   23.72 +                        } else {
   23.73 +                            setModified(true);
   23.74 +                        }
   23.75 +                    }
   23.76 +                } else {
   23.77 +                    // We can still be tricked by hotkeys, so do it the hard way
   23.78 +                    if (!getText().matches("^[1-9]$")) {
   23.79 +                        setText("");
   23.80 +                    }
   23.81 +                }
   23.82 +            }
   23.83 +            
   23.84 +            @Override
   23.85 +            public void keyPressed(KeyEvent e) {
   23.86 +                handle(e);
   23.87 +            }
   23.88 +
   23.89 +            @Override
   23.90 +            public void keyTyped(KeyEvent e) {
   23.91 +                handle(e);
   23.92 +            }
   23.93 +
   23.94 +            @Override
   23.95 +            public void keyReleased(KeyEvent e) {
   23.96 +                handle(e);
   23.97 +            }
   23.98 +            
   23.99 +        });
  23.100 +        addFocusListener(new FocusAdapter() {
  23.101 +            @Override
  23.102 +            public void focusGained(FocusEvent e) {
  23.103 +                selectAll();
  23.104 +            }
  23.105 +            @Override
  23.106 +            public void focusLost(FocusEvent e) {
  23.107 +                select(0, 0);
  23.108 +            }
  23.109 +        });
  23.110 +    }
  23.111 +    
  23.112 +    public int getValue() {
  23.113 +        if (getText().length() > 0) {
  23.114 +            return Integer.valueOf(getText());
  23.115 +        } else {
  23.116 +            return 0;
  23.117 +        }
  23.118 +    }
  23.119 +    
  23.120 +    public void setValue(int v) {
  23.121 +        if (v == 0) {
  23.122 +            setText("");
  23.123 +        } else if (v < 10) {
  23.124 +            setText(String.valueOf(v));
  23.125 +        } else {
  23.126 +            throw new IllegalArgumentException(
  23.127 +                    "Sudoku numbers must be in range 0-9 (0 means 'not set')");
  23.128 +        }
  23.129 +    }
  23.130 +    
  23.131 +    public void setModified(boolean modified) {
  23.132 +        this.modified = modified;
  23.133 +        setForeground(modified?Color.BLUE:Color.BLACK);
  23.134 +    }
  23.135 +    
  23.136 +    public boolean isModified() {
  23.137 +        return modified;
  23.138 +    }
  23.139 +}

mercurial