I designed a simple virtual keyboard in JavaFX, for a Hangman-style game. The only problem is that I can't get the right alignment for the second and third row, as a real keyboard design has (for example, the A key is almost in the middle between the Q and W ones).
The keyboard is simply implemented using a GridPane
filled with a button for each character.
Is there a way to insert a little blank space?
I honestly thought of stacking three GridPane
, one for each row, and then adding the right offsets as blank texts, but this seemed to me a little bit forced, so I wanted to know if there was a "cleaner" way of doing it.
Here's my code:
package gui;
import game.GameManager;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
public class VirtualKeyboard extends HBox {
private final GridPane pane;
private final GameManager gameManager;
private static final char[] orderedKeys = {'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P',
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L',
'Z', 'X', 'C', 'V', 'B', 'N', 'M'};
public VirtualKeyboard(GameManager gameManager) {
this.pane = new GridPane();
this.gameManager = gameManager;
this.getChildren().add(pane);
setup();
}
@Override
public void setPrefSize(double v, double v1) {
super.setPrefSize(v, v1);
pane.setPrefSize(v, v1);
}
private void setup() {
var qButton = new Button("Q");
var wButton = new Button("W");
var eButton = new Button("E");
var rButton = new Button("R");
var tButton = new Button("T");
var yButton = new Button("Y");
var uButton = new Button("U");
var iButton = new Button("I");
var oButton = new Button("O");
var pButton = new Button("P");
var aButton = new Button("A");
var sButton = new Button("S");
var dButton = new Button("D");
var fButton = new Button("F");
var gButton = new Button("G");
var hButton = new Button("H");
var jButton = new Button("J");
var kButton = new Button("K");
var lButton = new Button("L");
var zButton = new Button("Z");
var xButton = new Button("X");
var cButton = new Button("C");
var vButton = new Button("V");
var bButton = new Button("B");
var nButton = new Button("N");
var mButton = new Button("M ");
setRowIndexes(0, qButton, wButton, eButton, rButton, tButton, yButton, uButton, iButton, oButton, pButton);
setRowIndexes(1, aButton, sButton, dButton, fButton, gButton, hButton, jButton, kButton, lButton);
setRowIndexes(2, zButton, xButton, cButton, vButton, bButton, nButton, mButton);
buttonSetup(qButton, wButton, eButton, rButton, tButton, yButton, uButton, iButton, oButton, pButton,
aButton, sButton, dButton, fButton, gButton, hButton, jButton, kButton, lButton,
zButton, xButton, cButton, vButton, bButton, nButton, mButton);
pane.getChildren().addAll(
qButton, wButton, eButton, rButton, tButton, yButton, uButton, iButton, oButton, pButton,
aButton, sButton, dButton, fButton, gButton, hButton, jButton, kButton, lButton,
zButton, xButton, cButton, vButton, bButton, nButton, mButton);
}
private void buttonSetup(Button... buttons) {
var keyCounter = 0;
for (Button button : buttons) {
button.setPrefSize(60.0, 60.0);
int finalKeyCounter = keyCounter;
button.setOnMouseClicked(mouseEvent -> gameManager.guess(orderedKeys[finalKeyCounter]));
button.getStyleClass().add("keyboard-button");
button.getStylesheets().add("file:stylesheets/virtual-keyboard.css");
keyCounter++;
//TODO: add in stylesheet and remove
button.setStyle("-fx-font-size: 22; -fx-font-weight: bold");
}
}
private void setRowIndexes(int row, Button... buttons) {
var column = 0;
for (Button button : buttons) {
GridPane.setConstraints(button, column, row);
column++;
}
}
}