将数据返回给调用者的Modal JInternalFrame

时间:2013-05-16 14:37:59

标签: java swing joptionpane jinternalframe

我有一个Java Swing应用程序和一个JInternalFrame ..

在JInternalFrame中我有一些输入字段,当我按下热键时,我希望发生以下情况:

  1. 暂停当前JInternalFrame中的所有执行,并且没有任何输入字段可以重新聚焦。
  2. 新的框架(inputFrame)将以某种模态模式打开,并向用户提供填写正确值的帮助。 (数据从EJB获取,并根据用户选择进行过滤)
  3. 当用户单击“确定”时,将关闭inputFrame并将数据返回到mainFrame。
  4. mainFrame接受数据并继续处理。
  5. 如果可能,我希望inputFrame成为JInternalFrame,但这不是主要问题。

    有谁知道实现这个目标的方法?

2 个答案:

答案 0 :(得分:2)

查看How to Use Internal Frames并搜索showInternal。这就是答案。

答案 1 :(得分:0)

我在JOptionPane的源代码中找到了答案,我复制了两个静态方法createInternalFrame和startModal(只做了一些小改动)并在下面创建了我自己的类:

public class ModalInternalPanel {

    public static  Object showInternalDialog(Component parentComponent, Container container, HasReturnValue hasReturnValue, String title)  {
        JInternalFrame frame = createInternalFrame(parentComponent, title, container);
        startModal(frame);
        if (hasReturnValue!=null) return hasReturnValue.getReturnValue(); else return null;
    }


    public static JInternalFrame createInternalFrame(Component parentComponent, String title, Container container) throws RuntimeException  {
        // Try to find a JDesktopPane.
        JLayeredPane toUse = JOptionPane.getDesktopPaneForComponent(parentComponent);
        // If we don't have a JDesktopPane, we try to find a JLayeredPane.
        if (toUse == null)  toUse = JLayeredPane.getLayeredPaneAbove(parentComponent);
        // If this still fails, we throw a RuntimeException.
        if (toUse == null) throw new RuntimeException   ("parentComponent does not have a valid parent");

        JInternalFrame frame = new JInternalFrame(title); 


        frame.setContentPane(container);
        frame.setClosable(true);

        toUse.add(frame);
        frame.setLayer(JLayeredPane.MODAL_LAYER);

        frame.pack();
        frame.setVisible(true);

        return frame;
    }



    private static void startModal(JInternalFrame f) {
        // We need to add an additional glasspane-like component directly
        // below the frame, which intercepts all mouse events that are not
        // directed at the frame itself.
        JPanel modalInterceptor = new JPanel();
        modalInterceptor.setOpaque(false);
        JLayeredPane lp = JLayeredPane.getLayeredPaneAbove(f);
        lp.setLayer(modalInterceptor, JLayeredPane.MODAL_LAYER.intValue());
        modalInterceptor.setBounds(0, 0, lp.getWidth(), lp.getHeight());
        modalInterceptor.addMouseListener(new MouseAdapter(){});
        modalInterceptor.addMouseMotionListener(new MouseMotionAdapter(){});
        lp.add(modalInterceptor);
        f.toFront();

        // We need to explicitly dispatch events when we are blocking the event
        // dispatch thread.
        EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
        try {
            while (! f.isClosed())       {
                if (EventQueue.isDispatchThread())    {
                    // The getNextEventMethod() issues wait() when no
                    // event is available, so we don't need do explicitly wait().
                    AWTEvent ev = queue.getNextEvent();
                    // This mimics EventQueue.dispatchEvent(). We can't use
                    // EventQueue.dispatchEvent() directly, because it is
                    // protected, unfortunately.
                    if (ev instanceof ActiveEvent)  ((ActiveEvent) ev).dispatch();
                    else if (ev.getSource() instanceof Component)  ((Component) ev.getSource()).dispatchEvent(ev);
                    else if (ev.getSource() instanceof MenuComponent)  ((MenuComponent) ev.getSource()).dispatchEvent(ev);
                    // Other events are ignored as per spec in
                    // EventQueue.dispatchEvent
                } else  {
                    // Give other threads a chance to become active.
                    Thread.yield();
                }
            }
        }
        catch (InterruptedException ex) {
            // If we get interrupted, then leave the modal state.
        }
        finally {
            // Clean up the modal interceptor.
            lp.remove(modalInterceptor);

            // Remove the internal frame from its parent, so it is no longer
            // lurking around and clogging memory.
            Container parent = f.getParent();
            if (parent != null) parent.remove(f);
        }
    }
}