SwingWorker(不工作),循环在第一次迭代后结束

时间:2013-10-29 23:29:31

标签: java swing loops swingworker

我希望在此代码中看到来自循环的接近200,000行(196,608)的输出。它只打印一行。谁能发现错误?

import java.awt.*;
import java.util.*;
import javax.swing.*;

class SwingWorkerUnicodeTest {

    private String[] fontNameArray;
    private JLabel output = new JLabel("Processing..");
    private JProgressBar progressBar = new JProgressBar();

    class CodePointDetailWorker extends SwingWorker<Object, Object> {

        private ArrayList<Character.UnicodeBlock> unicodeBlockNames;
        private ArrayList<Character.UnicodeScript> unicodeScripts;
        private int[] glyphCount = new int[fontNameArray.length];

        public CodePointDetailWorker() {
            progressBar.setVisible(true);
            Arrays.fill(glyphCount, 0);
        }

        @Override
        protected Void doInBackground() throws Exception {
            // Check for for the first 3 planes.  The next 11 are unassigned
            int pS = 3*65536;
            for (int kk = 0; kk < pS; kk++) {
                System.out.println("doInBackground " + kk + " " + pS);
                doForEveryCodePoint(kk);
            }
            return null;
        }

        @Override
        public void done() {
            output.setText("Done!");
        }

        private final void doForEveryCodePoint(final int codePoint) {
            Character.UnicodeBlock block = Character.UnicodeBlock.of(codePoint);
            if (block != null && !unicodeBlockNames.contains(block)) {
                unicodeBlockNames.add(block);
            }

            Character.UnicodeScript us = Character.UnicodeScript.of(codePoint);
            if (us == null || us.toString() == null) {
            } else {
                if (!unicodeScripts.contains(us)) {
                    unicodeScripts.add(us);
                }
            }

            // fonts - test for points in all 6 defined blocks.
            for (int ii = 0; ii < fontNameArray.length; ii++) {
                Font f = new Font(fontNameArray[ii], Font.PLAIN, 16);
                if (f.canDisplay(codePoint)) {
                    glyphCount[ii]++;
                }
            }
        }
    }

    public SwingWorkerUnicodeTest() {
        GraphicsEnvironment ge =
                GraphicsEnvironment.getLocalGraphicsEnvironment();
        fontNameArray = ge.getAvailableFontFamilyNames();
        JPanel gui = new JPanel(new BorderLayout());

        gui.add(progressBar, BorderLayout.CENTER);
        gui.add(output, BorderLayout.PAGE_END);

        CodePointDetailWorker cpdw = new CodePointDetailWorker();
        cpdw.execute();

        JOptionPane.showMessageDialog(null, gui);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                new SwingWorkerUnicodeTest();
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}

修改

固定代码,基于前2个答案的建议。

它现在都实现了报告错误的重写方法,但是初始化数组以获取..much输出并显示进度条中的进度。

import java.awt.*;
import java.util.*;
import javax.swing.*;

class SwingWorkerUnicodeTest {

    private JLabel output = new JLabel("Processing..");
    // Check for for the first 3 planes.  The next 11 are unassigned
    int pS = 3 * 65536;
    private JProgressBar progressBar = new JProgressBar(0, pS);

    class CodePointDetailWorker extends SwingWorker<Object, Object> {

        private ArrayList<Character.UnicodeBlock> unicodeBlockNames;
        private ArrayList<Character.UnicodeScript> unicodeScripts;
        private int[] glyphCount;
        private String[] fontNameArray;

        public CodePointDetailWorker(String[] fontNameArray) {
            this.fontNameArray = fontNameArray;
            progressBar.setVisible(true);
            glyphCount = new int[fontNameArray.length];
            Arrays.fill(glyphCount, 0);
            unicodeBlockNames = new ArrayList<Character.UnicodeBlock>();
            unicodeScripts = new ArrayList<Character.UnicodeScript>();
        }

        @Override
        protected Void doInBackground() throws Exception {
            for (int kk = 0; kk < pS; kk++) {
                if (kk % 500 == 0) {
                    progressBar.setValue(kk);
                }
                doForEveryCodePoint(kk);
            }
            progressBar.setValue(0);
            return null;
        }

        @Override
        public void done() {
            try {
                get();
                output.setText("Done!");
            } catch (Exception ex) {
                ex.printStackTrace();
                output.setText("Bad: " + ex.getMessage());
            }
        }

        private final void doForEveryCodePoint(final int codePoint) {
            Character.UnicodeBlock block = Character.UnicodeBlock.of(codePoint);
            if (block != null && !unicodeBlockNames.contains(block)) {
                unicodeBlockNames.add(block);
            }

            Character.UnicodeScript us = Character.UnicodeScript.of(codePoint);
            if (us == null || us.toString() == null) {
            } else {
                if (!unicodeScripts.contains(us)) {
                    unicodeScripts.add(us);
                }
            }

            // fonts - test for points in all 6 defined blocks.
            for (int ii = 0; ii < fontNameArray.length; ii++) {
                Font f = new Font(fontNameArray[ii], Font.PLAIN, 16);
                if (f.canDisplay(codePoint)) {
                    glyphCount[ii]++;
                }
            }
        }
    }

    public SwingWorkerUnicodeTest(String[] names) {
        JPanel gui = new JPanel(new BorderLayout());

        gui.add(progressBar, BorderLayout.CENTER);
        gui.add(output, BorderLayout.PAGE_END);

        CodePointDetailWorker cpdw = new CodePointDetailWorker(names);
        cpdw.execute();

        JOptionPane.showMessageDialog(null, gui);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {

                GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                String[] fontNames = ge.getAvailableFontFamilyNames();
                new SwingWorkerUnicodeTest(fontNames);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}

2 个答案:

答案 0 :(得分:3)

Exception方法中可能会抛出doInBackground,这显然会导致它退出。

done方法中,即使它不返回任何内容,也应调用get以确保在执行doInBackground方法时没有出错

@Override
public void done() {
    try {
        get();
        output.setText("Done!");
    } catch (InterruptedException | ExecutionException ex) {
        ex.printStackTrace();
        output.setText("Bad: " + ex.getMessage());
    }
}

答案 1 :(得分:3)

您尚未初始化ArrayLists

public CodePointDetailWorker() {
    unicodeBlockNames = new ArrayList<>();
    unicodeScripts = new ArrayList<>();
    ...
}

所以遇到此语句后,NPESwingWorker无声地抛出<{1}}

if (block != null && !unicodeBlockNames.contains(block)) {
                       ^---null