代码之家  ›  专栏  ›  技术社区  ›  mikera

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

  •  2
  • mikera  · 技术社区  · 14 年前

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

    在此上下文中,我希望向用户显示自定义模式对话框(即具有自定义布局和逻辑的复杂对话框,而不仅仅是简单JoptionPane提示之一)。如果对话框是完全包含在应用程序窗口中的轻量级组件,则可以。

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

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

    2 回复  |  直到 13 年前
        1
  •  4
  •   Devon_C_Miller    14 年前

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

    我看过它使用的代码,但它确实不是你想要重新发明的东西。

    如果您非模态地运行它,您可能需要添加一个监听器来在它最终关闭时被调用。就这样结束了 addWindowListener 以及一个重写 windowClosing .

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

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

    其中comp是一些可见组件。

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

        2
  •  1
  •   Marek Grzenkowicz    13 年前

    这里描述了将帧显示为指定所有者的模式的有趣方法: Show the given frame as modal to the specified owner

    然而, start() 类方法 EventPump 应该这样修改:

    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);
    }