简体   繁体   English

JProgressBar没有从SwingWorker更新,而调试工作正常

[英]JProgressBar not updating from SwingWorker, while debugs work fine

This has been driving me up the wall for 2 days now. 这已经让我在墙上停留了2天了。 I can't seem to make the JProgressBar update properly and I'm not sure why. 我似乎无法正确更新JProgressBar,我不知道为什么。 I've read through the concurrency and SwingWorker tutorials, I've tested outside of my program and been able to get it working fine using simple code. 我已经阅读了并发和SwingWorker教程,我已经在我的程序之外进行了测试,并且能够使用简单的代码使其工作正常。 I understand the concepts, and am just not seeing why it's not working as the code has been re-written in many different ways and still I can't make it work. 我理解这些概念,我只是没有看到为什么它不起作用,因为代码已经以许多不同的方式重写,但我仍然无法使其工作。 I'll post a SSCE using as much code from my program as I can, and explain things best I can here as well. 我会尽可能多地使用我的程序中的代码发布SSCE,并在这里解释最好的东西。

Basically I have a auto-updater/Installer program to update and/or install World of Warcraft addons to our customers computers. 基本上我有一个自动更新程序/安装程序来更新和/或安装我们的客户计算机上的魔兽世界插件。 The first thing the 'updater' does is check the server to see if it's version is the same as the version of the updater installer on the server. 'updater'做的第一件事是检查服务器,看它的版本是否与服务器上更新程序安装程序的版本相同。 This works swimmingly! 这很有效! In fact the entire updater works great except for this one issue. 事实上,除了这个问题之外,整个更新程序都很有效。 If the updater sees that the server has a different version number than the updater it downloads the installer (in a zip) from the server, unzips it, starts the installation from the exe that was contained in the zip and closes the currently open updater so the install can complete properly. 如果更新程序发现服务器具有与更新程序不同的版本号,则从服务器下载安装程序(以zip格式),解压缩它,从zip中包含的exe开始安装并关闭当前打开的更新程序,以便安装可以正常完成。

So I have a progress bar on the card (using cardLayout to show the three different cards for the updater, SelfUpdate, Login, and AddonList) for the self updater. 所以我在卡上有一个进度条(使用cardLayout为自动更新程序显示更新程序的三个不同的卡,SelfUpdate,Login和AddonList)。 as well as a JTextArea below the JProgressBar and that's all that shows on the particular SelfUpdate card. 以及JProgressBar下面的JTextArea,以及特定SelfUpdate卡上显示的所有内容。 It query's the server for the version number on the server and it compares that version to the version number on the updater currently installed. 它在服务器上查询服务器上的版本号,并将该版本与当前安装的更新程序上的版本号进行比较。 If the version is the same it changes to the Login card and moves along to the next bits of the program, which work great so far, if the versions are different it sends a query to the server and the server sends the zip file back to the updater for processing. 如果版本相同,它将更改为登录卡并移动到程序的下一位,到目前为止工作得很好,如果版本不同,它会向服务器发送查询,服务器将zip文件发送回用于处理的更新程序。

This is where it's not working. 这是它无法正常工作的地方。 The zip is a decent size and of course I want to show the progress of this download. 拉链是一个不错的大小,当然我想显示此下载的进度。 The zip file download works fine (it runs in the SwingWorker doInBackground() method), the updater then unzips the installer.exe file to a folder on the customers system drive, fires off using Runtime and starts the installer.exe which pops up the installer screen, then closes the current updater using System.exit(0). zip文件下载工作正常(它在SwingWorker doInBackground()方法中运行),更新程序然后将installer.exe文件解压缩到客户系统驱动器上的文件夹,使用Runtime触发并启动installer.exe弹出安装程序屏幕,然后使用System.exit(0)关闭当前更新程序。 again, all this works but the JProgressBar itself will NOT update. 再次,这一切都有效,但JProgressBar本身不会更新。 it sits at 0% for the whole thing. 它占据整个事物的0%。 Also, the taskOutput JTextArea doesn't get updated either, but the main problem is the progressbar not updating. 此外,taskOutput JTextArea也没有更新,但主要问题是进度条没有更新。 I can live with that getting fixed and the JTextArea not updating. 我可以忍受修复和JTextArea不更新。 (tried a JLabel in place of a textarea as well and no joy) (尝试用JLabel代替textarea而且没有喜悦)

