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

标签 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 个答案的建议。

它现在都实现了报告错误的覆盖方法,但初始化数组for ..much output 并在进度条中显示进度。

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

最佳答案

很可能在 doInBackground 方法中抛出了一个 Exception,这显然会导致它退出。

在您的done 方法中,即使它没有返回任何内容,您也应该调用get 以确保在执行doInBackground 期间没有任何错误> 方法

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

关于java - SwingWorker(不工作),循环在第一次迭代后结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19671086/

相关文章:

java - 存储二维数据的数据结构的想法?

java - 我如何改变这个贪心算法来预测最全面的分数?

java - 如何从图像文件中读取文本

Laravel Blade 模板 - 如何在 foreach 循环中使用增量变量

java - Java 中的多重继承。通过扩展命令分配优先级

java - 是什么导致 Tomcat 7 中出现 NotSerializableException?

java - JScrollPane 的问题——尝试在模型更改时更新它

java - JPopupMenu 菜单不出现

r - 使用循环(或向量化)通过向量中的多个元素对列表进行子集化

python - 将for循环输出写入python中的文本文件