import java.awt.*; import java.util.StringTokenizer; public class kw extends java.applet.Applet { final static int Kästchengröße = 30; final static int kUp = 0; final static int kDown = 1; final static int kAcross = 0; final static int kPadding = 20; final static int kQuestionAreaHeight = 20; int kAppWidth; int kAppHeight; int kBlocksWide; int kBlocksHigh; int layout[][]; String gGuesses[][]; String gQuestionsAcross[]; String gQuestionsDown[]; String answers[][]; Button btn; int gDirection = kAcross; int gCurX = 0; int gCurY = 0; int clipLeft = -1; int clipTop = -1; int clipWidth = -1; int clipHeight = -1; int gBlockMinY = 0; int gBlockMaxY = 0; int gBlockMinX = 0; int gBlockMaxX = 0; int gOldBlockMinY = 0; int gOldBlockMaxY = 0; int gOldBlockMinX = 0; int gOldBlockMaxX = 0; boolean gUpdateActiveAreaFlag = false; boolean gChangedActiveAreaFlag = false; /* ******************** */ public String StrToChar(String SourceStr , int Zahl) { /* Funktion, welche einen einzelnen Char an Position -Zahl- aus einem String -SourceStr- zieht, und diesen als String (!!) zurückgibt. */ int i = Zahl; int length = SourceStr.length(); StringBuffer DestStr = new StringBuffer(length); for (i = (length - 1); i >= 0; i--) { DestStr.append(SourceStr.charAt(Zahl)); return (DestStr.toString()); } return "Fehler"; // Fkt. muß in Java garantierte Rückgabe haben. } public int getParam(String name) { /* Fkt. welche einen Parameter -name- ausliest, diesen falls möglich in eine int-Variable umwandelt und zurückgibt. */ int intvalue = Integer.parseInt(getParameter(name)); return intvalue; } public void init() { Graphics gs = this.getGraphics(); int xCoord; int yCoord; int AnzahlTokens; int hCounter = 1; int vCounter = 1; int Counter = 1; String richtung = ""; String frage = ""; String antwort = ""; kBlocksWide = getParam("breite"); kBlocksHigh = getParam("hoehe"); kAppWidth = kBlocksWide * Kästchengröße; //gesamtbreite berechnen (Pixel) kAppHeight = kBlocksHigh * Kästchengröße; //gesamthöhe berechnen (Pixel) gGuesses = new String[kBlocksHigh][kBlocksWide]; String pString = this.getParameter("daten"); StringTokenizer t = new StringTokenizer(pString, ";,"); AnzahlTokens = t.countTokens(); gQuestionsAcross = new String[AnzahlTokens]; gQuestionsDown = new String[AnzahlTokens]; answers = new String[AnzahlTokens][AnzahlTokens]; layout = new int[AnzahlTokens][AnzahlTokens]; // solange Token durchlaufen bis Ende while (t.hasMoreTokens() == true) { // Parameter auslesen xCoord = Integer.parseInt(t.nextToken()); yCoord = Integer.parseInt(t.nextToken()); richtung = t.nextToken(); frage = t.nextToken(); antwort = t.nextToken(); // wenn horizontal if (richtung.startsWith("h") || richtung.startsWith("H")) { if (layout[yCoord-1][xCoord-1] < 1) { layout[yCoord-1][xCoord-1] = Counter; Counter++; } gQuestionsAcross[layout[yCoord-1][xCoord-1]] = new String(frage); for (int ai = 0; ai < antwort.length(); ai++) { answers[xCoord+ai-1][yCoord-1] = new String(StrToChar(antwort,ai)); } } // ende if horizontal // wenn vertikal if (richtung.startsWith("v") || richtung.startsWith("V")) { if (layout[yCoord-1][xCoord-1] < 1) { layout[yCoord-1][xCoord-1] = Counter; Counter++; } gQuestionsDown[layout[yCoord-1][xCoord-1]] = new String(frage); for (int bi = 0; bi < antwort.length(); bi++) { answers[xCoord-1][yCoord+bi-1] = new String(StrToChar(antwort,bi)); } } // ende if vertikal } // ende while /* Arrays an nicht uebergebenen Parametern auffüllen, das erspart später bei der entspr. Abfrage das abfangen von null-dingens-Exceptions. */ for (int aj = 0; aj < AnzahlTokens; aj++) { for (int ai = 0; ai < AnzahlTokens; ai++) { if (answers[ai][aj] == null) { answers[ai][aj] = " "; layout[aj][ai] = -1; } } } for (int aj = 0; aj < AnzahlTokens; aj++) { if (gQuestionsAcross[aj] == null) gQuestionsAcross[aj] = ""; if (gQuestionsDown[aj] == null) gQuestionsDown[aj] = ""; } // 0-Felder der Arrays initialisieren gQuestionsAcross[0] = ""; gQuestionsDown[0] = ""; int left; int top; // Feldgröße resize((kBlocksWide * Kästchengröße) + (kPadding * 2), (kBlocksHigh * Kästchengröße) + (kPadding * 3) + kQuestionAreaHeight); // Array für die Eingaben initialisieren for (int j = 0; j < kBlocksHigh; j++) { for (int i = 0; i < kBlocksWide; i++) { gGuesses[i][j] = ""; } } gOldBlockMinY = 0; gOldBlockMaxY = 0; gOldBlockMinX = 0; gOldBlockMaxX = 0; gDirection = kAcross; gCurX = 0; gCurY = 0; btn = new Button("Eingabe prüfen..."); this.add(btn); SetActiveBlock(gCurX, gCurY, gDirection); } public void paint(Graphics g) { int left = 5; int right = kAppWidth - 1; int top = 0; int bottom = kAppHeight - 1; int tempLeft = 0; int tempRight = 0; int tempTop = 0; Font f = new java.awt.Font("Helvetica", 0, 12); Font numFont = new java.awt.Font("Helvetica", 0, 10); Font answerFont = new java.awt.Font("Helvetica", 0, 18); FontMetrics answerFontMetrics = g.getFontMetrics(answerFont); FontMetrics questionFontMetrics = g.getFontMetrics(f); top = kPadding; g.setFont(f); g.setColor(Color.black); if (gDirection == kAcross) { String hs = new String ("horizontal: "); g.clearRect(0,0,200,50); hs = hs.concat(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]]); g.drawString(hs, left + 5, top + 22); } else { String vs = new String ("vertikal: "); g.clearRect(0,0,200,50); vs = vs.concat(gQuestionsDown[layout[gBlockMinY][gBlockMinX]]); g.drawString(vs, left + 5, top + 22); } top = (kPadding * 2) + kQuestionAreaHeight; for (int j = 0 ; j < kBlocksHigh ; j++) { for (int i = 0 ; i < kBlocksWide ; i++) { tempLeft = left + (i * Kästchengröße); tempTop = top + (j * Kästchengröße); if (InActiveBlock(i, j)) { if (i-1 == gCurX && j-1 == gCurY) g.setColor(Color.cyan); else g.setColor(Color.yellow); g.fillRect(tempLeft, tempTop, Kästchengröße, Kästchengröße); } else { g.setColor(Color.white); g.fillRect(tempLeft, tempTop, Kästchengröße, Kästchengröße); } g.setColor(Color.black); g.drawRect(tempLeft, tempTop, Kästchengröße , Kästchengröße ); if (layout[j][i] == -1){ g.setColor(Color.black); g.fillRect(tempLeft, tempTop, Kästchengröße, Kästchengröße); } else if (layout[j][i] != 0) { String numStr = String.valueOf(layout[j][i]); g.setFont(numFont); g.drawString(numStr, tempLeft + 4 , tempTop + 10); } } } } // void paint void PaintWord(Graphics g, int minX, int maxX, int minY, int maxY) { int left = 5; int top = (kPadding * 2) + kQuestionAreaHeight; int tempLeft = 0; int tempRight = 0; int tempTop = 0; Font f = new java.awt.Font("Helvetica", 0, 12); Font numFont = new java.awt.Font("Helvetica", 0, 10); Font answerFont = new java.awt.Font("Helvetica", 0, 18); FontMetrics answerFontMetrics = g.getFontMetrics(answerFont); g.setFont(f); top = (kPadding * 2) + kQuestionAreaHeight; for (int j = minY ; j <= maxY ; j++) { for (int i = minX ; i <= maxX ; i++) { tempLeft = left + (i * Kästchengröße); tempTop = top + (j * Kästchengröße); if (InActiveBlock(i, j)) { if (i == gCurX && j == gCurY) g.setColor(Color.cyan); else g.setColor(Color.yellow); g.fillRect(tempLeft, tempTop, Kästchengröße, Kästchengröße); } else { g.setColor(Color.white); g.fillRect(tempLeft, tempTop, Kästchengröße, Kästchengröße); } g.setColor(Color.black); g.drawRect(tempLeft, tempTop, Kästchengröße , Kästchengröße ); if (layout[j][i] == -1) { //schwarze Kaestchen fllen g.setColor(Color.black); g.fillRect(tempLeft, tempTop, Kästchengröße, Kästchengröße); } else if (layout[j][i] != 0) { // ausgabe der kleinen Ziffern String numStr = String.valueOf(layout[j][i]); g.setFont(numFont); g.drawString(numStr, tempLeft + 4 , tempTop + 10); } if (layout[j][i] != -1) { // wenn feld nicht schwarz dann... if (gGuesses[i][j].length() != 0) { if (gGuesses[i][j].equalsIgnoreCase(answers[i][j]) == false) g.setColor(Color.black); else g.setColor(Color.black); int sWidth = answerFontMetrics.stringWidth(gGuesses[i][j]); g.setFont(answerFont); g.drawString( gGuesses[i][j], tempLeft + ((Kästchengröße / 2) - (sWidth / 2)), (tempTop + Kästchengröße) - 6); } } } } } void PaintQuestionArea(Graphics g) { Font f = new java.awt.Font("Helvetica", 0, 12); int top = kPadding; int left = 5; g.setColor(Color.black); // farbe der Rätselfragen g.setFont(f); // oben definierten Font setzen // Rätselfragen ausgeben if (gDirection == kAcross) { String hs = new String ("horizontal: "); g.clearRect(0,0,200,50); hs = hs.concat(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]]); g.drawString(hs, left + 5, top + 22); } else { String vs = new String ("vertikal: "); g.clearRect(0,0,200,50); vs = vs.concat(gQuestionsDown[layout[gBlockMinY][gBlockMinX]]); g.drawString(vs, left + 5, top + 22); } // if gDirection } // PaintQuestionArea private boolean InActiveBlock(int x, int y) { if (x < gBlockMinX) return(false); if (x > gBlockMaxX) return(false); if (y < gBlockMinY) return(false); if (y > gBlockMaxY) return(false); return(true); } private void SetActiveBlock(int x, int y, int direction) { int tempx; int tempy; gOldBlockMinY = gBlockMinY; gOldBlockMaxY = gBlockMaxY; gOldBlockMinX = gBlockMinX; gOldBlockMaxX = gBlockMaxX; if (direction == kAcross) { gBlockMinY = y; gBlockMaxY = y; tempx = x; while (tempx > 0 && layout[y][tempx] != -1) { tempx--; } if (tempx > 0) gBlockMinX = tempx + 1; else { if (layout[y][0] == -1) gBlockMinX = 1; else gBlockMinX = 0; } tempx = x; while (tempx < kBlocksWide && layout[y][tempx] != -1){ tempx++; } gBlockMaxX = tempx - 1; } // if direction == kAcross else { gBlockMinX = x; gBlockMaxX = x; tempy = y; while (tempy > 0 && layout[tempy][x] != -1) { tempy--; } if (tempy > 0) gBlockMinY = tempy + 1; else { if (layout[0][x] == -1) gBlockMinY = 1; else gBlockMinY = 0; } tempy = y; while (tempy < kBlocksHigh && layout[tempy][x] != -1) { tempy++; } gBlockMaxY = tempy - 1; } } public void update(Graphics g) { if (clipLeft != -1 && clipTop != -1) { clipLeft = clipTop = clipWidth = clipHeight = -1; } if (gChangedActiveAreaFlag == false && gUpdateActiveAreaFlag == false) { paint(g); return; } if (gChangedActiveAreaFlag == true) { PaintQuestionArea(g); PaintWord(g, gOldBlockMinX, gOldBlockMaxX, gOldBlockMinY, gOldBlockMaxY); PaintWord(g, gBlockMinX, gBlockMaxX, gBlockMinY, gBlockMaxY); gChangedActiveAreaFlag = false; return; } if (gUpdateActiveAreaFlag == true) { gUpdateActiveAreaFlag = false; PaintWord(g, gBlockMinX, gBlockMaxX, gBlockMinY, gBlockMaxY); return; } } public boolean mouseDown(java.awt.Event evt, int x, int y) { int left = 5; int tempLeft; int tempTop; int top = (kPadding * 2) + kQuestionAreaHeight; Graphics ga = this.getGraphics(); Font answerFont = new java.awt.Font("Helvetica", 0, 18); FontMetrics answerFontMetrics = ga.getFontMetrics(answerFont); if (evt.target == btn) { for (int j = 0 ; j < kBlocksHigh ; j++) { for (int i = 0 ; i < kBlocksWide ; i++) { tempLeft = left + (i * Kästchengröße); tempTop = top + (j * Kästchengröße); if (gGuesses[i][j].equalsIgnoreCase(answers[i][j]) == false) ga.setColor(Color.red); else ga.setColor(Color.black); int sWidth = answerFontMetrics.stringWidth(gGuesses[i][j]); ga.setFont(answerFont); ga.drawString(gGuesses[i][j],tempLeft+((Kästchengröße/2)-(sWidth/2)),(tempTop+Kästchengröße)-6); } } return true; } requestFocus(); if (x < left) return false; if (y < top) return false; int j = y - top; j /= Kästchengröße; int i = x - left; i /= Kästchengröße; if (i >= 0 && i < kBlocksWide && j >= 0 && j < kBlocksHigh) { if (layout[j][i] != -1) { gCurX = i; gCurY = j; if (InActiveBlock(gCurX, gCurY)) { gUpdateActiveAreaFlag = true; repaint(); } else { SetActiveBlock(gCurX, gCurY, gDirection); gChangedActiveAreaFlag = true; repaint(); } return true; } } return true; } public boolean keyDown(java.awt.Event evt, int key) { // buchstaben eingeben, evtl umwandeln und ausgeben. if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z')) { char charArray[] = new char[1]; charArray[0] = (char)key; gGuesses[gCurX][gCurY] = new String(charArray); gGuesses[gCurX][gCurY] = gGuesses[gCurX][gCurY].toUpperCase(); // nur grosschrift bitte if (gDirection == kAcross) { //erh”hen der x-Richtung bei horizontal if (gCurX < kBlocksWide - 1 && layout[gCurY][gCurX+1] != -1) gCurX++; } else { //erh”hen der y-richtung bei vertikal (default) if (gCurY < kBlocksHigh - 1 && layout[gCurY + 1][gCurX] != -1) gCurY++; } gUpdateActiveAreaFlag = true; repaint(); return true; } switch ((char)key) { case ' ': ChangeDirection(); gChangedActiveAreaFlag = true; repaint(); break; case 0x08: if (gGuesses[gCurX][gCurY] != "") { gGuesses[gCurX][gCurY] = ""; gUpdateActiveAreaFlag = true; repaint(); } else { if (gDirection == kAcross) { if (gCurX != 0 && layout[gCurY][gCurX-1] != -1) { gCurX--; gGuesses[gCurX][gCurY] = ""; gUpdateActiveAreaFlag = true; repaint(); } } else { if (gCurY != 0 && layout[gCurY - 1][gCurX] != -1) { gCurY--; gGuesses[gCurX][gCurY] = ""; gUpdateActiveAreaFlag = true; repaint(); } } } break; } return true; } void ChangeDirection() { if (gDirection == kDown) gDirection = kUp; else gDirection = kDown; // default (:= also horizontal --> vertikal) SetActiveBlock(gCurX, gCurY, gDirection); } } // Programmende