📜 ⬆️ ⬇️

Java weather for beginners and older

image

Greetings to all on this wonderful day of waiting for a holiday, this is my first article on Habré, in which I would like a story about the open weather API of Yandex. The article is a continuation of the Java series for beginners. It should be noted, the article is intended for those who have recently started learning the language or for those who are not familiar with this service, but in any case, I will be glad to any readers (eh tautology ...). Yandex gives a good opportunity for developers who need to place the weather in their program or on their website, moreover, there is more than enough information that Yandex provides.

Weather you can choose any day for the week ahead. Different states (clear, overcast, etc.), many languages ​​(for cities, for example, Russian and English, for states, all languages ​​of the CIS countries and not only: clear, Ayaz, açık, ashy, etc.), I don’t very good in geography, but it seems that the information is there for all countries, even there are miniature pictures of the weather conditions, but most importantly, I chose this service - a simple and clear structure. Immediately make a reservation, for the "advertising" I did not pay.

')
Class with external representation, I think it is not necessary to describe, I just give the code so that later there are no inconsistencies. I recommend not to write off, but to make your own, for my poor:

public WFrame() { today = null; GridBagLayout layout = new GridBagLayout(); //  ,       ,    setTitle("Weather"); setPreferredSize(new Dimension(350, 300)); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); setVisible(true); contentPane = getContentPane(); panel = new JPanel(); panel.setLayout(layout); idField = new JtextField(); idField.setColumns(6); //   xml,      //   btn = new JButton("  "); //  ,  GUI   ,   label = new JLabel("   ID  "); label.setFont(new Font("Verdana", Font.PLAIN, 14)); tLabel = new JLabel(" "); tLabel.setFont(new Font("Verdana", Font.PLAIN, 14)); iLabel = new JLabel(); panel.add(label, new GBC(0, 0, 2, 1).setFill(GBC.NORTH).setWeight(100, 0)); panel.add(iLabel, new GBC(0, 1, 2, 1).setFill(GBC.NORTH).setWeight(100, 0)); panel.add(btn, new GBC(0, 3, 2, 1).setFill(GBC.NORTH).setWeight(100, 0)); panel.add(idField, new GBC(0, 2, 2, 1).setAnchor(GBC.NORTH) .setFill(GBC.HORIZONTAL).setIpad(50, 0)); panel.add(tLabel, new GBC(0, 4, 2, 1).setAnchor(GBC.NORTH) .setFill(GBC.HORIZONTAL).setIpad(50, 0)); add(panel); panel.setComponentPopupMenu(menu); pack(); } 


In idField, we will record the ID of our city (a list of cities and states can be found here weather.yandex.ru/static/cities.xml ). Well, in the labels - the information itself. I perceive criticism normally, I will be glad if you make comments or corrections. The GBC class is a successor of GridBagConstraints, I will give its code at the end of the post.

I would also add a pop-up menu for convenience, so that the city’s go will not be typed every time:

 JPopupMenu menu = new JPopupMenu(); menu.add(new AbstractAction("") { @Override public void actionPerformed(ActionEvent e) { setCity("27962"); } }); 


Naturally, you need to add more than one city, but I still have enough Penza. To add cities to the menu it is better to create a separate class, but this is another topic, I did not bother with it.

The next class I created is the Weather class for storing variables with weather information. There is nothing difficult:

 public class Weather { String city; String weatherType; String imgType; String humidity;//  String tom, tomNight; int temperature; public String toString() { return "Weather[city= " + city + ", weatherType=" + weatherType + ", temperature= " + temperature + ",humidity= " + humidity + "]"; } } 


Next, create a document for parsing
 Document doc = null; URL url = new URL("http://export.yandex.ru/weather-ng/forecasts/" + cityID + ".xml"); //     ,     //      URLConnection uc = url.openConnection(); InputStream is = uc.getInputStream();//  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); doc = db.parse(is);//  doc.getDocumentElement().normalize(); 


Associate the NodeList class variable with the forecast tag (see export.yandex.ru/weather-ng/forecasts/29642.xml - the weather page)

 nl = doc.getElementsByTagName("forecast").item(0).getChildNodes(); 


Those. we have something like:

 try { Document doc = null; URL url = new URL("http://export.yandex.ru/weather-ng/forecasts/" + cityID + ".xml"); //     ,     //      URLConnection uc = url.openConnection(); InputStream is = uc.getInputStream();//  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); doc = db.parse(is);//  doc.getDocumentElement().normalize(); nl = doc.getElementsByTagName("forecast").item(0).getChildNodes(); //       } catch (Exception ex) { JOptionPane.showMessageDialog(null, "     "); ex.printStackTrace(); } 


Well tied and disassembled, it's time to take the weather directly. As you can see, the forecast has a heir to the fact, and in turn, the station and temperature (the airport is sometimes indicated in the city name). Now, from the station and temperature, let's get out the weather and the name of the city:

 for (int i = 0; i < nl.getLength(); i++) { Node child = nl.item(i); if (child instanceof Element) { if (child.getNodeName().equals("fact")) { Node childOfChild = null; for (int j = 0; j < child.getChildNodes().getLength(); j++) { childOfChild = child.getChildNodes().item(j); if ("station".equals(childOfChild.getNodeName())) { todayWeather.city = childOfChild.getTextContent(); } if ("temperature".equals(childOfChild.getNodeName())) todayWeather.temperature = Integer .parseInt(childOfChild.getTextContent()); if ("weather_type_short".equals(childOfChild .getNodeName())) { todayWeather.weatherType = childOfChild .getTextContent(); } if ("image".equals(childOfChild.getNodeName())) { todayWeather.imgType = childOfChild .getTextContent(); } if ("humidity".equals(childOfChild.getNodeName())) { todayWeather.humidity = childOfChild .getTextContent(); } } } if (child.getNodeName().equals("informer")) { Node childOfChild = null; for (int j =0; j<child.getChildNodes().getLength(); j++){ childOfChild = child.getChildNodes().item(j); if ((childOfChild.getNodeName().equals("temperature")) && (childOfChild.getAttributes().item(1).getTextContent().equals("night"))) { todayWeather.tomNight = childOfChild.getTextContent(); } if (childOfChild.getNodeName().equals("temperature") && (childOfChild.getAttributes().item(1).getTextContent().equals("tomorrow"))) { todayWeather.tom = childOfChild.getTextContent();} } } } } WFrame.today = todayWeather; 


For for loop we iterate over all the children and select only those we need, as you can see, I also chose the humidity and type of the picture. Otherwise, I think everything is very clear.

It remains only to write an event handler for the button:
 btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { String cityID = idField.getText(); if (cityID == null) throw new IOException("  ID "); WeatherParser.parse(cityID); //      label.setText(today.city + "(): " + today.temperature + " ; " + today.weatherType + " :" + today.humidity + " %"); iLabel = new JLabel(new ImageIcon(ImageIO.read(new URL( "http://img.yandex.net/i/wiz" + today.imgType + ".png")))); tLabel.setText("  /: "+ today.tomNight+"/"+ today.tom); //    } catch (IOException e1) { e1.printStackTrace(); } contentPane.add(iLabel); } }); 

In conclusion, I would like to apologize for bydlokoding in some places, I will be glad if you poke your nose in such. Another problem that has arisen for me and which I haven’t decided is the display of a picture that appears only if the form is stretched. So I am ready to listen to any valid criticism.

Thank you all for your attention, have a nice day!

Complete code:

1. Class with frame
 <code> public class WFrame extends JFrame { static Weather today; JPanel panel; JTextField idField; JButton btn; JLabel label; JLabel tLabel; JLabel iLabel; Box b; static String id; static int t; Container contentPane; public WFrame() { today = null; JPopupMenu menu = new JPopupMenu(); menu.add(new AbstractAction("") { @Override public void actionPerformed(ActionEvent e) { setCity("27962"); } }); //,    ,      // http://weather.yandex.ru/static/cities.xml GridBagLayout layout = new GridBagLayout(); //  ,       ,    setTitle("Weather"); setPreferredSize(new Dimension(350, 300)); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); setVisible(true); contentPane = getContentPane(); panel = new JPanel(); panel.setLayout(layout); idField = new JTextField(); idField.setColumns(6); idField.addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent arg0) { } @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { btn.doClick(); } } @Override public void keyPressed(KeyEvent arg0) { } }); //   xml,      //   btn = new JButton("  "); btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { String cityID = idField.getText(); if (cityID == null) throw new IOException("  ID "); WeatherParser.parse(cityID); //      label.setText(today.city + "(): " + today.temperature + " ; " + today.weatherType + " :" + today.humidity + " %"); iLabel = new JLabel(new ImageIcon(ImageIO.read(new URL( "http://img.yandex.net/i/wiz" + today.imgType + ".png")))); tLabel.setText("  /: "+ today.tomNight+"/"+ today.tom); //    } catch (IOException e1) { e1.printStackTrace(); } contentPane.add(iLabel); } }); //  ,  GUI   ,   label = new JLabel("   ID  "); label.setFont(new Font("Verdana", Font.PLAIN, 14)); tLabel = new JLabel(" "); tLabel.setFont(new Font("Verdana", Font.PLAIN, 14)); iLabel = new JLabel(); panel.add(label, new GBC(0, 0, 2, 1).setFill(GBC.NORTH).setWeight(100, 0)); panel.add(iLabel, new GBC(0, 1, 2, 1).setFill(GBC.NORTH).setWeight(100, 0)); panel.add(btn, new GBC(0, 3, 2, 1).setFill(GBC.NORTH).setWeight(100, 0)); panel.add(idField, new GBC(0, 2, 2, 1).setAnchor(GBC.NORTH) .setFill(GBC.HORIZONTAL).setIpad(50, 0)); panel.add(tLabel, new GBC(0, 4, 2, 1).setAnchor(GBC.NORTH) .setFill(GBC.HORIZONTAL).setIpad(50, 0)); add(panel); panel.setComponentPopupMenu(menu); pack(); } public static void main(String[] args) { // loginWithProxy(); javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { WFrame frame = new WFrame(); frame.setDefaultLookAndFeelDecorated(true); } }); } public void setCity(String id) { this.id = id; idField.setText(id); } } 


2. Class Weather

 public class Weather { String city; String weatherType; String imgType; String humidity;//  String tom, tomNight; int temperature; public String toString() { return "Weather[city= " + city + ", weatherType=" + weatherType + ", temperature= " + temperature + ",humidity= " + humidity + "]"; } } 


3. Parsing class:

 public class WeatherParser { static Weather tomorrowWeather; WeatherParser(WFrame f) { tomorrowWeather = new Weather(); } public static void parse(String cityID) { Weather todayWeather = new Weather(); NodeList nl = null; try { Document doc = null; URL url = new URL("http://export.yandex.ru/weather-ng/forecasts/" + cityID + ".xml"); //     ,     //      URLConnection uc = url.openConnection(); InputStream is = uc.getInputStream();//  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); doc = db.parse(is);//  doc.getDocumentElement().normalize(); nl = doc.getElementsByTagName("forecast").item(0).getChildNodes(); //       } catch (Exception ex) { JOptionPane.showMessageDialog(null, "     "); ex.printStackTrace(); } for (int i = 0; i < nl.getLength(); i++) { Node child = nl.item(i); if (child instanceof Element) { if (child.getNodeName().equals("fact")) { Node childOfChild = null; for (int j = 0; j < child.getChildNodes().getLength(); j++) { childOfChild = child.getChildNodes().item(j); if ("station".equals(childOfChild.getNodeName())) { todayWeather.city = childOfChild.getTextContent(); } if ("temperature".equals(childOfChild.getNodeName())) todayWeather.temperature = Integer .parseInt(childOfChild.getTextContent()); if ("weather_type_short".equals(childOfChild .getNodeName())) { todayWeather.weatherType = childOfChild .getTextContent(); } if ("image".equals(childOfChild.getNodeName())) { todayWeather.imgType = childOfChild .getTextContent(); } if ("humidity".equals(childOfChild.getNodeName())) { todayWeather.humidity = childOfChild .getTextContent(); } } } if (child.getNodeName().equals("informer")) { Node childOfChild = null; for (int j =0; j<child.getChildNodes().getLength(); j++){ childOfChild = child.getChildNodes().item(j); if ((childOfChild.getNodeName().equals("temperature")) && (childOfChild.getAttributes().item(1).getTextContent().equals("night"))) { todayWeather.tomNight = childOfChild.getTextContent(); } if (childOfChild.getNodeName().equals("temperature") && (childOfChild.getAttributes().item(1).getTextContent().equals("tomorrow"))) { todayWeather.tom = childOfChild.getTextContent();} } } } } WFrame.today = todayWeather; } } 


4. Well, GBC class

 import java.awt.GridBagConstraints; public class GBC extends GridBagConstraints { public GBC(int gridx, int gridy) { this.gridx = gridx; this.gridy = gridy; } public GBC(int gridx, int gridy, int gridwidth, int gridheight) { this.gridx = gridx; this.gridy = gridy; this.gridwidth = gridwidth; this.gridheight = gridheight; } public GBC setAnchor(int anchor) { this.anchor = anchor; return this; } public GBC setFill(int fill) { this.fill = fill; return this; } public GBC setWeight(double weightx, double weighty) { this.weightx = weightx; this.weighty = weighty; return this; } public GBC setInsets(int distance) { this.insets = new java.awt.Insets( distance, distance, distance, distance); return this; } public GBC setInsets(int top, int left, int bottom, int right) { this.insets = new java.awt.Insets( top, left, bottom, right); return this; } public GBC setIpad(int ipadx, int ipady) { this.ipadx = ipadx; this.ipady = ipady; return this; } } 


Archive on the people

Source: https://habr.com/ru/post/164101/


All Articles