Stack Overflow first timer here!
First off, I\'m creating a Sudoku Solver using JavaFX. I\'ve got everything working, however, the only issue I\'m having is creating
The basic idea I would use is to put the text fields inside another container (e.g. a StackPane
) and then add some style to the stack pane. You should use an external style sheet to define the styles.
As the style depends on the location of the cell inside the "block", you need to somehow manipulate the style class depending on that location. Essentially you need a border on the bottom for rows 2 and 5, and a border on the right for columns 2 and 5. I think the cleanest way to do that part is to set or unset CSS PseudoClasses to indicate if the cell is in the right column, or bottom row of the respective blocks.
To generate the actual borders, use a "nested background" approach. The basic idea is to paint two rectangular backgrounds. The first is for the border, and fills the entire space. The second is for portion inside the border, and is painted over the top of the first, but with a 1 pixel inset along the edges where you want the border visible.
The CSS looks like:
sudoku.css:
.root {
-fx-padding: 5px ;
}
.cell {
/* Defines a black border around the standard color -fx-base */
-fx-background-color: black, -fx-base ;
/* By default draw the base color over the whole region, so no border visible */
-fx-background-insets: 0, 0 ;
-fx-padding: 5px ;
}
.cell:right {
-fx-background-insets: 0, 0 1 0 0 ;
}
.cell:bottom {
-fx-background-insets: 0, 0 0 1 0 ;
}
.cell:right:bottom {
-fx-background-insets: 0, 0 1 1 0 ;
}
.cell .text-field {
-fx-pref-width: 3em ;
-fx-pref-height: 3em ;
}
And here's a sample that uses it:
import javafx.application.Application;
import javafx.css.PseudoClass;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class SudokuBoard extends Application {
@Override
public void start(Stage primaryStage) {
GridPane board = new GridPane();
PseudoClass right = PseudoClass.getPseudoClass("right");
PseudoClass bottom = PseudoClass.getPseudoClass("bottom");
for (int col = 0; col < 9; col++) {
for (int row = 0; row < 9; row++) {
StackPane cell = new StackPane();
cell.getStyleClass().add("cell");
cell.pseudoClassStateChanged(right, col == 2 || col == 5);
cell.pseudoClassStateChanged(bottom, row == 2 || row == 5);
cell.getChildren().add(createTextField());
board.add(cell, col, row);
}
}
Scene scene = new Scene(board);
scene.getStylesheets().add("sudoku.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private TextField createTextField() {
TextField textField = new TextField();
// restrict input to integers:
textField.setTextFormatter(new TextFormatter<Integer>(c -> {
if (c.getControlNewText().matches("\\d?")) {
return c ;
} else {
return null ;
}
}));
return textField ;
}
public static void main(String[] args) {
launch(args);
}
}