cygorx
cygorx

Reputation: 228

Java doesn't like downloading files.

I'm creating a Swing GUI that will have multiple features for updating. If a user is not properly updated, it will display a "Download & Install" button. That works fine, but pressing the button does nothing. It doesn't freeze, it just sort of sits there. Nonetheless, "setup.exe" is a pretty large file (~600MB), but it doesn't show me anything nor does the file even begin to appear in the C:\ directory. What am I doing wrong here?

protected static JButton aroundTheLake; 

private static JButton aroundTheRiver() {
    aroundTheLake = new JButton("DOWNLOAD & INSTALL!");
    aroundTheLake.setVerticalTextPosition(AbstractButton.CENTER);
    aroundTheLake.setHorizontalTextPosition(AbstractButton.LEADING); //aka LEFT, for left-to-right locales
    aroundTheLake.setMnemonic(KeyEvent.VK_D);
    aroundTheLake.setActionCommand("aroundthelake");
    return aroundTheLake;
}

private static String readURL(String targetURL) {
    String returnish = "";
    try {
        URL tempURL = new URL(targetURL); 
        Scanner s = new Scanner(tempURL.openStream()); 
        while (s.hasNextLine()) {
            returnish = returnish+s.nextLine(); 
        }
    } catch (IOException e) {
        System.out.println(e); 
    }
    return returnish;
}

private static String readFile(String targetFile) { 
    String returnString = "";
    try {
        File tempFile = new File(targetFile);
        Scanner s = new Scanner(tempFile);
        while (s.hasNextLine()) {
            returnString = returnString + s.nextLine(); 
        }
    } catch(IOException e) { 
        // !
        System.out.println(e);
    }
    return returnString;
}

public void actionPerformed(ActionEvent e) {
    if ("aroundthelake".equals(e.getActionCommand())) {
        try { 
                System.out.println("initiated");
                URL website = new URL("http://theneverhood.sourceforge.net/setup.exe");
                ReadableByteChannel rbc = Channels.newChannel(website.openStream());
                FileOutputStream fos = new FileOutputStream("setup.exe");
                fos.getChannel().transferFrom(rbc, 0, 1 << 24);
        } catch (IOException exc) { 
            System.out.println(exc);
        }
    } else {
        // man
    }
}

