如何使用内部框架

原文: https://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html

使用 JInternalFrame 类,您可以在另一个窗口中显示 JFrame 类似的窗口。通常,您将内部框架添加到桌面窗格。反过来,桌面窗格可以用作JFrame的内容窗格。桌面窗格是 JDesktopPane 的一个实例,它是 JLayeredPane 的子类,添加了用于管理多个重叠内部帧的 API。

您应该仔细考虑是否将程序的 GUI 基于框架或内部框架。从内部帧切换到帧或反之亦然不一定是简单的任务。通过试验框架和内部框架,您可以了解选择一个框架和另一个框架所涉及的权衡。

这是一个应用程序的图片,在常规框架内有两个内部框架(其中一个图标化):

InternalFrameDemo has multiple internal frames, managed by a desktop pane


Try this:

  1. 单击“启动”按钮以使用 Java™Web Start下载 JDK 7 或更高版本)运行 InternalFrameDemo。或者,要自己编译并运行示例,请参考示例索引Launches the InternalFrameDemo example

  2. 使用“文档”菜单中的“创建”项创建新的内部框架。 每个内部框架低至 30 像素,位于前一个内部框架首次出现的位置的右​​侧。此功能在MyInternalFrame类中实现,该类是JInternalFrame的自定义子类。


以下代码取自 InternalFrameDemo.java ,在上一个示例中创建了桌面和内部帧。

  1. ...//In the constructor of InternalFrameDemo, a JFrame subclass:
  2. desktop = new JDesktopPane();
  3. createFrame(); //Create first window
  4. setContentPane(desktop);
  5. ...
  6. //Make dragging a little faster but perhaps uglier.
  7. desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
  8. ...
  9. protected void createFrame() {
  10. MyInternalFrame frame = new MyInternalFrame();
  11. frame.setVisible(true);
  12. desktop.add(frame);
  13. try {
  14. frame.setSelected(true);
  15. } catch (java.beans.PropertyVetoException e) {}
  16. }
  17. ...//In the constructor of MyInternalFrame, a JInternalFrame subclass:
  18. static int openFrameCount = 0;
  19. static final int xOffset = 30, yOffset = 30;
  20. public MyInternalFrame() {
  21. super("Document #" + (++openFrameCount),
  22. true, //resizable
  23. true, //closable
  24. true, //maximizable
  25. true);//iconifiable
  26. //...Create the GUI and put it in the window...
  27. //...Then set the window size or call pack...
  28. ...
  29. //Set the window's location.
  30. setLocation(xOffset*openFrameCount, yOffset*openFrameCount);
  31. }

使用内部帧的代码在很多方面类似于使用常规 Swing 帧的代码。由于内部框架具有根窗格,因此为JInternalFrame设置 GUI 与为JFrame设置 GUI 非常相似。 JInternalFrame还提供其他 API,例如pack,使其类似于JFrame


Note:

与常规帧一样,您必须在内部帧上调用setVisible(true)show()来显示它。在您明确显示内部框架之前,内部框架不会出现。


但是,内部框架不是窗口或顶级容器,这使得它们与框架不同。例如,您必须将一个内部框架添加到容器(通常是JDesktopPane);内部框架不能是包含层次结构的根。此外,内部帧不会生成窗口事件。相反,导致框架触发窗口事件的用户操作会导致内部框架触发内部框架事件。

由于内部框架是使用与平台无关的代码实现的,因此它们会添加一些框架无法提供的功能。其中一个特点是内部框架可以让您比帧更能控制其状态和功能。您可以以编程方式图标化或最大化内部框架。您还可以指定内部框架标题栏中的图标。您甚至可以指定内部框架是否具有窗口装饰以支持调整大小,图标化,关闭和最大化。

另一个特性是内部框架设计用于桌面窗格。 JInternalFrame API 包含moveToFront等方法,仅当内部框架的容器是JDesktopPane等分层窗格时才有效。