So I know I'm doing something wrong, but I can't imagine what. 所以我知道我做错了什么,但我无法想象。 Here's the bits where the magic happens. 这是魔术发生的地方。 :) Forgive me if I explain as I go along here. :)请原谅我如果我在这里解释一下。

So Controller.java handles all the flow of the program here's the parts you need to see. 因此,Controller.java处理程序的所有流程,这是您需要查看的部分。

// Imports packages needed for use in this file.
import javax.swing.*;
import java.awt.CardLayout;
import java.io.*;
// class instantiation
public class Controller {

// Variables needed for use in this class
private static Updater util;
private static int loginReturnState = 0;
/**
*   Single contructor for this class
*/
public Controller() {

}


/**
*   Main method which runes everything in the updater program
*
*/
public static void main(String[] args) {
    util = new Updater();
    // Schedule a job for the event dispatch thread.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {

            // setup a new GUI
            util.createGUI();
            JFrame rFrame = util.getRootFrame();                
            JPanel gFrame = util.getCardLayoutFrame();
            CardLayout cards = (CardLayout) gFrame.getLayout();
            cards.show(gFrame, "UpdateUpdaterPanel");

            rFrame.pack();
            rFrame.setLocationRelativeTo(null);
            rFrame.setVisible(true);

            SelfUpdater selfUp = new SelfUpdater();             
            int needUpdate = selfUp.checkForUpdate();                                       if (needUpdate == 2) {// Update available for download. Download it.
                selfUp.downloadUpdate();

            } 


        }
    });


}
}

OK Next file is the Updater class. 确定下一个文件是Updater类。 To put code in here that will hopefully compile and show the issue I need to put this class in there or the utility methods I have in the uPdater class will not be around to be called and I use them extensively. 要把代码放在这里,希望编译并显示问题,我需要将这个类放在那里,或者我在uPdater类中使用的实用程序方法不会被调用,我会广泛使用它们。

// Packages needed for use in this file
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.CardLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseAdapter;
import java.io.*;


