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

手把手教你用 Java Swing 打造 XML 編輯器(三):菜單、文件操作與對話框完善

     編輯:Java 相關知識

系列回顧

  • 第一篇:XML 樹形展示原理、JAXP 解析、可複用 XTree 組件開發。
  • 第二篇:雙分欄編輯器框架(JSplitPane + JScrollPane)、XTree 增強(默認歡迎樹、錯誤容錯)、XmlEditor 主視窗構建。

本文完善菜單系統、文件打開/保存、退出確認對話框,打造一個功能完整的桌面級 XML 編輯器。

一、構建專業菜單系統

核心組件層級

JMenuBar (菜單欄)
 └─ JMenu "File" (文件菜單)
      ├─ JMenuItem "New"     (新建)
      ├─ JMenuItem "Open"    (打開)
      ├─ JMenuItem "Save"    (保存)
      ├─ JSeparator
      └─ JMenuItem "Exit"    (退出)

代碼實現

JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F); // Alt+F 快捷鍵

// 新建
JMenuItem newItem = new JMenuItem("New", KeyEvent.VK_N);
newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_DOWN_MASK));
newItem.addActionListener(new NewAction());

// 打開
JMenuItem openItem = new JMenuItem("Open...", KeyEvent.VK_O);
openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK));
openItem.addActionListener(new OpenAction());

// 保存
JMenuItem saveItem = new JMenuItem("Save", KeyEvent.VK_S);
saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK));
saveItem.addActionListener(new SaveAction());

// 退出
JMenuItem exitItem = new JMenuItem("Exit", KeyEvent.VK_X);
exitItem.addActionListener(new ExitAction());

fileMenu.add(newItem);
fileMenu.add(openItem);
fileMenu.add(saveItem);
fileMenu.addSeparator();
fileMenu.add(exitItem);
menuBar.add(fileMenu);
setJMenuBar(menuBar);

二、事件處理器模式:職責分離

每個菜單項對應獨立 ActionListener 實現類,便於復用與測試:

class ExitAction implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        verifyDialog.setVisible(true); // 顯示確認對話框
    }
}

三、JFileChooser 實現文件系統訪問

文件過濾器:僅顯示 XML 文件

class XmlFileFilter extends FileFilter {
    public boolean accept(File f) {
        return f.isDirectory() || f.getName().toLowerCase().endsWith(".xml");
    }
    public String getDescription() { return "XML Files (*.xml)"; }
}

打開文件邏輯

class OpenAction implements ActionListener {
    private final JFileChooser chooser = new JFileChooser();
    private final Container parent;

    OpenAction(Container parent) {
        this.parent = parent;
        chooser.setFileFilter(new XmlFileFilter());
        chooser.setPreferredSize(new Dimension(500, 300));
    }

    public void actionPerformed(ActionEvent e) {
        if (chooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
            File file = chooser.getSelectedFile();
            try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
                textArea.read(reader, null); // JTextArea 直接讀取
                xTree.refresh(textArea.getText()); // 同步更新樹視圖
                chooser.setCurrentDirectory(file.getParentFile());
            } catch (IOException ex) {
                showError("打開失敗: " + ex.getMessage());
            }
        }
    }
}

保存文件邏輯

class SaveAction implements ActionListener {
    private final JFileChooser chooser = new JFileChooser();
    private final Container parent;

    SaveAction(Container parent) {
        this.parent = parent;
        chooser.setFileFilter(new XmlFileFilter());
    }

    public void actionPerformed(ActionEvent e) {
        if (chooser.showSaveDialog(parent) == JFileChooser.APPROVE_OPTION) {
            File file = chooser.getSelectedFile();
            // 自動補全 .xml 後綴
            if (!file.getName().toLowerCase().endsWith(".xml")) {
                file = new File(file.getParentFile(), file.getName() + ".xml");
            }
            try (FileWriter writer = new FileWriter(file)) {
                textArea.write(writer);
                chooser.setCurrentDirectory(file.getParentFile());
            } catch (IOException ex) {
                showError("保存失敗: " + ex.getMessage());
            }
        }
    }
}

四、JDialog 實現退出確認,防止數據誤丟失

對話框構建

JDialog verifyDialog = new JDialog(this, "Confirm Exit", true); // 模態對話框
verifyDialog.setLayout(new FlowLayout());
verifyDialog.add(new JLabel("Are you sure you want to exit? Unsaved changes will be lost."));

JButton okBtn = new JButton("OK");
okBtn.addActionListener(e -> System.exit(0));

JButton cancelBtn = new JButton("Cancel");
cancelBtn.addActionListener(e -> verifyDialog.setVisible(false));

verifyDialog.add(okBtn);
verifyDialog.add(cancelBtn);
verifyDialog.pack();
verifyDialog.setLocationRelativeTo(this); // 居中顯示

攔截窗口關閉事件

setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
        verifyDialog.setVisible(true); // 用戶點擊右上角 X 時彈出確認
    }
});

五、完整代碼結構概覽

XmlEditor extends JFrame implements ActionListener {
    // 組件
    XTree xTree;
    JTextArea textArea;
    JDialog verifyDialog;
    JFileChooser openChooser, saveChooser;
    
    // 內部類:NewAction, OpenAction, SaveAction, ExitAction, XmlFileFilter
    
    // 主入口 main():支援命令行參數打開文件,或啟動默認歡迎界面
}

總結與擴展方向

至此,一個具備語法高亮、樹文本雙視圖同步、文件操作、誤操作防護的 XML 編輯器核心已成型。後續可擴展:

  • 採用 RSyntaxTextArea 實現 XML 語法高亮與自動縮進。
  • 集成 XSD/DTD 驗證,紅線標記錯誤節點。
  • 添加 XPath 查詢欄、XSLT 轉換預覽。
  • 打包為可執行 JAR,配合 java -jar xmleditor.jar 一鍵啟動。

Swing 雖非主流,但其輕量、跨平台、無外部依賴特性,仍是桌面工具快速開發的利器。

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