如果您使用JFrame和其他 Swing 组件构建了任何程序,那么您已经了解了很多关于如何使用内部框架的知识。以下列表总结了使用内部框架的规则。有关其他信息,请参见如何制作帧JComponent 类

You must set the size of the internal frame.

If you do not set the size of the internal frame, it will have zero size and thus never be visible. You can set the size using one of the following methods: setSize, pack, or setBounds.

As a rule, you should set the location of the internal frame.

If you do not set the location of the internal frame, it will come up at 0,0 (the upper left of its container). You can use the setLocation or setBounds method to specify the upper left point of the internal frame, relative to its container.

To add components to an internal frame, you add them to the internal frame’s content pane.

This is exactly like the JFrame situation. See Adding Components to the Content Pane for details.

Dialogs that are internal frames should be implemented using JOptionPane or JInternalFrame, not JDialog.

To create a simple dialog, you can use the JOptionPane showInternal_Xxx_Dialog methods, as described in How to Make Dialogs.

You must add an internal frame to a container.

If you do not add the internal frame to a container (usually a JDesktopPane), the internal frame will not appear.

You need to call show or setVisible on internal frames.

Internal frames are invisible by default. You must invoke setVisible(true) or show() to make them visible.

Internal frames fire internal frame events, not window events.

Handling internal frame events is almost identical to handling window events. See How to Write an Internal Frame Listener for more information.


Performance tip:

当桌面有许多内部框架时,用户可能会注意到移动它们似乎很慢。大纲拖动是避免此问题的一种方法。使用轮廓拖动时,只有内部框架的轮廓在当前鼠标位置被绘制,同时内部框架被拖动。在拖动停止之前,内部框架的内部不会在新位置重新绘制。默认行为(称为 live 拖动)是在移动时连续重新定位和重绘部分或全部内部帧;如果桌面有许多内部框架,这可能会很慢。

使用JDesktopPane方法setDragMode *指定轮廓拖动。例如:

  1. desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);

下表列出了常用的JInternalFrame构造器和方法,以及JDesktopPane提供的一些方法。除了本节中列出的 API 之外,JInternalFrame还从其超类JComponentComponentContainer继承了有用的 API。有关这些类的方法列表,请参见 JComponent 类

JInternalFrame类似,JDesktopPaneJComponent下降,因此提供 JComponent 类中描述的方法。因为JDesktopPane扩展了JLayeredPane,它还支持分层窗格 API 中描述的方法。

使用内部框架的 API 属于以下类别:

构造器或方法 目的
JInternalFrame()

JInternalFrame(String) JInternalFrame(String,boolean) JInternalFrame(String,boolean,boolean ) JInternalFrame(String,boolean,boolean,boolean) JInternalFrame(String,boolean,boolean,boolean,boolean) | 创建JInternalFrame实例。第一个参数指定内部框架显示的标题(如果有)。其余参数指定内部框架是否应包含允许用户调整内部框架(按该顺序指定)的大小,关闭,最大化和图标化的装饰。每个布尔参数的默认值为false,这意味着不允许该操作。 | | static int showInternalConfirmDialog(Component,Object) static String showInternalInputDialog(Component,Object) static Object showInternalMessageDialog(Component,Object) static int showInternalOptionDialog(Component,Object,String,int,int,Icon,Object [],Object) | 创建一个模拟对话框的JInternalFrame。有关详细信息,请参见如何制作对话框。 |

方法 目的
void setContentPane(Container)

Container getContentPane() | 设置或获取内部框架的内容窗格,该窗格通常包含所有内部框架的 GUI,但菜单栏和窗口装饰除外。 | | void setJMenuBar(JMenuBar) JMenuBar getJMenuBar() | 设置或获取内部框架的菜单栏。 | | void setLayeredPane(JLayeredPane) JLayeredPane getLayeredPane() | 设置或获取内部框架的分层窗格。 |

方法 目的
void setVisible(boolean) 使内部框架可见(如果true)或不可见(如果false)。在将每个JInternalFrame添加到其容器之前,您应该调用setVisible(true)。 (继承自Component)。
void pack() 调整内部框架的尺寸,使其组件处于首选尺寸。
void setLocation(Point)

void setLocation(int,int) | 设置内部框架的位置。 (继承自Component)。 | | void setBounds(Rectangle) void setBounds(int,int,int,int) | 明确设置内部框架的大小和位置。 (继承自Component)。 | | void setSize(Dimension) void setSize(int,int) | 明确设置内部框架的大小。 (继承自Component)。 |

方法 目的
void setDefaultCloseOperation(int)

int getDefaultCloseOperation() | 设置或获取用户尝试“关闭”内部框架时内部框架的作用。默认值为DISPOSE_ON_CLOSE。其他可能的值是DO_NOTHING_ON_CLOSEHIDE_ON_CLOSE有关详细信息,请参阅响应窗口关闭事件。 | | void addInternalFrameListener(InternalFrameListener) void removeInternalFrameListener(InternalFrameListener) | 添加或删除内部框架监听器(JInternalFrame相当于窗口监听器)。有关详细信息,请参见如何编写内部帧监听器。 | | void moveToFront() void moveToBack() | 如果内部框架的父级是分层窗格(如桌面窗格),则将内部框架移动到其图层的前面或后面(分别)。 | | void setClosed(boolean) boolean isClosed() | 设置或获取内部框架当前是否已关闭。 setClosed的参数必须是true。重新打开关闭的内部框架时,可以将其显示并将其添加到容器(通常是最初添加到其中的桌面窗格)。 | | void setIcon(boolean) boolean isIcon() | 对内部框架进行图标化或取消图标化,或确定其当前是否已图标化。 | | void setMaximum(boolean) boolean isMaximum() | 最大化或恢复内部框架,或确定它是否已最大化。 | | void setSelected(boolean) boolean isSelected() | 设置或获取内部框架是否为当前“选定”(激活)的内部框架。 |

方法 目的
void setFrameIcon(Icon)

Icon getFrameIcon() | 设置或获取内部框架标题栏中显示的图标(通常位于左上角)。 | | void setClosable(boolean) boolean isClosable() | 设置或获取用户是否可以关闭内部框架。 | | void setIconifiable(boolean) boolean isIconifiable() | 设置或获取内部框架是否可以图标化。 | | void setMaximizable(boolean) boolean isMaximizable() | 设置或获取用户是否可以最大化此内部框架。 | | void setResizable(boolean) boolean isResizable() | 设置或获取内部框架是否可以调整大小。 | | void setTitle(String) String getTitle() | 设置或获取窗口标题。 |

构造器或方法 目的
JDesktopPane() 创建JDesktopPane的新实例。
JInternalFrame [] getAllFrames() 返回桌面包含的所有JInternalFrame对象。
JInternalFrame [] getAllFramesInLayer(int) 返回桌面包含的指定图层中的所有JInternalFrame对象。有关图层的信息,请参见如何使用分层窗格
void setDragMode(int)

int getDragMode() | 设置或获取此桌面中用于内部帧的拖动模式。整数可以是JDesktopPane.LIVE_DRAG_MODEJDesktopPane.OUTLINE_DRAG_MODE。 Java 外观的默认设置是实时拖动模式。 |

以下示例使用内部框架。因为内部帧与常规帧类似,所以您还应该查看使用帧的示例。

在哪里描述 笔记
MyInternalFrame 这一页。 实现一个内部框架,该框架出现在先前创建的内部框架的偏移处。
InternalFrameDemo 这一页。 允许您创建进入应用程序JDesktopPane的内部框架(MyInternalFrame的实例)。
InternalFrameEventDemo 如何编写内部帧监听器 演示侦听内部帧事件。还演示了在桌面窗格中定位内部框架。