// Class instantiation
public class Updater {

// These final variables are set to the path for each of the images used
public static final String BG_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\background.png";
public static final String APP_ICON_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\app-icon.png";
public static final String CLOSE_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\close.png";
public static final String FINOFF_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\FinishedOff.png";
public static final String FINON_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\FinishedOn.png";
public static final String ICON_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\icon.png";
public static final String ICON64_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\icon64x64.png";
public static final String ICON256_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\icon256x256.png";
public static final String INSTOFF_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\InstallUpdatesOFF.png";
public static final String INSTON_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\InstallUpdatesON.png";
public static final String LOGO_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\logo.png";
public static final String MIN_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\minimize.png";
public static final String PROGBACK_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\ProgressBackground.png";
public static final String PROGBAR_IMAGE_PATH = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\ProgressBar.png";
public static final String INSTRUCTIONS_BUTTON = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\instructions.png";
public static final String PURCHASE_BUTTON = "F:\\Java Programs\\Updater\\src\\com\\dynastyaddons\\updater\\images\\Purchase.png";
// These are various final variables for use throughout the updater
public static final String URL_CONNECT = "http://dynastyaddons.com/api/index2.php?";
public static final String TITLE_TEXT = "Dynasty Updater";
public static final int BUFFER_SIZE = 4096;
public static final double UPDATER_VERSION = 1.1;

// Public variables needed for this class workings
private static JFileChooser fc;
private static JFrame rootFrame;

// Private variables for this class use alone
private static String PHPSessionID;
private static boolean debugToggle = true;
private CardLayout cards;
private JPanel guiFrame;
private Point mouseDownCompCoords;
private Login login;
private Addons addons;

/**
*   Sole contructor. (For invocation by subclass contructors, typically implicit.)
*/
public Updater() {
    // First instantiate any variables needed
    PHPSessionID = "notset";
    guiFrame = new JPanel();
    cards = new CardLayout();
    guiFrame.setLayout(cards);
}


// Various methods follow
/**
*   This will create the root gui for showing in the main method
*
*/
public void createGUI() {
    rootFrame = new JFrame();
    SpringLayout rootLayout = new SpringLayout();

    // setup root frame
    rootFrame.setUndecorated(true);
    rootFrame.setBackground(new Color(0,0,0,0));
    rootFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    rootFrame.setPreferredSize(new Dimension(800,600));
    rootFrame.setTitle(TITLE_TEXT);

    // add the background image
    JLabel bg = new JLabel(new ImageIcon(BG_IMAGE_PATH));
    bg.setLayout(rootLayout);
    rootFrame.add(bg);

    // setup title bar
    mouseDownCompCoords = null;
    mouseDownCompCoords = null;
    rootFrame.addMouseListener(new MouseListener() {
        public void mouseReleased(MouseEvent e){ mouseDownCompCoords = null; }
        public void mousePressed(MouseEvent e){ mouseDownCompCoords = e.getPoint(); }
        public void mouseExited(MouseEvent e){}
        public void mouseEntered(MouseEvent e){ }
        public void mouseClicked(MouseEvent e){ }
    });
    rootFrame.addMouseMotionListener(new MouseMotionListener() {
        public void mouseMoved(MouseEvent e){}
        public void mouseDragged(MouseEvent e){
            Point currCoords = e.getLocationOnScreen();
            rootFrame.setLocation(currCoords.x - mouseDownCompCoords.x, currCoords.y - mouseDownCompCoords.y);
        }
    });

    // Display and place the logo
    JLabel logo = new JLabel(new ImageIcon(LOGO_IMAGE_PATH));
    bg.add(logo);

    // add Close and Minimize buttons
    JPanel cmButt = createCloseAndMinButtons();
    bg.add(cmButt);

    // create card frame
    guiFrame.setPreferredSize(new Dimension(800, 435));
    guiFrame.setOpaque(false);
    bg.add(guiFrame);

    // Constrain the parts of your BG
    rootLayout.putConstraint(SpringLayout.WEST, logo, 30, SpringLayout.WEST, rootFrame);
    rootLayout.putConstraint(SpringLayout.NORTH, logo, 70, SpringLayout.NORTH, rootFrame);
    rootLayout.putConstraint(SpringLayout.NORTH, cmButt, 0, SpringLayout.NORTH, rootFrame);
    rootLayout.putConstraint(SpringLayout.EAST, cmButt, 0, SpringLayout.EAST, rootFrame);
    rootLayout.putConstraint(SpringLayout.SOUTH, guiFrame, 0, SpringLayout.SOUTH, rootFrame);
    rootLayout.putConstraint(SpringLayout.WEST, guiFrame, 0, SpringLayout.WEST, rootFrame);
    rootLayout.putConstraint(SpringLayout.EAST, guiFrame, 0, SpringLayout.EAST, rootFrame);


    // Create self updater panel and get it ready to show
    SelfUpdater selfUp = new SelfUpdater();
    JPanel selfUpd = selfUp.getSelfUpdatePanel();

            // get the cardlayout and add the three panels to it, then show the self-updater to begin.

    guiFrame.add(selfUpd, "UpdateUpdaterPanel");    }

/**
*   Creates a panel which has the close and minimize buttons on it.
*/
private static JPanel createCloseAndMinButtons() {
    JPanel a = new JPanel();
    SpringLayout closeLO = new SpringLayout();
    a.setLayout(closeLO);
    a.setPreferredSize(new Dimension(150,150));
    a.setOpaque(false);

    // Close Button
    JButton cButt = new JButton(new ImageIcon(Updater.CLOSE_IMAGE_PATH));
    cButt.setBorderPainted(false);
    cButt.setContentAreaFilled(false);
    cButt.setFocusPainted(false);
    cButt.setOpaque(false);
    cButt.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) { System.exit(0); }
    });
    a.add(cButt);

    // Minimize Button
    JButton mButt = new JButton(new ImageIcon(Updater.MIN_IMAGE_PATH));
    mButt.setBorderPainted(false);
    mButt.setContentAreaFilled(false);
    mButt.setFocusPainted(false);
    mButt.setOpaque(false);
    mButt.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) { rootFrame.setState(JFrame.ICONIFIED); }
    });
    a.add(mButt);

    // Constrain parts on panel
    closeLO.putConstraint(SpringLayout.EAST, cButt, 12, SpringLayout.EAST, a);
    closeLO.putConstraint(SpringLayout.NORTH, cButt, -2, SpringLayout.NORTH, a);
    closeLO.putConstraint(SpringLayout.EAST, mButt, 30, SpringLayout.WEST, cButt);
    closeLO.putConstraint(SpringLayout.NORTH, mButt, -2, SpringLayout.NORTH, a);

    // Return the jframe
    return a;

}

