等待并通知等待按钮按下导致jframe不加载
Wait and notify to wait for button press causing jframe not to load
我正在编写一个方法 (getInfo),我的程序 class 会调用该方法。在某些情况下,用户需要从列表(在 JComboBox 中)中 select 来确定该方法 return 编辑的内容,因此我希望该方法等到用户做出选择。我正在尝试使用 wait 和 notify 来执行此操作,但是当弹出 jframe 并保存用户在其中创建 selection 的 JComboBox 时,它是空的。我怀疑这是因为调用 wait() 暂停了我的整个程序,所以我如何等待按下按钮来完成该方法并让它 return 一些东西。这是有问题的class:
package sm;
import org.jsoup.Jsoup;
//import org.jsoup.*;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ScrapingManager {
String courseName;
String courseType;
String site;
Element row;
Elements allWithName;
JComboBox<String> options;
JFrame frame;
String slots;
String location;
public static final Object obj = new Object();
public ScrapingManager(String name) {
courseName = name;
try {
courseType = name.substring(0, 4);
} catch(Exception e) {System.out.println("Error: Course code must be at least 4 characters");};
//getInfo(searchFirstPage());
}
public String searchFirstPage() {
Document page;
String result = "error";
try {
page = Jsoup.connect("https://app.stfx.ca/web/Forms/shared/Registrar_website_Timetable.htm").get();
Element link = page.getElementsContainingOwnText(courseType).first();
//System.out.println(link.attr("href"));
result = link.attr("href");
} catch(Exception e) {/*e.printStackTrace();*/System.out.println("Error: Course code not recognized");}
return result;
}
public String[] getInfo() {
Document doc;
slots = "Error";
location = "Error";
try {
doc = Jsoup.connect(searchFirstPage()).get();
allWithName = doc.getElementsContainingOwnText(courseName).select(":not(:contains('L'))");//it works without select part but shows labs too
if(allWithName.size() > 1) {
//give warning that it might be the wrong times
frame = new JFrame("Warning");
JPanel panel = new JPanel();
JLabel warning1 = new JLabel("There are multiple classes with that name,");
JLabel warning2 = new JLabel("select yours from the list below:");
String[] array = new String[allWithName.size()];
for(int i = 0; i < allWithName.size(); i++) {
array[i] = allWithName.get(i).parent().child(8).text();
}
options = new JComboBox<String>(array);
JButton ok = new JButton("Select");
ok.addActionListener(new SubmitListener());
panel.add(warning1);
panel.add(warning2);
panel.add(options);
panel.add(ok);
frame.getContentPane().add(panel);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
synchronized(obj) {
try {
obj.wait();
} catch(Exception e) {}
}
} else {
row = doc.getElementsContainingOwnText(courseName).first().parent();
}
slots = row.child(8).text();
location = row.child(9).text();
//System.out.println(slots + " " + location);
} catch(Exception e) {e.printStackTrace();}
return new String[] {slots, location};
}
public class SubmitListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
row = allWithName.get(options.getSelectedIndex());
frame.dispose();
synchronized(obj) {
obj.notify();
}
}
}
}
提前致谢!
而不是 wait()
,使用 JOptionPane.showInputDialog(...)
,就像这里:
import javax.swing.JOptionPane;
public class LanguagesSelector{
public static void main(String[] args) {
String[] languages = {"Spanish", "English", "Italian", "Other"};
Object language = JOptionPane.showInputDialog(null,
"Choose Language", "language", JOptionPane.PLAIN_MESSAGE,
null, languages, languages[0]);
System.out.println("Selected " + language);
}
}
在JOptionPane
class中,AWT(which swing based on)线程等待用户选择一个选项,所以它应该可以解决你的问题。
我正在编写一个方法 (getInfo),我的程序 class 会调用该方法。在某些情况下,用户需要从列表(在 JComboBox 中)中 select 来确定该方法 return 编辑的内容,因此我希望该方法等到用户做出选择。我正在尝试使用 wait 和 notify 来执行此操作,但是当弹出 jframe 并保存用户在其中创建 selection 的 JComboBox 时,它是空的。我怀疑这是因为调用 wait() 暂停了我的整个程序,所以我如何等待按下按钮来完成该方法并让它 return 一些东西。这是有问题的class:
package sm;
import org.jsoup.Jsoup;
//import org.jsoup.*;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ScrapingManager {
String courseName;
String courseType;
String site;
Element row;
Elements allWithName;
JComboBox<String> options;
JFrame frame;
String slots;
String location;
public static final Object obj = new Object();
public ScrapingManager(String name) {
courseName = name;
try {
courseType = name.substring(0, 4);
} catch(Exception e) {System.out.println("Error: Course code must be at least 4 characters");};
//getInfo(searchFirstPage());
}
public String searchFirstPage() {
Document page;
String result = "error";
try {
page = Jsoup.connect("https://app.stfx.ca/web/Forms/shared/Registrar_website_Timetable.htm").get();
Element link = page.getElementsContainingOwnText(courseType).first();
//System.out.println(link.attr("href"));
result = link.attr("href");
} catch(Exception e) {/*e.printStackTrace();*/System.out.println("Error: Course code not recognized");}
return result;
}
public String[] getInfo() {
Document doc;
slots = "Error";
location = "Error";
try {
doc = Jsoup.connect(searchFirstPage()).get();
allWithName = doc.getElementsContainingOwnText(courseName).select(":not(:contains('L'))");//it works without select part but shows labs too
if(allWithName.size() > 1) {
//give warning that it might be the wrong times
frame = new JFrame("Warning");
JPanel panel = new JPanel();
JLabel warning1 = new JLabel("There are multiple classes with that name,");
JLabel warning2 = new JLabel("select yours from the list below:");
String[] array = new String[allWithName.size()];
for(int i = 0; i < allWithName.size(); i++) {
array[i] = allWithName.get(i).parent().child(8).text();
}
options = new JComboBox<String>(array);
JButton ok = new JButton("Select");
ok.addActionListener(new SubmitListener());
panel.add(warning1);
panel.add(warning2);
panel.add(options);
panel.add(ok);
frame.getContentPane().add(panel);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
synchronized(obj) {
try {
obj.wait();
} catch(Exception e) {}
}
} else {
row = doc.getElementsContainingOwnText(courseName).first().parent();
}
slots = row.child(8).text();
location = row.child(9).text();
//System.out.println(slots + " " + location);
} catch(Exception e) {e.printStackTrace();}
return new String[] {slots, location};
}
public class SubmitListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
row = allWithName.get(options.getSelectedIndex());
frame.dispose();
synchronized(obj) {
obj.notify();
}
}
}
}
提前致谢!
而不是 wait()
,使用 JOptionPane.showInputDialog(...)
,就像这里:
import javax.swing.JOptionPane;
public class LanguagesSelector{
public static void main(String[] args) {
String[] languages = {"Spanish", "English", "Italian", "Other"};
Object language = JOptionPane.showInputDialog(null,
"Choose Language", "language", JOptionPane.PLAIN_MESSAGE,
null, languages, languages[0]);
System.out.println("Selected " + language);
}
}
在JOptionPane
class中,AWT(which swing based on)线程等待用户选择一个选项,所以它应该可以解决你的问题。