【问题标题】:Creating a custom modal dialog for a Swing applet / application为 Swing 小程序/应用程序创建自定义模式对话框
【发布时间】:2010-07-14 21:33:42
【问题描述】:
我正在编写一个 Swing 应用程序,它需要作为浏览器中的小程序或独立应用程序运行,即它可能包含在 JFrame 或 JApplet 中。
在这种情况下,我想向用户显示一个自定义模式对话框(即具有自定义布局和逻辑的复杂对话框,而不仅仅是简单的 JOptionPane 提示之一)。如果对话框是完全包含在应用程序窗口中的轻量级组件,那很好。
同时,应用程序中会发生后台处理(网络线程、动画等)。这需要在显示对话框时继续。
实现这一点的最佳方法是什么?
【问题讨论】:
标签:
java
user-interface
swing
applet
【解决方案1】:
看看JDialog。如果您将其设置为模态,它将运行自己的事件处理以使 GUI 保持最新,同时捕获鼠标和键盘事件以供自己使用。
我查看了它使用的代码,这真的不是你想尝试重新发明的东西。
如果您以非模态方式运行它,您可能需要添加一个侦听器,以便在它最终关闭时调用。这是通过addWindowListener 和覆盖windowClosing 的WindowAdapter 完成的。
至于构造函数的owner参数,我用
Window w = (Window) SwingUtilities.getAncestorOfClass(Window.class, comp);
comp 是一些可见的组件。
它之所以有效,是因为总有一个顶级窗口,无论是作为小程序还是作为应用程序运行。
【解决方案2】:
这里描述了将帧显示为指定所有者的模式的有趣方法:
Show the given frame as modal to the specified owner
但是,EventPump 类的start() 方法应该这样修改:
protected void start() throws Exception
{
Class<?> cl = Class.forName("java.awt.Conditional");
Object conditional = Proxy.newProxyInstance(cl.getClassLoader(), new Class[] { cl }, this);
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
String name = Thread.currentThread().getName();
EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
Constructor constructor = Class.forName("java.awt.EventDispatchThread").
getDeclaredConstructor(ThreadGroup.class, name.getClass(), eventQueue.getClass());
constructor.setAccessible(true);
Object eventDispatchThread = constructor.newInstance(threadGroup, name, eventQueue);
Method pumpMethod = eventDispatchThread.getClass().getDeclaredMethod("pumpEvents", cl);
pumpMethod.setAccessible(true);
pumpMethod.invoke(eventDispatchThread, conditional);
}