/**
*   Returns the guiFrame which holds the cardlayout for the changing of the panels.
*
*   @return JPanel  Returns the frame which holds the cardlayout.
*/
public JPanel getCardLayoutFrame() {
    return guiFrame; 
}   

/**
*   This will return the cardlayout for use in the controller.
*
*   @return CardLayout  Returns the cardlayout for use in the Controller.
*/
public CardLayout getCardLayout() { return cards; }


/**
*   Returns the current version of this updater as a double
*
*   @return     the version of this updater as a double.
*/
public double getUpdaterVersion() { return UPDATER_VERSION; }

/**
*   Returns a string that tells if the customer is useing windows or mac
*
*   @return     the operating system in use by the customer
*/
public static String getOSType() {
    String retString = "";
    String oST = System.getProperty("os.name").toLowerCase();
    int spacePos = oST.indexOf(" ");
    if (spacePos > 0) {
        retString = oST.substring(0, spacePos);
    }
    retString.trim();
    return retString;
}


/**
*   Returns the main root frame for display purposes in controller.java
*
*   @return JFrame  returns rootFrame.
*/
public JFrame getRootFrame() { return rootFrame; }

}

OK< Keep in mind this class really just does some utility stuff in the background and likely isn't involved in anything other than creatin the background gui and tellin the SelfUpdate card to show up. 确定<请记住,这个类实际上只是在后台执行一些实用工具,并且可能不会涉及除了背景gui之外的任何内容,并告诉SelfUpdate卡显示。

Finally here's the SelfUpdater.java file which displays the SelfUpdater panel with the progress bar in it and does all the server querying which works fine again. 最后这里是SelfUpdater.java文件,它显示SelfUpdater面板及其中的进度条,并且所有服务器查询再次正常工作。 Pay attention to the System.out.println debug statements I have in the downloadUpdate method (which is called in the controller file), as they work fine and print out in the console no problem. 请注意我在downloadUpdate方法(在控制器文件中调用)中的System.out.println调试语句,因为它们工作正常并且在控制台中打印没问题。 The selfUpdateProgress.setValue(int) and taskOutput.setText(txt) statements in that method do nothing .Also I've put a println in the doInBackground where it does setProgress(int) and that prints to the console fine but the bar doesn't update with setProgress. 该方法中的selfUpdateProgress.setValue(int)和taskOutput.setText(txt)语句不执行任何操作。此外,我在doInBackground中放置了一个println,它处理setProgress(int)并且打印到控制台很好但是栏没有'用setProgress更新。 Here it is. 这里是。

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.zip.*;

