我有一个类读取从服务器发送的消息,该消息可以包含一个命令,用于根据消息内的数据创建一个gui,即消息可以是一个Object {“show”,data,guiData}。 / p>
该类有一个私有HashMap,在createAndShowGui方法中添加了新的GUI。但是当我从所述方法内部调用.put()时,它不起作用,因为在调用createAndShowGui方法之后调用时,HashMap.get()返回null。
我已经尝试将哈希映射的修饰符更改为final,但它似乎不起作用。
代码:
public class GuiController implements Runnable{
private final HashMap<String, JFrame> frameHashMap; //hashmap that contains the JFrame's
public GuiController(LinkedBlockingQueue<Object> inq, LinkedBlockingQueue<String> outq) {
//constructor, loads blocking queue that messages are read off
}
@Override
public void run() {
//recieves data from server, calls recieveMessage() with data object
}
private void receiveMessage(Object input) {
if (c.qn(input)) return; //server api function to test if object is null
final Object msg = input;
final String message = (String)c.at(msg,0);
final String name = (String)c.at(msg,1);
final Object data;
System.out.println(message + " " +name);
switch (message){
case "show":
data = c.at(msg,2);
if (!frameHashMap.containsKey(name)){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGui(name, data, c.at(msg, 3), String.valueOf((char[])c.at(msg, 4)));
}
});
}
for (String x: frameHashMap.keySet()) System.out.println(x + " -> " + frameHashMap.get(x));
break;
//other cases
}
}
private void createAndShowGui(String name, Object data, Object gData, String title){
System.out.println("Creating GUI with data at " + name + ", title: " + title + "...");
JFrame temp = new JFrame();
temp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
temp.setLocationRelativeTo(null);
temp.setTitle(title);
temp.setContentPane(new KPanel(data, gData, outqueue)); //Subclass of JPanel for handling gui data
temp.setName(name);
this.frameHashMap.put(name, temp); //this doesn't work
}
}
代码在createAndShowGui方法中打印出println,但switch语句中的for循环不打印任何内容,并且运行.get(name)返回null。
编辑:对不起我没有更多的细节,这个类只是从main方法的一个新线程开始。代码打印出输入数据的名称和KPanel构造函数中的任何println,唯一不起作用的是我自己可以告诉的.put()语句。我会做一个推动,所以你可以从github下载源代码。请注意,这是一个私人项目,我还没有真正对其进行评论。 的fs_createandshow分支中答案 0 :(得分:2)
如果您使用
SwingUtilities.invokeAndWait(Runnable doRun)
而不是
SwingUtilities.invokeLater(Runnable doRun)
你的踩踏问题应该解决了。 invokeAndWait
会将线程放在EDT上,但也要等到EDT处理完之后再继续你调用它。这样你就可以保证put(...)
在get(...)
之前执行了}