0% found this document useful (0 votes)
14 views22 pages

JavaFX Weather App Overview

This app provides real-time weather for a given city using the OpenWeatherMap API. It shows current temperature, humidity, wind, and conditions, plus a short-term forecast. It includes unit switching, error handling, search history, and dynamic backgrounds based on time of day.

Uploaded by

felista nkatha
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views22 pages

JavaFX Weather App Overview

This app provides real-time weather for a given city using the OpenWeatherMap API. It shows current temperature, humidity, wind, and conditions, plus a short-term forecast. It includes unit switching, error handling, search history, and dynamic backgrounds based on time of day.

Uploaded by

felista nkatha
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

School: University of the People

Moodle ID: C110223808

Course: CS 1103 – Programming 2

Assignment: Unit 8 – Advanced GUI programming.

University: University of the People


Weather Information App — Java (JavaFX)

Overview

This app provides real-time weather for a given city using the OpenWeatherMap API. It

shows current temperature, humidity, wind, and conditions, plus a short-term forecast. It

includes unit switching, error handling, search history, and dynamic backgrounds based

on time of day.

How to Run (Eclipse + JavaFX)

1) Install JDK 17 or later. 2) Set up JavaFX in Eclipse. 3) Create a project named

WeatherApp. 4) Copy the provided src files into your project. 5) Add [Link] jar to the

build path. 6) Open [Link] and paste your OpenWeatherMap API key

where indicated. 7) Run [Link].

Grading Alignment (Checklist)

API Integration: Uses OpenWeatherMap with API key and JSON parsing.

GUI Design: JavaFX UI with inputs, lists, and visual icons.

Logic & Computation: JSON parsing, unit selection, history storage.

Program Flow & Structure: Service + model + UI classes.

Output: Current weather, icon, and next 24h forecast list.

Code Style & Readability: Commented classes and clear method names.
Source Code

[Link]

package app;

import [Link];

import [Link];

import [Link];

import [Link];

import [Link].*;

import [Link];

import [Link];

