1

在下面的SSCCE中,您可以看到如果最大化JInternalFrame之一,那么它最大化它们两者。只有(AFAIK)发生在“Windows”LookAndFeel(如果您省略了LookAndFeel代码,则按预期工作)。使JInternalFrame Windows最大化外观和感觉最大化所有JInternalFrame

重现:

  1. 运行SSCCE下方。
  2. 最大化其中一个JInternalFrame s。
  3. 关闭(X)你最大化的那个
  4. 观察另一个也是最大化的。

有没有什么办法可以阻止这种行为?这是一个错误?

SSCCE:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Font; 
import javax.swing.JDesktopPane; 
import javax.swing.JFrame; 
import javax.swing.JInternalFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingConstants; 

class Test2 { 
    public static void main(String[] args) { 
     try { 
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
       if ("Windows".equals(info.getName())) { 
        javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException e) { 
      e.printStackTrace(); 
     } 
     JFrame frame = new JFrame(); 
     JDesktopPane jdp = new JDesktopPane(); 
     jdp.setBackground(Color.gray); 
     frame.add(jdp); 
     jdp.setVisible(true); 
     frame.setExtendedState(frame.getExtendedState()|JFrame.MAXIMIZED_BOTH); 
     frame.setVisible(true); 

     JInternalFrame jiffy1 = new JInternalFrame("Jiffy1", true, true, true, true); 
     jdp.add(jiffy1); 
     JLabel jiffy1_label = new JLabel("Jiffy1"); 
     jiffy1_label.setHorizontalAlignment(SwingConstants.CENTER); 
     jiffy1_label.setFont(new Font("Tahoma", 0, 50)); 
     jiffy1.add(jiffy1_label); 
     jiffy1.setPreferredSize(new Dimension(300,300)); 
     jiffy1.setVisible(true); 
     jiffy1.pack(); 
     centerJIF(jdp, jiffy1); 

     JInternalFrame jiffy2 = new JInternalFrame("Jiffy2", true, true, true, true); 
     jdp.add(jiffy2); 
     JLabel jiffy2_label = new JLabel("Jiffy2"); 
     jiffy2_label.setHorizontalAlignment(SwingConstants.CENTER); 
     jiffy2_label.setFont(new Font("Tahoma", 0, 50)); 
     jiffy2.add(jiffy2_label); 
     jiffy2.setPreferredSize(new Dimension(200,200)); 
     jiffy2.setVisible(true); 
     jiffy2.pack(); 
     centerJIF(jdp, jiffy2); 

     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    private static void centerJIF(JDesktopPane jdp, JInternalFrame jiffy) { 
     Dimension desktopSize = jdp.getSize(); 
     Dimension VInternalFrameSize = jiffy.getSize(); 
     int width = (desktopSize.width - VInternalFrameSize.width)/2; 
     int height = (desktopSize.height - VInternalFrameSize.height)/2; 
     jiffy.setLocation(width, height); 
    } 
} 
+0

是这是一个机智问题h Windows外观和感觉'DesktopManager' – MadProgrammer

+0

@MadProgrammer *“这是Windows外观和感觉的问题”*它是什么?我的意思是,做其他内部框架的Windows应用程序。做同样的事情(1)?如果是这样,它几乎不像是一个“问题”,而不是简单地遵守那个外观和感觉。 1)这不是一个浮夸的问题,我真的不知道答案。 –

+0

@AndrewThompson这实际上可能是它设计的方式(对不起,我试图找出为什么我们放弃它)。我们从金属外观和感觉切换到Windows,并且偶然发现了这个问题,所以不,其他的外观和感觉都会有所不同。是在标准的Windows ...嗯,不知道MDIs与Windows 3.1贬值。我们切换到使用'DefaultDesktopManager',不记得我们是否修改它... – MadProgrammer

回答

2

在Windows的DesktopManager有一个功能(在我看来一个bug ......)当你最大化一个框架,最大限度地提高所有帧。

WindowsDesktopManager.java(Java 7中)从管线62

... 
public void activateFrame(JInternalFrame f) { 
    JInternalFrame currentFrame = currentFrameRef != null ? 
     currentFrameRef.get() : null; 
    try { 
     super.activateFrame(f); 
     if (currentFrame != null && f != currentFrame) { 
  // If the current frame is maximized, transfer that 
      // attribute to the frame being activated. 
  if (currentFrame.isMaximum() && 
     (f.getClientProperty("JInternalFrame.frameType") != 
     "optionDialog")) { 
       //Special case. If key binding was used to select next 
       //frame instead of minimizing the icon via the minimize 
       //icon. 
       if (!currentFrame.isIcon()) { 
        currentFrame.setMaximum(false); 
        if (f.isMaximizable()) { 
         if (!f.isMaximum()) { 
          f.setMaximum(true); 
         } else if (f.isMaximum() && f.isIcon()) { 
          f.setIcon(false); 
         } else { 
          f.setMaximum(false); 
         } 
        } 
       } 
      } 
      if (currentFrame.isSelected()) { 
       currentFrame.setSelected(false); 
      } 
     } 

     if (!f.isSelected()) { 
      f.setSelected(true); 
     } 
    } catch (PropertyVetoException e) {} 
    if (f != currentFrame) { 
     currentFrameRef = new WeakReference(f); 
    } 
} 
... 

这样你就可以重新安装DefaultDesktopManager代替WindowsDesktopManager和解决的问题:

JDesktopPane jdp = new JDesktopPane(); 
jdp.setDesktopManager(new DefaultDesktopManager()); 
+1

哇,这伎俩!谢谢! – ryvantage