// Create and start class
public class SelfUpdater extends JPanel {

// These are the variables needed for use in this class
private JPanel selfUpdatePanel;
private JProgressBar selfUpdateProgress;
private Task task;
private JTextArea taskOutput;
private Updater util;

/**
*   Default class constructor, instantiates variables and sets up GUI.
*
*
**/
public SelfUpdater() {
    // Progress Bar
    selfUpdateProgress = new JProgressBar(0, 100);
    selfUpdateProgress.setValue(0);
    selfUpdateProgress.setStringPainted(true);
    selfUpdateProgress.setPreferredSize(new Dimension(470,29));

    // Layout
    SpringLayout selfUpdateLayout = new SpringLayout();
    SpringLayout pBarLayout = new SpringLayout();


    // Font and color setup for Task Output
    Font myFont = new Font("Serif", Font.BOLD, 16);
    Color myColor = new Color(255, 170, 0);


    // Description of progress pane
    taskOutput = new JTextArea("Checking server for updates to the updater.", 1, 39);
    taskOutput.setFont(myFont);
    taskOutput.setForeground(myColor);
    taskOutput.setEditable(false);
    taskOutput.setOpaque(false); // this is false after setting up the window.

    //extras needed for the class workings
    util = new Updater();

    // Images for progress bar setup
    JLabel pBar = new JLabel(new ImageIcon(util.PROGBACK_IMAGE_PATH));
    pBar.setOpaque(false);
    //pBar.setLayout(pBarLayout);
    //pBar.add(taskOutput);
    //pBar.add(selfUpdateProgress);

    // Main panel
    selfUpdatePanel = new JPanel();
    selfUpdatePanel.setPreferredSize(new Dimension(800, 435));
    selfUpdatePanel.setLayout(selfUpdateLayout);
    selfUpdatePanel.setOpaque(false); 
    selfUpdatePanel.add(taskOutput);
    selfUpdatePanel.add(selfUpdateProgress);
    selfUpdatePanel.add(pBar);  

    // Constrain your bits.
    // First constrain PBar to the self update panel
    selfUpdateLayout.putConstraint(SpringLayout.SOUTH, pBar, -40, SpringLayout.SOUTH, selfUpdatePanel);
    selfUpdateLayout.putConstraint(SpringLayout.WEST, pBar, 150, SpringLayout.WEST, selfUpdatePanel);
    selfUpdateLayout.putConstraint(SpringLayout.SOUTH, taskOutput, -50, SpringLayout.SOUTH, selfUpdatePanel);
    selfUpdateLayout.putConstraint(SpringLayout.WEST, taskOutput, 175, SpringLayout.WEST, selfUpdatePanel);
    selfUpdateLayout.putConstraint(SpringLayout.SOUTH, selfUpdateProgress, -84, SpringLayout.SOUTH, selfUpdatePanel);
    selfUpdateLayout.putConstraint(SpringLayout.WEST, selfUpdateProgress, 171, SpringLayout.WEST, selfUpdatePanel); }

/**
*   Will return the jpanel that contains the gui elements for the Self-Update
*
*   @return JPanel  The Self-Update gui.
*
*/
public JPanel getSelfUpdatePanel() { return selfUpdatePanel; }

/**
*   This will check the server to see if an update is available for the updater
*
*   @return int     Returns an int that will describe the answer from the server.
*                   Possible Return values:
*                   0 = Problem checking for update: Server return NULL
*                   1 = Second type of problem checking for update: Server returned empty string
*                   2 = Update available.
*                   3 = Update not needed.
*
*/
public int checkForUpdate() {
    // ask the server what version it's updater is.
    String serverUpdaterVersion = "";

    try {

        HttpConnect conn = new HttpConnect();
        String urlRequest = util.URL_CONNECT + "action=get_updater&platform=" + util.getOSType();
        serverUpdaterVersion = conn.textRequest(urlRequest, 1);

    } catch (MalformedURLException e) {
        JOptionPane.showMessageDialog(null, "We were unable to connect to the server while checking for an updater update, please check your internet connection.", "Attention!",JOptionPane.ERROR_MESSAGE);            
    } catch (IOException e) {
        JOptionPane.showMessageDialog(null, "We were unable to open the connection to the server while checking for an updater update, please check your internet connection.", "Attention!",JOptionPane.ERROR_MESSAGE);        
    }

    // check for errors and return proper int.
    if (serverUpdaterVersion == null) { // There is an error if the server returns null, return 0
        return 0;
    } else if (serverUpdaterVersion.equals("")) { // if the server returns an empty string return 1 for an error
        return 1;
    } else { // not null or empty string. check versions
        // Check version of this updater to servers version
        double sVers = Double.parseDouble(serverUpdaterVersion);

        if((double)sVers == util.getUpdaterVersion()) { // return 3 if no update needed here.
            return 3;
        } else { // otherwise return 2 so we can get the update
            return 2;
        }

    }
}

/**
*   This will download the update from the server.
*
*   @return File        The downloaded file from the server. A zip file usually.
*
*/
public void downloadUpdate() {
    // turn on wait cursor
    util.getRootFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

    // start a new task which does the download
    // Instances of javax.swing.SwingWorker are not reusuable, so
    // we create new instances as needed.
    task = new Task();
    // add a property listener to the task so it knows to update the progress meter.
    task.addPropertyChangeListener(new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {

            switch(evt.getPropertyName()) {
                case "progress":// set the progress value and the task output value.
                    selfUpdateProgress.setIndeterminate(false);
                    int prg = (Integer) evt.getNewValue();
                    selfUpdateProgress.setValue(prg);
                    taskOutput.setText("Downloading and unzipping update. Progress = " + prg + "%");
                    System.out.println("Percent progress: " + prg + "%");
                    break;
            }
        }
    });
    // execute or start the task.
    task.execute();
}

