首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Swing 內部窗體實戰:JDesktopPane 與 JInternalFrame 多文檔界面 (MDI)

     編輯:Java 程式設計入門

MDI 架構核心

Swing 通過 JDesktopPane(桌面容器)管理多個 JInternalFrame(內部窗體),實現類似 Windows 多文檔界面:

  • 內部窗體可最小化/最大化/關閉/調整大小/拖動
  • 支持圖標化最小化到桌面底部
  • 桌面面板支持拖拽輪廓模式(OUTLINE_DRAG_MODE),提升性能

主框架:InternalFrameDemo

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class InternalFrameDemo extends JFrame implements ActionListener {
    private JDesktopPane desktop;

    public InternalFrameDemo() {
        super("InternalFrameDemo");

        // 窗體佔據螢幕大部,四周留 50px 邊距
        int inset = 50;
        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds(inset, inset, screen.width - inset * 2, screen.height - inset * 2);

        desktop = new JDesktopPane();
        createFrame(); // 創建首個內部窗體
        setContentPane(desktop);
        setJMenuBar(createMenuBar());

        // 拖拽時僅顯示輪廓,減少重繪開銷
        desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
    }

    private JMenuBar createMenuBar() {
        JMenuBar bar = new JMenuBar();
        JMenu fileMenu = new JMenu("文件");
        fileMenu.setMnemonic(KeyEvent.VK_D);

        JMenuItem newItem = new JMenuItem("新文檔");
        newItem.setMnemonic(KeyEvent.VK_N);
        newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.ALT_MASK));
        newItem.setActionCommand("new");
        newItem.addActionListener(this);
        fileMenu.add(newItem);

        JMenuItem quitItem = new JMenuItem("退出");
        quitItem.setMnemonic(KeyEvent.VK_Q);
        quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.ALT_MASK));
        quitItem.setActionCommand("quit");
        quitItem.addActionListener(this);
        fileMenu.add(quitItem);

        bar.add(fileMenu);
        return bar;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if ("new".equals(e.getActionCommand())) createFrame();
        else quit();
    }

    private void createFrame() {
        MyInternalFrame frame = new MyInternalFrame();
        frame.setVisible(true);
        desktop.add(frame);
        try { frame.setSelected(true); } catch (java.beans.PropertyVetoException ignored) {}
    }

    private void quit() { System.exit(0); }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame f = new InternalFrameDemo();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setVisible(true);
        });
    }
}

內部窗體:MyInternalFrame

import javax.swing.*;
import java.awt.*;

public class MyInternalFrame extends JInternalFrame {
    private static int count = 0;
    private static final int OFFSET = 30;

    public MyInternalFrame() {
        super("文檔 #" + (++count), true, true, true, true); // 可縮放/關閉/最大化/最小化
        getContentPane().add(new JTextArea(5, 20));
        setSize(300, 300);
        setLocation(OFFSET * count, OFFSET * count); // 錯開顯示,避免完全重疊
    }
}

關鍵 API 與行為

方法/屬性說明
JInternalFrame(title, resizable, closable, maximizable, iconifiable)五參構造器全開啟窗體控制鈕
desktop.add(frame)將內部窗體加入桌面層級管理
frame.setSelected(true)激活並置頂(可能拋出 PropertyVetoException)
desktop.setDragMode(OUTLINE_DRAG_MODE)拖動時僅繪製邊框輪廓,釋放後再重繪內容
frame.setIcon(true)程序化最小化為圖標(桌面底部)

常見業務場景

  • 文本編輯器:每個標籤頁對應一個 JInternalFrame,包含 JTextArea + 工具欄
  • 報表查看器:多報表並排對比,支持獨立縮放/打印
  • 監控儀表盤:多圖表窗體自由佈局,保存/恢復工作區配置

遷移建議

現代應用多採用單窗體 + 選項卡(JTabbedPane)或分割面板(JSplitPane)替代 MDI,降低認知負荷。若需保留 MDI,JavaFX 可通過 Stage + Scene 模擬,或使用第三方庫 DockFX、TornadoFX 實現可停靠窗格系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved