I'm taking Pattern Oriented Software Architecture for Concurrent and Networked Software course on Coursera now. And I've decided to practice a bit, namely to apply Proxy pattern for a real program. Namely, here's my goal:

1. I have a GUI program which consists of a JButton and JLabel
2. When the user clicks a button, an image is downloaded from the internet and placed as an icon of JLabel

I want to implement it using a Proxy pattern. Namely, I create a proxy class, who implements Icon interface and loads an image on demand. Here's the code:
public class NetIcon implements Icon {
 
    private URL location;
    private ImageIcon image;
 
    public NetIcon(URL location){
        this.location = location;
    }
 
    private void loadImage(){
        try{
            BufferedImage img = null;
            while(img == null) img = ImageIO.read(location);
            image = new ImageIcon(img);
        } catch(IOException ex){}
    }
 
    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        if(image == null) loadImage();
        image.paintIcon(c, g, x, y);
    }
 
    @Override
    public int getIconWidth() {
        if(image != null) return image.getIconWidth();
        return -1;
    }
 
    @Override
    public int getIconHeight() {
        if(image != null) return image.getIconHeight();
        return -1;
    }
}

But here are some difficulties. Namely, when I set an instance of NetIcon class as an Icon of a label and repaint it, GUI blocks because it's repainting takes too long (due to the necessity to download image). I want to indicate that the image is downloading with a gif-file on the label, but I can't do that. Here's the code (without gif-file, because I even have no idea where to put it's code...):
    public static void main(String[] args) throws IOException, JSONException{
        final JFrame f = createFrame();
 
        final JLabel l = new JLabel("Picture");
        f.add(l, BorderLayout.CENTER);
 
        JButton btn = new JButton("Load Image");
        ActionListener btnActionListener = new ActionListener() {
 
            @Override
            public void actionPerformed(ActionEvent e) {
                try{
                    URL url = new URL("http://us.123rf.com/400wm/400/400/dixi_/dixi_1101/dixi_110100024/8669259-siberian-cat-isolated-on-white.jpg");
                    NetIcon ico = new NetIcon(url);
 
                    l.setIcon(ico);
 
                    //GUI blocks
                    f.repaint();
                    //GUI unblocks
                } catch(IOException ex) {}
            }
        };
        btn.addActionListener(btnActionListener);
 
        f.add(btn, BorderLayout.SOUTH);
    }
 
    private static JFrame createFrame() {
        JFrame result = new JFrame();
 
        result.setBounds(200, 200, 300, 300);
        result.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
        result.setVisible(true);
 
        return result;
    }

Where do I have architectural flaws? How can I improve this design?