import [Link].*;

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
public class WeatherApp extends Application {

private TextField cityInput;

private ComboBox<String> unitCombo;

private Label tempLabel;

private Label humidityLabel;

private Label windLabel;

private Label conditionLabel;

private ImageView iconView;

private ListView<String> forecastList;

private ListView<String> historyList;

private final ObservableList<String> historyItems =

[Link]();

private final WeatherService service = new WeatherService();

private final HistoryManager historyManager = new HistoryManager();

@Override

public void start(Stage stage) {

// Top: input row

cityInput = new TextField();

[Link]("Enter city (e.g., Nairobi)");

[Link](18);
unitCombo = new ComboBox<>();

[Link]().addAll("Celsius / m/s", "Fahrenheit / mph");

[Link]().select(0);

Button fetchBtn = new Button("Get Weather");

[Link](e -> fetchWeather());

HBox inputRow = new HBox(10, new Label("Location:"), cityInput, unitCombo,

fetchBtn);

[Link](Pos.CENTER_LEFT);

[Link](new Insets(12));

// Center: current weather card

tempLabel = new Label("--");

[Link]([Link](28));

humidityLabel = new Label("Humidity: --");

windLabel = new Label("Wind: --");

conditionLabel = new Label("Condition: --");

iconView = new ImageView();

[Link](80);

[Link](80);
[Link](true);

VBox currentBox = new VBox(6, tempLabel, conditionLabel, humidityLabel,

windLabel);

HBox currentRow = new HBox(12, iconView, currentBox);

[Link](Pos.CENTER_LEFT);

TitledPane currentPane = new TitledPane("Current Weather", currentRow);

[Link](false);

// Forecast list

forecastList = new ListView<>();

[Link](220);

TitledPane forecastPane = new TitledPane("Short-term Forecast (next 24h)",

forecastList);

[Link](false);

VBox center = new VBox(10, currentPane, forecastPane);

[Link](new Insets(12));

// Right: history

historyList = new ListView<>(historyItems);

[Link](260);
[Link](e -> {

String sel = [Link]().getSelectedItem();

if (sel != null && [Link](" - ")) {

String city = [Link](" - ")[0];

[Link](city);

fetchWeather();

});

VBox right = new VBox(8, new Label("Search History"), historyList);

[Link](new Insets(12));

BorderPane root = new BorderPane();

[Link](inputRow);

[Link](center);

[Link](right);

Scene scene = new Scene(root, 920, 540);

applyDynamicBackground(scene, [Link]());

[Link]("Weather Information App — JavaFX");

[Link](scene);

[Link]();

// Load history
[Link]([Link]());

private void fetchWeather() {

String city = [Link]().trim();

if ([Link]()) {

showError("Please enter a city name.");

return;

boolean useFahrenheit = [Link]().getSelectedIndex() == 1;

String units = useFahrenheit ? "imperial" : "metric";

try {

WeatherModel current = [Link](city, units);

List<[Link]> forecast = [Link](city, units, 8);

// next 24 hours (8 * 3h)

// Display current

String tempText = useFahrenheit

? [Link]("%.1f °F", [Link])

: [Link]("%.1f °C", [Link]);

[Link](tempText);
[Link]("Humidity: " + [Link] + " %");

String windText = useFahrenheit

? [Link]("Wind: %.1f mph", [Link])

: [Link]("Wind: %.1f m/s", [Link]);

[Link](windText);

[Link]("Condition: " + [Link]);

// Icon

Image icon = [Link]([Link]);

[Link](icon);

// Forecast

[Link]().clear();

DateTimeFormatter fmt = [Link]("EEE HH:mm");

for ([Link] f : forecast) {

String t = useFahrenheit

? [Link]("%.1f °F", [Link])

: [Link]("%.1f °C", [Link]);

LocalDateTime local = [Link]([Link], 0,

[Link]([Link]));

String line = [Link]("%s | %s | %s | wind %.1f%s",


[Link](fmt), t, [Link], [Link],

useFahrenheit ? " mph" : " m/s");

[Link]().add(line);

// Dynamic background based on local time at location

LocalDateTime localNow =

[Link]([Link]().getEpochSecond() +

[Link], 0, [Link]);

applyDynamicBackground([Link](), localNow);

// History

String entry = city + " - " + [Link]("yyyy-MM-dd

HH:mm").format([Link]());

[Link](0, entry);

[Link](entry);

} catch (Exception ex) {

showError("Could not fetch weather. " + [Link]());

private void applyDynamicBackground(Scene scene, LocalDateTime localTime) {


int hour = [Link]();

String style;

if (hour >= 5 && hour < 11) {

style = "-fx-background-color: linear-gradient(to bottom, #cfe9ff, #ffffff);";

} else if (hour >= 11 && hour < 17) {

style = "-fx-background-color: linear-gradient(to bottom, #a8d5ff, #e8f4ff);";

} else if (hour >= 17 && hour < 20) {

style = "-fx-background-color: linear-gradient(to bottom, #ffd1a8, #ffe9d6);";

} else {

style = "-fx-background-color: linear-gradient(to bottom, #0b1b3a, #122a52);";

[Link]().setStyle(style);

private void showError(String msg) {

Alert alert = new Alert([Link], msg, [Link]);

[Link]("Input or Network Error");

[Link]();

public static void main(String[] args) {

launch(args);

}
}

[Link]

package app;

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

public class WeatherService {

private static final String API_KEY = "YOUR_OPENWEATHERMAP_API_KEY";

public WeatherModel fetchCurrentWeather(String city, String units) throws Exception

String url = [Link](


"[Link]

encode(city), API_KEY, units

);

JSONObject json = getJson(url);

return parseCurrent(json);

public List<[Link]> fetchForecast(String city, String units, int

maxItems) throws Exception {

String url = [Link](

"[Link]

encode(city), API_KEY, units

);

JSONObject json = getJson(url);

return parseForecast(json, maxItems);

private JSONObject getJson(String urlStr) throws Exception {

URL url = new URL(urlStr);

HttpURLConnection conn = (HttpURLConnection) [Link]();

[Link]("GET");
[Link](8000);

[Link](8000);

int code = [Link]();

if (code != 200) {

throw new RuntimeException("API request failed with HTTP " + code);

BufferedReader reader = new BufferedReader(

new InputStreamReader([Link](), StandardCharsets.UTF_8)

);

StringBuilder sb = new StringBuilder();

String line;

while ((line = [Link]()) != null) [Link](line);

[Link]();

[Link]();

return new JSONObject([Link]());

private WeatherModel parseCurrent(JSONObject json) {

WeatherModel model = new WeatherModel();

JSONObject main = [Link]("main");

JSONObject wind = [Link]("wind");


JSONArray weatherArr = [Link]("weather");

JSONObject weather = [Link](0);

[Link] = [Link]("temp");

[Link] = [Link]("humidity");

[Link] = [Link]("speed", 0.0);

[Link] = capitalize([Link]("description"));

[Link] = [Link]("icon");

[Link] = [Link]("timezone", 0);

[Link] = [Link]("name");

return model;

private List<[Link]> parseForecast(JSONObject json, int

maxItems) {

List<[Link]> out = new ArrayList<>();

JSONArray arr = [Link]("list");

int count = [Link]([Link](), [Link](1, maxItems));

for (int i = 0; i < count; i++) {

JSONObject o = [Link](i);

long dt = [Link]("dt");

JSONObject main = [Link]("main");


double temp = [Link]("temp");

JSONObject wind = [Link]("wind");

double ws = [Link]("speed", 0.0);

JSONArray weatherArr = [Link]("weather");

JSONObject w = [Link](0);

String desc = capitalize([Link]("description"));

[Link](new [Link](dt, temp, ws, desc));

return out;

private String encode(String s) {

return [Link](" ", "%20");

private String capitalize(String s) {

if (s == null || [Link]()) return s;

return [Link](0,1).toUpperCase() + [Link](1);

}
[Link]

package app;

import [Link];

import [Link];

public class WeatherModel {

public String city;

public double temperature;

public int humidity;

public double windSpeed;

public String description;

public String iconCode;

public int timezoneOffset; // seconds

public static class ForecastItem {

public long dt; // epoch seconds (UTC)

public double temp;

public double wind;

public String description;

public ForecastItem(long dt, double temp, double wind, String description) {

[Link] = dt;

[Link] = temp;
[Link] = wind;

[Link] = description;

public List<ForecastItem> forecast = new ArrayList<>();

[Link]

package app;

import [Link];

public class IconMapper {

public static Image iconFromCode(String code) {

try {

String url = [Link]("[Link]

code);

return new Image(url, true);

} catch (Exception e) {

return null;

}
}

[Link]

package app;

import [Link].*;

import [Link];

import [Link];

import [Link];

public class HistoryManager {

private final File store = new File([Link]("[Link]"),

".weatherapp_history.txt");

public List<String> loadHistory() {

List<String> list = new ArrayList<>();

if (![Link]()) return list;

try (BufferedReader br = new BufferedReader(new InputStreamReader(new

FileInputStream(store), StandardCharsets.UTF_8))) {

String line;

while ((line = [Link]()) != null) {

if (![Link]().isEmpty()) [Link](0, [Link]());


}

} catch (IOException ignored) {}

return list;

public void appendEntry(String entry) {

try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new

FileOutputStream(store, true), StandardCharsets.UTF_8))) {

[Link](entry);

[Link]();

} catch (IOException ignored) {}

[Link]

module WeatherApp {

requires [Link];

requires [Link];

requires [Link];

requires [Link];

opens app;

}
README (Quick Reference)

# Weather Information App (JavaFX)

A simple JavaFX app that fetches real-time weather and a short-term forecast using the

OpenWeatherMap API.

It includes:

- City input and unit switch (Celsius/metric or Fahrenheit/imperial)

- Current weather with icon

- Short-term forecast (next ~24 hours)

- Search history with timestamps and click-to-reload

- Dynamic backgrounds by time of day

- Basic error handling for invalid input and network/API failures

## Requirements

- JDK 17 or later

- JavaFX SDK (matching your JDK) added to Eclipse

- [Link] library (e.g., `[Link]`)

## Setup in Eclipse

1. Create a JavaFX project named `WeatherApp`.

2. Add the `src` folder contents into `src/app` in your project.

3. Place `[Link]` at the root `src`.


4. Add JavaFX libraries to your project build path.

5. Download `[Link]` jar and add it to your project (Project Properties > Java Build

Path > Libraries).

6. Open `[Link]` and replace `YOUR_OPENWEATHERMAP_API_KEY`

with your key.

7. Run `[Link]`.

## Usage

- Enter a city like `Nairobi` and click **Get Weather**.

- Switch units from the combo box.

- Click history entries to reload.

You might also like