也许我只是不知道在哪里看或者不完全理解线程是如何工作的,但我有两个不同的JFrame(J1,J2)。 J1是主JFrame,它有一个选择J2的下拉菜单。当这个J2变得可见时,我需要J1等待J2的foobar值变为-1以外的值。我试图用几种不同的方法给这只猫上皮而没有成功。
我现在正在尝试...
// located in J1
J2 otherFrame = new J2();
....
private synchronized void getNum() {
try {
while (otherFrame.returnNum() == -1) wait();
}
catch (Exception e) {}
Long myResult = otherFrame.returnNum();
...
}
// located in J2
public synchronized Long returnNum() {
try {
while (someNum == -1) wait();
}
catch (Exception e) {}
notify();
return someNum;
}
我确信这看起来很愚蠢,但是我需要J1等到J2有一个分配给someNum的值。用户单击“提交”时将分配该值。它没有做好这项工作。我在这里做错了什么(更重要的是),如果这是一个线程,我的线程概念在哪里失败?
答案 0 :(得分:6)
解决方案不是将JFrame用于第二个窗口,而是使用模态对话框,例如模态JDialog。这正是为此类型的顶级窗口构建的。
这个问题是为什么人们应该避免编写扩展JFrame的Swing类的另一个原因,因为这样做会将编码器描绘成一个角落并限制他们的选择。更好的是创建扩展或构建用于创建JPanel的类,从那时起JPanel可以放在JFrame或模态JDialog中,如果需要,或者放在另一个JPanel中,或者在CardLayout中交换,或者......
请注意,除了一些差异之外,使用JDialog与JFrame非常相似。你应该在对话框中传入一个对调用窗口的引用(这里是你的第一个JFrame),你应该使用构造函数来使对话框模态化,但API可以帮助你完成所有这些。
当您使模态窗口可见时,调用代码中的代码流会停止,并且在JDialog不再可见之前不会恢复。那时你可以查询JDialog的组件的状态,并在调用代码中使用它。
例如:
CREATE VIEW spenttime_week AS
SELECT
s1.userid,
s1.serverid,
s1.total_time,
s1.week,
count(s2.total_time)+1 AS rank
FROM
total_spent_time s1 LEFT JOIN total_spent_time s2
ON s1.serverid=s2.serverid
AND s1.userid!=s2.userid
AND s1.week = s2.week
AND s1.total_time<=s2.total_time
GROUP BY
s1.userid,
s1.serverid,
s1.total_time,
s1.week
ORDER BY
s1.week, s1.serverid, s1.userid