SwingWorker done()方法使用get()抛出nullpointerexception



我写了一个swing worker,负责计算一些文本统计信息,然后用结果更新EDT中的GUI元素。经过一些实验,我发现应该只在done()方法中操作GUI,而不是在doInBackground()方法中。为了实现这一点,我将工人改造为具有返回值String[],我应该能够用get()获取该值。除了一些publish()方法之外,您可能会发现来自doInBackground()方法的一些错误调用直接操纵GUI,如果您认为我的问题可能是由此引起的,请告诉我。

package my.worker;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import my.tools.CountKeywords;
import my.tools.FilterStopwords;
import my.tools.KeywordSuggestion;
import my.tools.RelevanceRanking;
public class ProcessDatabaseWorker extends SwingWorker<String[], String> {
    private final JLabel debugJLabel;
    private final JLabel infoJLabel;
    private final JLabel warnJLabel;
    private final JLabel errorJLabel;
    private final JLabel infoboxJLabel;
    private final String databaseString;
    private final JProgressBar jProgressBar;
    private final JComboBox keywordJComboBox;
    private int percent;
    private int index;
public ProcessDatabaseWorker(JProgressBar jProgressBar, String databaseString,
            JLabel debugJLabel, JLabel errorJLabel, JLabel warnJLabel,
            JLabel infoJLabel, JLabel infoboxJLabel,
            JComboBox keywordJComboBox) {
        this.percent = 1;
        this.jProgressBar = jProgressBar;
        this.databaseString = databaseString;
        this.debugJLabel = debugJLabel;
        this.errorJLabel = errorJLabel;
        this.infoJLabel = infoJLabel;
        this.warnJLabel = warnJLabel;
        this.infoboxJLabel = infoboxJLabel;
        this.keywordJComboBox = keywordJComboBox;
    }
    @Override
    protected String[] doInBackground() throws Exception {
        FilterStopwords fs = new FilterStopwords();
        CountKeywords ck = new CountKeywords();
        RelevanceRanking rr = new RelevanceRanking();
        HashMap<String, Integer> nKeywords = new HashMap();
        Map<String, TreeSet<Map.Entry<String, Double>>> keywordsPerDocument = new HashMap();
        String replace = databaseString.toLowerCase();
        String splitter = ("\n");
        String[] documentLines = replace.split(splitter);
        int N = documentLines.length;
        publish("Stopworte werden gefiltert...", "10");
        String[] completeFilteredText = fs.filterStopwords(replace);
        publish("Keywords werden gezählt...", "20");
        HashMap<String, Integer> completeKeywords = ck.countKeywords(completeFilteredText);
        index = 0;
        percent = 1;
        final double oneLinePercent = N / 100;
        final double oneKeywordPercent = completeKeywords.size() / 100;
        completeKeywords.forEach((String key, Integer value) -> {
            int n = 0;
            key = String.valueOf(key).trim();
            for (String line : documentLines) {
                String[] lineWords = line.split(" ");
                for (String word : lineWords) {
                    word = word.trim();
                    if (word.equals(key)) {
                        n++;
                        nKeywords.put(key, n);
                    }
                }
            }
            index++;
            if (index == oneKeywordPercent) {
                percent++;
                publish("Zählung...", String.valueOf(percent));
                index = 0;
            }
        });
        publish("Keywords werden geranked...", "40");
        index = 0;
        percent = 1;
        for (String documentLine : documentLines) {
            TreeSet<Map.Entry<String, Double>> rankedKeywords;
            String[] lineFilteredWords = fs.filterStopwords(documentLine);
            HashMap<String, Integer> keywords = ck.countKeywords(lineFilteredWords);
            rankedKeywords = rr.rankKeywords(keywords, lineFilteredWords, N, nKeywords);
            keywordsPerDocument.put(documentLine, rankedKeywords);
            index++;
            if (index == oneLinePercent) {
                percent++;
                publish("Ranking...", String.valueOf(percent));
                index = 0;
            }
        }
        publish("Keyword-Vorschläge werden generiert...", "70");
        KeywordSuggestion ks = new KeywordSuggestion();
        TreeSet<Map.Entry<String, Double>> keywordSuggestionsTree = ks.keywordSuggestion(keywordsPerDocument);
        String[] keywordSuggestionsArray = new String[keywordSuggestionsTree.size()];
        index = 0;
        int index2 = 0;
        double onePercent = keywordSuggestionsTree.size() / 100;
        percent = 1;
        publish("Keyword-Vorschläge werden generiert...", "75");
        for (Map.Entry<String, Double> entry : keywordSuggestionsTree) {
            double round = round(entry.getValue(), 2);
            keywordSuggestionsArray[index2] = round + " - " + entry.getKey();
            index2++;
            index++;
            if (index == onePercent) {
                percent++;
                publish("Keywords...", String.valueOf(percent));
                index = 0;
            }
        }
        keywordJComboBox.removeAllItems();
        for (String entry : keywordSuggestionsArray) {
            publish("Keyword-Vorschläge werden befüllt...", "80");
        }

这是返回get()所需值的行。。。

        return keywordSuggestionsArray;
    }
    public static double round(double value, int places) {
        if (places < 0) {
            throw new IllegalArgumentException();
        }
        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(places, RoundingMode.HALF_UP);
        return bd.doubleValue();
    }
    @Override
    public void process(List<String> s) {
        infoboxJLabel.setText(s.get(0));
        jProgressBar.setValue(Integer.valueOf(s.get(1)));
    }
    @Override
    protected void done() {
        try {

这是引发NullPointerException的地方。。。

            String[] get = get();
            for (String entry : get) {
                keywordJComboBox.addItem(entry);
            }
        } catch (InterruptedException | ExecutionException ex) {
            Logger.getLogger(ProcessDatabaseWorker.class.getName()).log(Level.SEVERE, null, ex);
        }
        publish("Verarbeitung der Daten abgeschlossen!", "100");
    }
}

