模态对话框很好做,可是非常不好看.
特别是和我的整个软件的风格不一致,所以我想用JInternalFrame达到模态的效果.
我初步想的是让其拒绝失去焦点这个属性请求.
可好像不行.

解决方案 »

  1.   

    首先,只提供了InternalFrame下用的简单的Dialog,不是和JDialog那样任意的Dialog.
    再则,那样的外观也不符合我的要求.
      

  2.   

    那就有些麻烦了,我又些相关的原码,没有具体再试,你参考一下巴。
    package accessible;import javax.accessibility.*;
    import javax.swing.*;
    import java.awt.*;class CustomInternalFrame extends JInternalFrame {
      public boolean isModel = false;
      public CustomInternalFrame(String str,boolean a,boolean b,boolean c,boolean d){
        super(str,a,b,c,d);
      }  public synchronized void startModal()
        {
            System.out.println("startModa");
            if(isVisible() && !isShowing())
            {
               System.out.println("isSho");
                for(Container container = super.getParent(); container != null; container = container.getParent())
                    if(!container.isVisible())
                        container.setVisible(true);        }
            try
            {
                if(SwingUtilities.isEventDispatchThread())
                {
                    System.out.print("isEventDispatchThread");
                    EventQueue eventqueue = getToolkit().getSystemEventQueue();
                    while(isVisible())
                    {
                        AWTEvent awtevent = eventqueue.getNextEvent();
                        Object obj = awtevent.getSource();
                        if(awtevent instanceof ActiveEvent)
                            ((ActiveEvent)awtevent).dispatch();
                        else
                        if(obj instanceof Component)
                            ((Component)obj).dispatchEvent(awtevent);
                        else
                        if(obj instanceof MenuComponent)
                            ((MenuComponent)obj).dispatchEvent(awtevent);
                        else
                            System.err.println("unable to dispatch event: " + awtevent);
                    }
                } else
                {
                    System.out.print("wait");
                    for(; isVisible(); wait());
                }
            }
            catch(InterruptedException interruptedexception) { }
            isModel = true;
        }    public synchronized void stopModal()
        {
            super.notifyAll();
            isModel = true;
        }}
      

  3.   

    public static Object showInternalInputDialog(Component component, Object obj, String s, int i, Icon icon1, Object aobj[], Object obj1)
        {
            JOptionPane joptionpane = new JOptionPane(obj, i, 2, icon1, null, null);
            joptionpane.setWantsInput(true);
            joptionpane.setSelectionValues(aobj);
            joptionpane.setInitialSelectionValue(obj1);
            JInternalFrame jinternalframe = joptionpane.createInternalFrame(component, s);
            joptionpane.selectInitialValue();
            jinternalframe.setVisible(true);
            jinternalframe.startModal();
            Object obj2 = joptionpane.getInputValue();
            if(obj2 == UNINITIALIZED_VALUE)
                return null;
            else
                return (String)obj2;
        }    public JInternalFrame createInternalFrame(Component component, String s)
        {
            Object obj = getDesktopPaneForComponent(component);
            if(obj == null && (component == null || (obj = component.getParent()) == null))
                throw new RuntimeException("JOptionPane: parentComponent does not have a valid parent");
            final JInternalFrame iFrame = new JInternalFrame(s, false, false, false, false);
            iFrame.putClientProperty("JInternalFrame.frameType", "optionDialog");
            addPropertyChangeListener(new PropertyChangeListener() {            public void propertyChange(PropertyChangeEvent propertychangeevent)
                {
                    if(iFrame.isVisible() && propertychangeevent.getSource() == JOptionPane.this && (propertychangeevent.getPropertyName().equals("value") || propertychangeevent.getPropertyName().equals("inputValue")))
                    {
                        try
                        {
                            iFrame.setClosed(true);
                        }
                        catch(PropertyVetoException propertyvetoexception1) { }
                        iFrame.setVisible(false);
                        iFrame.stopModal();
                    }
                }        });
            iFrame.getContentPane().add(this, "Center");
            if(obj instanceof JDesktopPane)
                ((Container) (obj)).add(iFrame, JLayeredPane.MODAL_LAYER);
            else
                ((Container) (obj)).add(iFrame, "Center");
            Dimension dimension = iFrame.getPreferredSize();
            Dimension dimension1 = ((Component) (obj)).getSize();
            iFrame.setBounds((dimension1.width - dimension.width) / 2, (dimension1.height - dimension.height) / 2, dimension.width, dimension.height);
            ((Container) (obj)).validate();
            try
            {
                iFrame.setSelected(true);
            }
            catch(PropertyVetoException propertyvetoexception) { }
            return iFrame;
        }
      

  4.   

    大哥...能不能把和这些原码一起的其他码或则别的什么发过来看看.
    [email protected]
      

  5.   

    到javaworld上去搜索:model或internalframe
      

  6.   

    其实JInternalFrame已经实现了模态,在JOptionPane.showInternalInputDialog()的原码中已经利用了这点,所以出来的Dialog其实也是一个JInternalFrame,但是JInternalFrame中的startModal()和stopModal()是受保护的,只能本包内的用,所以外面不能用。
    你可以直接另写一个类把这两个方法改为公用的,然后参考JOption的方法来用它。原码我已经反编了,给你发过去。
      

  7.   

    OK.搞定了.我开始以为是这样的.
    但结果发现如果上面放了个JComboBox,JComboBox不能正常工作.
    原因应该是这个InternalFrame是Toppest,而点击ComboBox时弹出了一个新的窗口...这样,就选不到这个新弹出的窗口了(ComboBox弹出的).
    原代码:
    文件1------------------Modal.java
    ///////Modal.java/////////////////////
    package modalframe;import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import java.beans.*;public class Modal
    {
    public static void main(String args[])
    {
        final JFrame frame = new JFrame("Main");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JDesktopPane desktop = new JDesktopPane();
        ActionListener showModal =
            new ActionListener()
                {
                   public void actionPerformed(ActionEvent e)
                   {
                      // Construct a message internal frame popup
                      JInternalFrame iFrame =
                          new ModalFrame("Really Modal",frame.getRootPane(), desktop);
                      iFrame.setVisible(true);
                   }
                };    JInternalFrame internal =
          new JInternalFrame("Open",true,true,true,true);
        desktop.add(internal);    JButton button = new JButton("Open");
        button.addActionListener(showModal);    Container iContent = internal.getContentPane();
        iContent.add(button, BorderLayout.CENTER);
        internal.setBounds(25, 25, 200, 100);
        internal.setVisible(true);    Container content = frame.getContentPane();
        content.add(desktop, BorderLayout.CENTER);
        frame.setSize(500, 300);
        frame.setVisible(true);
      }
    }
    文件2---ModalFrame.java
    ///////////////////////ModalFrame.java///////////////////////
    package modalframe;import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import java.beans.*;public class ModalFrame extends JInternalFrame
    {
    public ModalFrame(String title, JRootPane rootPane, Component desktop)
    {
    super(title,true,true,true,true);
        // create opaque glass pane
        final JPanel glass = new JPanel();
        glass.setOpaque(false);
        // Attach mouse listeners
        MouseInputAdapter adapter =
          new MouseInputAdapter(){};
        glass.addMouseListener(adapter);
        glass.addMouseMotionListener(adapter);
        // Define close behavior
        PropertyChangeListener pcl =
            new PropertyChangeListener()
             {
                   public void propertyChange(PropertyChangeEvent event)
                   {
                      if (isVisible() &&event.getPropertyName().equals("closed"))
                      {
                        ModalFrame.this.setVisible(false);
                        glass.setVisible(false);
                      }
                   }
            };
        addPropertyChangeListener(pcl);    try {
          setSelected(true);
        } catch (PropertyVetoException ignored) {
        }
        // Add modal internal frame to glass pane
        glass.add(this);
        // Change glass pane to our panel
        rootPane.setGlassPane(glass);
        // Show glass pane, then modal dialog
        glass.setVisible(true);
        // Add in option pane
            // Size frame
        Dimension size = getPreferredSize();
        Dimension rootSize = desktop.getSize();
        setBounds((rootSize.width - size.width) / 2,
                  (rootSize.height - size.height) / 2,
                   size.width, size.height);
            desktop.validate();
        Create();  }
      public void setVisible(boolean value) {
        super.setVisible(value);
        if (value) {
          startModal();
        } else {
          stopModal();
        }
      }  private synchronized void startModal() {
        try {
          if (SwingUtilities.isEventDispatchThread()) {
            EventQueue theQueue =
              getToolkit().getSystemEventQueue();
            while (isVisible()) {
              AWTEvent event = theQueue.getNextEvent();
              Object source = event.getSource();
              if (source==statusCombo)
              {
                 System.out.println("Combo");
              }
              if (event instanceof ActiveEvent) {
                ((ActiveEvent)event).dispatch();
              } else if (source instanceof Component) {
                ((Component)source).dispatchEvent(
                  event);
              } else if (source instanceof MenuComponent) {
                ((MenuComponent)source).dispatchEvent(
                  event);
              } else {
                System.err.println(
                  "Unable to dispatch: " + event);
              }
            }
          } else {
            while (isVisible()) {
              wait();
            }
          }
        } catch (InterruptedException ignored) {
        }
      }  private synchronized void stopModal() {
        notifyAll();
      }    private boolean Create()
      {
       //create
        statusCombo = new JComboBox();
        statusCombo.addItem("up");
        statusCombo.addItem("down");
        JPanel panelx=new JPanel();
        //layout
        panelx.add(new JLabel("1"));
        panelx.add(new JLabel("2"));
        panelx.add(new JLabel("3"));
        panelx.add(new JLabel("4"));
        panelx.add(statusCombo);
        getContentPane().add(panelx,"Center");
        return true;
      }
    private JComboBox statusCombo;
    }
      

  8.   

    各位大大,再过两天,JComboBox不能正常工作的这个问题没办法解决,我也一样给分,呵呵.
    如果解决了,我再开帖子给200分.
      

  9.   

    问一个另外的问题:在JInternalFrame中可以使用JSplitPane吗?
    你上面提到的:“这个InternalFrame是Toppest”是什么意思?和我问的问题有没有什么关系?
      

  10.   

    JComboBox不是不能正常工作,而是当你的鼠标事件点击到模态JInternalFrame之外的地方都被截获没有发出去,所以不能正常工作。只要让他的下啦范围在你的模态JInternalFrame之内就不会出现问题。