Merge branch 'feature/Persitsting_language_options' into 'main'

Add persistent language selection with ConfigService integration

Closes #25

See merge request cse1105/2025-2026/teams/csep-team-76!57
This commit is contained in:
Rithvik Sriram 2026-01-16 12:33:00 +01:00
commit 920eca13d3
4 changed files with 87 additions and 4 deletions

View file

@ -19,6 +19,7 @@ import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import client.utils.LocaleManager;
import com.google.inject.Injector; import com.google.inject.Injector;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
@ -38,7 +39,8 @@ public class MyFXML {
public <T> Pair<T, Parent> load(Class<T> c, String... parts) { public <T> Pair<T, Parent> load(Class<T> c, String... parts) {
try { try {
var loader = new FXMLLoader(getLocation(parts), null, null, new MyFactory(), StandardCharsets.UTF_8); var localeManager = injector.getInstance(LocaleManager.class);
var loader = new FXMLLoader(getLocation(parts), localeManager.getBundle(), null, new MyFactory(), StandardCharsets.UTF_8);
Parent parent = loader.load(); Parent parent = loader.load();
T ctrl = loader.getController(); T ctrl = loader.getController();
return new Pair<>(ctrl, parent); return new Pair<>(ctrl, parent);

View file

@ -46,6 +46,7 @@ public class LangSelectMenuCtrl implements LocaleAware {
@Override @Override
public void initializeComponents() { public void initializeComponents() {
langSelectMenu.getItems().setAll("en", "pl", "nl"); langSelectMenu.getItems().setAll("en", "pl", "nl");
langSelectMenu.setValue(manager.getLocale().getLanguage());
langSelectMenu.setConverter(new StringConverter<String>() { langSelectMenu.setConverter(new StringConverter<String>() {
@Override @Override
public String toString(String s) { public String toString(String s) {

View file

@ -1,5 +1,6 @@
package client.utils; package client.utils;
import com.google.inject.Inject;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import java.util.Locale; import java.util.Locale;
@ -10,11 +11,27 @@ public class LocaleManager {
private final ObjectProperty<ResourceBundle> currentBundle = new SimpleObjectProperty<>(); private final ObjectProperty<ResourceBundle> currentBundle = new SimpleObjectProperty<>();
private static final String RESOURCE_BUNDLE_PATH = "locale/lang"; private static final String RESOURCE_BUNDLE_PATH = "locale/lang";
private final ConfigService configService;
@Inject
public LocaleManager(ConfigService configService) {
this.configService = configService;
String savedLanguage = configService.getConfig().getLanguage();
Locale initialLocale = Locale.forLanguageTag(savedLanguage);
currentLocale.set(initialLocale);
public LocaleManager() {
// TODO: Set currentLocale to config value instead of EN default.
updateBundle(); updateBundle();
currentLocale.addListener((_, _, _) -> updateBundle());
currentLocale.addListener((_, oldLocale, newLocale) -> {
updateBundle();
saveLanguagePreference(newLocale.getLanguage());
});
}
private void saveLanguagePreference(String languageCode) {
configService.getConfig().setLanguage(languageCode);
configService.save();
} }
private void updateBundle() { private void updateBundle() {
@ -44,4 +61,6 @@ public class LocaleManager {
public ObjectProperty<ResourceBundle> getBundleProperty() { public ObjectProperty<ResourceBundle> getBundleProperty() {
return currentBundle; return currentBundle;
} }
} }

View file

@ -0,0 +1,61 @@
package client.scenes;
import client.utils.ConfigService;
import client.utils.LocaleManager;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.nio.file.Path;
import java.util.Locale;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
public class LocaleManagerTest {
@TempDir
Path tempDir;
private ConfigService configService;
private LocaleManager localeManager;
@BeforeEach
void setUp() {
Path configPath = tempDir.resolve("test-config.json");
configService = new ConfigService(configPath);
localeManager = new LocaleManager(configService);
}
@Test
void testSetLocaleChangesCurrentLocale() {
localeManager.setLocale(Locale.forLanguageTag("nl"));
assertEquals("nl", localeManager.getLocale().getLanguage());
}
@Test
void testSetLocaleSavesToConfig() {
localeManager.setLocale(Locale.forLanguageTag("pl"));
assertEquals("pl", configService.getConfig().getLanguage());
}
@Test
void testLocalePersistsAcrossInstances() {
localeManager.setLocale(Locale.forLanguageTag("en"));
LocaleManager newLocaleManager = new LocaleManager(configService);
assertEquals("en", newLocaleManager.getLocale().getLanguage());
}
@Test
void testBundleIsNotNull() {
assertNotNull(localeManager.getBundle());
}
@Test
void testBundlePropertyIsNotNull() {
assertNotNull(localeManager.getBundleProperty());
assertNotNull(localeManager.getBundleProperty().get());
}
}