【问题标题】:JProgressBar not updating from SwingWorker, while debugs work fineJProgressBar 没有从 SwingWorker 更新,而调试工作正常
【发布时间】:2014-08-08 08:13:24
【问题描述】:

这已经把我逼疯了 2 天了。我似乎无法正确更新 JProgressBar,我不知道为什么。我已经阅读了并发和 SwingWorker 教程,我已经在我的程序之外进行了测试,并且能够使用简单的代码让它正常工作。我理解这些概念,只是不明白为什么它不工作,因为代码已经以许多不同的方式重新编写,但我仍然无法使其工作。我将尽可能多地使用我的程序中的代码发布一个 SSCE,并在这里尽可能地解释事情。

基本上我有一个自动更新程序/安装程序来更新和/或安装魔兽世界插件到我们客户的计算机。 “更新程序”所做的第一件事是检查服务器以查看其版本是否与服务器上更新程序安装程序的版本相同。这很有效!事实上,除了这个问题,整个更新程序都很好用。如果更新程序发现服务器的版本号与更新程序不同,它会从服务器下载安装程序(以 zip 格式),解压缩,从 zip 中包含的 exe 开始安装并关闭当前打开的更新程序,以便安装可以正常完成。

所以我在卡片上有一个用于自我更新程序的进度条(使用 cardLayout 显示更新程序的三个不同卡片,SelfUpdate、Login 和 AddonList)。以及 JProgressBar 下方的 JTextArea,这就是特定 SelfUpdate 卡上显示的全部内容。它向服务器查询服务器上的版本号,并将该版本与当前安装的更新程序上的版本号进行比较。如果版本相同,它会更改登录卡并移动到程序的下一部分,到目前为止效果很好,如果版本不同,它会向服务器发送查询,服务器将 zip 文件发送回用于处理的更新程序。

这是它不起作用的地方。 zip 大小合适,当然我想显示下载的进度。 zip 文件下载工作正常(它在 SwingWorker doInBackground() 方法中运行),然后更新程序将 installer.exe 文件解压缩到客户系统驱动器上的文件夹中,使用运行时启动并启动 installer.exe,它会弹出安装程序屏幕,然后使用 System.exit(0) 关闭当前更新程序。同样,所有这些都有效,但 JProgressBar 本身不会更新。它在整个过程中为 0%。此外,taskOutput JTextArea 也没有更新,但主要问题是进度条没有更新。我可以忍受这个问题得到修复并且 JTextArea 没有更新。 (也尝试用 JLabel 代替 textarea,但没有任何乐趣)

所以我知道我做错了什么,但我无法想象是什么。这是魔术发生的地方。 :) 如果我在这里进行解释,请原谅我。

所以 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 下一个文件是 Updater 类。把代码放在这里,希望能编译并显示我需要把这个类放在那里的问题,否则我在 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

最后是 SelfUpdater.java 文件,它显示了带有进度条的 SelfUpdater 面板,并执行了所有服务器查询,这又可以正常工作了。注意我在 downloadUpdate 方法(在控制器文件中调用)中的 System.out.println 调试语句,因为它们工作正常并且在控制台中打印出来没问题。该方法中的 selfUpdateProgress.setValue(int) 和 taskOutput.setText(txt) 语句什么都不做。我还在 doInBackground 中放了一个 println ,它确实 setProgress(int) 并且可以很好地打印到控制台,但是栏没有t 使用 setProgress 进行更新。这里是。

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);
    }
}

}

如果您需要查看它的工作情况,我希望它能够正确编译。如果不让我知道,我会更新东西以使其在编译时工作。所以我尝试了很多事情,使 SelfUpdater 类实现 PropertyChangeListener 并实现 PropertyChange(event),我尝试将 JProgressBar 提供给 Task 类中的构造函数。我尝试在 SwingWorker 中输出一个 Integer 并使用 Publish 和 Process 更新 taskOutput 和 JProgressBar,我尝试重写整个该死的类来修复代码并使其更容易找出问题。我已经使用教程和我的一些代码进行了测试以使其工作(它们工作得很好)但每次我回到我的更新程序代码时,该死的进度条都不会更新。我真的很祈祷有人能给我一些关于这个问题的见解,这样我就可以结束这个项目并开始一些新的事情!这是我必须修复的最后一件事(除非 Mac 上有问题),我已经完成了,可以返回测试并将其分发给我们的客户。