有关详细信息,请参阅完整的跟踪:

Apr 14, 2016 10:40:06 AM my.worker.ProcessDatabaseWorker done
SCHWERWIEGEND: null
java.util.concurrent.ExecutionException: java.lang.NullPointerException
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at javax.swing.SwingWorker.get(SwingWorker.java:602)
    at my.worker.ProcessDatabaseWorker.done(ProcessDatabaseWorker.java:197)
    at javax.swing.SwingWorker$5.run(SwingWorker.java:737)
    at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:832)
    at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112)
    at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:842)
    at javax.swing.Timer.fireActionPerformed(Timer.java:313)
    at javax.swing.Timer$DoPostEvent.run(Timer.java:245)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.NullPointerException
    at my.logfileanalyzer.LogFileAnalyzerGUI.keywordJComboBoxItemStateChanged(LogFileAnalyzerGUI.java:830)
    at my.logfileanalyzer.LogFileAnalyzerGUI.access$2400(LogFileAnalyzerGUI.java:48)
    at my.logfileanalyzer.LogFileAnalyzerGUI$15.itemStateChanged(LogFileAnalyzerGUI.java:329)
    at javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1223)
    at javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1271)
    at javax.swing.JComboBox.contentsChanged(JComboBox.java:1330)
    at javax.swing.JComboBox.intervalRemoved(JComboBox.java:1352)
    at javax.swing.AbstractListModel.fireIntervalRemoved(AbstractListModel.java:179)
    at javax.swing.DefaultComboBoxModel.removeAllElements(DefaultComboBoxModel.java:174)
    at javax.swing.JComboBox.removeAllItems(JComboBox.java:771)
    at my.worker.ProcessDatabaseWorker.doInBackground(ProcessDatabaseWorker.java:165)
    at my.worker.ProcessDatabaseWorker.doInBackground(ProcessDatabaseWorker.java:43)
    at javax.swing.SwingWorker$1.call(SwingWorker.java:295)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at javax.swing.SwingWorker.run(SwingWorker.java:334)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

现在,我的问题是:我使用的工人的哪一部分不正确,或者我的程序逻辑哪里出了问题?正如你所看到的,我对使用swing worker和线程进行编程还很陌生,所以我相信有一个简单的解决方案可以解决由于缺乏经验而导致的简单错误。

此外,让我知道,如果我的程序的任何其他部分需要,以便更好地描绘正在发生的事情。

编辑:错误正是用户Moh Aw描述的地方-编辑我的代码如下修复它:

private void keywordJComboBoxItemStateChanged(java.awt.event.ItemEvent evt) {                                                  
        if (keywordJComboBox.getItemCount() != 0){
            if (!((String) keywordJComboBox.getSelectedItem()).equals("")) {
                String selected = (String) keywordJComboBox.getSelectedItem();
                String[] blubb = selected.split(" ");
                searchJTextField.setText(blubb[2]);
            }
        }
    }   

编辑:关于可能的重复-我很确定这篇文章是真的。我真的认为这是swing workers的错误实现,而不是像实际情况那样简单-所以这篇文章可能会被关闭^^

问题出在LogFileAnalyzerGUI类的第830行。keywordJComboBoxitemStateChanged()方法导致NullPointerException

此方法由您的ProcessDatabaseWorkerkeywordJComboBox.removeAllItems() 触发

通过删除所有项目,ItemState将变为取消选择。

方法itemStateChanged()再次运行,但ComboBox中没有更多的项目,因此导致NPE。

最新更新