Skip to content
This repository has been archived by the owner on Jan 6, 2025. It is now read-only.

Commit

Permalink
Merge pull request #2 from wkktoria/multilingual-support
Browse files Browse the repository at this point in the history
Add multilingual support
  • Loading branch information
wkktoria authored Jul 11, 2024
2 parents 58e460f + 96e026a commit b39c013
Show file tree
Hide file tree
Showing 16 changed files with 400 additions and 71 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ An application that provides up-to-date weather information based on the user's
the [OpenWeatherMap API](https://openweathermap.org/current) to fetch real-time weather data. Application also allows
user to generate weather reports which are saved as [PDFs](demo-report.pdf).

Pogodynka is multilingual, for now it supports only English and Polish.

## Building

Pogodynka uses Maven to handle dependencies and building.
Expand All @@ -15,7 +17,7 @@ Pogodynka uses Maven to handle dependencies and building.
- [Java Development Kit 21](https://www.oracle.com/java/technologies/downloads/#jdk21) or higher
- [OpenWeather's](https://openweathermap.org) API key

#### Compile
### Compile

Windows (PowerShell):

Expand All @@ -37,5 +39,5 @@ export WEATHER_API_KEY=YOUR_API_KEY
> Running application may require to set up the API key.
```shell
java -jar pogodynka-1.0.0-jar-with-dependencies.jar
java -jar pogodynka-1.0.1-jar-with-dependencies.jar
```
Binary file modified demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>io.github.wkktoria</groupId>
<name>Pogodynka</name>
<artifactId>pogodynka</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<description>Desktop weather application</description>
<packaging>jar</packaging>

Expand Down
146 changes: 113 additions & 33 deletions src/main/java/io/github/wkktoria/pogodynka/Pogodynka.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package io.github.wkktoria.pogodynka;

import com.formdev.flatlaf.FlatDarkLaf;
import io.github.wkktoria.pogodynka.config.LocaleConfig;
import io.github.wkktoria.pogodynka.controller.LocationPreferencesController;
import io.github.wkktoria.pogodynka.controller.ReportController;
import io.github.wkktoria.pogodynka.controller.ResourceController;
import io.github.wkktoria.pogodynka.controller.WeatherController;
import io.github.wkktoria.pogodynka.exception.ApiProblemException;
import io.github.wkktoria.pogodynka.exception.MissingApiKeyException;
import io.github.wkktoria.pogodynka.model.Weather;
import io.github.wkktoria.pogodynka.service.LocationPreferencesService;
import io.github.wkktoria.pogodynka.service.ReportService;
import io.github.wkktoria.pogodynka.service.ResourceService;
import io.github.wkktoria.pogodynka.service.WeatherService;
import org.apache.commons.text.WordUtils;
import org.slf4j.Logger;
Expand All @@ -22,22 +25,38 @@
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;

class Pogodynka {
private static final Logger LOGGER = LoggerFactory.getLogger(Pogodynka.class);
private static final WeatherController weatherController;
private static final ReportController reportController;
private static final LocationPreferencesController locationPreferencesController;
private static final Weather defaultWeather;
private static final LocaleConfig localeConfig;
private static final ResourceController resourceController;

private static Weather weather;

private static JButton configureDefaultLocationButton;
private static JButton changeLanguageButton;
private static JButton searchButton;
private static JButton generateReportButton;

private static JLabel temperatureLabel;
private static JLabel humidityLabel;
private static JLabel windSpeedLabel;
private static JLabel pressureLabel;

static {
try {
localeConfig = new LocaleConfig();
resourceController = new ResourceController(new ResourceService(localeConfig));
weatherController = new WeatherController(new WeatherService());
reportController = new ReportController(new ReportService(weatherController));
reportController = new ReportController(new ReportService(weatherController, resourceController));
locationPreferencesController = new LocationPreferencesController(new LocationPreferencesService(weatherController));
defaultWeather = weatherController.getWeather(locationPreferencesController.getLocation());
weather = weatherController.getWeather(locationPreferencesController.getLocation());

if (defaultWeather == null) {
if (weather == null) {
throw new ApiProblemException("Couldn't get weather information");
}
} catch (MissingApiKeyException | ApiProblemException e) {
Expand All @@ -63,10 +82,34 @@ public static void main(String[] args) {
toolBar.setFloatable(false);
toolBar.setRollover(true);

JButton configDefaultLocationButton = new JButton("Configure default location");
configDefaultLocationButton.addActionListener(e -> configureDefaultLocation());
configureDefaultLocationButton = new JButton("Configure default location");
configureDefaultLocationButton.addActionListener(e -> configureDefaultLocation());

changeLanguageButton = new JButton("Change language");
changeLanguageButton.addActionListener(e -> {
Object[] languages = resourceController.getByKey("availableLanguages").split(",");

int languageIndex = JOptionPane.showOptionDialog(null,
resourceController.getByKey("selectLanguage") + ": ",
resourceController.getByKey("changeLanguage"),
JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, languages, languages[0]);

switch (languageIndex) {
case 0:
localeConfig.setLocale(Locale.ENGLISH);
break;
case 1:
localeConfig.setLocale(Locale.of("pl", "PL"));
break;
default:
return;
}

update();
});

toolBar.add(configDefaultLocationButton);
toolBar.add(configureDefaultLocationButton);
toolBar.add(changeLanguageButton);

JPanel locationPanel = new JPanel();

Expand All @@ -81,13 +124,13 @@ public static void main(String[] args) {
infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.Y_AXIS));
infoPanel.setAlignmentX(Component.CENTER_ALIGNMENT);

JLabel temperatureLabel = new JLabel("Temperature: " + defaultWeather.getTemperature() + "°C");
temperatureLabel = new JLabel("Temperature");
temperatureLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
JLabel humidityLabel = new JLabel("Humidity: " + defaultWeather.getHumidity() + "%");
humidityLabel = new JLabel("Humidity");
humidityLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
JLabel windSpeedLabel = new JLabel("Wind speed: " + defaultWeather.getWindSpeed() + " m/s");
windSpeedLabel = new JLabel("Wind speed");
windSpeedLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
JLabel pressureLabel = new JLabel("Pressure: " + defaultWeather.getPressure() + " hPa");
pressureLabel = new JLabel("Pressure");
pressureLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

infoPanel.add(locationPanel);
Expand All @@ -112,8 +155,8 @@ public void keyTyped(final KeyEvent e) {
@Override
public void keyPressed(final KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
searchWeather(locationField, imageLabel, locationLabel, temperatureLabel, humidityLabel,
windSpeedLabel, pressureLabel);
searchWeather(locationField, locationLabel
);
}
}

Expand All @@ -122,14 +165,14 @@ public void keyReleased(final KeyEvent e) {

}
});
JButton searchButton = new JButton("Search");
searchButton.addActionListener(e -> searchWeather(locationField, imageLabel, locationLabel, temperatureLabel,
humidityLabel, windSpeedLabel, pressureLabel));
searchButton = new JButton("Search");
searchButton.addActionListener(e -> searchWeather(locationField, locationLabel
));

inputPanel.add(locationField);
inputPanel.add(searchButton);

JButton generateReportButton = new JButton("Generate Report");
generateReportButton = new JButton("Generate report");
generateReportButton.setAlignmentX(Component.CENTER_ALIGNMENT);
generateReportButton.addActionListener(e -> generateReport(locationLabel));

Expand All @@ -140,9 +183,23 @@ public void keyReleased(final KeyEvent e) {

frame.add(panel);

update();

frame.setVisible(true);
}

private static void update() {
configureDefaultLocationButton.setText(resourceController.getByKey("configureDefaultLocation"));
changeLanguageButton.setText(resourceController.getByKey("changeLanguage"));
searchButton.setText(resourceController.getByKey("search"));
generateReportButton.setText(resourceController.getByKey("generateReport"));

temperatureLabel.setText(resourceController.getByKey("temperature") + ": " + weather.getTemperature() + "°C");
humidityLabel.setText(resourceController.getByKey("humidity") + ": " + weather.getHumidity() + "%");
windSpeedLabel.setText(resourceController.getByKey("windSpeed") + ": " + weather.getWindSpeed() + " m/s");
pressureLabel.setText(resourceController.getByKey("pressure") + ": " + weather.getPressure() + " hPa");
}

private static void setImageLabel(JLabel imageLabel, final String location) {
try {
Image image = ImageIO.read(new URI(weatherController.getWeather(location).getImageSource()).toURL());
Expand All @@ -152,55 +209,78 @@ private static void setImageLabel(JLabel imageLabel, final String location) {
}
}

private static void searchWeather(JTextField locationField, JLabel imageLabel, JLabel locationLabel,
JLabel temperatureLabel, JLabel humidityLabel, JLabel windSpeedLabel, JLabel pressureLabel) {
private static void searchWeather(JTextField locationField, JLabel locationLabel) {
String location = locationField.getText();

if (location.isEmpty()) {
return;
}

Weather weather = weatherController.getWeather(location);
weather = weatherController.getWeather(location);

if (weather == null) {
JOptionPane.showMessageDialog(null, "Couldn't find weather for '" + location + "'.", "Invalid location", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(null,
resourceController.getByKey("couldNotFindWeatherInformationFor") + " " + location + ".",
resourceController.getByKey("invalidLocation"),
JOptionPane.ERROR_MESSAGE);
return;
}

locationLabel.setText(weather.getLocation());
temperatureLabel.setText("Temperature: " + weather.getTemperature() + "°C");
humidityLabel.setText("Humidity: " + weather.getHumidity() + "%");
setImageLabel(imageLabel, weather.getLocation());
windSpeedLabel.setText("Wind speed: " + weather.getWindSpeed() + " m/s");
pressureLabel.setText("Pressure: " + weather.getPressure() + " hPa");
locationField.setText("");

update();
}

private static void generateReport(final JLabel locationLabel) {
String filename = JOptionPane.showInputDialog(null,
resourceController.getByKey("reportFilename") + ": ",
resourceController.getByKey("chooseReportFilename"),
JOptionPane.QUESTION_MESSAGE);

if (filename == null || filename.isEmpty()) {
return;
}

String location = locationLabel.getText();

if (location.isEmpty()) {
if (location == null || location.isEmpty()) {
return;
}

if (reportController.generate(location)) {
JOptionPane.showMessageDialog(null, "Report was successfully generated.", "Report generated", JOptionPane.INFORMATION_MESSAGE);
if (reportController.generate(filename, location)) {
JOptionPane.showMessageDialog(null,
resourceController.getByKey("reportWasSuccessfullyGenerated") + ".",
resourceController.getByKey("reportGenerated"),
JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(null, "Couldn't generate report.", "Generation failed", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(null,
resourceController.getByKey("couldNotGenerateReport") + ".",
resourceController.getByKey("reportGenerationFailed"),
JOptionPane.ERROR_MESSAGE);
}
}

private static void configureDefaultLocation() {
String location = JOptionPane.showInputDialog(null, "Default location:", "Configure default location", JOptionPane.QUESTION_MESSAGE);
String location = JOptionPane.showInputDialog(null,
resourceController.getByKey("defaultLocation") + ": ",
resourceController.getByKey("configureDefaultLocation"),
JOptionPane.QUESTION_MESSAGE);

if (location != null) {
WordUtils.capitalizeFully(location);
}

if (location != null && locationPreferencesController.setLocation(location)) {
JOptionPane.showMessageDialog(null, "Default location set successfully to " + location + ".", "Default location configured", JOptionPane.INFORMATION_MESSAGE);
JOptionPane.showMessageDialog(null,
resourceController.getByKey("defaultLocationSetSuccessfullyTo") + " " + location + ".",
resourceController.getByKey("defaultLocationSetUp"),
JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(null, "Couldn't set default location to " + location + ".", "Invalid location", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(null,
resourceController.getByKey("couldNotSetDefaultLocationTo") + " " + location + ".",
resourceController.getByKey("invalidLocation"),
JOptionPane.ERROR_MESSAGE);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.github.wkktoria.pogodynka.config;

import java.util.Locale;
import java.util.ResourceBundle;

public class LocaleConfig {
private Locale locale;
private ResourceBundle resourceBundle;

public LocaleConfig() {
this.locale = Locale.getDefault();
resourceBundle = ResourceBundle.getBundle("pogodynka.resource", locale);
}

public void setLocale(final Locale locale) {
this.locale = locale;
resourceBundle = ResourceBundle.getBundle("pogodynka.resource", locale);
}

public ResourceBundle getResourceBundle() {
return resourceBundle;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public ReportController(final ReportService reportService) {
this.reportService = reportService;
}

public boolean generate(final String location) {
public boolean generate(final String filename, final String location) {
try {
reportService.generate(location);
reportService.generate(filename, location);
return true;
} catch (ReportGenerationProblemException | InvalidLocationException e) {
LOGGER.error("Cannot generate report");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.github.wkktoria.pogodynka.controller;

import io.github.wkktoria.pogodynka.service.ResourceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.MissingResourceException;

public class ResourceController {
private final static Logger LOGGER = LoggerFactory.getLogger(ResourceController.class);
private final ResourceService resourceService;

public ResourceController(final ResourceService resourceService) {
this.resourceService = resourceService;
}

public String getByKey(final String key) {
try {
return resourceService.getByKey(key);
} catch (MissingResourceException e) {
LOGGER.error("Cannot get resource: {}", key);
return null;
}
}
}
Loading

0 comments on commit b39c013

Please sign in to comment.