雖然 JavaFX、TornadoFX、Compose for Desktop 等新框架層出不窮,但 Swing 因**成熟穩定、JDK 內建、海量存量專案**仍佔據企業級桌面應用大多數。本文透過兩個完整範例,示範 JFrame 視窗狀態監聽(最小化/最大化/還原)與基礎元件佈局(JPanel、JScrollPane、JTextArea)。
windowStateChanged(WindowEvent e):視窗狀態改變時觸發。e.getNewState() 返回位元遮罩:NORMAL=0、ICONIFIED=1、MAXIMIZED_HORIZ=2、MAXIMIZED_VERT=4、MAXIMIZED_BOTH=6。(state & MAXIMIZED_BOTH) != 0。
import java.awt.event.*;
import javax.swing.*;
public class WindowStateDemo extends JFrame {
public WindowStateDemo() {
setTitle("視窗狀態監聽示範");
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null); // 置中
addWindowStateListener(new WindowStateListener() {
@Override public void windowStateChanged(WindowEvent e) {
int state = e.getNewState();
if ((state & Frame.ICONIFIED) != 0) {
System.out.println("→ 視窗最小化");
} else if ((state & Frame.MAXIMIZED_BOTH) != 0) {
System.out.println("→ 視窗最大化");
} else if (state == Frame.NORMAL) {
System.out.println("→ 視窗還原/正常");
}
}
});
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(WindowStateDemo::new); // 確保在 EDT 建立 UI
}
}
setLocationRelativeTo(null):視窗置中於螢幕,體驗更好。getNewState() == 6 (MAXIMIZED_HORIZ | MAXIMIZED_VERT)。JFrame (BorderLayout)
└─ JPanel (FlowLayout/GridLayout)
└─ JScrollPane
└─ JTextArea
import javax.swing.*;
import java.awt.*;
public class TextAreaDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("文字區域示範");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
JPanel panel = new JPanel(new BorderLayout()); // 邊界佈局,讓捲軸填滿
JTextArea textArea = new JTextArea(10, 30);
textArea.setText("這裡是初始文字內容...\n支援多行\n自動換行需設定 setLineWrap(true)");
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
JScrollPane scrollPane = new JScrollPane(textArea,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
panel.add(scrollPane, BorderLayout.CENTER);
frame.add(panel);
frame.setVisible(true);
});
}
}
| 方法 | 說明 |
|---|---|
setLineWrap(true) | 自動換行(預設 false,單行超寬不換行) |
setWrapStyleWord(true) | 按單字換行而非字元截斷(英文環境重要) |
setEditable(false) | 唯讀模式(日誌顯示常用) |
setFont(new Font("Monospaced", Font.PLAIN, 14)) | 等寬字體,適合程式碼/日誌 |
append(str) | 高效追加文字(比 setText + getText 快) |
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent e) {
int opt = JOptionPane.showConfirmDialog(frame,
"確定要離開?", "確認", JOptionPane.YES_NO_OPTION);
if (opt == JOptionPane.YES_OPTION) {
// 執行清理:儲存設定、關閉連線池、停止執行緒...
System.exit(0);
}
}
});
Swing 雖屬舊世代,但其事件模型(EDT、Listener 模式)、佈局管理器(BorderLayout、GridBagLayout、MigLayout)、元件生態極為成熟。掌握 JFrame 生命週期、視窗狀態監聽、捲軸佈局、EDT 規則,即可應對絕大多數桌面工具、管理後台、監控儀表板的開發需求。新專案若需現代 UI、CSS 樣式、GPU 加速,可評估 JavaFX 或 Compose for Desktop。