/**
*   This method will unzip the downloaded file, and start the installation.
*   Then it will close this program while the installation completes.
*
*
*/
public void unzipNewUpdater() {
    // create strings for naming the zip file to open up and where to put it.
    String zipFile = "NewUpdater.zip";
    String outputFolder = System.getenv("SystemDrive") + "\\DynastyAddons";
    // Try the unzipping and catch any errors.
    try {

        // Setup the input stream and get the entry ready to unzip.
        ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
        ZipEntry ze = zis.getNextEntry();

        // loop to open each entry and output it to the output folder and file.
        while(ze!=null) {
            // Get the name
            String entryName = ze.getName();

            // get the file to unzip
            File f = new File(outputFolder + File.separator + entryName);

            // Create folders needed to hold the unzipped stuff
            f.getParentFile().mkdirs();

            // get output stream setup to copy the file to from the zip
            FileOutputStream fos = new FileOutputStream(f);

            // get length of file to make sure we get the whole thing moved
            int len;
            byte buffer[] = new byte[1024];

            // loop thru the entry writing the whole file to the output directory
            while((len = zis.read(buffer)) > 0){
                fos.write(buffer, 0, len);
            }

            // close the output stream and get the next entry ready for the next iteration of the loop.
            fos.close();
            ze = zis.getNextEntry();

        }

        // close the entry and input stream since we're done.
        zis.closeEntry();
        zis.close();

    } catch (FileNotFoundException ex) {
        // throw error
    } catch (IOException ex) {
        // throw error
    }
}

// This private class handles the download and unzip of the new updater if needed.
class Task extends SwingWorker<Void, Void> {


    @Override
    public Void doInBackground() {
        try {
            HttpConnect conn = new HttpConnect();
            String downloadURL = util.URL_CONNECT + "action=download_updater&platform=" + util.getOSType();
            conn.downloadFile(downloadURL);

            InputStream inputStream = conn.getInputStream();

            FileOutputStream outputStream = new FileOutputStream(System.getenv("SystemDrive") + "\\DynastyAddons\\NewUpdater.zip");

            byte[] buffer = new byte[util.BUFFER_SIZE];
            int bytesRead = -1;
            long totalBytesRead = 0;
            int percentCompleted = 0;
            long fileSize = conn.getContentLength();

            taskOutput.setText("Downloading Newest Updater.");
            //setProgress(0);

            while ((bytesRead = inputStream.read(buffer)) != -1) {

                outputStream.write(buffer, 0, bytesRead);
                totalBytesRead += bytesRead;
                percentCompleted = (int) (totalBytesRead * 100 / fileSize);
                setProgress(percentCompleted);

            }

            outputStream.close();
            conn.disconnect();

        } catch (IOException ex) {
            JOptionPane.showMessageDialog(util.getRootFrame(), "Error downloading Updater file. Please send this entire error to support@dynastyaddons.com. \n Error: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            setProgress(0);
        }
        return null;
    }

    @Override
    public void done() {
        // Create msg window saying update downloaded.
        JOptionPane.showMessageDialog(util.getRootFrame(), "The new updater has been downloaded. \nClick OK to close this updater and start the installation of the new version.", "Attention", JOptionPane.PLAIN_MESSAGE);

        // Unzip the updater
        unzipNewUpdater();

        // Tell the cursor we're not busy anymore
        setProgress(100);
        selfUpdateProgress.setValue(100);
        taskOutput.setText("Done Downloading New Updater. Installing...");
        util.getRootFrame().setCursor(null);

        // Create command used to open the udpater installer.
        String cmd = "cmd /c " + System.getenv("SystemDrive") + "\\DynastyAddons\\InstallDynastyAddonsUpdater.exe";

        // Here is where we run the exe that will install the new updater.
        try{
            Runtime.getRuntime().exec(cmd);
        }catch (FileNotFoundException ex){
            // handle this error
        }catch (IOException ex) {
            // handle this error
        }

        // Now close this updater so the new one can install.
        System.exit(0);
    }
}

}

I'm hopin it'll all compile properly if you need to see it working. 如果你需要看到它正常工作的话,我就可以正常编译。 If not let me know and i'll update stuff to make it work on a compile. 如果没有让我知道,我会更新东西,使其在编译上工作。 So I've tried a number of things, making the SelfUpdater class implement PropertyChangeListener and implementing PropertyChange(event), I've tried feeding the JProgressBar to a constructor in the Task class. 所以我尝试了很多东西,使SelfUpdater类实现PropertyChangeListener并实现PropertyChange(事件),我尝试将JProgressBar提供给Task类中的构造函数。 I've tried outputting an Integer in the SwingWorker and using Publish and Process to update the taskOutput and JProgressBar, I've tried re-writing the whole damn class to fix up the code and make it eaiser to pick out issues. 我已经尝试在SwingWorker中输出一个Integer并使用Publish and Process来更新taskOutput和JProgressBar,我已经尝试重写整个该死的类来修复代码并让它更容易找出问题。 I've done tests using the tutorials and some of my code to make it work (they worked great) but every time I come back to my updater code here, the darn progressbar wont update. 我已经使用教程和一些代码完成了测试以使其工作(它们工作得很好)但每次我回到我的更新程序代码时,darn进度条都不会更新。 I'm really prayin someone can give me a bit of insight on this problem so I can wrap up this project and start on something new! 我真的在祈祷有人可以给我一些关于这个问题的见解,所以我可以结束这个项目并开始新的事情! This is the very last thing I have to fix (unless there's problems on the Mac) and I'm done it and can go back to testing and getting it distributed to our customers. 这是我必须解决的最后一件事(除非Mac上有问题),我已经完成了它,可以回到测试并将其分发给我们的客户。

