所以我有一个按钮,用于在按下后将新用户(其名称取自另一个类)添加到列表中。当我在构建和运行后通过手动点击它按下按钮时,它工作正常。问题是,当我通过另一个方法调用ActionEvent方法时,它会输出我的System.out.println文本,但不会向列表中添加任何新条目。
有什么建议吗?
这是按下按钮时调用的代码(标有“< - ”的行是我手动按下按钮时似乎只能工作的行):
public void actionPerformed(ActionEvent e) {
listModel.insertElementAt(name, index); // <--
System.out.println("finished running action");
}
这是我的代码的更完整版本:
public void actionPerformed(ActionEvent e) {
System.out.println("ran action");
addAuthor();
System.out.println("authornamefinalfunc name: " + name);
//Reset the text field.
employeeName.requestFocusInWindow();
//employeeName.setText("");
//Select the new item and make it visible.
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
System.out.println("ran action final");
}
private void addAuthor()
{
String name = Global.s;
int index = list.getSelectedIndex(); //get selected index
if (index == -1) { //no selection, so insert at beginning
index = 0;
} else { //add after the selected item
index++;
}
listModel.insertElementAt(name, index);
}
答案 0 :(得分:0)
是否始终在事件派发线程上调用addAuthor
方法? JList
(以及Swing中的所有内容)不同步或线程安全,因此任何与Swing相关的修改/操作必须在该线程上发生。由于addAuthor
方法与Swing组件交互,因此必须从除此之外的任何线程调用从不。这适用于您在该课程中使用的任何其他方法(如果编写得很好,则可能是main
方法除外)。
如果你需要调用addAuthor
或任何其他与Swing组件直接交互的方法,而不是事件调度线程的线程,请使用类似的方法来调用方法(这假设你的Swing表单名为&#34; myUI&#34;):
SwingUtilities.invokeAndWait(new Runnable() {
@Override public void run() {
addAuthor();
}
});
如果您想运行代码而不是等待代码完成,也可以使用invokeLater
。
如果您不确定运行的线程代码是什么,请使用以下经验法则:
main
方法中的任何代码,或main
方法调用的代码(无论深度多少)都由&#34; main&#34;运行。线。
main
方法会调用foo()
,而bar()
会调用foobar()
,而main
会调用new Thread(...).start()
。所有这些方法中的所有代码都由ActionListener
线程运行。ActionListener
,那个代码,以及它调用的所有方法中的代码,都是从这个线程运行的。addAuthor
)由事件调度线程上的代码调用。在事件调度线程上运行的代码是唯一代码,可以安全地与Swing组件交互。因此,只能从在EDT中运行的代码调用包含与Swing组件(例如{{1}}和{{1}}方法)交互的代码的方法。
如果你想从任何其他线程(上面的1和2)调用方法,你需要使用上面给出的方法,因为你不能直接这样做。