001 package de.hska.java.aufgaben.backtracking;
002
003 import java.awt.Color;
004 import java.awt.Dimension;
005 import java.awt.Font;
006 import java.awt.Graphics;
007 import java.awt.Graphics2D;
008 import java.awt.event.MouseEvent;
009 import java.awt.event.MouseListener;
010 import java.awt.event.WindowEvent;
011 import java.awt.event.WindowListener;
012
013 import javax.swing.JFrame;
014
015
016
017 /**
018 * Visualisierung eines Sudokus in einem Fenster.
019 * Durch Klicken mit der Maus wird immer der nächste Schritt des Backtracking-Algorithmus
020 * ausgelöst.
021 *
022 * @author Christian Pape
023 *
024 */
025 public class JSudokuFrame extends JFrame implements SudokuListener, MouseListener, WindowListener {
026
027 private boolean naechstenSchrittAusfuehren;
028
029 private Sudoku sudoku;
030
031 private char [] [] zahlen = {{'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'} };
032
033 /**
034 * Erzeugt ein neues Sudoku-Frame für das gegebene <code>sudoku</code>
035 * @param sudoku
036 */
037 public JSudokuFrame(Sudoku sudoku) {
038 this.sudoku = sudoku;
039 this.sudoku.addSudokuListener(this);
040 this.addMouseListener(this);
041 this.addWindowListener(this);
042 setPreferredSize(new Dimension(800, 600));
043 }
044
045 /**
046 * Wird von <code>sudoku</code> aufgerufen, wenn
047 * sich der Wert einer Zelle im Sudoku geändert hat.
048 */
049 public void zahlHatSichGeaendert(int zeile, int spalte, final int zahl) {
050 this.repaint(10);
051 while (! naechstenSchrittAusfuehren) {
052 try {
053 Thread.sleep(100);
054 } catch (InterruptedException e) {
055 naechstenSchrittAusfuehren = true;
056 }
057 }
058 naechstenSchrittAusfuehren = false;
059 }
060
061 /**
062 * Zeichnet das gesamte Sudoku neu.
063 */
064 public void paint(Graphics g) {
065 Graphics2D graphics = (Graphics2D) g;
066
067 graphics.setBackground(Color.WHITE);
068 graphics.clearRect(getRootPane().getX(), getRootPane().getY(),
069 getRootPane().getWidth(), getRootPane().getHeight());
070 int x = getRootPane().getX();
071 int y = getRootPane().getY();
072 int cellWidth = (getRootPane().getWidth() - x) / 9;
073 int cellHeight = (getRootPane().getHeight() - y) / 9;
074 Font font = graphics.getFont();
075 font = font.deriveFont( (cellWidth + cellHeight) / 1.8f );
076 graphics.setFont(font);
077 for (int zeile = 0; zeile < 9; zeile++) {
078 for (int spalte = 0; spalte < 9; spalte++) {
079 graphics.setColor(Color.GRAY);
080 graphics.drawRect(x + cellWidth * spalte, y + cellHeight * zeile, cellWidth, cellHeight);
081 graphics.setColor(Color.BLACK);
082 int zahl = this.sudoku.getZahl(zeile, spalte);
083 if (1 <= zahl && zahl <= 9) {
084 graphics.drawChars( zahlen[zahl], 0,
085 1, x + cellWidth * spalte, y + font.getBaselineFor(zahlen[zahl][0])+ cellHeight * (zeile + 1));
086 }
087 }
088 }
089 }
090
091 public static final void main(String [] argv) throws InterruptedException {
092 final Sudoku sudoku = new Sudoku(new int[][] {
093 { 9, -1, 3, -1, 1, -1, 7, -1, -1},
094 {-1, 6, -1, -1, -1, 8, 5, -1, -1},
095 {-1, 5, -1, -1, -1, -1, -1, 9, 6},
096 {-1, -1, -1, -1, 3, -1, 6, -1, 4},
097 {-1, 4, -1, 9, -1, 1, 3, 7, 2},
098 {-1, -1, -1, 8, 7, 4, -1, 1, -1},
099 {-1, -1, 5, -1, -1, 3, 2, -1, 1},
100 { 6, 8, 7, -1, -1, -1, -1, -1, -1},
101 { 3, -1, -1, -1, -1, -1, -1, 5, -1}
102 });
103 JSudokuFrame jSudokuFrame = new JSudokuFrame(sudoku);
104 jSudokuFrame.pack();
105 jSudokuFrame.setVisible(true);
106 Thread thread = new Thread( new Runnable() {
107 public void run() {
108 sudoku.sucheLoesung(0);
109 }
110 });
111 thread.start();
112 thread.join();
113 }
114
115 public void mouseClicked(MouseEvent e) {
116 naechstenSchrittAusfuehren = true;
117 }
118
119 public void mouseEntered(MouseEvent e) {
120
121 }
122
123 public void mouseExited(MouseEvent e) {
124
125 }
126
127 public void mousePressed(MouseEvent e) {
128
129 }
130
131 public void mouseReleased(MouseEvent e) {
132
133 }
134
135 public void windowActivated(WindowEvent e) {
136 }
137
138 public void windowClosed(WindowEvent e) {
139
140 }
141
142 public void windowClosing(WindowEvent e) {
143 System.exit(0);
144 }
145
146 public void windowDeactivated(WindowEvent e) {
147
148 }
149
150 public void windowDeiconified(WindowEvent e) {
151
152
153 }
154
155 public void windowIconified(WindowEvent e) {
156
157
158 }
159
160 public void windowOpened(WindowEvent e) {
161
162
163 }
164
165
166 }