This answer is not to do with AppData, but you did ask about other solutions, so this is one based upon the Preferences API. The sample is for a preferences based API storage for a high-score system. The sample does not encrypt data.
You mention in your question that you are worried about the user modifying the preferences to fudge high scores. Encrypting or hiding data for a client application such that a user is not able to modify the data is a tricky proposition, so I won't go into how to do that here. If that is a requirement for you, then you can research other info on the internet for methods to accomplish that.

ScoreStorage.java
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
public class ScoreStorage {
private static final int MAX_NUM_SCORES = 3;
private static final String SCORE_PREFERENCE_KEY_PREFIX = "score-";
private ObservableList<Integer> scores = FXCollections.observableArrayList();
private Preferences scorePreferences = Preferences.userNodeForPackage(
ScoreStorage.class
);
public ScoreStorage() throws BackingStoreException {
for (String key: scorePreferences.keys()) {
scores.add(scorePreferences.getInt(key, 0));
}
}
public ObservableList<Integer> getUnmodifiableScores() {
return FXCollections.unmodifiableObservableList(scores);
}
public void clearScores() {
scores.clear();
storeScores();
}
public void recordScore(int score) {
int i = 0;
while (i < MAX_NUM_SCORES && i < scores.size() && scores.get(i) >= score) {
i++;
}
if (i < MAX_NUM_SCORES) {
if (scores.size() == MAX_NUM_SCORES) {
scores.remove(scores.size() - 1);
}
scores.add(i, score);
storeScores();
}
}
private void storeScores() {
int i = 0;
for (int score: scores) {
scorePreferences.putInt(SCORE_PREFERENCE_KEY_PREFIX + i, score);
i++;
}
while (i < MAX_NUM_SCORES) {
scorePreferences.remove(SCORE_PREFERENCE_KEY_PREFIX + i);
i++;
}
}
}
HighScoreApp.java
Test harness:
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.util.Random;
import java.util.prefs.BackingStoreException;
public class HighScoreApp extends Application {
private static ScoreStorage scoreStorage;
private Random random = new Random(42);
@Override
public void start(Stage stage) throws Exception {
ListView<Integer> scoreList = new ListView<>(scoreStorage.getUnmodifiableScores());
scoreList.setPrefHeight(150);
Label lastScoreLabel = new Label();
Button generateScore = new Button("Generate new score");
generateScore.setOnAction(event -> {
int lastScore = random.nextInt(11_000);
lastScoreLabel.setText("" + lastScore);
scoreStorage.recordScore(lastScore);
});
Button clearScores = new Button("Clear scores");
clearScores.setOnAction(event -> scoreStorage.clearScores());
HBox scoreGenerator = new HBox(10, generateScore, lastScoreLabel);
scoreGenerator.setAlignment(Pos.BASELINE_LEFT);
VBox layout = new VBox(10, scoreGenerator, scoreList, clearScores);
layout.setPadding(new Insets(10));
stage.setScene(new Scene(layout));
stage.show();
}
public static void main(String[] args) throws BackingStoreException {
scoreStorage = new ScoreStorage();
launch(args);
}
}