本文介绍了SwingWorker 进度条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用进度条来准确反映我的 SwingWorker.但我真的不知道该怎么做.我让栏只做一个静态动画,直到操作完成,但我想要一个真正的活动栏.

I am trying to get a progress bar to accurately reflect my SwingWorker. But I really can't figure out how to do it. I got the bar to just do a static animation until the operation has completed but I want a real active bar.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package frglauncher;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

/**
 *
 * @author KYLE-LAPTOP
 */
class DownloadWorker extends SwingWorker<String, Object> {

    private String game;
    private JProgressBar bar;
    private JLabel label;

    public DownloadWorker(JProgressBar bar, String game, JLabel label) {
        this.game = game;
        this.bar = bar;
        this.label = label;
    }

    @Override
    public String doInBackground() {

        // Download here
        label.setText("test");
        try {
            // ProgressBar/Install
            System.out.println("FILELOCATION:
----------");
            String URL_LOCATION = "http://www.futureretrogaming.tk/gamefiles/ProfessorPhys.jar";
            String LOCAL_FILE = ("\" + game + "\");
            File localfile = new File(LOCAL_FILE);
            if (localfile.exists()) {
                System.out.println("Directory exists!");
            }
            else {
                System.out.println("Directory doesn't exist! Creating...");
                localfile.mkdir();
                if (localfile.exists()) {
                    System.out.println("Directory created!");
                }
            }
            System.out.println("LOCALFILE:
-------");
            System.out.println(LOCAL_FILE);
            URL website = new URL(URL_LOCATION);
            ReadableByteChannel rbc = Channels.newChannel(website.openStream());
            FileOutputStream fos = new FileOutputStream(LOCAL_FILE + "\ProfessorPhys.jar\");
            fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
            System.out.println("--------
Done Downloading
---------");

            RandomAccessFile randomAccessFile = null;

            File file = new File(LOCAL_FILE + "ProfessorPhys.jar\");
            JarFile jar = new JarFile(file);
            Enumeration enum1 = jar.entries();
            while (enum1.hasMoreElements()) {
                JarEntry file1 = (JarEntry) enum1.nextElement();
                System.out.println("Directory to extract: " + LOCAL_FILE);
                System.out.println("
" + file1.getName() + "
");
                File f = new File(file1.getName());
                if (file1.isDirectory()) { // If it's a directory, create it
                    f.mkdir();
                    continue;
                }
                try (InputStream is1 = jar.getInputStream(file1)) {
                    FileOutputStream fos1 = new FileOutputStream(f);
                    while (is1.available() > 0) {  // Write contents of 'is' to 'fos'
                        fos1.write(is1.read());
                    }
                    fos1.close();
                }
            }
        }
        catch (FileNotFoundException ex) {
            Logger.getLogger(DownloadWorker.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (MalformedURLException ex) {
            Logger.getLogger(DownloadWorker.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (IOException ex) {
            Logger.getLogger(DownloadWorker.class.getName()).log(Level.SEVERE, null, ex);
        }
        return "done";
    }

    @Override
    protected void done() {

        // Done
        label.setText("Download of " + game + "is done.");
        System.exit(0);
    }
}

推荐答案

几件事:

  1. SwingWorker 有四个规则要遵循.可以参考这个图:.
  1. There are four rules to follow with SwingWorker. You can refer to this diagram: .

所以,这段代码:

@Override
public String doInBackground() {
    //download here
    label.setText("test");

违反了该规则.您的 label.setText() 应该移到构造函数中.

violates that rule. Your label.setText() should be moved to the constructor.

  1. 要将更新"发送到 Swing 组件(如进度条),您需要使用 process() 方法,您可以从内部使用 publish() 调用该方法你的 doInBackground().您的 second SwingWorker 参数反映了您要传递的值的类型.我附上了两个 SSCCE.一个传递一个 Integerprocess() 方法,另一个传递一个 String.应该让您了解正在发生的事情.
  1. To send "updates" to Swing components (like your progress bar) you want to use the process() method, which you invoke using publish() from inside your doInBackground(). Your second SwingWorker parameter reflects the type of value you want to pass. I've attached two SSCCEs. One passes an Integer to the process() method, the other passes a String. Should give you an idea of what's going on.

使用 Integer 的 SSCCE:

SSCCE using Integer:

import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

/**
 *
 * @author Ryan
 */
public class Test {

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

    public static void go() {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        JLabel label = new JLabel("Loading...");
        JProgressBar jpb = new JProgressBar();
        jpb.setIndeterminate(false);
        int max = 1000;
        jpb.setMaximum(max);
        panel.add(label);
        panel.add(jpb);
        frame.add(panel);
        frame.pack();
        frame.setSize(200,90);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        new Task_IntegerUpdate(jpb, max, label).execute();

    }

    static class Task_IntegerUpdate extends SwingWorker<Void, Integer> {

        JProgressBar jpb;
        int max;
        JLabel label;
        public Task_IntegerUpdate(JProgressBar jpb, int max, JLabel label) {
            this.jpb = jpb;
            this.max = max;
            this.label = label;
        }

        @Override
        protected void process(List<Integer> chunks) {
            int i = chunks.get(chunks.size()-1);
            jpb.setValue(i); // The last value in this array is all we care about.
            System.out.println(i);
            label.setText("Loading " + i + " of " + max);
        }

        @Override
        protected Void doInBackground() throws Exception {
            for(int i = 0; i < max; i++) {
                Thread.sleep(10); // Illustrating long-running code.
                publish(i);
            }
            return null;
        }

        @Override
        protected void done() {
            try {
                get();
                JOptionPane.showMessageDialog(jpb.getParent(), "Success", "Success", JOptionPane.INFORMATION_MESSAGE);
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

使用 String 的 SSCCE:

SSCCE using String:

import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

/**
 *
 * @author Ryan
 */
public class Test2 {

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

    public static void go() {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        JLabel label = new JLabel("Loading...");
        JProgressBar jpb = new JProgressBar();
        jpb.setIndeterminate(true);
        panel.add(label);
        panel.add(jpb);
        frame.add(panel);
        frame.pack();
        frame.setSize(200,90);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        new Task_StringUpdate(label).execute();
    }

    static class Task_StringUpdate extends SwingWorker<Void, String> {

        JLabel jlabel;
        public Task_StringUpdate(JLabel jlabel) {
            this.jlabel = jlabel;
        }

        @Override
        protected void process(List<String> chunks) {
            jlabel.setText(chunks.get(chunks.size()-1)); // The last value in this array is all we care about.
            System.out.println(chunks.get(chunks.size()-1));
        }

        @Override
        protected Void doInBackground() throws Exception {

            publish("Loading Step 1...");
            Thread.sleep(1000);
            publish("Loading Step 2...");
            Thread.sleep(1000);
            publish("Loading Step 3...");
            Thread.sleep(1000);
            publish("Loading Step 4...");
            Thread.sleep(1000);

            return null;
        }

        @Override
        protected void done() {
            try {
                get();
                JOptionPane.showMessageDialog(jlabel.getParent(), "Success", "Success", JOptionPane.INFORMATION_MESSAGE);
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

这篇关于SwingWorker 进度条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 23:41