The following source code creates a multiplication table for teaching purposes. It should run in the most recent Processing editor (v. 4.3.2) since all the JavaFX modules have now been added:
import javafx.scene.Scene;
import javafx.application.Platform;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.event.EventHandler;
import javafx.scene.input.MouseEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
final int _wndW = 700;
final int _wndH = 480;
final int _numRows = 12;
final int _numCols = 12;
int colNum = 1;
int rowNum = 1;
int id = 0;
float correct = 0.0;
float incorrect = 0.0;
float score = 0.00;
int[] answer;
String strID = str(0);
String inputStr = "";
String correctStr = "";
String incorrectStr = "";
String scoreStr = "";
TextField[] txtFld;
Label instructionLabel;
Label correctLabel;
Label incorrectLabel;
Label scoreLabel;
Button resetBtn;
Button quitBtn;
Pane pane;
void resetAction() {
for (int i = 0; i < txtFld.length-1; i++) {
txtFld[i].setEditable(true);
txtFld[i].setText("");
}
correct = 0.0;
incorrect = 0.0;
score = 0.00;
correctStr = "Correct: " + int(correct);
correctLabel.setText(correctStr);
incorrectStr = "Incorrect: " + int(incorrect);
incorrectLabel.setText(incorrectStr);
scoreStr = "Score: " + nf(score, 2, 0);
scoreLabel.setText(scoreStr);
}
void resetButton(int x, int y, int w, int h) {
resetBtn = new Button("Reset");
resetBtn.setLayoutX(x);
resetBtn.setLayoutY(y);
resetBtn.setMaxSize(w, h);
resetBtn.setOnAction(event -> {
resetAction();
}
);
pane.getChildren().add(resetBtn);
}
void quitButton(int x, int y, int w, int h) {
quitBtn = new Button("Quit");
quitBtn.setLayoutX(x);
quitBtn.setLayoutY(y);
quitBtn.setMaxSize(w, h);
quitBtn.setOnAction(event -> {
System.exit(0);
}
);
pane.getChildren().add(quitBtn);
}
void instructionLabel(int x, int y, int w, int h) {
String instructionStr = "Hit return(enter) to register answer.";
instructionLabel = new Label();
Font font = Font.font("Menlo", FontWeight.BOLD, FontPosture.REGULAR, 15);
instructionLabel.setFont(font);
instructionLabel.setTextFill(Color.BLUE);
instructionLabel.setLayoutX(x);
instructionLabel.setLayoutY(y);
instructionLabel.setPrefSize(w, h);
instructionLabel.setText(instructionStr);
pane.getChildren().add(instructionLabel);
}
void correctLabel(int x, int y, int w, int h) {
correctLabel = new Label();
Font font = Font.font("Menlo", FontWeight.BOLD, FontPosture.REGULAR, 15);
correctLabel.setFont(font);
correctLabel.setTextFill(Color.GREEN);
correctLabel.setLayoutX(x);
correctLabel.setLayoutY(y);
correctLabel.setPrefSize(w, h);
correctLabel.setText("Correct: " + int(correct));
pane.getChildren().add(correctLabel);
}
void incorrectLabel(int x, int y, int w, int h) {
incorrectLabel = new Label();
Font font = Font.font("Menlo", FontWeight.BOLD, FontPosture.REGULAR, 15);
incorrectLabel.setFont(font);
incorrectLabel.setTextFill(Color.RED);
incorrectLabel.setLayoutX(x);
incorrectLabel.setLayoutY(y);
incorrectLabel.setPrefSize(w, h);
incorrectLabel.setText("Incorrect: " + int(incorrect));
pane.getChildren().add(incorrectLabel);
}
void scoreLabel(int x, int y, int w, int h) {
scoreLabel = new Label();
Font font = Font.font("Menlo", FontWeight.BOLD, FontPosture.REGULAR, 15);
scoreLabel.setFont(font);
scoreLabel.setTextFill(Color.BLUE);
scoreLabel.setLayoutX(x);
scoreLabel.setLayoutY(y);
scoreLabel.setPrefSize(w, h);
scoreLabel.setText("Score: ");
pane.getChildren().add(scoreLabel);
}
void horzLabelGrid(int left, int top, int w, int h, int vg) {
for (int j = 0; j < _numCols; j++) {
int x = left + j*(w+vg);
int y = top;
Label label = new Label(str(colNum));
Font font = Font.font("Menlo", FontWeight.BOLD, FontPosture.REGULAR, 15);
label.setFont(font);
label.setTextFill(Color.BLUE);
label.setLayoutX(x);
label.setLayoutY(y);
label.setPrefSize(w, h);
pane.getChildren().add(label);
colNum++;
}
}
void vertLabelGrid(int left, int top, int w, int h, int gap) {
for (int k = 0; k < _numRows; k++) {
int x = left;
int y = top + k*(h+gap);
Label label = new Label(str(rowNum));
Font font = Font.font("Menlo", FontWeight.BOLD, FontPosture.REGULAR, 15);
label.setFont(font);
label.setTextFill(Color.BLUE);
label.setLayoutX(x);
label.setLayoutY(y);
label.setPrefSize(w, h);
pane.getChildren().add(label);
rowNum++;
}
}
void txtFldGrid(int left, int top, int w, int h, int vg, int hg) {
for (int k = 0; k < _numRows; k++) {
for (int j = 0; j < _numCols; j++) {
int product = (j+1)*(k+1);
answer[id] = product;
int x = left + j*(w+vg);
int y = top + k*(h+hg);
txtFld[id] = new TextField("");
txtFld[id].setFont(Font.font("Verdana", FontWeight.BOLD, FontPosture.REGULAR, 13));
txtFld[id].setLayoutX(x);
txtFld[id].setLayoutY(y);
txtFld[id].setMaxSize((double) w, (double) h);
txtFld[id].setId(str(id));
txtFld[id].addEventFilter(MouseEvent.MOUSE_CLICKED, eventHandler);
txtFld[id].setOnAction(event -> {
getInput();
}
);
pane.getChildren().add(txtFld[id]);
id++;
}
}
}
EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
strID = ((TextField)e.getSource()).getId();
}
};
void getInput() {
int i = Integer.parseInt(strID);
inputStr = txtFld[i].getText();
if (inputStr.equals(str(answer[i]))) {
correct++;
txtFld[i].setStyle("-fx-text-fill: green;");
txtFld[i].setEditable(false);
correctStr = "Correct: " + int(correct);
correctLabel.setText(correctStr);
} else {
txtFld[i].setStyle("-fx-text-fill: red;");
txtFld[i].setEditable(false);
incorrect++;
incorrectStr = "Incorrect: " + int(incorrect);
incorrectLabel.setText(incorrectStr);
}
if (correct+incorrect > 0) {
float total = correct + incorrect;
score = correct/total*100;
scoreStr = "Score: " + nf(score, 2, 0);
scoreLabel.setText(scoreStr);
}
}
void setup() {
size(1, 1, FX2D);
Stage stage = new Stage();
stage.setTitle("Multiply rows x cols");
pane = new Pane();
txtFld = new TextField[_numRows*_numCols+1];
answer = new int[_numRows*_numCols+1];
instructionLabel(45, 10, _wndW - 45, 30);
horzLabelGrid(90, 35, 49, 30, 0);
vertLabelGrid(45, 58, 40, 30, 0);
txtFldGrid(70, 60, 45, 30, 5, 0);
correctLabel(45, _wndH - 50, 120, 30);
incorrectLabel(170, _wndH - 50, 150, 30);
scoreLabel(330, _wndH - 50, 140, 30);
resetButton(500, _wndH - 50, 100, 30);
quitButton(_wndW - 80, _wndH - 50, 100, 30);
Scene scene = new Scene(pane, _wndW, _wndH);
stage.setScene(scene);
stage.show();
}
void draw() {
// Does nothing in JavaFX!
}
Output: