【发布时间】:2014-11-09 18:18:14
【问题描述】:
首先,我不是以英语为母语的人,所以我为任何最终“怪异”的写作道歉。
我正在 Eclipse 上开发一个用于更新 Jpanel 的 Swing Java 应用程序。这个面板包含几个子面板,我不断切换面板的“模式”,而 MouseListener 发生了变化,因此它们对用户鼠标输入的响应方式略有不同。
无论应用程序做什么,它都会发生一个错误,对我来说似乎没有合乎逻辑的解释。在我的代码中的某个时刻,我尝试将面板更新为我所谓的中性模式。这发生在以下方法上:
//Guarded block (see http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html)
private synchronized boolean waitsForUserSatisfactionAnswer()
{
while(!userIndicatedSatisfaction)
{
try {
wait();
} catch (InterruptedException e) {}
}
userIndicatedSatisfaction = false; //reset for future new query
getObjectSetVisualizationPanel().neutralMode();
//getObjectSetVisualizationPanel().queryPatternMode();
return userSatisfied;
}
此更新不起作用(对中性模式()的调用不符合预期)。然而,对 queryPatternMode() 的调用(在下面的行中注释)完美地工作。所以我决定复制 queryPatternMode() 的主体并将其粘贴到中性模式 () 的主体上,ECXATLY 相同!它仍然无法正常工作!
方法代码如下:
public void queryPatternMode()
{
System.out.println("Inside queryPatternMode!!!");
System.out.println("panels.size(): " + panels.size());
for (DigitalObjectPanel panel : panels)
{
System.out.println("Inside the loop!!!");
panel.resetBehavior();
panel.setQuerySelectionBehavior(gui);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
panel.validate();
}
});
}
}
public void neutralMode()
{
System.out.println("Inside neutralMode!!!");
System.out.println("panels.size(): " + panels.size());
for (DigitalObjectPanel panel : panels)
{
System.out.println("Inside the loop!!!");
panel.resetBehavior();
panel.setQuerySelectionBehavior(gui);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
panel.validate();
}
});
}
}
发生的情况是,当我调用neutralMode() 时,“panels”集合恰好是空的(panels.size() 等于0)。但是,当我改为调用 queryPatternMode() 时,该集合恰好具有预期的大小(20 个面板)。但是这两个方法是相等的,而且都是从同一个地方调用的!!!
可能是什么???有什么可能的解释吗??
【问题讨论】:
-
你是否在Event Dispatch Thread?上更新了 Swing 对象
-
panels的范围是什么?也许您将其隐藏在一种方法中,而不是另一种?你的 IDE 是怎么说的?用this.panels替换panels会改变什么吗?你有一个完整的功能示例我们可以尝试吗? -
您的代码看起来可能忽略了事件驱动编程的原则。通常你不应该不断地轮询诸如
userIndicatedSatisfaction之类的变量,而是使用侦听器或观察者模式,从而收到更改通知。按照其他人的建议,考虑创建并发布Minimal, Complete, and Verifiable Example Program。 -
是的,我在 EDT 上完成了所有的 ui 更新。 panel 是一个私有成员,两个方法都来自 panel 所属的同一个类。 IDE什么也没说,根本没有异常或错误,它只是在应用程序行为上。我只是尝试更改为 this.panels 并不起作用...
-
该轮询是一个称为 Guarded block 的习语,由 oracle java 教程建议。毕竟,它似乎工作正常,while 条件检查是为了防止一些意外的唤醒。当我调用“模式”方法时会出现问题。具体的方法作用域是定义面板可见大小,根本没有意义!
标签: java multithreading swing memory