提问者:小点点

JDesktopPane调整大小


我们有一个带有两个JFrame和两个JDesktopPane的应用程序。我们需要将内部框架从一个框架移动到另一个框架。

我们遇到的问题是,在我们将内部框架从第一个窗口移动到第二个窗口之后,当我们调整第一个窗口的大小时,第二个窗的内部框架也会被调整大小。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyVetoException;

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

class FirstFrame extends JFrame
{
  JDesktopPane desktopPane = new JDesktopPane();

  SecondFrame secondFrame;

  public FirstFrame(SecondFrame secondFrame)
  {
    this.secondFrame = secondFrame;
    setTitle("FirstFrame example");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    add(desktopPane);

    JMenuBar menuBar = new JMenuBar();
    JMenu menu = new JMenu("File");
    JMenuItem item = new JMenuItem("Move");

    item.addActionListener(new ActionListener()
    {

      @Override
      public void actionPerformed(ActionEvent actionevent)
      {
        moveFrame();
      }
    });

    menu.add(item);
    menuBar.add(menu);
    setJMenuBar(menuBar);

  }

  public void addAnInternalFrame()
  {
    JInternalFrame frame = new JInternalFrame();
    frame.setTitle("An Internal Frame");

    desktopPane.add(frame);
    frame.setVisible(true);
    frame.setMaximizable(true);
    try
    {
      frame.setSelected(true);
      frame.setMaximum(true);
    }
    catch (PropertyVetoException e)
    {
      e.printStackTrace();
    }

  }

  public void moveFrame()
  {
    JInternalFrame selectedFrame = desktopPane.getSelectedFrame();
    desktopPane.remove(selectedFrame);
    desktopPane.repaint();

    secondFrame.addInternalFrame(selectedFrame);
  }
}

class SecondFrame extends JFrame
{
  JDesktopPane desktopPane = new JDesktopPane();

  public SecondFrame()
  {
    setTitle("SecondFrame example");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    add(desktopPane);
  }

  public void addInternalFrame(JInternalFrame frame)
  {
    desktopPane.add(frame);
  }
}

public class DesktopPaneExample
{
  public static void main(String args[]) throws PropertyVetoException
  {

    SecondFrame secondFrame = new SecondFrame();

    FirstFrame firstFrame = new FirstFrame(secondFrame);

    firstFrame.setSize(400, 400);
    firstFrame.setLocation(100, 100);
    firstFrame.setVisible(true);
    firstFrame.addAnInternalFrame();

    secondFrame.setSize(400, 400);
    secondFrame.setLocation(520, 100);
    secondFrame.setVisible(true);




  }
}

在上面的示例应用程序中,要重现1)单击菜单文件

注意:这仅在Java1.7中可复制。我使用jdk1.7。0_03。

这在Java 1.6 (jdk1.6.0_21)上是不可再现的


共2个答案

匿名用户

该问题是由于Java 7对javax.swing.plaf.basic.BasicInternalFrameUI实现的调整。

>

  • Java1.6代码

    public void propertyChange(PropertyChangeEvent evt){

            if ((frame.getParent() != null) && !componentListenerAdded) {
                f.getParent().addComponentListener(componentListener);
                componentListenerAdded = true;
            } else if ((newValue == null) && componentListenerAdded) {
                if (f.getParent() != null) {
                    f.getParent()
                            .removeComponentListener(componentListener);
                }
                componentListenerAdded = false;
            }
    

    Java1.7代码

    public void propertyChange(PropertyChangeEvent evt){

            if ((frame.getParent() != null) && !componentListenerAdded) {
                f.getParent().addComponentListener(componentListener);
                componentListenerAdded = true;
            }
    

    注意:删除了else if条件。这是罪魁祸首。

    我建议您两种选择:

    > < li>

    选项一

    JInternalFrame selectedFrame = desktopPane.getSelectedFrame();
    desktopPane.remove(selectedFrame);
    desktopPane.repaint();
    
    secondFrame.updateUI(); // The magic part, less expensive execution.
    
    secondFrame.addInternalFrame(selectedFrame);
    

    选项二

    您可能需要使用上述“else if”条件重新编译javax.swing.plaf.basic.BasicInternalFrameUI.java并添加到rt.jar库的javax.swing.plaf.basic位置。

    我附上了1.7Java重新编译的文件。0_25http://www.datafilehost.com/d/dfb7238c

    希望这能有所帮助!!!

    此致,Nilindra

  • 匿名用户

    似乎在最大状态下添加框架是罪魁祸首。要在第一帧到第二帧之间保持其当前大小,请尝试以下方法:

    public void moveFrame()
    {
      JInternalFrame selectedFrame = desktopPane.getSelectedFrame();
      Dimension currentSize = selectedFrame.getSize();
      try
      {
        selectedFrame.setMaximum(false);
      }
      catch (PropertyVetoException ex)
      {
        ex.printStackTrace();
      }
      selectedFrame.setSize(currentSize);
    
      desktopPane.remove(selectedFrame);
      desktopPane.repaint();
      secondFrame.addInternalFrame(selectedFrame);
    }
    

    编辑:

    在阅读了Container#删除(组件c)的API后,我得到了这个似乎有效的想法:

    public void moveFrame()
    {
      final JInternalFrame selectedFrame = desktopPane.getSelectedFrame();
    
      desktopPane.remove(selectedFrame);
      desktopPane.repaint();
      SwingUtilities.updateComponentTreeUI(selectedFrame);
    
      SwingUtilities.invokeLater(new Runnable()
      {
        public void run()
        {
          secondFrame.addInternalFrame(selectedFrame);
        }
      });
    }