private static void showGUI() {
    JFrame frame = new JFrame("The Neverhood Restoration Project");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(new Dimension(1024, 600));
    frame.setExtendedState(frame.MAXIMIZED_BOTH);
    frame.getContentPane().setBackground(new Color(0xA64343));

    File fileCheck = new File("C:/Program Files (x86)");
    String returnString = null;
    String rootDirectory = null;
    if (fileCheck.exists()) {
        rootDirectory = "C:/Program Files (x86)/DreamWorks Interactive"; 
        String checkFile = rootDirectory+"/Neverhood/version.txt"; 
        File tempFile = new File(checkFile);
        if (tempFile.exists()) {
            returnString = readFile(checkFile);
        } else {
            returnString = "It appears you do not have the Neverhood Restoration Project installed, or you are using an earlier version."; 
        }
    } else {
        rootDirectory = "C:/Program Files/DreamWorks Interactive";
        String checkFile = rootDirectory+"/Neverhood/version.txt"; 
        File tempFile = new File(checkFile);
        if (tempFile.exists()) {
            returnString = readFile(checkFile);
        } else {
            returnString = "It appears you do not have the Neverhood Restoration Project installed, or you are using an earlier version.";
        }
    }
    if (returnString.equals(readURL("http://theneverhood.sourceforge.net/version.txt"))) {
        returnString = "You are updated to the recent version!"; 
    } else { 
        returnString = "It appears you're not updated.";
    }

    JLabel headerLabel = new JLabel("The Neverhood Restoration Project");
    headerLabel.setHorizontalAlignment(JLabel.CENTER);
    JPanel heapPanel = new JPanel();
    heapPanel.setLayout(new BoxLayout(heapPanel, BoxLayout.PAGE_AXIS));
    heapPanel.setPreferredSize(new Dimension(500, heapPanel.getPreferredSize().height));
    JTextArea heapLabel = new JTextArea(50, 50);        
    heapLabel.setLineWrap(true);
    heapLabel.setWrapStyleWord(true);
    heapLabel.setEditable(false);
    heapLabel.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
    heapLabel.setFont(new Font("Serif", Font.PLAIN, 14));
    heapLabel.append("Current version: "+readURL("http://theneverhood.sourceforge.net/prettyversion.txt")+".\nInstalled version: "+readFile(rootDirectory+"/Neverhood/prettyversion.txt")+".\n"+returnString+"\n" + 
        "You can read the full version of the document to the left at http://theneverhood.sourceforge.net."
        + "\nHaven't installed yet? Below is the download button. Just click to save setup.exe in and enjoy!");
    heapPanel.add(heapLabel);
    if (returnString == "It appears you're not updated.") { 
        heapPanel.add(aroundTheRiver());
    }

    try {
        Font sFont = Font.createFont(Font.TRUETYPE_FONT, new File("DUGFB___.TTF"));
        sFont = sFont.deriveFont(Font.PLAIN, 48);
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        ge.registerFont(sFont);
        headerLabel.setFont(sFont);
    } catch (FontFormatException | IOException e) {
        System.out.println(e);
    }

    BufferedImage icoImage = null;
    try {
        icoImage = ImageIO.read(
            frame.getClass().getResource("/nhood.bmp"));
    } catch (IOException e) {
        System.out.println(e);
    }
    frame.setIconImage(icoImage);

    JEditorPane updateLog = new JEditorPane();
    JScrollPane scrollPane = new JScrollPane(updateLog);
    updateLog.setEditable(false);

    try {
        updateLog.setPage("http://theneverhood.sourceforge.net/");
    } catch (IOException e) {
        updateLog.setContentType("text/html");
        updateLog.setText("<html>The application could not load the webpage.</html>");
    }

    frame.add(headerLabel, BorderLayout.NORTH);
    frame.add(scrollPane);
    frame.add(heapPanel, BorderLayout.EAST);
    frame.pack();
    frame.setVisible(true);
}


public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            showGUI();
        }
    });
}

Upvotes: 0

Views: 205

Answers (3)

Joni
Joni

Reputation: 111239

The user interface freezes because you are keeping the event dispatch thread busy for download.

The event dispatch thread is the same thread that maintains the UI "alive" - you should never do anything that takes a perceivably long time directly in an event handler.

What you should do instead is launch a separate thread that downloads the file. To make this user friendly you can use a progress monitor so that the user sees what your program is doing, and ideally how long it is going to take. I recommend going through the tutorial to see how that is done.

A quick solution is just launching a new thread. This is not very user friendly though, since there will be absolutely no user feedback.

public void actionPerformed(ActionEvent e) {
    if ("aroundthelake".equals(e.getActionCommand())) {
        new Thread() {
            public void run() {
                try { 
                    System.out.println("initiated");
                    URL website = new URL("http://theneverhood.sourceforge.net/setup.exe"); 
                    ReadableByteChannel rbc = Channels.newChannel(website.openStream());
                    FileOutputStream fos = new FileOutputStream("setup.exe");
                    fos.getChannel().transferFrom(rbc, 0, 1 << 24);
                } catch (IOException exc) { 
                    System.out.println(exc);
                }   
            }   
        }.start();

    } else {
        // man
    }   
}   

Upvotes: 1

Eng.Fouad
Eng.Fouad

Reputation: 117587

You have two main issues within your code:

  • You haven't registered the action listener to your button. Do it like this:

button.addActionListener(this);

Upvotes: 3

Jason Nichols
Jason Nichols

Reputation: 11733

A couple of things:

1) NEVER make network calls from the Swing thread! Use a SwingWorker. When the Swing EDT is blocked all UI action ceases. See here for more info.

2) You really don't need to override JButton. Just add an ActionListener instead. You're making your code less flexible this way.

3) Make sure you actually call addActionListener().

Upvotes: 1

Related Questions