我试图在一个小代码生成器' -application中实现一个函数 showTexfieldSettingsDialouge(Map fields),将一个充满字符串的Hashmap作为输入,显示一个带有迭代创建的面板和文本字段的摇摆窗口,用于Hashmap中提到的每个键,并在单击按钮后返回填充了用户输入的Hashmap。
问题:要等待单击按钮,我必须创建一个ActionListener,它在一个新的(Swing-)线程中运行。 如何让函数等待ActionListener被触发,继续,写入输入然后返回?
为了更好的帮助,我可以发布我写的代码,直到现在:
public class GUIMacroHandler {
//diverse other functions
public HashMap<String, String> showTexfieldSettingsDialouge(Map<String, String> fields){
JFrame mainFrame = new JFrame("Please fill every Textfield with the correct Data");
Map<String, JLabel> labels = new HashMap<String, JLabel>();
Map<String, JTextField> textfields = new HashMap<String, JTextField>();
JPanel optionpanel = new JPanel(new GridLayout(fields.size(), 2, 10, 10));
JSplitPane splitPane = new JSplitPane();
JButton btnSubmit = new JButton("Submit");
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
mainFrame.getContentPane().add(splitPane, BorderLayout.NORTH);
splitPane.setTopComponent(optionpanel);
splitPane.setBottomComponent(btnSubmit);
for (Entry<String, String> entry : fields.entrySet()) {
labels.put(entry.getKey(),new JLabel(entry.getKey() + ":"));
textfields.put(entry.getKey(),new JTextField(entry.getValue());
optionpanel.add(labels.get(entry.getKey()));
optionpanel.add(textfields.get(entry.getKey()));
}
btnSubmit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Can't do stuff here because the function needs to return after the button is clicked and not before
}
});
mainFrame.pack();
mainFrame.setVisible(true);
//TODO:
//Wait for button to be clicked somehow
//Fill the given values with the input of the text fields
return fields;
}
}
该函数在代码中被多次强制转换,并且被认为可以根据用户需要的值轻松更改任何给定的String / String HashMap。 F.E.像这样:
GUIMacroHandler guiMacroHandler = new GUIMacroHandler();
combatsettings = guiMacroHandler.showTexfieldSettingsDialouge(combatsettings);
我已经搜索了一段时间没有找到问题的解决方案,我会非常乐意提供帮助,谢谢! :d
修改 如果我只在代码中使用此函数一次,那么在Action执行语句中发布内容只会是一种可能的解决方案,但这里不会因为函数被迫等待点击按钮返回在实际代码中,gui窗口将使用Hashmap的输入创建,然后返回给定的Hashmap,代码将继续,没有用户输入,窗口仍然存在,等待按钮最终被点击到期,但没有使用用户更改的数据和代码将继续使用默认值,因为它不会等待用户输入。
答案 0 :(得分:2)
如果您确定从某个线程调用此方法,则可以执行此类操作!= EDT。例如,像这样
public static String getFrameResult() throws InterruptedException {
if (SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("Can't be called from EDT.");
}
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(1);
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Hello");
JButton button = new JButton("Done");
button.addActionListener((ActionEvent e) -> {
String result = "Done at : " + LocalDateTime.now();
queue.offer(result);
frame.dispose();
});
frame.add(button);
frame.pack();
frame.setVisible(true);
});
return queue.take();
}
这里的技巧是将结果存储在内存中,并通知调用线程它已被保存,以便它可以接受并返回它。 BlockingQueue
效果很好,因为Java 8是CompletableFuture
,甚至可以手动通过wait / notify和共享变量。