How to build weather app in java

Learn how to how to build weather app in java with GUI using swing. This article guides you through designing a user-friendly interface, retrieving live weather data from the OpenWeatherMap API. Discover step-by-step instructions and code examples to build your own advanced weather app with modern features and user-friendly design gradient background in java.

Implementing the Gradient Background in java

A static background image can make an application feel rigid and outdated. Instead, we chose to use a gradient background, which is not only modern but also allows for a more dynamic visual experience.

  • Why Gradient? Gradients create a sense of depth and movement. The transition from light blue to dark blue mimics the sky, making the interface feel more alive and engaging.
  • How It’s Done: We achieved the gradient effect by overriding the paintComponent method in a JPanel. By using Graphics2D and GradientPaint, we created a smooth color transition from top to bottom. This approach is more flexible than a static image and adapts well to different screen sizes.

Input Panel

  • JLabel: Prompts the user to enter a city name. This label uses a bold font and white color to stand out against the gradient background.
  • JTextField: Where users type the city name. It is styled with a clean border and a font that matches the label for consistency.
  • JButton: Initiates the weather data retrieval process. It’s styled with a background color that contrasts with the gradient and has white text to ensure readability.
  • Functionality: When the button is clicked, it triggers the ActionListener, which retrieves and processes the weather data.

Output panel

Once the weather data is fetched, it needs to be displayed in a user-friendly manner.

  • Temperature and Description: These are the two most critical pieces of information for the user. We display them prominently in the center of the application, using large, bold fonts for clarity.
  • Dynamic Weather Icons: The application retrieves the appropriate weather icon from the OpenWeatherMap API based on the current weather conditions. These icons are displayed alongside the temperature and description, providing a quick visual cue about the weather.
how to build weather app in java

API request in java

  • Base URL: https://api.openweathermap.org/data/2.5/weather is the endpoint used to get weather data.
  • API Key: A unique key (in this case, d7ec9ff81a91c3c42fdc3e9e38c02af4) is used to authenticate requests to OpenWeatherMap.
  • Parameters:
  • City: The city name entered by the user.
  • Units: The measurement system (metric for Celsius).
  • HttpClient: Used to send the HTTP request and receive the response. Java’s HttpClient API handles communication with the server and simplifies asynchronous operations.

Weather app project in java with source code is available on my GitHub repository.

The source code is also available for download as a ZIP file

Parsing and Displaying Weather Data

Parsing Data

  • Objective: Extract relevant information from the JSON response.
  • Technique: Uses substring operations to locate and extract the temperature, description, and icon code from the raw JSON string. While this is a simple approach, it assumes the response format is consistent and may not handle all edge cases.

Displaying Data

  • Temperature and Description: Updated in the respective JLabel components to reflect the fetched weather data.
  • Weather Icon: The ImageIcon is created using a URL that points to the weather icon image. The image is scaled to fit the label while maintaining quality.

Error Handling

  • Network Issues: If the request fails or the network is unavailable, the user is notified with an error message.
  • Empty Input: If the user does not enter a city name and clicks the button, a prompt informs them to enter a city.

Running the Application

  • Purpose: Initializes and displays the application.
  • SwingUtilities.invokeLater: Ensures that the GUI updates are performed on the Event Dispatch Thread (EDT), which is crucial for thread safety in Swing applications.

Summary of how to build weather app in java

The Advanced Weather App combines several Java technologies to build a weather app in java that is both functional and aesthetically pleasing. It demonstrates how to integrate a web API into a Java Swing application, manage user input, and handle real-time data retrieval and display. By understanding each component’s role and how they interact, you can create robust and interactive desktop applications in Java.

