本文通過一個完整可運行的示例,演示如何在 Swing 中使用 JInternalFrame 與 JDesktopPane 構建多文檔界面 (MDI) 風格的內部窗體,並採用 getPreferredSize() 覆寫而非 setSize() 配合 pack() 實現更優雅的窗體尺寸自適應與螢幕居中顯示。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class MyWindow extends JFrame {
JButton btn1, btn2;
JInternalFrame iframe1, iframe2;
JPanel panel;
MyWindow() {
setVisible(true); // 提前可見,內部框架需先可見才能加入桌面面板
panel = (JPanel) getContentPane();
panel.setLayout(new GridLayout(1, 2)); // 左右分欄
btn1 = new JButton("我");
btn2 = new JButton("你");
// 內部框架 A
iframe1 = new JInternalFrame("內窗體A", true, true, true, true); // 可縮放、關閉、最大化、圖標化
iframe1.setSize(150, 250);
iframe1.setVisible(true); // 必須!否則不顯示
iframe1.getContentPane().add(btn1);
JDesktopPane desk1 = new JDesktopPane();
desk1.add(iframe1);
panel.add(desk1);
// 內部框架 B
iframe2 = new JInternalFrame("內窗體B", true, true, true, true);
iframe2.setSize(150, 250);
iframe2.setVisible(true);
iframe2.getContentPane().add(btn2, BorderLayout.CENTER);
iframe2.getContentPane().add(new JLabel("你好啊"), BorderLayout.NORTH);
JDesktopPane desk2 = new JDesktopPane();
desk2.add(iframe2);
panel.add(desk2);
}
// 關鍵:覆寫 getPreferredSize 替代 setSize,配合 pack() 使用效果更佳
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
}
public class InternalFrameDemo {
public static void main(String[] args) {
MyWindow win = new MyWindow();
win.pack(); // 根據 preferredSize 自適應佈局
// 螢幕居中邏輯
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frame = win.getSize();
if (frame.height > screen.height) frame.height = screen.height;
if (frame.width > screen.width) frame.width = screen.width;
win.setLocation((screen.width - frame.width) / 2,
(screen.height - frame.height) / 2);
win.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent e) { System.exit(0); }
});
}
}
setVisible(true) 後再加入 JDesktopPane,否則不渲染。getPreferredSize() 返回期望尺寸,主程序調用 pack() 自動佈局,比直接 setSize() 效果更自然,避免佈局管理器衝突。setLocation(),並處理窗體超出螢幕邊界情況。WindowAdapter 監聽 windowClosing 執行 System.exit(0)。啟動後顯示 500×500 像素主窗體,左右各佔一半,分別包含標題為「內窗體A」「內窗體B」的可拖拽、縮放、最小化、最大化、關閉的內部框架,主窗體居中於螢幕。適合作為 MDI 應用(如簡易 IDE、多文檔編輯器)的起始模板。