import java.io.File; import javafx.application.Application; import javafx.stage.Stage; import javafx.stage.FileChooser; import javafx.scene.Scene; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.control.Label; import javafx.scene.control.Button; import javafx.scene.control.Alert; import javafx.scene.layout.HBox; import javafx.scene.layout.GridPane; import javafx.scene.layout.BorderPane; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Pane; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.RowConstraints; import javafx.scene.input.KeyEvent; import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCombination; import javafx.scene.input.KeyCode; import javafx.event.EventHandler; import javafx.event.ActionEvent; abstract class ActionHandler implements EventHandler {} abstract class KeyHandler implements EventHandler {} abstract class Util { static Brett loadBoard(Stage stage) { boolean loaded = false; Brett board = null; while (!loaded) { File f = getFile(stage); if (f == null) return null; try { board = new Brett(f); loaded = true; } catch (Exception ex) { error(ex.getMessage()); } } return board; } static void error(String msg) { Alert alert = new Alert(Alert.AlertType.ERROR, msg); alert.showAndWait(); } static File getFile(Stage stage) { FileChooser chooser = new FileChooser(); return chooser.showOpenDialog(stage); } } class SolutionGrid { GridPane grid; SolutionGrid(Brett board, SudokuBeholder.Losning solution) { grid = new GridPane(); grid.setMinSize(200, 200); // Add labels to grid int x = 0; int y = 0; for (SudokuBeholder.Losning.Verdi val: solution) { Label l; if (val.tall == -1) { l = new Label(" "); } else { l = new Label(""+val.tall); } l.setFont(Font.font("Sans-Serif", 16)); if (val.original) { l.setTextFill(Color.web("red")); } // Rather ugly way of getting pretty lines String style = "-fx-border-style: solid;"; style += "-fx-border-width: 3px;"; String bColor = "-fx-border-color: "; bColor += "COLY "; bColor += (x == board.storrelse - 1 ? "COL " : "transparent "); bColor += (y == board.storrelse - 1 ? "COL " : "transparent "); bColor += "COLX "; if (x % board.antallBokserX == 0 && x != 0) { bColor = bColor.replace("COLX", "red"); } else { bColor = bColor.replace("COLX", "grey"); } if (y % board.antallBokserY == 0 && y != 0) { bColor = bColor.replace("COLY", "red"); } else { bColor = bColor.replace("COLY", "grey"); } bColor = bColor.replace("COL", "grey"); style += bColor + ";"; BorderPane bp = new BorderPane(); bp.setStyle(style); bp.setCenter(l); grid.getChildren().add(bp); grid.setConstraints(bp, x, y); x += 1; if (x >= board.storrelse) { x = 0; y += 1; } } // Set constraints double percent = (1.0 / board.storrelse) * 100; for (int i = 0; i < board.storrelse; ++i) { ColumnConstraints cc = new ColumnConstraints(); RowConstraints rc = new RowConstraints(); cc.setPercentWidth(percent); rc.setPercentHeight(percent); grid.getColumnConstraints().add(cc); grid.getRowConstraints().add(rc); } } public Pane getPane() { return grid; } } class SolvedView { int index; Stage stage; Brett board; BorderPane root; SudokuBeholder sb; Label lblNumSolutions; Button btnPrev; Button btnNext; private void drawGrid() { Pane grid = new SolutionGrid(board, sb.hent(index)).getPane(); root.setCenter(grid); lblNumSolutions.setText( "Solution "+(index+1)+"/"+sb.hentAntallLosninger() ); } SolvedView(Stage stage, Brett board, SudokuBeholder sb) { index = 0; this.stage = stage; this.board = board; root = new BorderPane(); this.sb = sb; // Menu HBox menu = new HBox(12); lblNumSolutions = new Label(""); lblNumSolutions.setPrefHeight(30); menu.getChildren().add(lblNumSolutions); // Button prev btnPrev = new Button("Prev"); btnPrev.setPrefHeight(30); if (sb.hentAntallLosninger() > 1) { menu.getChildren().add(btnPrev); } btnPrev.setOnAction(new ActionHandler() { public void handle(ActionEvent evt) { if (index < 1) return; index -= 1; drawGrid(); } }); // Button next btnNext = new Button("Next"); btnNext.setPrefHeight(30); if (sb.hentAntallLosninger() > 1) { menu.getChildren().add(btnNext); } btnNext.setOnAction(new ActionHandler() { public void handle(ActionEvent evt) { if (index >= sb.hentAntallLosninger() - 1) return; index += 1; drawGrid(); } }); root.setTop(menu); drawGrid(); } public void show() { stage.getScene().setRoot(root); stage.show(); } } class UnsolvedView { Stage stage; BorderPane root; UnsolvedView(Stage stage, Brett board) { this.stage = stage; root = new BorderPane(); // Menu HBox menu = new HBox(12); Button btnSolve = new Button("Solve"); btnSolve.setPrefHeight(30); btnSolve.setOnAction(new ActionHandler() { @Override public void handle(ActionEvent ae) { SudokuBeholder sb = board.los(); new SolvedView(stage, board, sb).show(); } }); menu.getChildren().add(btnSolve); root.setTop(menu); // Grid Pane grid = new SolutionGrid(board, board.tilLosning()).getPane(); root.setCenter(grid); } public void show() { stage.getScene().setRoot(root); stage.show(); } } public class Gui extends Application { @Override public void start(Stage stage) { Brett board = Util.loadBoard(stage); if (board == null) { System.exit(1); return; } stage.setTitle("Sudoku"); SudokuBeholder.Losning unsolved = board.tilLosning(); Scene scene = new Scene(new BorderPane(), 500, 500); stage.setScene(scene); KeyCodeCombination openFileComb = new KeyCodeCombination( KeyCode.O, KeyCombination.CONTROL_DOWN ); scene.addEventHandler(KeyEvent.KEY_RELEASED, new KeyHandler() { @Override public void handle(KeyEvent evt) { if (openFileComb.match(evt)) { Brett board = Util.loadBoard(stage); if (board != null) new UnsolvedView(stage, board).show(); } } }); new UnsolvedView(stage, board).show(); } public static void main(String[] args) { launch(); } public Gui() { super(); } }