Source code of weather app in java using GUI

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

 class AdvancedWeatherApp extends JFrame {

    private static final String API_KEY = "d7ec9ff81a91c3c42fdc3e9e38c02af4";  // Replace with your OpenWeatherMap API Key
    private static final String BASE_URL = "https://api.openweathermap.org/data/2.5/weather";

    private JTextField cityField;
    private JLabel temperatureLabel;
    private JLabel descriptionLabel;
    private JLabel weatherIconLabel;
    private JPanel contentPanel;

    public AdvancedWeatherApp() {
        setTitle("Weather App");
        setSize(500, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        // Content Panel with gradient background
        contentPanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                Color color1 = new Color(135, 206, 250);
                Color color2 = new Color(25, 25, 112);
                GradientPaint gp = new GradientPaint(0, 0, color1, 0, getHeight(), color2);
                g2d.setPaint(gp);
                g2d.fillRect(0, 0, getWidth(), getHeight());
            }
        };
        contentPanel.setLayout(new BorderLayout());
        setContentPane(contentPanel);

        // Input Panel
        JPanel inputPanel = new JPanel();
        inputPanel.setOpaque(false);
        inputPanel.setLayout(new FlowLayout());

        JLabel cityLabel = new JLabel("Enter City: ");
        cityLabel.setFont(new Font("Segoe UI", Font.BOLD, 16));
        cityLabel.setForeground(Color.WHITE);

        cityField = new JTextField(15);
        cityField.setFont(new Font("Segoe UI", Font.PLAIN, 16));
        cityField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        cityField.setPreferredSize(new Dimension(200, 30));

        JButton getWeatherButton = new JButton("Get Weather");
        getWeatherButton.setFont(new Font("Segoe UI", Font.BOLD, 16));
        getWeatherButton.setForeground(Color.WHITE);
        getWeatherButton.setBackground(new Color(30, 144, 255));
        getWeatherButton.setFocusPainted(false);
        getWeatherButton.setPreferredSize(new Dimension(150, 30));
        getWeatherButton.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        getWeatherButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String city = cityField.getText().trim();
                if (!city.isEmpty()) {
                    try {
                        String weatherData = getWeatherData(city, "metric");
                        displaySimplifiedWeatherData(weatherData);
                    } catch (IOException | InterruptedException ex) {
                        JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
                    }
                } else {
                    JOptionPane.showMessageDialog(null, "Please enter a city name.");
                }
            }
        });

        inputPanel.add(cityLabel);
        inputPanel.add(cityField);
        inputPanel.add(getWeatherButton);

        // Output Panel
        JPanel outputPanel = new JPanel();
        outputPanel.setOpaque(false);
        outputPanel.setLayout(new BoxLayout(outputPanel, BoxLayout.Y_AXIS));
        outputPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

        temperatureLabel = new JLabel("Temperature: ", SwingConstants.CENTER);
        temperatureLabel.setFont(new Font("Segoe UI", Font.BOLD, 24));
        temperatureLabel.setForeground(Color.WHITE);
        temperatureLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        descriptionLabel = new JLabel("Description: ", SwingConstants.CENTER);
        descriptionLabel.setFont(new Font("Segoe UI", Font.BOLD, 24));
        descriptionLabel.setForeground(Color.WHITE);
        descriptionLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        weatherIconLabel = new JLabel("", SwingConstants.CENTER);
        weatherIconLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        outputPanel.add(Box.createRigidArea(new Dimension(0, 20)));
        outputPanel.add(weatherIconLabel);
        outputPanel.add(Box.createRigidArea(new Dimension(0, 20)));
        outputPanel.add(temperatureLabel);
        outputPanel.add(Box.createRigidArea(new Dimension(0, 20)));
        outputPanel.add(descriptionLabel);

        // Add panels to contentPanel
        contentPanel.add(inputPanel, BorderLayout.NORTH);
        contentPanel.add(outputPanel, BorderLayout.CENTER);
    }

    private String getWeatherData(String city, String units) throws IOException, InterruptedException {
        String url = BASE_URL + "?q=" + city + "&units=" + units + "&appid=" + API_KEY;
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    private void displaySimplifiedWeatherData(String weatherData) {
        String tempKeyword = "\"temp\":";
        String descriptionKeyword = "\"description\":\"";
        String iconKeyword = "\"icon\":\"";

        int tempIndex = weatherData.indexOf(tempKeyword);
        int descriptionIndex = weatherData.indexOf(descriptionKeyword);
        int iconIndex = weatherData.indexOf(iconKeyword);

        if (tempIndex != -1 && descriptionIndex != -1 && iconIndex != -1) {
            String temp = weatherData.substring(tempIndex + tempKeyword.length(), weatherData.indexOf(",", tempIndex)) + "°C";
            String description = weatherData.substring(descriptionIndex + descriptionKeyword.length(), weatherData.indexOf("\"", descriptionIndex + descriptionKeyword.length()));
            String iconCode = weatherData.substring(iconIndex + iconKeyword.length(), weatherData.indexOf("\"", iconIndex + iconKeyword.length()));

            temperatureLabel.setText("Temperature: " + temp);
            descriptionLabel.setText("Description: " + description);
            weatherIconLabel.setIcon(new ImageIcon(new ImageIcon("http://openweathermap.org/img/wn/" + iconCode + "@2x.png").getImage().getScaledInstance(100, 100, Image.SCALE_SMOOTH)));
        } else {
            temperatureLabel.setText("Temperature: N/A");
            descriptionLabel.setText("Description: N/A");
            weatherIconLabel.setIcon(null);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new AdvancedWeatherApp().setVisible(true);
            }
        });
    }
}

Leave a comment