我在窗口上使用锁定对象,我想阻止:当用户点击"点击我"按钮时,我想打开一个包含日历的窗口,用户应该在日历中选择一个日期。用户应该被阻止,直到他选择日期,所以我写了这个:
Button button = new Button("Click Me");
button.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
synchronized (Lock.getInstance()) {
DateChooser dateChooser = new DateChooser(new com.kopiright.xkopi.lib.type.Date(2013, 12, 9));
UI.getCurrent().addWindow(dateChooser);
System.out.println("!!!!!!!!!!!I'm waiting ...");
try {
Lock.getInstance().wait();
System.out.println("I'm waiting ...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
当用户点击按钮时,窗口不会显示,页面会无限等待。问题是我阻塞了启动应用程序的principle类。那么如何防止这种情况发生。我应该创建一个单独的线程来显示DateChooser窗口吗。
这是通知电话:在DateChooser类中,我写道:
@Override
public void valueChange(ValueChangeEvent event) {
synchronized(Lock.getInstance()) {
String date = String.valueOf(event.getProperty().getValue());
Calendar cal = Calendar.getInstance(Locale.FRANCE);
cal.setTime((java.util.Date) event.getProperty().getValue());
setSelectedDate(new NotNullDate(cal));
this.close();
Lock.getInstance().notify();
}
}
这是锁定类
public class Lock
{
private static Lock lockInstance;
public static Lock getInstance()
{
if (lockInstance == null)
{lockInstance = new Lock();
System.out.println("Creating a lock instance ...");}
return lockInstance;
}
}
您误解了两个wait
概念:GUI块和同步。
在您的情况下,您不需要同步任何内容,只需要找到一种方法,在用户单击按钮时禁用打开程序GUI窗口,并显示新窗口。
在vaadin中,http请求-响应的相同web原则也适用。当用户单击按钮时,会发出请求,为了显示窗口,必须完成服务器的响应。但是,当线程被阻塞时,这种情况不会发生。
此外,要实现您所描述的内容,您不需要线程控制。只需在模式窗口上显示日历,从窗口中删除关闭控件,然后只使用dateChooser对象的值更改侦听器关闭窗口。
假设DateChooser是一个vaadin窗口,您可以调用setModal(true);
使其成为模态。也可以看一下vaadin https://vaadin.com/book/vaadin7/-/page/layout.sub-window.html
的书。