-
-
Save starks981/3037fabada4aa9c628e59ccfa8ecafe0 to your computer and use it in GitHub Desktop.
Weather App using Openweathermap.org API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package weatherapp; | |
// Imports for the class | |
import java.io.BufferedReader; | |
import java.io.InputStreamReader; | |
import java.net.HttpURLConnection; | |
import java.net.URL; | |
import javafx.scene.control.Alert; | |
import javafx.scene.control.Alert.AlertType; | |
// CurrentConditionsConnection Class | |
public class CurrentConditionsConnection { | |
// Declare the private variables needed for the class | |
private static String currentTemp; | |
private static String description; | |
private static String humidity; | |
private static String cityName; | |
private static String icon; | |
// BuildCurrentConnection Method | |
public static void buildCurrentConnection(String zip) { | |
// Declare a string and stringbuilder to handle the get request | |
String inputLine; | |
StringBuilder response = new StringBuilder(); | |
// Try-catch block | |
try { | |
// Create a URL object with the zip collected from the opening scene | |
URL url = new URL("http://api.openweathermap.org/data/2.5/weather?zip=" + zip + "&units=imperial&APPID=6eb402785cda7bb438558f56aa0235c8"); | |
// Attempt to open the connection with the openweathermap API | |
HttpURLConnection con = (HttpURLConnection) url.openConnection(); | |
// If the connection was successful (200 response) read the JSON | |
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) { | |
// Create a buffered reader to read the JSON | |
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); | |
// feed response into the StringBuilder while there is a response to read | |
while ((inputLine = in.readLine()) != null) { | |
response.append(inputLine); | |
} | |
// Close the bufferedreader | |
in.close(); | |
} | |
// Set the connected variable to TRUE | |
WeatherApp.connected = true; | |
// Call the Weather Info Method | |
weatherInfo(response.toString()); | |
} | |
// If the connection was invalid show error message | |
catch(Exception e) { | |
Alert alert = new Alert(AlertType.WARNING); | |
alert.setTitle("Error"); | |
alert.setHeaderText("Zip Code Not Valid.\nPlease Re-enter"); | |
alert.showAndWait(); | |
// Set the Connected variable to FALSE | |
WeatherApp.connected = false; | |
} | |
} | |
// WeatherInfo method | |
public static void weatherInfo(String currentWeather) { | |
// call the RetrieveData method to parse the JSON response | |
currentTemp = retrieveData("temp", currentWeather); | |
description = retrieveData("description", currentWeather).replaceAll("\"",""); | |
humidity = retrieveData("humidity", currentWeather); | |
cityName = retrieveData("name", currentWeather).replaceAll("\"",""); | |
icon = retrieveData("icon", currentWeather).replaceAll("}","").replaceAll("\"", "").replaceAll("]",""); | |
} | |
// RetrieveData method | |
public static String retrieveData(String data, String currentWeather) { | |
// Return the parsed string | |
return currentWeather.substring(currentWeather.indexOf(":",currentWeather.indexOf(data))+1, | |
currentWeather.indexOf(",",currentWeather.indexOf(data))); | |
} | |
// Getters | |
public String getCurrentTemp() { | |
return currentTemp; | |
} | |
public String getDescription() { | |
return description; | |
} | |
public String getHumidity() { | |
return humidity; | |
} | |
public String getCityName() { | |
return cityName; | |
} | |
public String getIcon() { | |
icon = "http://openweathermap.org/img/w/" + icon + ".png"; | |
return icon; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package weatherapp; | |
// Imports for the class | |
import java.io.BufferedReader; | |
import java.io.InputStreamReader; | |
import java.net.HttpURLConnection; | |
import java.net.URL; | |
import javafx.scene.control.Alert; | |
import javafx.scene.control.Alert.AlertType; | |
// HourlyConditionsConnection Class | |
public class HourlyConditionsConnection { | |
// Declare the variables for the class | |
private static String[] description = new String[4]; | |
private static int[] descIndex = new int[4]; | |
private static String[] temp = new String[4]; | |
private static int[] tempIndex = new int[4]; | |
private static String[] hourly = new String[4]; | |
private static int[] hourlyIndex = new int[4]; | |
private static String[] icons = new String[4]; | |
private static int[] iconsIndex = new int[4]; | |
// BuildHourlyConnection Method | |
public static void buildHourlyConnection(String zip) { | |
// Declare a string and stringbuilder to handle the get request | |
String inputLine; | |
StringBuilder response = new StringBuilder(); | |
// Try-catch block | |
try { | |
// Create a URL object with the zip collected from the opening scene | |
URL url = new URL("http://api.openweathermap.org/data/2.5/forecast?zip=" + zip + "&units=imperial&APPID=6eb402785cda7bb438558f56aa0235c8"); | |
// Attempt to open the connection with the openweathermap API | |
HttpURLConnection con = (HttpURLConnection) url.openConnection(); | |
// If the connection was successful (200 response) read the JSON | |
if(con.getResponseCode() == HttpURLConnection.HTTP_OK) { | |
// Create a buffered reader to read the JSON | |
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); | |
// feed response into the StringBuilder while there is a response to read | |
while((inputLine = in.readLine()) != null) { | |
response.append(inputLine); | |
} | |
// Close the bufferedreader | |
in.close(); | |
} | |
} | |
// If the connection was invalid show error message | |
catch(Exception e) { | |
Alert alert = new Alert(AlertType.WARNING); | |
alert.setTitle("Error"); | |
alert.setHeaderText("Zip Code Not Valid.\nPlease Re-enter"); | |
alert.showAndWait(); | |
} | |
// Call the Weather Info Method | |
weatherInfo(response.toString()); | |
} | |
// WeatherInfo method | |
public static void weatherInfo(String currentWeather) { | |
// Call the findIndex method to find the index needed for the retrievedata method | |
for(int i = 0; i < 4; i++) { | |
// Start with the second occurence of the word (first occurence would be current conditions) | |
iconsIndex[i] = findIndex(currentWeather, "icon", i + 1); | |
descIndex[i] = findIndex(currentWeather, "description", i + 1); | |
tempIndex[i] = findIndex(currentWeather, "temp_max", i + 1); | |
hourlyIndex[i] = findIndex(currentWeather, "dt_txt", i + 1); | |
} | |
// Call the RetrieveData method to parse the JSON response | |
icons = retrieveData(iconsIndex, currentWeather); | |
description = retrieveData(descIndex, currentWeather); | |
temp = retrieveData(tempIndex, currentWeather); | |
hourly = retrieveData(hourlyIndex, currentWeather); | |
} | |
// FindIndex method | |
public static int findIndex(String str, String substr, int n) { | |
// Set pos equal to the first index of the substring | |
int pos = str.indexOf(substr); | |
// Loop to find the appropriate index for the array | |
while(--n > 0 && pos != -1) { | |
// find the appropriate position of the substring to populate the array | |
pos = str.indexOf(substr, pos + 1); | |
} | |
// Returns the found index | |
return pos; | |
} | |
// Retrieve Data method | |
public static String[] retrieveData(int[] index, String currentWeather) { | |
// Array to handle the data parsing | |
String[] arr = new String[4]; | |
// Loop to populate the array with appropriate data, using indices found in respective index arrays | |
for(int i = 0; i < arr.length; i++) { | |
arr[i] = currentWeather.substring(currentWeather.indexOf(":", index[i])+1, currentWeather.indexOf(",", index[i])) | |
.replaceAll("}","").replaceAll("\"", "").replaceAll("]",""); | |
} | |
// Return the populated array | |
return arr; | |
} | |
// Getters | |
public String[] getIcons() { | |
for(int i = 0; i < icons.length; i++) { | |
icons[i] = "http://openweathermap.org/img/w/" + icons[i] + ".png"; | |
} | |
return icons; | |
} | |
public String[] getDescription() { | |
return description; | |
} | |
public String[] getTemp() { | |
return temp; | |
} | |
public String[] getHourly() { | |
for(int i = 0; i < hourly.length; i++) { | |
hourly[i] = hourly[i].substring(hourly[i].indexOf(" "), hourly[i].indexOf(":")).trim(); | |
int temp = Integer.parseInt(hourly[i]); | |
temp = temp - 5; | |
if(temp > 12) { | |
hourly[i] = temp - 12 + ":00"; | |
} | |
else if (temp < 0) { | |
hourly[i] = 12 + temp + ":00"; | |
} | |
else if (temp <= 12) { | |
hourly[i] = temp + ":00"; | |
} | |
} | |
return hourly; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.root{ | |
-fx-background-image: url("/Resources/bckgrnd1.jpg"); | |
-fx-font-weight: bold; | |
} | |
#zip{ | |
-fx-font: 15px Arial; | |
-fx-font-weight: bold; | |
-fx-fill: #5d445d; | |
} | |
.button{ | |
-fx-background-color: #5d445d; | |
-fx-text-fill: #F1E3F3; | |
} | |
.button:hover{ | |
-fx-background-color: #F1E3F3; | |
-fx-text-fill: #5d445d; | |
} | |
.button:focused{ | |
-fx-background-color: #F1E3F3; | |
-fx-text-fill: #5d445d; | |
} | |
.label{ | |
-fx-font: 13px Arial; | |
-fx-font-weight: bold; | |
-fx-text-fill: #674172; | |
} | |
.separator *.line{ | |
-fx-background-color: #e79423; | |
-fx-background-radius: 5; | |
-fx-border-style: solid; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package weatherapp; | |
/* | |
* Homemade Weather Application | |
* Author - Chris Starkey | |
* Work Started 8-2-2018 | |
* Work Completed 9-12-2018 | |
*/ | |
// Imports for the application | |
import javafx.application.Application; | |
import javafx.geometry.HPos; | |
import javafx.geometry.Insets; | |
import javafx.geometry.Pos; | |
import javafx.scene.Scene; | |
import javafx.scene.control.Button; | |
import javafx.scene.control.Label; | |
import javafx.scene.control.Separator; | |
import javafx.scene.control.TextField; | |
import javafx.scene.image.Image; | |
import javafx.scene.image.ImageView; | |
import javafx.scene.layout.GridPane; | |
import javafx.scene.layout.HBox; | |
import javafx.scene.text.Text; | |
import javafx.stage.Stage; | |
// Weather App Class | |
public class WeatherApp extends Application { | |
// Main Stage | |
Stage window; | |
// Zip Code Scene, Current Conditions Scene | |
Scene zipCodeScene, currentConditions; | |
// Create the root node | |
GridPane root = new GridPane(); | |
// Text asking to enter the zip code | |
Text zipTxt = new Text("Enter Zip Code:"); | |
// Text field for zip code entry | |
TextField zipTxtFld = new TextField("(e.g. 22802)"); | |
// Button to trigger the call to the API | |
Button enterBtn = new Button("Enter"); | |
// HBox to house the Enter button | |
HBox hboxBtn = new HBox(); | |
// Connection Confirmation boolean | |
static boolean connected = true; | |
// Main Method | |
public static void main(String[] args) { | |
launch(); | |
} | |
// Override the start method | |
public void start(Stage myStage) { | |
// Set the main stage | |
window = myStage; | |
// Set the title of the stage | |
window.setTitle("Stark-U-Weather Forecast"); | |
// Align the root node in the center | |
root.setAlignment(Pos.CENTER); | |
// Set a horizontal gap between controls | |
root.setHgap(10); | |
// Set a vertical gap between controls | |
root.setVgap(10); | |
// Set padding of the root node | |
root.setPadding(new Insets(25, 25, 25, 25)); | |
// Set the alignment of the hbox | |
hboxBtn.setAlignment(Pos.BOTTOM_RIGHT); | |
// Add the Enter Button to the Hbox | |
hboxBtn.getChildren().add(enterBtn); | |
// Add the components to the root node | |
root.add(zipTxt, 0, 0); | |
root.add(zipTxtFld, 0, 1); | |
root.add(hboxBtn, 0, 2); | |
// Add a CSS ID to the ZipTxt | |
zipTxt.setId("zip"); | |
// On Button click attempt a GET request | |
enterBtn.setOnAction(ae -> { | |
// Collect zip code to send to the buildConnection method. | |
CurrentConditionsConnection.buildCurrentConnection(zipTxtFld.getText()); | |
// If the connection was successful, attempt the second get request | |
if(connected) { | |
HourlyConditionsConnection.buildHourlyConnection(zipTxtFld.getText()); | |
// Call the currentConditions Scene method to display the second scene | |
buildCurrentConditionsScene(); | |
} | |
}); | |
// Create the zip code scene | |
zipCodeScene = new Scene(root, 615, 350); | |
// Add the scene to the stage | |
window.setScene(zipCodeScene); | |
// Attach the stylesheet to the scene | |
zipCodeScene.getStylesheets().add("/Resources/Stylesheet.css"); | |
// Do not let the stage be resized | |
window.setResizable(false); | |
// Show the main stage | |
window.show(); | |
} | |
public void buildCurrentConditionsScene(){ | |
// Create a new CurrentConditionsConnection object | |
CurrentConditionsConnection connection = new CurrentConditionsConnection(); | |
// Create the labels, buttons and images for the scene | |
Label currentLabel = new Label("Current Temp: " + connection.getCurrentTemp()); | |
Label descriptionLabel = new Label(connection.getDescription()); | |
Label humidityLabel = new Label("Current Humidity: " + connection.getHumidity() + "%"); | |
Label cityLabel = new Label("City: " + connection.getCityName()); | |
Image iconImg = new Image(connection.getIcon()); | |
ImageView imgView = new ImageView(iconImg); | |
HBox hbox = new HBox(10); | |
hbox.setAlignment(Pos.CENTER); | |
hbox.getChildren().addAll(zipTxt, zipTxtFld, enterBtn); | |
// Create the root node for the scene | |
GridPane ccRoot = new GridPane(); | |
// Set the Vertical and Horizontal gaps between nodes | |
ccRoot.setVgap(10); | |
ccRoot.setHgap(10); | |
// Align the root node in the Center | |
ccRoot.setAlignment(Pos.CENTER); | |
// Add the elements to the root node | |
ccRoot.add(cityLabel, 0,2,2,1); | |
ccRoot.add(currentLabel, 2, 3,2,1); | |
ccRoot.add(humidityLabel, 2, 4,2,1); | |
ccRoot.add(descriptionLabel, 5, 3); | |
ccRoot.add(imgView, 5, 4); | |
ccRoot.add(hbox, 3, 0, 5, 1); | |
// Center the elements within their grid | |
GridPane.setHalignment(cityLabel, HPos.CENTER); | |
GridPane.setHalignment(descriptionLabel, HPos.CENTER); | |
GridPane.setHalignment(imgView, HPos.CENTER); | |
// Create a new HourlyConditionsConnection object | |
HourlyConditionsConnection hrlyConnection = new HourlyConditionsConnection(); | |
// Create arrays to house the hourly details | |
String[] icons = hrlyConnection.getIcons(); | |
String[] description = hrlyConnection.getDescription(); | |
String[] temp = hrlyConnection.getTemp(); | |
String[] hrlyTime = hrlyConnection.getHourly(); | |
// Loop to populate the arrays, center the elements, and add them the root node | |
for(int i = 0; i < 4; i++) { | |
Label hrlyTimeLabel = new Label(hrlyTime[i]); | |
GridPane.setHalignment(hrlyTimeLabel, HPos.CENTER); | |
ccRoot.add(hrlyTimeLabel, 2+i, 7); | |
Label hrlyTempLabel = new Label(temp[i]); | |
GridPane.setHalignment(hrlyTempLabel, HPos.CENTER); | |
ccRoot.add(hrlyTempLabel, 2+i, 8); | |
Image hrlyIconImg = new Image(icons[i]); | |
ImageView hrlyIconView = new ImageView(hrlyIconImg); | |
GridPane.setHalignment(hrlyIconView, HPos.CENTER); | |
ccRoot.add(hrlyIconView, 2+i, 9); | |
Label hrlyDescriptionLabel = new Label(description[i]); | |
GridPane.setHalignment(hrlyDescriptionLabel, HPos.CENTER); | |
ccRoot.add(hrlyDescriptionLabel, 2+i, 10); | |
} | |
// Create forecast header, center it and add it to the root node | |
Label upcomingLbl = new Label("Upcoming Forecast"); | |
GridPane.setHalignment(upcomingLbl, HPos.CENTER); | |
ccRoot.add(upcomingLbl, 0,5,2,1); | |
// Create the time label, center it and add it to the root node | |
Label timeLbl = new Label("Time:"); | |
GridPane.setHalignment(timeLbl, HPos.CENTER); | |
ccRoot.add(timeLbl , 0,7,2,1); | |
// Create the temp label, center it and add it to the root node | |
Label tempLbl = new Label("Temp:"); | |
GridPane.setHalignment(tempLbl, HPos.CENTER); | |
ccRoot.add(tempLbl , 0,8,2,1); | |
// Create two horizontal lines and add them to the root node | |
Separator sepHor = new Separator(); | |
GridPane.setConstraints(sepHor,0,1); | |
GridPane.setColumnSpan(sepHor,9); | |
ccRoot.getChildren().add(sepHor); | |
Separator sepHor2 = new Separator(); | |
GridPane.setConstraints(sepHor2,0,6); | |
GridPane.setColumnSpan(sepHor2,9); | |
ccRoot.getChildren().add(sepHor2); | |
// Create the currentconditions scene | |
currentConditions = new Scene(ccRoot, 615, 350); | |
// Add the stylesheet to this scene | |
currentConditions.getStylesheets().add("/Resources/Stylesheet.css"); | |
// Set the scene to the stage | |
window.setScene(currentConditions); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment