关闭内部JFrame而不选择框架



我对Java真的很陌生。我对获取 JInternalFrame 有疑问。我在网上搜索并找到了示例。我稍微修改了一下示例,添加一个关闭菜单项,但它对我的代码不起作用。在项目中,如果我关闭了 JInternalFrame 而没有先选择它,那么我就有错误。我试图遍历 WindowMenu 以获取选定的 JcheckboxMenuitem,但它没有得到任何组件。有人会告诉我该怎么做吗?

有代码:

// This is example is from Kjell Dirdal.
// Referenced from http://www.javaworld.com/javaworld/jw-05-2001/jw-0525-mdi.html

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyVetoException;
import javax.swing.DefaultDesktopManager;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JViewport;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;

public class KjellDirdalNotepad extends JFrame {
private MDIDesktopPane desktop = new MDIDesktopPane();
private JMenuBar menuBar = new JMenuBar();
private JMenu fileMenu = new JMenu("File");
private JMenuItem newMenu = new JMenuItem("New");
private JScrollPane scrollPane = new JScrollPane();
private JMenuItem closeMenu=new JMenuItem("Close");
private int index=1;
private WindowMenu wMenu=null;
public KjellDirdalNotepad() {
   menuBar.add(fileMenu);
   wMenu=new WindowMenu(desktop);
   menuBar.add(wMenu);
   fileMenu.add(newMenu);
   fileMenu.add(closeMenu);
   setJMenuBar(menuBar);
   setTitle("MDI Test");
   scrollPane.getViewport().add(desktop);
   getContentPane().setLayout(new BorderLayout());
   getContentPane().add(scrollPane, BorderLayout.CENTER);
   addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
     System.exit(0);
   }
  });
newMenu.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent ae) {
    desktop.add(new TextFrame(String.valueOf(index)));
    index=index+1;
  }
});
//I added the close menu
closeMenu.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
        JInternalFrame f=desktop.getSelectedFrame();
         if (f==null)
         {
             for (Component child: wMenu.getComponents()){
                 if (child instanceof WindowMenu.ChildMenuItem){
                     JCheckBoxMenuItem item=(JCheckBoxMenuItem) child;
                    if( item.isSelected()){
                        DisplayTestMsg(item.getText());
                 }
             }
           }
           }
           else{
             f.dispose(); 
           }
        }
        });
     }
        public   void DisplayTestMsg(String msg){
    //custom title, error icon
     JTextArea textArea=new JTextArea(msg);
     textArea.setColumns(30);
     textArea.setLineWrap( true );
     textArea.setWrapStyleWord( true );
     textArea.setSize(textArea.getPreferredSize().width, 1);
     JOptionPane.showMessageDialog(null,
            textArea,
         "Test",
         JOptionPane.WARNING_MESSAGE);
 }
      public static void main(String[] args) {
        KjellDirdalNotepad notepad = new KjellDirdalNotepad();
        notepad.setSize(600, 400);
       notepad.setVisible(true);
      }
}
class TextFrame extends JInternalFrame {
  private JTextArea textArea = new JTextArea();
  private JScrollPane scrollPane = new JScrollPane();
 public TextFrame(String title) {
 setSize(200, 300);
 setTitle("Edit Text-" + title);
setMaximizable(true);
setIconifiable(true);
setClosable(true);
setResizable(true);
scrollPane.getViewport().add(textArea);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(scrollPane, BorderLayout.CENTER);
 }
}
/**
 * An extension of WDesktopPane that supports often used MDI functionality. This
 * class also handles setting scroll bars for when windows move too far to the
 * left or bottom, providing the MDIDesktopPane is in a ScrollPane.
 */
class MDIDesktopPane extends JDesktopPane {
private static int FRAME_OFFSET = 20;
 private MDIDesktopManager manager;
  public MDIDesktopPane() {
    manager = new MDIDesktopManager(this);
    setDesktopManager(manager);
    setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
   }
  public void setBounds(int x, int y, int w, int h) {
    super.setBounds(x, y, w, h);
    checkDesktopSize();
  }
  public Component add(JInternalFrame frame) {
    JInternalFrame[] array = getAllFrames();
    Point p;
    int w;
    int h;
    Component retval = super.add(frame);
    checkDesktopSize();
    if (array.length > 0) {
      p = array[0].getLocation();
      p.x = p.x + FRAME_OFFSET;
      p.y = p.y + FRAME_OFFSET;
    } else {
     p = new Point(0, 0);
    }
    frame.setLocation(p.x, p.y);
    if (frame.isResizable()) {
      w = getWidth() - (getWidth() / 3);
      h = getHeight() - (getHeight() / 3);
      if (w < frame.getMinimumSize().getWidth())
         w = (int) frame.getMinimumSize().getWidth();
      if (h < frame.getMinimumSize().getHeight())
         h = (int) frame.getMinimumSize().getHeight();
      frame.setSize(w, h);
   }
    moveToFront(frame);
   frame.setVisible(true);
   try {
     frame.setSelected(true);
   } catch (PropertyVetoException e) {
      frame.toBack();
    }
    return retval;
  }
 public void remove(Component c) {
    super.remove(c);
   checkDesktopSize();
 }
  /**
   * Cascade all internal frames
   */
  public void cascadeFrames() {
    int x = 0;
    int y = 0;
    JInternalFrame allFrames[] = getAllFrames();
    manager.setNormalSize();
    int frameHeight = (getBounds().height - 5) - allFrames.length * FRAME_OFFSET;
    int frameWidth = (getBounds().width - 5) - allFrames.length * FRAME_OFFSET;
    for (int i = allFrames.length - 1; i >= 0; i--) {
         allFrames[i].setSize(frameWidth, frameHeight);
        allFrames[i].setLocation(x, y);
       x = x + FRAME_OFFSET;
      y = y + FRAME_OFFSET;
    }
  }
  /**
   * Tile all internal frames
   */
  public void tileFrames() {
    java.awt.Component allFrames[] = getAllFrames();
    manager.setNormalSize();
    int frameHeight = getBounds().height / allFrames.length;
    int y = 0;
    for (int i = 0; i < allFrames.length; i++) {
       allFrames[i].setSize(getBounds().width, frameHeight);
      allFrames[i].setLocation(0, y);
      y = y + frameHeight;
    }
  }
  /**
   * Sets all component size properties ( maximum, minimum, preferred) to the
   * given dimension.
   */
  public void setAllSize(Dimension d) {
    setMinimumSize(d);
    setMaximumSize(d);
    setPreferredSize(d);
  }
  /**
    * Sets all component size properties ( maximum, minimum, preferred) to the
   * given width and height.
   */
  public void setAllSize(int width, int height) {
    setAllSize(new Dimension(width, height));
  }
  private void checkDesktopSize() {
    if (getParent() != null && isVisible())
      manager.resizeDesktop();
  }
}
/**
 * Private class used to replace the standard DesktopManager for JDesktopPane.
 * Used to provide scrollbar functionality.
 */
class MDIDesktopManager extends DefaultDesktopManager {
  private MDIDesktopPane desktop;
  public MDIDesktopManager(MDIDesktopPane desktop) {
    this.desktop = desktop;
  }
  public void endResizingFrame(JComponent f) {
    super.endResizingFrame(f);
    resizeDesktop();
  }
  public void endDraggingFrame(JComponent f) {
    super.endDraggingFrame(f);
    resizeDesktop();
  }
  public void setNormalSize() {
    JScrollPane scrollPane = getScrollPane();
    int x = 0;
    int y = 0;
    Insets scrollInsets = getScrollPaneInsets();
    if (scrollPane != null) {
      Dimension d = scrollPane.getVisibleRect().getSize();
      if (scrollPane.getBorder() != null) {
        d.setSize(d.getWidth() - scrollInsets.left - scrollInsets.right, d.getHeight()
            - scrollInsets.top - scrollInsets.bottom);
      }
       d.setSize(d.getWidth() - 20, d.getHeight() - 20);
      desktop.setAllSize(x, y);
      scrollPane.invalidate();
      scrollPane.validate();
    }
  }
  private Insets getScrollPaneInsets() {
    JScrollPane scrollPane = getScrollPane();
    if (scrollPane == null)
      return new Insets(0, 0, 0, 0);
    else
      return getScrollPane().getBorder().getBorderInsets(scrollPane);
  }
   private JScrollPane getScrollPane() {
     if (desktop.getParent() instanceof JViewport) {
       JViewport viewPort = (JViewport) desktop.getParent();
     if (viewPort.getParent() instanceof JScrollPane)
       return (JScrollPane) viewPort.getParent();
    }
     return null;
   }
  protected void resizeDesktop() {
    int x = 0;
    int y = 0;
    JScrollPane scrollPane = getScrollPane();
    Insets scrollInsets = getScrollPaneInsets();
    if (scrollPane != null) {
      JInternalFrame allFrames[] = desktop.getAllFrames();
      for (int i = 0; i < allFrames.length; i++) {
        if (allFrames[i].getX() + allFrames[i].getWidth() > x) {
           x = allFrames[i].getX() + allFrames[i].getWidth();
        }
        if (allFrames[i].getY() + allFrames[i].getHeight() > y) {
          y = allFrames[i].getY() + allFrames[i].getHeight();
        }
      }
      Dimension d = scrollPane.getVisibleRect().getSize();
      if (scrollPane.getBorder() != null) {
        d.setSize(d.getWidth() - scrollInsets.left - scrollInsets.right, d.getHeight()
        - scrollInsets.top - scrollInsets.bottom);
      }
      if (x <= d.getWidth())
        x = ((int) d.getWidth()) - 20;
      if (y <= d.getHeight())
        y = ((int) d.getHeight()) - 20;
      desktop.setAllSize(x, y);
      scrollPane.invalidate();
      scrollPane.validate();
    }
  }
}
/**
 * Menu component that handles the functionality expected of a standard
 * "Windows" menu for MDI applications.
 */
 class WindowMenu extends JMenu {
  private MDIDesktopPane desktop;
  private JMenuItem cascade = new JMenuItem("Cascade");
  private JMenuItem tile = new JMenuItem("Tile");
  public WindowMenu(MDIDesktopPane desktop) {
    this.desktop = desktop;
    setText("Window");
    cascade.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        WindowMenu.this.desktop.cascadeFrames();
      }
    });
    tile.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        WindowMenu.this.desktop.tileFrames();
      }
    });
    addMenuListener(new MenuListener() {
      public void menuCanceled(MenuEvent e) {
      }
  public void menuDeselected(MenuEvent e) {
    removeAll();
  }
  public void menuSelected(MenuEvent e) {
    buildChildMenus();
  }
});
  }
  /* Sets up the children menus depending on the current desktop state */
  private void buildChildMenus() {
      int i;
     ChildMenuItem menu;
     JInternalFrame[] array = desktop.getAllFrames();
     add(cascade);
     add(tile);
     if (array.length > 0)
       addSeparator();
       cascade.setEnabled(array.length > 0);
      tile.setEnabled(array.length > 0);
    for (i = 0; i < array.length; i++) {
      menu = new ChildMenuItem(array[i]);
      menu.setState(i == 0);
      menu.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
          JInternalFrame frame = ((ChildMenuItem) ae.getSource()).getFrame();
          frame.moveToFront();
          try {
            frame.setSelected(true);
          } catch (PropertyVetoException e) {
            e.printStackTrace();
          }
        }
      });
      menu.setIcon(array[i].getFrameIcon());
      add(menu);
    }
  }
  /*
   * This JCheckBoxMenuItem descendant is used to track the child frame that
   * corresponds to a give menu.
   */
  class ChildMenuItem extends JCheckBoxMenuItem {
    private JInternalFrame frame;
    public ChildMenuItem(JInternalFrame frame) {
      super(frame.getTitle());
      this.frame = frame;
    }
    public JInternalFrame getFrame() {
      return frame;
    }
  }

}
如果你想在

按下按钮时删除 JPanel,你可以调用 JFrame.remove(panel),例如:

final JFrame frame = new JFrame("test");
final JPanel panel = new JPanel();
//add the panel at the start
frame.add(panel);
// when the buttons clicked
button.addActionListener(new ActionListener() {
    @Override
    public void ActionPerformed(ActionEvent e) {
        frame.remove(panel);
        frame.repaint();
    };
});

我想通了。我在类窗口菜单上添加了该方法,如下所示。单击关闭按钮而不选择内部框架时,将调用此方法。

   public JInternalFrame getFrontFrame(){       
   InternalFrame[] array = desktop.getAllFrames();
  JInternalFrame f=(JInternalFrame)array[0];
 return f;
 }