您也可以随意评论代码的任何部分(任何我可能做的愚蠢的事情或其他事情) . 呃大脑僵住了,忘记了这里的词。当然,如果需要更多信息,我可以轻松地将所有代码粘贴到构成此更新程序的 7 个类中。

这一切都可以编译,并且工作正常,除了这个 jprogressbar 不会显示进度,即使我可以让它在控制台中打印出来。提前谢谢你,抱歉这里的迷你小说,还没有问过问题,已经能够从其他人的问题和答案中弄清楚一切,现在只是难住了,准备好了! :D

如果我在这里的帖子中搞砸了,我提前道歉,请记住这是我的第一篇文章,虽然我已经阅读了数百篇,但我确信我的菜鸟已经搞砸了,所以请随时谴责我因为我的错误,所以我可以修复它们。 :)

编辑更新了 selfUpdater.java 以反映仅使用一种弹簧布局。

【问题讨论】:

  • Runtime.getRuntime().exec(cmd);在完成???,嗯,example,并使用get() in done
  • 如果我没看错,done() 方法中的 get() 将返回下载的文件。我是否还需要执行某种 Runtime.exec 来运行从下载的 zip 中出来的 exe?
  • get() 返回结果或异常(然后你丢失了结果)
  • 是的,我明白了。但是我没有在 done() 方法中对来自 zip 的 exe 文件执行 Runtime.exec 有什么问题。
  • 以 done() 为 end_station,一切都应该在之前执行和/或准备其他用途

标签: java swing jtextarea swingworker jprogressbar


【解决方案1】:

你有什么布局问题,与SwingWorker 无关。 JProgressBar 更新得很好,你只是看不到它。

检查您的主要方法。您正在创建两个 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();

            } 


        }
    });

}

如果组件没有添加到任何地方,您就不能期望它们会被显示。 :)

【讨论】:

  • 我不知道我是否完全遵循。我在这里创建面板,并将其添加到更新程序中的主面板,这是一个 CardLayout。我编译了这个,虽然我没有错误,但它也根本没有显示进度条。看起来您清除了进度条的布局以及进度条所在的主 jpanel。所以你是说我应该更改进度条显示的布局和发送到更新程序以放置在 CardLayout 上的主面板?或者只是忘记 pbar 图像的布局,只是将进度条添加到发送到更新程序的主面板?
  • 好的,我试过你说的。我将 JProgressBar 发送到更新程序文件,该文件将其附加到具有边框布局的普通 JPanel 上。然后该面板被用作卡片布局中的 UpdaterUpdatePanel。进度条占据了整个空间(这不是一个大蓝绿色,只是作为测试),它像往常一样通过并在控制台中打印出进度,这次进度条也没有发生任何事情。它保持在 0% 并且从未改变过。我把它改回来了,但这次剪掉了一个弹簧布局,只在主面板上发送了一个。
  • 您,先生,是正确的,我误导了您。我将编辑我的答案。
  • 嘘!非常感谢 Predi,我已经接受了您的回答并投票赞成。我非常感谢您的帮助,现在我将 selfupdater 对象从 Updater 传递给控制器​​,而不是创建它的另一个实例,它的工作就像一个魅力!我应该用正确的代码更新问题还是只接受你的回答就可以了?
【解决方案2】:

您是否尝试将 jProgressBar 的更新代码放在额外的线程中? http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html

我曾经遇到过类似的问题,进度条没有进度,完成后进度条显示100%。

【讨论】:

  • 我有,事情是实际的方法正在工作,setProgress 是“似乎”不起作用的部分。从 println 的情况来看,我在那里进行了设置,它们应该都可以正常工作,所以我认为 Predi 的答案是正确的,只需要理解它。除此之外,它根本不会更新进度条,它始终保持在 0 %。
  • 这正是SwingWorker 正在做的事情,在单独的线程中运行,只有内置的线程安全功能......
猜你喜欢
  • 2020-12-16
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
  • 2012-07-20
  • 2021-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多