为 Swing 小程序/应用程序创建自定义模式对话框

发布于 2024-09-10 02:31:37 字数 261 浏览 3 评论 0原文

我正在编写一个 Swing 应用程序,它需要作为浏览器中的小程序或作为独立应用程序运行,即它可能包含在 JFrame 或 JApplet 中。

在这种情况下,我想向用户显示一个自定义模式对话框(即具有自定义布局和逻辑的复杂对话框,而不仅仅是简单的 JOptionPane 提示之一)。如果对话框是完全包含在应用程序窗口中的轻量级组件,那就没问题了。

同时,应用程序中将会发生后台处理(网络线程、动画等)。这需要在显示对话框时继续。

实现这一点的最佳方法是什么?

I'm writing a Swing application that needs to function either as an applet in a browser or as a standalone application, i.e. it may be contained in either a JFrame or a JApplet.

In this context, I'd like to display a custom modal dialog box to the user (i.e. a complex dialog with a custom layout and logic, not just one of the simple JOptionPane prompts). It is fine if the dialog is a lightweight component fully contained within the application window.

At the same time, there will be background processing happening in the application (network threads, animations etc.). This needs to continue while the dialog is displayed.

What would be the best approach to implement this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我三岁 2024-09-17 02:31:37

看一下JDialog。如果将其设置为模态,它将运行自己的事件处理以使 GUI 保持最新,同时捕获鼠标和键盘事件供其自己使用。

我查看了它使用的代码,它确实不是您想要尝试重新发明的东西。

如果您以非模式方式运行它,您可能需要添加一个侦听器,以便在它最终关闭时调用。这是通过 addWindowListener 和覆盖 windowClosing 的 WindowAdapter 来完成的。

至于构造函数的 owner 参数,我使用

    Window w = (Window) SwingUtilities.getAncestorOfClass(Window.class, comp);

其中 comp 是一些可见组件。

它之所以有效,是因为无论是作为小程序还是应用程序运行,总是有一个顶级窗口。

Take a look at JDialog. If you set it modal it will run its own event processing to keep the GUI up to date, while capturing mouse and keyboard events for its own use.

I've looked at the code it uses and it's really not something you want to try to reinvent.

If you run it non modal, you 'll probably need to add a listener to be called when it finally closes. That is done with addWindowListener and a WindowAdapter that overrides windowClosing.

As for the owner parameter for the constructor, I use

    Window w = (Window) SwingUtilities.getAncestorOfClass(Window.class, comp);

where comp is some visible component.

It works because there is always a top level Window, whether running as an applet or application.

许你一世情深 2024-09-17 02:31:37

这里描述了将框架显示为指定所有者的模式的有趣方法:
将给定框架显示为指定所有者的模式

但是, 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);
}    

Here interesting method for showing frames as modal to specified owner is described:
Show the given frame as modal to the specified owner

However, start() method of class EventPump should be modified in such way:

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);
}    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文