我写了一个摇摆工作者,负责计算一些文本统计数据,然后用结果更新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)
现在,对于我的问题:工人的哪一部分没有使用正确或我的程序逻辑出错了?正如你所看到的,我对使用摇摆工作者和线程进行编程非常陌生,所以我确信有一个简单的解决方案可以解决因缺乏经验而导致的简单错误。
此外,请告诉我,如果需要我的计划的任何其他部分,以便更好地了解正在发生的事情。
编辑:错误正是用户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
的错误实现,而不是实际上那么简单 - 所以这篇文章也可能会被关闭^^
答案 0 :(得分:0)
问题是LogFileAnalyzerGUI
课程的第830行。 itemStateChanged()
的{{1}}方法导致keywordJComboBox
此方法由NullPointerException
ProcessDatabaseWorker
删除所有项目keywordJComboBox.removeAllItems()
更改为DESELECTED。
方法ItemState
再次运行,但itemStateChanged()
中没有更多项目因此导致NPE。