Feel more than free to comment on any part of the code as well (anything I maybe did stupid or something) I'm always lookin for critisim on my code especially if I'm not doing something according to good design and.. ugh brain froze forgot the word here. 感觉不仅仅是免费评论代码的任何部分(任何我可能做过的愚蠢或其他事情)我总是在寻找对我的代码的批评,特别是如果我没有按照良好的设计做一些事情......呃大脑冻结忘了这里的字。 and definitely if more info is needed I can easily just paste in all the code in the 7 classes that make up this updater. 并且如果需要更多信息,我可以轻松地粘贴构成此更新程序的7个类中的所有代码。

It all compiles, and works fine, except this jprogressbar wont display the progress, even tho I can get it to pring out in the console. 这一切都编译,并且工作正常,除了这个jprogressbar不会显示进度,即使我可以让它在控制台中进行调整。 Thank you in advance, sorry for the mini-novel here, Haven't had to ask a question yet, and have been able to figure everything eout from other peoples questions and answers, just stumped now and ready to be done with this! 提前谢谢你,对这里的迷你小说感到抱歉,还没有提出问题,并且已经能够从其他人的问题和答案中找到所有的东西,现在只是难倒,准备好了! :D :d

I apologize in advance if I've screwed something up in the post here, remember it's my first post and while I've read hundreds of them, I'm sure my noobness has messed something up so feel free to castigate me for my mistakes so I can fix them. 如果我在帖子中搞砸了一些内容,我会提前道歉,记得这是我的第一篇文章,虽然我已经阅读了数百篇文章,但我确信我的小说搞砸了,所以请随意谴责我的错误所以我可以解决它们。 :) :)

EDIT Updated the selfUpdater.java to reflect using of only one spring layout. 编辑更新了selfUpdater.java以反映仅使用一个弹簧布局。

What you have there are layout problems, not anything SwingWorker related. 你有什么布局问题,而不是SwingWorker相关的任何东西。 The JProgressBar is updating nicely, you just can't see it. JProgressBar正在更新,你只是看不到它。

Check your main method. 检查您的主要方法。 You are creating two instances of SelfUpdater, adding one to your GUI and updating the other. 您正在创建两个SelfUpdater实例,在GUI中添加一个并更新另一个。

public static void main(String[] args) {
    util = new Updater(); // <-- don't do this, it calls Swing code from a thread that is not EDT
    // Schedule a job for the event dispatch thread.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {

            // setup a new GUI
            util.createGUI(); // <-- creates an instance of SelfUpdater and adds it to GUI
            JFrame rFrame = util.getRootFrame();                
            JPanel gFrame = util.getCardLayoutFrame();
            CardLayout cards = (CardLayout) gFrame.getLayout();
            cards.show(gFrame, "UpdateUpdaterPanel");

            rFrame.pack();
            rFrame.setLocationRelativeTo(null);
            rFrame.setVisible(true);

            SelfUpdater selfUp = new SelfUpdater(); // <-- creates another instance             
            int needUpdate = selfUp.checkForUpdate();                                       
            if (needUpdate == 2) {// Update available for download. Download it.
                selfUp.downloadUpdate();

            } 


        }
    });

}

You can't expect components to be shown, if they are not added anywhere. 如果组件未添加到任何位置,则无法显示组件。 :) :)

Have you tried to put the updating code of the jProgressBar in an extra thread? 您是否尝试将jProgressBar的更新代码放在一个额外的线程中? http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html

I had a similar problem once, the progressbar didn't progress and when it was all done, the progressbar showed 100%. 我有一个类似的问题,进度条没有进展,当它完成时,进度条显示100%。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM