2012-07-03 20 views
0

我對使用MDI形式的Java項目的工作只是調用。我創建了一個框架,然後添加了一個桌面窗格。我的項目使用了很多內部框架。此外,這些內部框架需要顯示我自己創建的自定義對話框。爲了清楚起見,我說,一個jdialog有一個表要求用戶選擇一行。但問題是當我從內部框架調用jdialog(modality = true)時,對話框顯示在主框架的頂部,而不僅僅是內部框架的頂部。這使得當jdialog顯示時不可能使窗口最小化。如何添加一個JDialog到桌面窗格或從內部框架

在我看來有兩種可能的解決方案(這可能是不可能的!)..或者jdialog應該顯示在dektop窗格中,或者我應該創建一個內部框架而不是jdialog,並使其顯示爲模態父內部框架。即,當我想要顯示對話框時,我可以禁用內部框架並將表單設置爲無法對焦,然後在此內部框架的頂部顯示一個新的內部框架。我一直在尋找論壇幾個星期..但我找不到答案。我希望你能有一個解決方案。先謝謝了,先生。

回答

0

哇!我從webbyt答案......只要避免使用內部框架..嘗試使用類ModalityInternalFrame(JInternalFrame的子類)..和一切工作正常。這裏是類

import java.awt.*; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyVetoException; 
import java.beans.VetoableChangeListener; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.*; 
import javax.swing.event.InternalFrameAdapter; 
import javax.swing.event.InternalFrameEvent; 

/** 
* An extended 
* <code>JInternalFrame</code> that provides modality in a child/parent 
* hierarchy 
* 
* @author webbyit 
*/ 
public class ModalityInternalFrame extends JInternalFrame { 

    protected JDesktopPane desktopPane; 
    protected JComponent parent; 
    protected ModalityInternalFrame childFrame; 
    protected JComponent focusOwner; 
    private boolean wasCloseable; 

    public ModalityInternalFrame() { 
     init(); // here to allow netbeans to use class in gui builder 
    } 

    public ModalityInternalFrame(JComponent parent) { 
     this(parent, null); 
    } 

    public ModalityInternalFrame(JComponent parent, String title) { 
     this(parent, title, false); 
    } 

    public ModalityInternalFrame(JComponent parent, String title, boolean resizable) { 
     this(parent, title, resizable, false); 
    } 

    public ModalityInternalFrame(JComponent parent, String title, boolean resizable, boolean closeable) { 
     this(parent, title, resizable, closeable, false); 
    } 

    public ModalityInternalFrame(JComponent parent, String title, boolean resizable, boolean closeable, 
      boolean maximizable) { 
     this(parent, title, resizable, closeable, maximizable, false); 
    } 

    public ModalityInternalFrame(JComponent parent, String title, boolean resizable, boolean closeable, 
      boolean maximizable, 
      boolean iconifiable) { 
     super(title, resizable, closeable, maximizable, iconifiable); 
     setParentFrame(parent); 
     //setFocusTraversalKeysEnabled(false); 
     if (parent != null && parent instanceof ModalityInternalFrame) { 
      ((ModalityInternalFrame) parent).setChildFrame(ModalityInternalFrame.this); 

      /* 
      * set focus to the new frame and show the frame Code added by Jasir 
      */ 
      try { 
       ((ModalityInternalFrame) parent).setSelected(false); 
       setSelected(true); 
       setVisible(true); 
      } catch (PropertyVetoException ex) { 
       Logger.getLogger(ModalityInternalFrame.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 

     // Add glass pane 
     ModalityInternalGlassPane glassPane = new ModalityInternalGlassPane(this); 
     setGlassPane(glassPane); 


     // Add frame listeners 
     addFrameListener(); 

     // Add frame veto listenr 
     addFrameVetoListener(); 

     init(); 


     // calculate size and position 


    } 

    private void setParentFrame(JComponent parent) { 
     desktopPane = JOptionPane.getDesktopPaneForComponent(parent); 
     this.parent = parent == null ? JOptionPane.getDesktopPaneForComponent(parent) : parent; // default to desktop if no parent given 
    } 

    public JComponent getParentFrame() { 
     return parent; 
    } 

    public void setChildFrame(ModalityInternalFrame childFrame) { 
     this.childFrame = childFrame; 
    } 

    public ModalityInternalFrame getChildFrame() { 
     return childFrame; 
    } 

    public boolean hasChildFrame() { 
     return (childFrame != null); 
    } 

    protected void addFrameVetoListener() { 
     addVetoableChangeListener(new VetoableChangeListener() { 

      public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException { 
       if (evt.getPropertyName().equals(JInternalFrame.IS_SELECTED_PROPERTY) 
         && evt.getNewValue().equals(Boolean.TRUE)) { 
        if (hasChildFrame()) { 
         //childFrame.setSelected(true); 
         if (childFrame.isIcon()) { 
          childFrame.setIcon(false); 
         } 
         throw new PropertyVetoException("no!", evt); 
        } 
       } 
      } 
     }); 
    } 

    /** 
    * Method to control the display of the glass pane, dependant on the frame 
    * being active or not 
    */ 
    protected synchronized void addFrameListener() { 
     addInternalFrameListener(new InternalFrameAdapter() { 

      @Override 
      public void internalFrameActivated(InternalFrameEvent e) { 
       if (hasChildFrame() == true) { 
        getGlassPane().setVisible(true); 
        grabFocus(); 
       } else { 
        getGlassPane().setVisible(false); 
       } 
      } 

      @Override 
      public void internalFrameOpened(InternalFrameEvent e) { 
       getGlassPane().setVisible(false); 
       try { 
        setSelected(true); 
       } catch (PropertyVetoException ex) { 
        Logger.getLogger(ModalityInternalFrame.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 

      @Override 
      public void internalFrameClosing(InternalFrameEvent e) { 
       if (parent != null && parent instanceof ModalityInternalFrame) { 
        ((ModalityInternalFrame) parent).childClosing(); 
       } 
      } 
     }); 
    } 

    /** 
    * Method to handle child frame closing and make this frame available for 
    * user input again with no glass pane visible 
    */ 
    protected void childClosing() { 
     setClosable(wasCloseable); 
     getGlassPane().setVisible(false); 
     if (focusOwner != null) { 
      java.awt.EventQueue.invokeLater(new Runnable() { 

       @Override 
       public void run() { 
        try { 
         moveToFront(); 
         setSelected(true); 
         focusOwner.grabFocus(); 
        } catch (PropertyVetoException ex) { 
        } 
       } 
      }); 
      focusOwner.grabFocus(); 
     } 
     getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 
     setChildFrame(null); 
     getDesktopPane().setSelectedFrame(this); 
     System.out.println(getDesktopPane().getSelectedFrame()); 
    } 

    /* 
    * Method to handle child opening and becoming visible. 
    */ 
    protected void childOpening() { 
     // record the present focused component 
     wasCloseable = isClosable(); 
     setClosable(false); 
     focusOwner = (JComponent) getMostRecentFocusOwner(); 
     grabFocus(); 
     getGlassPane().setVisible(true); 
     getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 
    } 

    @Override 
    public void show() { 
     if (parent != null && parent instanceof ModalityInternalFrame) { 
      // Need to inform parent its about to lose its focus due 
      // to child opening 
      ((ModalityInternalFrame) parent).childOpening(); 
     } 
     calculateBounds(); 
     super.show(); 
    } 

    protected void init() { 
     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
       layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 394, Short.MAX_VALUE)); 
     layout.setVerticalGroup(
       layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 274, Short.MAX_VALUE)); 

     pack(); 
    } 

    public void calculateBounds() { 
     Dimension frameSize = getPreferredSize(); 
     Dimension parentSize = new Dimension(); 
     Dimension rootSize = new Dimension(); // size of desktop 
     Point frameCoord = new Point(); 

     if (desktopPane != null) { 
      rootSize = desktopPane.getSize(); // size of desktop 
      frameCoord = SwingUtilities.convertPoint(parent, 0, 0, desktopPane); 
      parentSize = parent.getSize(); 
     } 

     //setBounds((rootSize.width - frameSize.width)/2, (rootSize.height - frameSize.height)/2, frameSize.width, frameSize.height); 

     // We want dialog centered relative to its parent component 
     int x = (parentSize.width - frameSize.width)/2 + frameCoord.x; 
     int y = (parentSize.height - frameSize.height)/2 + frameCoord.y; 

     // If possible, dialog should be fully visible 
     int ovrx = x + frameSize.width - rootSize.width; 
     int ovry = y + frameSize.height - rootSize.height; 
     x = Math.max((ovrx > 0 ? x - ovrx : x), 0); 
     y = Math.max((ovry > 0 ? y - ovry : y), 0); 
     setBounds(x, y, frameSize.width, frameSize.height); 
    } 

    /** 
    * Glass pane to overlay. Listens for mouse clicks and sets selected on 
    * associated modal frame. Also if modal frame has no children make class 
    * pane invisible 
    */ 
    class ModalityInternalGlassPane extends JComponent { 

     private ModalityInternalFrame modalFrame; 

     public ModalityInternalGlassPane(ModalityInternalFrame frame) { 
      modalFrame = frame; 
      addMouseListener(new MouseAdapter() { 

       @Override 
       public void mouseClicked(MouseEvent e) { 
        if (modalFrame.isSelected() == false) { 
         try { 
          modalFrame.setSelected(true); 
          if (modalFrame.hasChildFrame() == false) { 
           setVisible(false); 
          } 
         } catch (PropertyVetoException e1) { 
          //e1.printStackTrace(); 
         } 
        } 
       } 
      }); 
     } 

     @Override 
     public void paint(Graphics g) { 
      super.paint(g); 
      g.setColor(new Color(255, 255, 255, 100)); 
      g.fillRect(0, 0, getWidth(), getHeight()); 
     } 
    } 
} 

但也存在一些問題仍然重點和別的東西..

1

我也正在使用其顯示自定義對話框一個LOF內部框架的MDI應用程序。我使我的對話框非模態化,以便內部框架可以被圖標化和/或整個桌面窗格可以最小化,而對話框仍然可見。

如果你絕對需要模態行爲(即,你想要求用戶與做其他事情之前的對話交互)也許你可以離開對話框無模式,但事實上形態代碼。您是否看到過 的行爲?setModalityType(java.awt.Dialog.ModalityType.DOCUMENT_MODAL);

2

我也有同樣的問題,在一個Java項目,工作在Java 6的相當不錯,但如果改爲java7顯示了同樣的問題而工作。

我找到了解決辦法。 我添加了一個 dialog.setVisible(false)後跟一個dialog.setVisible(true)。 然後對話框響應鍵盤。

相關問題