DimK
DimK

Reputation: 331

Problem with downloading and displaying image

I have made a program in Java, that downloads an image from the internet, given a link, and saves it into a specific folder in my computer, upon the pressing of a button in the gui. What I want to do next is to display that image on the screen. Please note, the URL input is not necessarily the URL of the image itself, but of an HTML webpage containing the image. The problem is, I can't simply create an ImageIcon object preemptively, because the image file doesn't exist in the system yet in compile time.

Panel Class

public class AdditionPanel extends JPanel
{

    // ...
    static JTextPane textpane;
    JLabel paneInstructions;
    JButton linkOk;

    public AdditionPanel() throws IOException
    {

        textpane = new JTextPane();         
        paneInstructions = new JLabel("Paste the link here:");
        linkOk = new JButton(" OK ");

        // ...

        linkOk.addActionListener(new LinkOkPressed());

        // ...

        this.add(textpane);
        this.add(paneInstructions);
        this.add(linkOk);
    }
}

An idea I've had is to create an ActionListener for that button, and try to access the file only after the button has been pressed, and thus the file has been downloaded. In this case, I don't know how to make an image display on a JPanel, from a different class.

Action Listener

public class LinkOkPressed implements ActionListener
{
    JLabel test;
    @Override
    public void actionPerformed(ActionEvent e)
    {
        // ImageDownloader is a class I have created, that simply saves the image
        // from the given URL in a predetermined directory
        ImageDownloader.saveImage(ImageDownloader.getImageUrl(AdditionPanel.textpane.getText()));
        ImageIcon poster = new ImageIcon(getClass().getResource("/resources/myimage.png"));
        test= new JLabel(poster);
        AdditionPanel.add(test); // Does not work
    }

}

So, can I add an image to the panel from a different class, or is there a better way to access a file that is downloaded during the runtime of the app? Thanks for the help.

ImageDownloader

public class ImageDownloader
{
    public static String getImageUrl(String imdbLink)
    {
        String imageLink = "";
        try
        {
            Document doc = Jsoup.connect(imdbLink).get();
            Elements divs = doc.getElementsByClass("poster");
            Element poster = divs.first();
            Elements image = poster.getElementsByTag("a");
            Element downloadImage = image.first();
            Elements img = downloadImage.getElementsByTag("img");
            imageLink = img.attr("src");
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return imageLink;
    }


    public static void saveImage(String imageLink)
    {
        BufferedImage image = null;
        try
        {
            URL url =new URL(imageLink);
            image = ImageIO.read(url);
            ImageIO.write(image, "png", new File("C:\\...\\resources\\myimage.png"));
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
}

Upvotes: 0

Views: 438

Answers (2)

Abra
Abra

Reputation: 20913

SwingWorker example.

Create a separate class like so...

public class SaveImage extends javax.swing.SwingWorker<Void, Void> {
    private AdditionPanel additionPanel;

    public SaveImage(AdditionPanel addPanel) {
        additionPanel = addPanel;
    }

    @Override
    protected Void doInBackground() throws Exception {
        ImageDownloader.saveImage(ImageDownloader.getImageUrl(AdditionPanel.textpane.getText()));
        // Wait until the image is saved.
        // Since I don't have code for class "ImageDownloader", can't tell you how to do this.
        return null;
    }

    @Override
    protected void done() {
        javax.swing.ImageIcon poster = new javax.swing.ImageIcon(getClass().getResource("/resources/myimage.png"));
        javax.swing.JLabel test= new javax.swing.JLabel(poster);
        additionPanel.add(test);
    }
}

And change your LinkOkPressed class like so...

public class LinkOkPressed implements ActionListener
{
    @Override
    public void actionPerformed(ActionEvent e)
    {
        Object obj = e.getSource(); // "obj" is really "linkOk" from class "AdditionPanel"
        java.awt.Container parent = ((JButton) obj).getParent(); // "parent" is instance of "AdditionPanel"
        SaveImage saveImage = new SaveImage((AdditionPanel) parent);
        saveImage.execute();
    }
}

Upvotes: 1

Abra
Abra

Reputation: 20913

Elaborating on PM 77-1's comment.

public class LinkOkPressed implements ActionListener
{
    JLabel test;
    @Override
    public void actionPerformed(ActionEvent e)
    {
        // ImageDownloader is a class I have created, that simply saves the image
        // from the given URL in a predetermined directory
        ImageDownloader.saveImage(ImageDownloader.getImageUrl(AdditionPanel.textpane.getText()));
        ImageIcon poster = new ImageIcon(getClass().getResource("/resources/myimage.png"));
        test= new JLabel(poster);
        Object obj = e.getSource(); // "obj" is really "linkOk" from class "AdditionPanel"
        java.awt.Container parent = ((JButton) obj).getParent(); // "parent" is instance of "AdditionPanel"
        ((JPanel) parent).add(test);
    }
}

Upvotes: 3

Related Questions