首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java Swing 字體對話框實現:字體選擇、大小調整與主窗口同步

     編輯:程式設計綜合問答

需求分析

實現一個模態對話框 FontDialog,包含字體名稱下拉框、字體大小下拉框、預覽標籤、確定/取消按鈕。主窗口點擊「設置字體」彈出對話框,用戶確定後將選中的字體應用到主窗口文本區。

關鍵問題與修復

1. 空指針異常:按鈕未初始化

// 錯誤:構造函數中先調用 init(),但 init() 內使用 button 前未 new
public Window1() {
    button.addActionListener(this); // button 為 null
    init();
}

// 正確:init() 內完成所有組件創建
public Window1() {
    init(); // 內部 new JButton()、addActionListener()
    setVisible(true);
}

2. 對話框模態設置

setModal(true); // 必須在 setVisible(true) 前調用,阻塞主窗口交互

3. 字體名稱獲取


GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontNames = ge.getAvailableFontFamilyNames(); // 系統安裝的所有字體

4. 事件監聽器簡化

使用 Lambda 表達式(Java 8+)或統一實現 ItemListener/ActionListener 接口,避免匿名內部類冗余。

完整結構示例


// FontDialog.java
public class FontDialog extends JDialog implements ItemListener, ActionListener {
    private JComboBox<String> fontNameBox, fontSizeBox;
    private JLabel previewLabel;
    private String selectedFont = "Serif";
    private int selectedSize = 24;
    private boolean confirmed = false;

    public FontDialog(Frame owner) {
        super(owner, "字體設置", true); // 模態
        initComponents();
        pack();
        setLocationRelativeTo(owner);
    }

    private void initComponents() {
        // 字體列表
        fontNameBox = new JComboBox<>(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
        fontNameBox.addItemListener(this);
        // 大小列表
        Integer[] sizes = new Integer[72];
        for (int i = 0; i < 72; i++) sizes[i] = i + 8;
        fontSizeBox = new JComboBox<>(sizes);
        fontSizeBox.addItemListener(this);
        // 預覽
        previewLabel = new JLabel("預覽文字 Preview");
        updatePreview();
        // 按鈕
        JButton ok = new JButton("確定");
        JButton cancel = new JButton("取消");
        ok.addActionListener(e -> { confirmed = true; dispose(); });
        cancel.addActionListener(e -> dispose());
        // 佈局...
    }

    @Override public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            updatePreview();
        }
    }

    private void updatePreview() {
        selectedFont = (String) fontNameBox.getSelectedItem();
        selectedSize = (Integer) fontSizeBox.getSelectedItem();
        previewLabel.setFont(new Font(selectedFont, Font.PLAIN, selectedSize));
    }

    public Font getSelectedFont() { return new Font(selectedFont, Font.PLAIN, selectedSize); }
    public boolean isConfirmed() { return confirmed; }
}

// 主窗口調用
JButton btnFont = new JButton("設置字體");
btnFont.addActionListener(e -> {
    FontDialog dialog = new FontDialog(this);
    dialog.setVisible(true);
    if (dialog.isConfirmed()) {
        textArea.setFont(dialog.getSelectedFont());
    }
});

編碼規範提示

  • 類名首字母大寫(FontDialog、MainWindow)。
  • 變量名駝峰式(fontNameBox)。
  • 將界面初始化代碼集中在 initComponents() 中,構造函數保持簡潔。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved