Java FX Breakout 2026
Part 2 - Paddle and Keyboard Input
In this Java FX Breakout update, we add a custom input handling object and paddle to control.
InputHandler.java
package ceccs;
import javafx.event.EventHandler;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
public class InputHandler {
JfxBreakoutApp app;
//TODO: add the mouse controls next session
EventHandler<MouseEvent> mouseEventEventHandler;
EventHandler<KeyEvent> keyEventEventHandler;
boolean move_right, move_left;
public InputHandler(JfxBreakoutApp app){
this.app = app;
keyEventEventHandler = new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
boolean state = false;
if(event.getEventType() == KeyEvent.KEY_PRESSED) {
state = true;
} else if (event.getEventType() == KeyEvent.KEY_RELEASED) {
state = false;
}
switch (event.getCode()){
case A:
case LEFT:
move_left = state;
break;
case D:
case RIGHT:
move_right = state;
break;
}
}
};
app.gameScene.setOnKeyPressed(keyEventEventHandler);
app.gameScene.setOnKeyReleased(keyEventEventHandler);
}
}
Paddle.java
package ceccs;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
public class Paddle extends Rectangle {
JfxBreakoutApp app;
double x,y;
double vx,vy;
double width, height;
final double baseSpeed = 1;
public Paddle(double width, double height, JfxBreakoutApp app){
this.app = app;
this.width = width;
this.height = height;
x = app.width/2 - width/2;
y = app.height - 1.5*height;
vx = 0;
vy = 0;
setFill(Color.CYAN);
updateGraphics();
app.motionPane.getChildren().add(this);
}
public void updateMotion(){
x += vx;
y += vy;
}
public void updateCollision(){
//left edge boundary
if(x < 0) x = 0;
if(x > app.width - this.width){
x = (app.width - this.width);
}
}
public void updateGraphics(){
setLayoutX(x);
setLayoutY(y);
setWidth(width);
setHeight(height);
}
}
ClassFile.java
package ceccs;
import javafx.animation.AnimationTimer;
public class GameTimer extends AnimationTimer {
...
@Override
public void handle(long now) {
updateInput(); //Added
updateMotion();
updateCollision();
updateGraphics();
}
private void updateInput(){
if(app.inputHandler.move_left && !app.inputHandler.move_right){
//go left
app.paddle.vx = -1.0 * app.paddle.baseSpeed;
} else if(!app.inputHandler.move_left && app.inputHandler.move_right){
//go right
app.paddle.vx = app.paddle.baseSpeed;
} else {
// x halt
// you are pressing both or niether...
app.paddle.vx = 0;
}
}
private void updateMotion(){
app.ball.updateMotion();
app.paddle.updateMotion(); //
}
private void updateCollision(){
app.ball.updateCollision();
app.paddle.updateCollision(); //
}
private void updateGraphics(){
app.ball.updateGraphics();
app.paddle.updateGraphics(); //
}
}
ClassFile.java
//file