0

I am an undergrad student working on creating a Java weather app (Executable JAR) with NetBeans IDE 7.4 and Swing GUI.So far I have managed to create this much. I have a very limited knowledge of Java as of now. I am having problems with loading images after the first time (that is problem loading the 2nd and further subsequent images onto another jFrame that is opened after clicking a jButton in jFrame 1) onto the GUI Panel. I have tried several methods including getResource() , ImageIcon and also tried Java 2-D documentation examples.

I had a partially success with ImageIcon, but after I have loaded one image I cannot load any others. The subsequent image(s) displayed is the same as before with no change and when I diagnosed with getImageLoadStatus() it returns a value of '8' which might indicate some connection problems. I need to load the images from a URL . Specifically I'm using Yahoo weather RSS feeds to implement everything in my program, including the images.

What is utterly baffling to me is that the same code works differently (in this case it doesn't work) when used in the same context. Please check below two snippets of code for further clarification

P.S. I don't know JSON/ XML parsing to get data , so what I've used is a very naive URL to string method.

Working Code in 1st jFrame >

 // TO GET CODE
        num = weather.indexOf("code");
        num1 = weather.indexOf(" ", num);
        String cod = weather.substring(num + 6, num1 - 1);

        String imgurl = "http://l.yimg.com/a/i/us/we/52/" + cod;
        String imgurl1 = imgurl + ".gif";
        System.out.println(imgurl1);

 // TO DISPLAY IMAGE 
        try{
         BufferedImage img = ImageIO.read(new URL(imgurl1));

      jLabel19.setIcon(new ImageIcon(img)); 
        }
        catch(Exception e){

        }

-- Non - Working Code in 2nd jFrame that opens up on clicking a button in jFrame 1 (

   // TO GET CODE
    num = weather_1.indexOf("day");
    num1 = weather_1.indexOf("code", num);
    num2 = weather_1.indexOf("/", num1);
    String cod = weather_1.substring(num1 + 6, num2 - 2);

    String imgurl = "http://l.yimg.com/a/i/us/we/52/" + cod;
    String imgurl1 = imgurl + ".gif";

        //TO GET IMAGE
     try{
     BufferedImage img = ImageIO.read(new URL(imgurl1));
   System.out.println(imgurl1);

    jLabel16.setIcon(new ImageIcon(img)); 
    }
    catch(Exception e){

    }

What is utterly baffling to me, is that if I change the variable 'imgurl1' to its URL form which is 'http://l.yimg.com/a/i/us/we/52/30.gif', then it works fine. But the code with the variable inside the "(new URL(imgurl1));" code worked the 1st time in jFrame 1.

  • 2
    Why don't you try getting it working with 1 JLabel and image before writing a 200 line program. It is easier to spot error when you only have 20 lines of code. Also, don't use setBounds(). Swing was designed to be used with Layout Managers. Start by reading the [Swing tutorial](http://docs.oracle.com/javase/tutorial/uiswing/TOC.html) for basic information and examples. Maybe the section on "How to Use Icons" which contains a working example. – camickr Mar 01 '14 at 20:35
  • An important rule in coding: when adding something new and different, to a program, especially something that you're not very familiar with, first get it working in a simple small program before trying to implement it into a large program. This not only makes it easier for you to work the bugs out, it also makes it much easier for ***us*** to help you if you're still stuck. As it is, you've posted a Godzilla of a program, most of it redundant code completely unrelated to your problem, and thus quite distracting to us. – Hovercraft Full Of Eels Mar 01 '14 at 20:35
  • @camickr Yes. I got the jLabel working only one time,i.e., in the 2nd part of the code, but in the new jFrame (3rd part), the jLabel images do not update. It remains the same. I have even tried flushing. –  Mar 01 '14 at 20:49
  • @HovercraftFullOfEels Yes. I have made the program a bit smaller and also edited it into 3 main parts with explanation on each part's beginning. The problematic one is from the 3rd part of the code above. –  Mar 01 '14 at 20:50
  • From the sounds of it, the image is stored on a remote/web server, this would suggest that would need to be using a `URL` as the source reference for the image, which both `ImageIO` and `ImageIcon` can read. Personally, I'd use `ImageIO` as it will not return until the image is loaded and will normally throw an exception when something goes wrong... – MadProgrammer Mar 01 '14 at 21:12
  • @camickr . I already tried reading the Java DOCS but maybe I'm not understanding/implementing it correct –  Mar 01 '14 at 21:16
  • @MadProgrammer . Can you please share how to implement ImageIO to read an image from a given URL, for example this GIF image from Yahoo >> "http://l.yimg.com/a/i/us/we/52/33.gif " and display it in a jLabel/ jPanel or any other things similar? –  Mar 01 '14 at 21:20
  • 1
    I've done a test, downloading the RSS feed from Yahoo and I have to say that trying to hand parse a XML document is not a good idea, there are a lot of really good XML APIs designed to just this. I'll post my test in a few hours when I finally get back home. – MadProgrammer Mar 01 '14 at 22:20
  • `I got the jLabel working only one time,i.e., in the 2nd part of the code, but in the new jFrame (3rd part), the jLabel images do not update.` - I don't know what the 1st/2nd part of the code is because there is too much code. If it works once it should work twice. Post your [SSCCE](http://www.sscce.org/) that demonstrate the working and non-working code. Again it should be about 20-30 lines of code because all you need is a frame with a couple of labels. – camickr Mar 02 '14 at 01:43
  • @camickr - I have modified the code showing the Working and non -working parts of code. It looks almost the same but it doesn't work in the 2nd jFrame. This is what's baffling to me. –  Mar 02 '14 at 09:58
  • I have edited my problems in a concise and clear manner in the post. Thank You for the help. –  Mar 02 '14 at 21:53

1 Answers1

2

So, I took at look at http://weather.yahooapis.com/forecastrss?w=1103816&u=c to see what it returns and got the following output...

<?xml version="1.0" encoding="UTF-8"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" version="2.0">
    <channel>

        <title>Yahoo! Weather - Melbourne, AU</title>
        <link>http://us.rd.yahoo.com/dailynews/rss/weather/Melbourne__AU/*http://weather.yahoo.com/forecast/ASXX0075_c.html</link>
        <description>Yahoo! Weather for Melbourne, AU</description>
        <language>en-us</language>
        <lastBuildDate>Sun, 02 Mar 2014 1:29 pm AEDT</lastBuildDate>
        <ttl>60</ttl>
        <yweather:location city="Melbourne" country="Australia" region="VIC"/>
        <yweather:units distance="km" pressure="mb" speed="km/h" temperature="C"/>
        <yweather:wind chill="21" direction="190" speed="19.31"/>
        <yweather:atmosphere humidity="46" pressure="1015.92" rising="0" visibility="9.99"/>
        <yweather:astronomy sunrise="7:03 am" sunset="7:57 pm"/>
        <image>
            <title>Yahoo! Weather</title>
            <width>142</width>
            <height>18</height>
            <link>http://weather.yahoo.com</link>
            <url>http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif</url>
        </image>
        <item>
            <title>Conditions for Melbourne, AU at 1:29 pm AEDT</title>
            <geo:lat>-37.87</geo:lat>
            <geo:long>145.1</geo:long>
            <link>http://us.rd.yahoo.com/dailynews/rss/weather/Melbourne__AU/*http://weather.yahoo.com/forecast/ASXX0075_c.html</link>
            <pubDate>Sun, 02 Mar 2014 1:29 pm AEDT</pubDate>
            <yweather:condition code="28" date="Sun, 02 Mar 2014 1:29 pm AEDT" temp="21" text="Mostly Cloudy"/>
            <description><![CDATA[
<img src="http://l.yimg.com/a/i/us/we/52/28.gif"/><br />
<b>Current Conditions:</b><br />
Mostly Cloudy, 21 C<BR />
<BR /><b>Forecast:</b><BR />
Sun - AM Clouds/PM Sun. High: 22 Low: 12<br />
Mon - Partly Cloudy. High: 27 Low: 14<br />
Tue - Mostly Sunny. High: 32 Low: 19<br />
Wed - AM Light Rain. High: 21 Low: 12<br />
Thu - Partly Cloudy. High: 22 Low: 13<br />
<br />
<a href="http://us.rd.yahoo.com/dailynews/rss/weather/Melbourne__AU/*http://weather.yahoo.com/forecast/ASXX0075_c.html">Full Forecast at Yahoo! Weather</a><BR/><BR/>
(provided by <a href="http://www.weather.com" >The Weather Channel</a>)<br/>
]]></description>
            <yweather:forecast code="30" date="2 Mar 2014" day="Sun" high="22" low="12" text="AM Clouds/PM Sun"/>
            <yweather:forecast code="30" date="3 Mar 2014" day="Mon" high="27" low="14" text="Partly Cloudy"/>
            <yweather:forecast code="34" date="4 Mar 2014" day="Tue" high="32" low="19" text="Mostly Sunny"/>
            <yweather:forecast code="11" date="5 Mar 2014" day="Wed" high="21" low="12" text="AM Light Rain"/>
            <yweather:forecast code="30" date="6 Mar 2014" day="Thu" high="22" low="13" text="Partly Cloudy"/>
            <guid isPermaLink="false">ASXX0075_2014_03_06_7_00_AEDT</guid>
        </item>
    </channel>
</rss><!-- fan516.sports.gq1.yahoo.com Sun Mar  2 03:08:38 PST 2014 -->

Round about here I thought to myself, there's simply no way I'm even going to try and parse that, not when there are APIs available to not only read the content, but also to query it.

So I wrote this quick test...

Which reads the RSS feed, finds the description element from the /rss/channel/item path, which contains the information you're after.

I then need to parse the description content, as it was in HTML format, this made it easy to find the img tag and extract the src attribute to the image.

Finally I displayed a JOptionPane showing the icon...

Weather

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

public class YahooTest {

    public static void main(String[] args) {
        Document doc = null;
        try {
            URL url = new URL("http://weather.yahooapis.com/forecastrss?w=1103816&u=c");
            Node descNode = getNodeFrom(url, "/rss/channel/item/description");

            if (descNode != null) {

                String desc = descNode.getTextContent();
                System.out.println(desc);

                desc = "<root>" + desc + "</root>";
                Node imgSourceNode = getNodeFrom(desc, "/root/img[@src]");
                if (imgSourceNode != null) {
                    String imgUrl = imgSourceNode.getAttributes().getNamedItem("src").getNodeValue();
                    BufferedImage img = ImageIO.read(new URL(imgUrl));
                    JOptionPane.showMessageDialog(
                                    null,
                                    "The Weather looks like...",
                                    "Weather",
                                    JOptionPane.PLAIN_MESSAGE,
                                    new ImageIcon(img));
                } else {
                    JOptionPane.showMessageDialog(null, "No image source found in description");
                }

            } else {
                JOptionPane.showMessageDialog(null, "No description node found");
            }           
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static Node getNodeFrom(URL url, String query) throws IOException, SAXException, ParserConfigurationException, XPathExpressionException {

        Node node = null;
        InputStream is = null;
        try {
            is = url.openStream();
            node = getNodeFrom(is, query);
        } finally {
            try {
                is.close();
            } catch (Exception e) {
            }
        }

        return node;

    }

    public static Node getNodeFrom(String text, String query) throws IOException, SAXException, ParserConfigurationException, XPathExpressionException {

        Node node = null;
        InputStream is = null;
        try {
            is = new ByteArrayInputStream(text.getBytes());
            node = getNodeFrom(is, query);
        } finally {
            try {
                is.close();
            } catch (Exception e) {
            }
        }

        return node;

    }

    public static Node getNodeFrom(InputStream is, String query) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
        return getNodeFrom(doc, query);
    }

    public static Node getNodeFrom(Document doc, String query) throws XPathExpressionException {
        return getNodeFrom(doc.getDocumentElement(), query);
    }

    public static Node getNodeFrom(Node node, String query) throws XPathExpressionException {
        XPath xPath = XPathFactory.newInstance().newXPath();
        XPathExpression xExp = xPath.compile(query);
        return (Node) xExp.evaluate(node, XPathConstants.NODE);
    }

}

I did spend some time looking through your code, but your poor variable naming choices made it next to near impossible to figure out what was going on...

Take a look at http://docs.oracle.com/javase/tutorial/jaxp/, How XPath Works and XPath Tutorial

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thank you for taking time to look at my code. Yes, I do have some problems with variable naming and other basic stuff which I need to improve. So it seems that XML parsing is the way to go. Btw, is there some way to parse the image also through the XML parser? –  Mar 02 '14 at 09:47
  • I have modified the code showing the Working and non -working parts of code. It looks almost the same but it doesn't work in the 2nd jFrame. This is what's baffling to me. –  Mar 02 '14 at 09:59
  • What I would do is have a look at what the imgurl1 is generating and paste the result into a web browser and have a look at what it is downloading, if anything – MadProgrammer Mar 02 '14 at 19:11
  • Hello, I just modified my code after looking at your code.String imgurl="http://l.yimg.com/a/i/us/we/52/" + cod; String imgurl1= imgurl + ".gif"; try{BufferedImage img = ImageIO.read(new URL("http://l.yimg.com/a/i/us/we/52/30.gif")); System.out.println(imgurl1);jLabel16.setIcon(new ImageIcon(img)); } catch(Exception e){} The problem is the above code works only if I put in the URL manually,instead if i specify the variable imgurl1 which displays "http://l.yimg.com/a/i/us/we/52/29.gif",it wont work. Whats even more strange is that the same code with the imgurl variable works in my first jPanel. –  Mar 02 '14 at 21:41
  • I have edited my problems in a concise and clear manner in the post. Thank You for the help. –  Mar 02 '14 at 21:52
  • You could have spaces in the URL, try using `trim` on `imgurl` and the various elements (like `cod` and `num`) to ensure you aren't putting in any additional content – MadProgrammer Mar 02 '14 at 22:24
  • I tried everything. But after that I just put the Image display code in jFrame 1 in comments and ran the program again. It worked!! After I removed the comments, even the image display in jFrame 1 along with in jFrame 2 began working. Strange indeed. But I could not have done it without your help., esp. since I changed my code to BufferedImage . Thank You for the support. –  Mar 03 '14 at 09:03