目錄
概述
常用組件如下:
?JFrame:
一.新建JFrame對象:
二.設置JFrame的大小:
三.設定JFrame的關閉方式
布局方式:
setLayout 方法概述
常用布局管理器
自定義布局
注意事項
面板與布局的嵌套:
監聽器:
監聽器的概念
監聽器的類型
監聽器的使用步驟
示例代碼
自定義監聽器
總結
滾動面板和列表
面板:
1.?Panel(AWT 組件)
2.?JPanel(Swing 組件)
2 滾動面板
1.?JScrollPane(Swing 組件)
2.?ScrollPane(AWT 組件)
列表組件:
1.?List 組件
2.?Choice 組件
常見組件:
標簽組件:
標簽組件的基本概念
創建標簽組件
設置標簽的文本和圖像
標簽的對齊方式
標簽的字體和顏色
標簽的事件處理
小結:
按鈕組件
創建按鈕
添加事件監聽器
設置按鈕屬性
按鈕布局
菜單欄和彈出菜單
?菜單的層級結構:
菜單欄(MenuBar)
菜單(Menu)
彈出菜單(PopupMenu)
菜單項(MenuItem)
彈出對話框:
彈出窗口:
?JDialog:
彈出對話框
使用JOptionPane創建彈出對話框
自定義對話框
使用JFileChooser選擇文件
使用JColorChooser選擇顏色
窗口修飾和自定義形狀
一、窗口修飾(去除標題欄、邊框)
二、自定義窗口形狀
三、透明窗口
四、關鍵注意事項
多面板和分割面板:
多面板(Multi-Panel)
分割面板(JSplitPane)
多面板與分割面板的主要區別
SWing和Awt的區別?
1.?歷史與定位
2.?核心架構差異
3.?組件對比
4.?功能特性對比
5.?線程安全性
6.?應用場景
7.?現代替代方案
總結
概述
Swing組件通常被稱為“輕量級組件”,他完全由Java編寫,不依賴操作系統語言,他的類繼承關系如下:
Java.lang.Object->Java.awt.Component->Java.awt.Container->Javax.swing.JCompoment
JCompoent是swing組件存放的位置,
常用組件如下:
組件名稱 | 說明 |
---|---|
JFrame | 框架 |
JDialog | 對話框 |
JOptionPane | 對話框 |
JButton | 按鈕 |
JCheckBox | 復選框 |
JComboBox | 下拉框 |
JLabel | 標簽 |
JRadioButton | 單選按鈕 |
JList | 顯示一組條目的組件 |
JTextField | 文本框 |
JPasswordField | 密碼框 |
JTextArea | 文本區域 |
繼承關系圖:
??
?JFrame:
JFrame是一個容器,他是各個組件的載體,在開發過程,我們通過繼承java.swing.JFrame來創建給窗體。一般使用BorderLayout布局方式
一.新建JFrame對象:
- new JFrame()創建沒有標題的。//也可以直接傳一個字符串當作標題
- Frame(String s)創建標題為s的窗口,
二.設置JFrame的大小:
- ?public void setSize(int width, int height)?設置窗口的大小。
- ?public void setLocation(int x, int y)?設置窗口的位置,默認位置是?(0, 0)?。
- ?public void setBounds(int a, int b, int width, int height)?設置窗口的初始位置是?(a, b)?,窗口的寬是?width?,高是?height?。
- ?public void setVisible(boolean b)?設置窗口是否可見,窗口默認是不可見的。
- ?public void setResizable(boolean b)?設置窗口是否可調整大小,默認可調整大小。
- ?public void dispose()?撤銷當前窗口,并釋放當前窗口所使用的資源。
- ?public void setExtendedState(int state)?設置窗口的擴展狀態,其中參數?state?取?JFrame?類中的下列類常量:
- - ?MAXIMIZED_HORIZ?(水平方向最大化)
- ?- ?MAXIMIZED_VERT?(垂直方向最大化)
- ?- ?MAXIMIZED_BOTH?(水平、垂直方向都最大化)
三.設定JFrame的關閉方式
- ?public void setDefaultCloseOperation(int operation)?該方法用來設置單擊窗體右上角的關閉圖標后,程序會做出怎樣的處理,其中的參數?operation?取?JFrame?類中的下列?int?型?static?常量,程序根據參數?operation?取值做出不同的處理:
- - ?DO_NOTHING_ON_CLOSE?(什么也不做)
- - ?HIDE_ON_CLOSE??(隱藏當前窗口)
- - ?DISPOSE_ON_CLOSE??(隱藏當前窗口,并釋放窗體占有的其他資源)
- - ?EXIT_ON_CLOSE??(結束窗口所在的應用程序)
下面來寫一下:
package pdsu__zjh;import javax.swing.*;import javax.swing.JFrame;
public class Textt {public static void main(String []args) {JFrame jf=new JFrame();jf.setSize(400,250);//設置長寬jf.setLocation(400,250);//設置位置jf.setVisible(true);//設置是否顯示!!!!jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//關閉方式}
}
結果:
布局方式:
setLayout 方法概述
在 Java 的 JFrame
中,setLayout
方法用于設置容器的布局管理器。布局管理器決定了容器中組件的排列方式。JFrame
默認使用 BorderLayout
,但可以通過 setLayout
方法更改為其他布局管理器。
好處:布局方式可以讓組件的位置隨著窗口的大小而改變。
常用布局管理器
-
BorderLayout(邊界布局)
- 將容器分為五個區域:
NORTH
、SOUTH
、EAST
、WEST
和CENTER
。 - 示例代碼:
JFrame frame = new JFrame("BorderLayout Example"); // 設置JFrame的布局管理器為BorderLayout,用于管理組件的布局 frame.setLayout(new BorderLayout()); // 創建一個按鈕,按鈕上的文本為"North",并將其添加到JFrame的NORTH區域 frame.add(new JButton("North"), BorderLayout.NORTH); // 創建一個按鈕,按鈕上的文本為"South",并將其添加到JFrame的SOUTH區域 frame.add(new JButton("South"), BorderLayout.SOUTH); // 創建一個按鈕,按鈕上的文本為"East",并將其添加到JFrame的EAST區域 frame.add(new JButton("East"), BorderLayout.EAST); // 創建一個按鈕,按鈕上的文本為"West",并將其添加到JFrame的WEST區域 frame.add(new JButton("West"), BorderLayout.WEST); // 創建一個按鈕,按鈕上的文本為"Center",并將其添加到JFrame的CENTER區域 frame.add(new JButton("Center"), BorderLayout.CENTER); // 設置JFrame的大小為寬度300像素,高度200像素 frame.setSize(300, 200); // 設置JFrame的默認關閉操作,當關閉窗口時退出應用程序 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 設置JFrame可見,即顯示窗口 frame.setVisible(true);
- 將容器分為五個區域:
-
FlowLayout(流式布局)
- (組件按照添加順序從左到右排列,當一行排滿時自動換行。
- 示例代碼:
JFrame frame = new JFrame("FlowLayout Example"); frame.setLayout(new FlowLayout()); frame.add(new JButton("Button 1")); frame.add(new JButton("Button 2")); frame.add(new JButton("Button 3")); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true);
-
GridLayout(網格布局)
- 將容器劃分為指定行數和列數的網格,組件按順序填充網格。
- 示例代碼:
JFrame frame = new JFrame("GridLayout Example"); frame.setLayout(new GridLayout(2, 3)); // 2行3列 frame.add(new JButton("Button 1")); frame.add(new JButton("Button 2")); frame.add(new JButton("Button 3")); frame.add(new JButton("Button 4")); frame.add(new JButton("Button 5")); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true);
-
GridBagLayout
- 提供更靈活的布局方式,允許組件跨越多個行和列。
- 示例代碼:
JFrame frame = new JFrame("GridBagLayout Example"); frame.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; frame.add(new JButton("Button 1"), gbc); gbc.gridx = 1; gbc.gridy = 0; frame.add(new JButton("Button 2"), gbc); gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 2; frame.add(new JButton("Button 3"), gbc); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true);
自定義布局
如果默認的布局管理器不滿足需求,可以通過實現 LayoutManager
接口來自定義布局。自定義布局需要實現 LayoutManager
接口中的方法,如 addLayoutComponent
、removeLayoutComponent
、layoutContainer
等。
注意事項
- 在設置布局管理器后,添加的組件將按照新的布局管理器進行排列。
- 如果不需要布局管理器,可以將布局管理器設置為
null
,此時需要手動設置組件的位置和大小。
JFrame frame = new JFrame("Null Layout Example");
frame.setLayout(null);
JButton button = new JButton("Button");
button.setBounds(50, 50, 100, 30); // 手動設置位置和大小
frame.add(button);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
通過 setLayout
方法,可以靈活地控制 JFrame
中組件的排列方式,滿足不同的界面設計需求。
面板與布局的嵌套:
我們都知道一個窗口只有一種布局方式,如果想讓你的窗口既有流水布局,又有網格布局等,要怎么操作呢?這個時候就要用到面板了,面板是個很小的容器,也是組件可以添加在窗口中。
簡單例子:
package pdsu__zjh;import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;public class Textt {public static void main(String[] args) {// 創建一個JFrame窗口JFrame frame = new JFrame();// 設置窗口的位置和大小(x坐標500, y坐標500, 寬度500, 高度400)frame.setBounds(500, 500, 500, 400);// 使窗口可見(注意:應在所有組件添加完成后再調用此方法)frame.setVisible(true);// 創建GridLayout布局管理器(默認2行1列)GridLayout gridLayout = new GridLayout();// 設置布局的行數為2(列數會根據添加的組件數量自動計算)gridLayout.setRows(2);// 將JFrame的布局管理器設置為GridLayoutframe.setLayout(gridLayout);// 創建第一個面板(使用AWT的Panel類)Panel panel1 = new Panel();// 設置面板背景顏色為粉色panel1.setBackground(Color.PINK);// 創建第二個面板(使用AWT的Panel類)Panel panel2 = new Panel();// 設置面板背景顏色為青色panel2.setBackground(Color.CYAN);// 將面板1添加到JFrame中(GridLayout的第一行)frame.add(panel1);// 將面板2添加到JFrame中(GridLayout的第二行)frame.add(panel2);}
}
監聽器:
監聽器的概念
在Java中,監聽器(Listener)是一種設計模式,用于監聽特定事件的發生。當事件發生時,監聽器會觸發相應的處理邏輯。監聽器通常用于GUI編程、網絡編程等場景,用于處理用戶交互、數據變化等事件。
監聽器的類型
Java中常見的監聽器類型包括:
- ActionListener:用于處理按鈕點擊等動作事件。
- MouseListener:用于處理鼠標點擊、移動等事件。
- KeyListener:用于處理鍵盤按鍵事件。
- WindowListener:用于處理窗口事件,如窗口打開、關閉等。
- ItemListener:用于處理復選框、下拉列表等組件的狀態變化事件。
監聽器的使用步驟
- 實現監聽器接口:創建一個類并實現相應的監聽器接口,重寫接口中的方法。
- 注冊監聽器:將監聽器對象注冊到需要監聽的組件上。
- 處理事件:在監聽器的方法中編寫事件處理邏輯。
- 還有一種是使用內部類,將1和2步驟寫在一起,用匿名內部類的格式
示例代碼
以下是一個使用ActionListener
的簡單示例,監聽按鈕點擊事件:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class ButtonClickListener {public static void main(String[] args) {JFrame frame = new JFrame("Button Click Example");JButton button = new JButton("Click Me");// 創建監聽器對象ActionListener listener = new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("Button clicked!");}};// 注冊監聽器button.addActionListener(listener);frame.add(button);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
自定義監聽器
除了使用Java提供的標準監聽器接口,還可以自定義監聽器接口和實現類。以下是一個自定義監聽器的示例:
// 自定義監聽器接口,定義了事件處理方法
interface MyEventListener {// 定義一個方法,用于處理事件,參數message表示事件相關的信息void onEvent(String message);
}// 事件源類,負責觸發事件并通知監聽器
class EventSource {// 聲明一個監聽器對象,用于存儲注冊的監聽器private MyEventListener listener;// 設置監聽器的方法,將傳入的監聽器對象賦值給成員變量listenerpublic void setEventListener(MyEventListener listener) {this.listener = listener;}// 觸發事件的方法,當調用此方法時會通知已注冊的監聽器處理事件public void triggerEvent(String message) {// 檢查是否有已注冊的監聽器if (listener != null) {// 如果有監聽器,則調用監聽器的onEvent方法,并傳遞事件信息messagelistener.onEvent(message);}}
}// 監聽器實現類,實現了MyEventListener接口,處理具體的事件邏輯
class MyEventListenerImpl implements MyEventListener {// 實現接口中的onEvent方法,用于處理接收到的事件@Overridepublic void onEvent(String message) {// 簡單地打印出接收到的事件信息System.out.println("Event received: " + message);}
}public class CustomListenerExample {public static void main(String[] args) {// 創建一個事件源對象EventSource source = new EventSource();// 為事件源設置一個監聽器,這里創建了一個監聽器實現類的實例并傳入source.setEventListener(new MyEventListenerImpl());// 觸發事件,調用事件源的triggerEvent方法并傳遞事件信息source.triggerEvent("Hello, Custom Listener!");}
}
使用自定義監聽器?
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;// 自定義監聽器接口
interface MyButtonListener {void onButtonClicked(String message);
}// 自定義JFrame類,包含按鈕和監聽器注冊機制
class MyFrame extends JFrame {private JButton button;private MyButtonListener listener;public MyFrame(String title) {super(title);setSize(300, 200);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLayout(new FlowLayout());// 創建按鈕button = new JButton("點擊我");add(button);// 為按鈕添加內置的ActionListenerbutton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// 當按鈕被點擊時,觸發自定義監聽器的事件if (listener != null) {listener.onButtonClicked("按鈕被點擊了!");}}});}// 注冊自定義監聽器的方法public void setMyButtonListener(MyButtonListener listener) {this.listener = listener;}
}// 主類:演示如何使用自定義監聽器
public class CustomListenerInFrameExample {public static void main(String[] args) {SwingUtilities.invokeLater(() -> {// 創建自定義窗口MyFrame frame = new MyFrame("自定義監聽器示例");// 注冊自定義監聽器frame.setMyButtonListener(new MyButtonListener() {@Overridepublic void onButtonClicked(String message) {// 實現自定義事件處理邏輯JOptionPane.showMessageDialog(frame, message, "事件通知", JOptionPane.INFORMATION_MESSAGE);}});frame.setVisible(true);});}
}
總結
Java中的監聽器機制為事件驅動編程提供了強大的支持。通過實現和注冊監聽器,可以有效地處理各種用戶交互和系統事件。無論是使用標準監聽器接口還是自定義監聽器,都可以根據具體需求靈活地設計和實現事件處理邏輯。
滾動面板和列表
面板:
1.?Panel(AWT 組件)
- AWT 組件:屬于
java.awt
包,是 AWT 庫中最基本的容器組件。 - 重量級:每個
Panel
對應一個原生窗口句柄,依賴底層操作系統繪制。 - 簡單功能:主要用于組織和布局其他組件,不支持復雜 UI 特性。
- 有限定制:外觀由操作系統決定,難以實現自定義樣式(如透明效果)。
- 事件模型:使用 AWT 事件模型,處理方式較繁瑣。
核心方法:
add(Component comp)
:添加子組件。setLayout(LayoutManager mgr)
:設置布局管理器。setBackground(Color c)
:設置背景顏色。
示例代碼:
java
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;public class PanelExample {public static void main(String[] args) {Frame frame = new Frame("AWT Panel示例");frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});// 創建Panel并設置布局Panel panel = new Panel();panel.setLayout(new FlowLayout());// 添加組件到Panelpanel.add(new Button("按鈕1"));panel.add(new Button("按鈕2"));frame.add(panel);frame.setSize(300, 200);frame.setVisible(true);}
}
2.?JPanel(Swing 組件)
特點:
- Swing 組件:屬于
javax.swing
包,是 Swing 庫中常用的輕量級容器。 - 輕量級:不依賴原生窗口句柄,由 Java 代碼繪制,跨平臺一致性好。
- 豐富功能:支持雙緩沖、透明效果、邊框裝飾等現代 UI 特性。
- 高度可定制:可自定義外觀、添加事件監聽器、使用 Swing 提供的各種 UI 組件。
- 事件模型:與 Swing 事件模型集成,處理更簡潔(如使用匿名內部類)。
核心方法:
add(Component comp)
:添加子組件。setLayout(LayoutManager mgr)
:設置布局管理器。setOpaque(boolean isOpaque)
:設置是否透明。setBorder(Border border)
:設置邊框樣式。
示例代碼:
java
package pdsu__zjh;import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;public class Textt {public static void main(String[] args) {JFrame frame=new JFrame("Hallow!,World");frame.setBounds(500, 500, 500, 500);frame.setAlwaysOnTop(true);//將窗口置頂ScrollPane scollPane=new ScrollPane();frame.add(scollPane);GridLayout gridLayout=new GridLayout();gridLayout.setRows(20);Panel panel=new Panel();panel.setLayout(gridLayout);for (int i = 0; i < 20; i++) {panel.add(new Button("按鈕"+i));}scollPane.add(panel);frame.setVisible(true);}
}
?主要區別對比
特性 | JPanel (Swing) | Panel (AWT) |
---|---|---|
包路徑 | javax.swing | java.awt |
組件類型 | 輕量級(Java 純代碼實現) | 重量級(依賴原生窗口系統) |
透明效果 | 支持setOpaque(false) | 不支持,始終完全不透明 |
邊框裝飾 | 支持各種邊框(BorderFactory ) | 無內置邊框支持 |
雙緩沖 | 默認啟用,減少閃爍 | 不支持,可能有繪制閃爍問題 |
事件處理 | 更簡潔(如匿名內部類) | 較繁瑣(需實現接口) |
布局管理器 | 完全支持所有布局管理器 | 支持基本布局,但對復雜布局支持有限 |
推薦場景 | 現代 Java GUI 應用(JFrame、JDialog) | 傳統 AWT 應用或簡單工具 |
選擇建議
-
優先使用 JPanel:
- 如果你的應用是基于 Swing 的。
- 需要透明效果、自定義邊框或其他現代 UI 特性。
- 需要更好的跨平臺一致性。
-
使用 Panel:
- 在純 AWT 應用中,或需要與舊代碼兼容時。
- 對 UI 要求簡單,不需要復雜的視覺效果。
-
注意事項:
- 避免在同一個界面中混用 AWT 和 Swing 組件,可能導致繪制問題和性能下降。
- 使用 Swing 組件時,確保在事件調度線程(EDT)中創建和操作 UI,避免線程安全問題。
?常見應用場景
-
JPanel:
- 創建復雜的表單界面(如注冊頁面)。
- 實現分區域布局(如左側菜單 + 右側內容)。
- 作為自定義組件的基類(如游戲面板)。
-
Panel:
- 簡單的工具窗口(如計算器)。
- 與 AWT 繪圖 API 結合使用(如
Graphics
)。 - 舊 Java 應用的維護和擴展。
2 滾動面板
Swing組件不能使用setDefaultCloseOperation()方法,如果想要關閉就要設置事件
1.?JScrollPane(Swing 組件)
特點:
- Swing 組件:屬于 Swing 包(
javax.swing
),支持現代 UI 特性(如雙緩沖、透明效果)。 - 可定制性強:支持水平和垂直滾動條的精細控制,可自定義滾動條樣式、顯示策略。
- 事件驅動:與 Swing 事件模型集成,適合復雜交互場景。
- 線程安全:建議在事件調度線程(EDT)中操作,避免 UI 更新沖突。
- 輕量級:不依賴底層窗口系統,跨平臺一致性好。
核心方法:
setViewportView(Component view)
:設置需要滾動顯示的組件。setHorizontalScrollBarPolicy(int policy)
:設置水平滾動條的顯示策略。setVerticalScrollBarPolicy(int policy)
:設置垂直滾動條的顯示策略。getHorizontalScrollBar()
/getVerticalScrollBar()
:獲取滾動條實例進行定制。
示例代碼(修正后的版本):
java
import javax.swing.*;
import java.awt.*;public class JScrollPaneExample {public static void main(String[] args) {SwingUtilities.invokeLater(() -> {JFrame frame = new JFrame("JScrollPane示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 創建內容面板JPanel contentPanel = new JPanel();contentPanel.setLayout(new GridLayout(20, 1)); // 20行1列for (int i = 0; i < 20; i++) {contentPanel.add(new JButton("按鈕" + i));}// 創建JScrollPane并設置內容面板JScrollPane scrollPane = new JScrollPane(contentPanel);scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);frame.add(scrollPane);frame.setSize(400, 300);frame.setVisible(true);});}
}
2.?ScrollPane(AWT 組件)
特點:
- AWT 組件:屬于 AWT 包(
java.awt
),依賴底層窗口系統繪制。 - 簡單直接:功能相對基礎,適合簡單滾動需求。
- 重量級:每個組件對應一個原生窗口句柄,可能影響性能。
- 有限定制:滾動條樣式和行為由操作系統決定,定制性差。
- 兼容性:與 AWT 事件模型集成,在純 AWT 應用中使用更方便。
核心方法:
add(Component comp)
:添加需要滾動顯示的組件(自動處理滾動)。setScrollbarDisplayPolicy(int policy)
:設置滾動條顯示策略。getHAdjustable()
/getVAdjustable()
:獲取滾動條的調整器(用于手動控制)。
示例代碼:
java
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;public class ScrollPaneExample {public static void main(String[] args) {Frame frame = new Frame("ScrollPane示例");frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});// 創建AWT ScrollPaneScrollPane scrollPane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);// 創建內容面板Panel contentPanel = new Panel();contentPanel.setLayout(new GridLayout(20, 1));for (int i = 0; i < 20; i++) {contentPanel.add(new Button("按鈕" + i)); // AWT Button}// 添加內容到ScrollPanescrollPane.add(contentPanel);frame.add(scrollPane);frame.setSize(400, 300);frame.setVisible(true);}
}
3.?主要區別對比
特性 | JScrollPane (Swing) | ScrollPane (AWT) |
---|---|---|
包路徑 | javax.swing | java.awt |
組件類型 | 輕量級(Java 純代碼實現) | 重量級(依賴原生窗口系統) |
添加內容方式 | setViewportView(component) | add(component) |
滾動條定制 | 高度可定制(顏色、樣式、策略) | 由操作系統決定,定制性差 |
事件處理 | 與 Swing 事件模型集成 | 與 AWT 事件模型集成 |
線程安全性 | 需要在 EDT 中操作 | 無需特殊處理(但可能有線程問題) |
布局管理器支持 | 支持復雜布局(如嵌套面板) | 簡單布局,依賴容器默認布局 |
推薦場景 | 現代 Java GUI 應用(JFrame、JDialog) | 傳統 AWT 應用或簡單工具 |
4.?選擇建議
- 優先使用 JScrollPane:如果你的應用是基于 Swing 的,需要更好的 UI 定制性和跨平臺一致性。
- 使用 ScrollPane:在純 AWT 應用中,或需要與舊代碼兼容時。
- 注意事項:避免在同一個界面中混用 AWT 和 Swing 組件,可能導致繪制問題和性能下降。
列表組件:
我只介紹一下AWT中的列表組件:
在 Java AWT(Abstract Window Toolkit)中,列表組件主要提供兩種:List
(下拉列表框)和Choice
(單選下拉菜單)。它們都是用戶界面中常用的選擇組件,但功能和使用場景略有不同。
1.?List 組件
java.awt.List
?是一個可滾動的多行選擇列表,支持單選或多選。
特點:
- 顯示多個選項,可通過滾動條瀏覽。
- 支持單選(默認)或多選(通過
setMultipleMode(true)
啟用)。 - 用戶可通過鼠標或鍵盤選擇一個或多個項目。
核心方法:
add(String item)
:添加選項。select(int index)
:選擇指定索引的選項。getSelectedIndex()
:獲取選中項的索引(單選模式)。getSelectedIndexes()
:獲取所有選中項的索引(多選模式)。setMultipleMode(boolean b)
:啟用 / 禁用多選模式。
示例代碼:
java
import java.awt.*;
import java.awt.event.*;public class ListExample {public static void main(String[] args) {Frame frame = new Frame("AWT List 示例");frame.setSize(300, 200);// 創建List組件(默認單選)List list = new List(5); // 顯示5行list.add("選項1");list.add("選項2");list.add("選項3");list.add("選項4");list.add("選項5");// 添加按鈕獲取選中項Button button = new Button("獲取選中項");button.addActionListener(e -> {int selectedIndex = list.getSelectedIndex();if (selectedIndex >= 0) {System.out.println("選中項: " + list.getItem(selectedIndex));}});frame.add(list, BorderLayout.CENTER);frame.add(button, BorderLayout.SOUTH);// 添加窗口關閉事件frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});frame.setVisible(true);}
}
2.?Choice 組件
java.awt.Choice
?是一個單行的下拉選擇菜單,用戶點擊后展開選項列表。
特點:
- 只顯示當前選中項,點擊后彈出選項列表。
- 僅支持單選。
- 占用空間小,適合選項較多的場景。
核心方法:
add(String item)
:添加選項。select(int index)
:選擇指定索引的選項。select(String item)
:選擇指定文本的選項。getSelectedIndex()
:獲取選中項的索引。getSelectedItem()
:獲取選中項的文本。
示例代碼:
java
import java.awt.*;
import java.awt.event.*;public class ChoiceExample {public static void main(String[] args) {Frame frame = new Frame("AWT Choice 示例");frame.setSize(300, 200);// 創建Choice組件Choice choice = new Choice();choice.add("紅色");choice.add("綠色");choice.add("藍色");choice.add("黃色");// 添加按鈕獲取選中項Button button = new Button("獲取顏色");button.addActionListener(e -> {String selectedColor = choice.getSelectedItem();System.out.println("選中的顏色: " + selectedColor);});frame.add(choice, BorderLayout.NORTH);frame.add(button, BorderLayout.SOUTH);// 添加窗口關閉事件frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});frame.setVisible(true);}
}
3.?List vs Choice 對比
特性 | List | Choice |
---|---|---|
顯示方式 | 多行列表,可滾動 | 單行下拉菜單,點擊展開 |
選擇模式 | 支持單選和多選 | 僅支持單選 |
默認行為 | 直接顯示所有選項(部分可見) | 僅顯示當前選中項 |
適用場景 | 選項較少,需快速瀏覽和選擇 | 選項較多,節省空間 |
常用方法 | getSelectedIndexes() (多選) | getSelectedItem() (單選) |
4.?事件處理
兩者都可通過ItemListener
監聽選擇變化:
java
list.addItemListener(e -> {if (e.getStateChange() == ItemEvent.SELECTED) {System.out.println("選中: " + list.getSelectedItem());}
});choice.addItemListener(e -> {if (e.getStateChange() == ItemEvent.SELECTED) {System.out.println("選中: " + choice.getSelectedItem());}
});
5.?注意事項
- AWT 組件的線程安全:雖然 AWT 不是嚴格線程安全的,但簡單應用通常無需特殊處理。對于復雜場景,建議在事件調度線程中操作 UI。
- Swing 替代方案:如果需要更現代的 UI 組件,可使用 Swing 的
JList
和JComboBox
,它們提供了更豐富的功能和更好的外觀控制。
如果你需要更多自定義選項(如自定義渲染器或復雜布局),建議轉向 Swing 或 JavaFX。
常見組件:
組件就是AWT為我們設置好的一些可以直接使用的界元素:按鈕,文本框,標簽,我們可以用這些幫我們寫好的組件來快速拼湊出功能強大的程序
標簽組件:
標簽組件的基本概念
在Java中,標簽組件通常用于在圖形用戶界面(GUI)中顯示文本或圖像。標簽組件是不可編輯的,主要用于提供信息或描述其他組件。Java提供了多種標簽組件,最常用的是JLabel
類,它屬于javax.swing
包。
創建標簽組件
使用JLabel
類可以輕松創建標簽組件。可以通過構造函數傳遞文本或圖像來初始化標簽。以下是一個簡單的示例,展示如何創建一個文本標簽:
import javax.swing.JFrame;
import javax.swing.JLabel;public class LabelExample {public static void main(String[] args) {JFrame frame = new JFrame("Label Example");JLabel label = new JLabel("Hello, World!");frame.add(label);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
設置標簽的文本和圖像
JLabel
類提供了多種方法來設置標簽的文本和圖像。可以使用setText()
方法設置文本,使用setIcon()
方法設置圖像。以下示例展示了如何同時設置文本和圖像:
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;public class LabelWithImage {public static void main(String[] args) {JFrame frame = new JFrame("Label with Image");JLabel label = new JLabel("Java Logo");ImageIcon icon = new ImageIcon("java_logo.png");label.setIcon(icon);frame.add(label);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
標簽的對齊方式
JLabel
類允許設置文本和圖像的對齊方式。可以使用setHorizontalAlignment()
和setVerticalAlignment()
方法來控制標簽內容的對齊方式。以下示例展示了如何設置標簽的水平和垂直對齊方式:
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;public class LabelAlignment {public static void main(String[] args) {JFrame frame = new JFrame("Label Alignment");JLabel label = new JLabel("Centered Text", SwingConstants.CENTER);label.setVerticalAlignment(SwingConstants.CENTER);frame.add(label);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
標簽的字體和顏色
可以通過setFont()
方法設置標簽的字體,通過setForeground()
方法設置文本顏色。以下示例展示了如何設置標簽的字體和顏色:
import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;public class LabelFontAndColor {public static void main(String[] args) {JFrame frame = new JFrame("Label Font and Color");JLabel label = new JLabel("Styled Text");Font font = new Font("Serif", Font.BOLD, 18);label.setFont(font);label.setForeground(Color.BLUE);frame.add(label);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
標簽的事件處理
雖然標簽組件通常不處理用戶輸入,但可以通過添加事件監聽器來實現一些交互功能。例如,可以為標簽添加鼠標點擊事件監聽器:
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;public class LabelClickEvent {public static void main(String[] args) {JFrame frame = new JFrame("Label Click Event");JLabel label = new JLabel("Click Me!");label.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {label.setText("Clicked!");}});frame.add(label);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
通過以上方法,可以在Java應用程序中靈活使用標簽組件,實現各種界面設計需求。
小結:
在這里我調試了許久,總結的有,如果要添加標簽,最好先添加在JPanel頁面中,然后再將JPanel添加進入JFrame中,并且他們的布局方式也不一樣,JFrame用的是BorderLayout,JPanel用的是FlowLayout布局方式,詳細可以看之前寫的內容。
按鈕組件
在Java中,按鈕組件通常通過JButton
類來實現,它是javax.swing
包的一部分。JButton
用于創建可點擊的按鈕,用戶可以通過點擊按鈕來觸發特定的事件。
創建按鈕
要創建一個按鈕,可以使用JButton
類的構造函數。最簡單的形式是創建一個帶有文本標簽的按鈕。
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.FlowLayout;public class ButtonExample {public static void main(String[] args) {JFrame frame = new JFrame("Button Example");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setLayout(new FlowLayout());JButton button = new JButton("Click Me");frame.add(button);frame.setSize(300, 200);frame.setVisible(true);}
}
添加事件監聽器
按鈕通常需要與用戶交互,因此需要為按鈕添加事件監聽器。可以使用ActionListener
接口來處理按鈕點擊事件。
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class ButtonExample {public static void main(String[] args) {JFrame frame = new JFrame("Button Example");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setLayout(new FlowLayout());JButton button = new JButton("Click Me");button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("Button clicked!");}});frame.add(button);frame.setSize(300, 200);frame.setVisible(true);}
}
設置按鈕屬性
JButton
類提供了多種方法來設置按鈕的屬性,例如設置按鈕的文本、圖標、工具提示等。
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import java.awt.FlowLayout;public class ButtonExample {public static void main(String[] args) {JFrame frame = new JFrame("Button Example");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setLayout(new FlowLayout());JButton button = new JButton("Click Me");button.setToolTipText("This is a button");button.setIcon(new ImageIcon("icon.png"));frame.add(button);frame.setSize(300, 200);frame.setVisible(true);}
}
按鈕布局
按鈕可以放置在容器的不同位置,通常使用布局管理器來控制按鈕的位置和大小。常見的布局管理器包括FlowLayout
、BorderLayout
、GridLayout
等。
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.BorderLayout;public class ButtonExample {public static void main(String[] args) {JFrame frame = new JFrame("Button Example");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setLayout(new BorderLayout());JButton button1 = new JButton("North");JButton button2 = new JButton("South");JButton button3 = new JButton("East");JButton button4 = new JButton("West");JButton button5 = new JButton("Center");frame.add(button1, BorderLayout.NORTH);frame.add(button2, BorderLayout.SOUTH);frame.add(button3, BorderLayout.EAST);frame.add(button4, BorderLayout.WEST);frame.add(button5, BorderLayout.CENTER);frame.setSize(300, 200);frame.setVisible(true);}
}
通過以上方法,可以在Java應用程序中創建和使用按鈕組件,并根據需要設置其屬性和事件處理邏輯。
菜單欄和彈出菜單
菜單:顧名思義就是包含各種基本操作的組件,程序中我們經常使用下拉菜單:
?菜單的層級結構:
MenuBar (菜單欄)
├─ Menu (文件)
│ ├─ MenuItem (新建)
│ ├─ MenuItem (打開)
│ └─ MenuItem (保存)
├─ Menu (編輯)
│ ├─ MenuItem (復制)
│ ├─ MenuItem (粘貼)
│ └─ Menu (查找)
│ └─ MenuItem (查找下一個)
└─ Menu (幫助)└─ MenuItem (關于)
下面是AWT中的菜單介紹:
在Java中,AWT(Abstract Window Toolkit)提供了創建圖形用戶界面(GUI)的基本工具。AWT中的菜單、彈出菜單和菜單欄是構建用戶界面的重要組件。以下是對這些組件的詳細介紹。
菜單欄(MenuBar)
菜單欄是窗口頂部的水平條,通常包含多個菜單。在AWT中,MenuBar
類用于創建菜單欄。菜單欄可以添加到Frame
或Dialog
中。
import java.awt.*;public class MenuBarExample {public static void main(String[] args) {JFrame frame = new JFrame("MenuBar Example");MenuBar menuBar = new MenuBar();Menu fileMenu = new Menu("File");Menu editMenu = new Menu("Edit");menuBar.add(fileMenu);menuBar.add(editMenu);frame.setMenuBar(menuBar);frame.setSize(300, 200);frame.setVisible(true);}
}
菜單(Menu)
菜單是菜單欄中的一個下拉列表,包含多個菜單項。Menu
類用于創建菜單。菜單可以包含其他菜單(子菜單)或菜單項(MenuItem
)。
import java.awt.*;public class MenuExample {public static void main(String[] args) {JFrame frame = new JFrame("MenuBar Example");MenuBar menuBar = new MenuBar();Menu fileMenu = new Menu("File");Menu editMenu = new Menu("Edit");menuBar.add(fileMenu);menuBar.add(editMenu);frame.setMenuBar(menuBar);frame.setSize(300, 200);frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}
}
彈出菜單(PopupMenu)
彈出菜單是用戶右鍵點擊時顯示的菜單。PopupMenu
類用于創建彈出菜單。彈出菜單可以添加到任何組件中,通常與鼠標事件結合使用。
import java.awt.*;
import java.awt.event.*;public class PopupMenuExample {public static void main(String[] args) {JFrame frame = new JFrame("PopupMenu Example");PopupMenu popupMenu = new PopupMenu();MenuItem cutItem = new MenuItem("Cut");MenuItem copyItem = new MenuItem("Copy");MenuItem pasteItem = new MenuItem("Paste");popupMenu.add(cutItem);popupMenu.add(copyItem);popupMenu.add(pasteItem);frame.add(popupMenu);frame.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {if (e.getButton() == MouseEvent.BUTTON3) {popupMenu.show(frame, e.getX(), e.getY());}}});frame.setSize(300, 200);frame.setVisible(true);}
}
菜單項(MenuItem)
菜單項是菜單中的單個選項,用戶可以選擇執行特定操作。MenuItem
類用于創建菜單項。菜單項可以添加到菜單或彈出菜單中。
import java.awt.*;
import java.awt.event.*;public class MenuItemExample {public static void main(String[] args) {Frame frame = new Frame("MenuItem Example");MenuBar menuBar = new MenuBar();Menu fileMenu = new Menu("File");MenuItem openItem = new MenuItem("Open");MenuItem saveItem = new MenuItem("Save");openItem.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.out.println("Open item clicked");}});saveItem.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.out.println("Save item clicked");}});fileMenu.add(openItem);fileMenu.add(saveItem);menuBar.add(fileMenu);frame.setMenuBar(menuBar);frame.setSize(300, 200);frame.setVisible(true);}
}
通過以上示例,可以了解如何在Java中使用AWT創建菜單欄、菜單、彈出菜單和菜單項。這些組件是構建用戶界面的基礎,能夠幫助用戶與應用程序進行交互。
彈出對話框:
彈出窗口:
?JDialog:
繼承自java.awt.Dialog類,他是從一個窗體彈出來的另一個窗體,他們JFrame類似,需要調用getContentPane將窗體轉換為容器,然后在容器中設置窗體的內容。
JDialog:可以當作JFrame使用,但是必須從屬于JFrame
構造函數:
- JDialog();
- JDialog(Frame f); //指定父窗口
- JDialog(Frame f,String title); //指定父窗口+標題
- JDialog關閉窗口的時候不能用DISPOSE_ON_CLOS,所以關閉大窗口會連著小的一起關閉,因為JDialog從屬于JFrame.
下面演示:
package pdsu__zjh;
import javax.swing.*;
import javax.swing.JFrame;
public class Textt {public static void main(String []args) {JFrame jf=new JFrame();jf.setBounds(400,250,600,550);//設置位置,長,寬;jf.setVisible(true);//設置是否顯示jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//關閉方式JDialog jDialog=new JDialog();jDialog.setBounds(400,250,400,250);jDialog.setVisible(true);jDialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);}
}
效果演示:
彈出對話框
使用JOptionPane創建彈出對話框
Java中可以通過JOptionPane
類來創建各種類型的彈出對話框。JOptionPane
提供了多種靜態方法來顯示消息對話框、確認對話框、輸入對話框等。
import javax.swing.JOptionPane;public class DialogExample {public static void main(String[] args) {// 顯示消息對話框JOptionPane.showMessageDialog(null, "這是一個消息對話框", "消息", JOptionPane.INFORMATION_MESSAGE);// 顯示確認對話框int response = JOptionPane.showConfirmDialog(null, "你確定要繼續嗎?", "確認", JOptionPane.YES_NO_OPTION);if (response == JOptionPane.YES_OPTION) {System.out.println("用戶選擇了是");} else {System.out.println("用戶選擇了否");}// 顯示輸入對話框String input = JOptionPane.showInputDialog(null, "請輸入你的名字:", "輸入", JOptionPane.QUESTION_MESSAGE);if (input != null) {System.out.println("你輸入的名字是:" + input);}}
}
自定義對話框
如果需要更復雜的對話框,可以繼承JDialog
類來創建自定義對話框。這種方式允許完全控制對話框的布局和行為。
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class CustomDialog extends JDialog {public CustomDialog(JFrame parent) {super(parent, "自定義對話框", true);setLayout(new FlowLayout());add(new JLabel("這是一個自定義對話框"));JButton closeButton = new JButton("關閉");closeButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {dispose();}});add(closeButton);pack();setLocationRelativeTo(parent);}public static void main(String[] args) {JFrame frame = new JFrame("主窗口");frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);CustomDialog dialog = new CustomDialog(frame);dialog.setVisible(true);}
}
使用JFileChooser選擇文件
JFileChooser
類可以用于創建文件選擇對話框,允許用戶選擇文件或目錄。
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileNameExtensionFilter;public class FileChooserExample {public static void main(String[] args) {JFileChooser fileChooser = new JFileChooser();FileNameExtensionFilter filter = new FileNameExtensionFilter("文本文件", "txt");fileChooser.setFileFilter(filter);int returnValue = fileChooser.showOpenDialog(null);if (returnValue == JFileChooser.APPROVE_OPTION) {System.out.println("選擇的文件是:" + fileChooser.getSelectedFile().getAbsolutePath());}}
}
使用JColorChooser選擇顏色
JColorChooser
類可以用于創建顏色選擇對話框,允許用戶選擇顏色。
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import java.awt.Color;public class ColorChooserExample {public static void main(String[] args) {Color selectedColor = JColorChooser.showDialog(null, "選擇顏色", Color.WHITE);if (selectedColor != null) {System.out.println("選擇的顏色是:" + selectedColor);}}
}
通過以上方法,可以在Java應用程序中輕松創建各種類型的彈出對話框,滿足不同的用戶交互需求。
窗口修飾和自定義形狀
一、窗口修飾(去除標題欄、邊框)
步驟:
frame.setUndecorated(true)
?移除默認修飾- 手動添加標題欄 / 按鈕
- 實現窗口拖動邏輯
示例代碼:
java
JFrame frame = new JFrame();
frame.setUndecorated(true); // 先移除默認修飾// 添加自定義標題欄和關閉按鈕
JPanel titleBar = new JPanel();
titleBar.add(new JLabel("自定義標題"));
titleBar.add(new JButton("X"));// 實現拖動功能(略,見之前示例)
二、自定義窗口形狀
步驟:
setUndecorated(true)
setShape(shape)
?設置形狀- 確保內容繪制與形狀一致
示例代碼(圓形窗口):
java
JFrame frame = new JFrame();
frame.setUndecorated(true); // 必須先移除默認修飾// 創建圓形面板
JPanel panel = new JPanel() {@Overrideprotected void paintComponent(Graphics g) {g.fillOval(0, 0, getWidth(), getHeight());}
};frame.setContentPane(panel);
frame.pack();// 設置窗口形狀為圓形(在pack之后)
frame.setShape(new Ellipse2D.Double(0, 0, frame.getWidth(), frame.getHeight()));
三、透明窗口
步驟:
setUndecorated(true)
setOpacity(0.5f)
?設置透明度(0.0-1.0)- 內容面板設為透明
示例代碼:
java
frame.setUndecorated(true);
frame.setOpacity(0.8f); // 80%透明度JPanel panel = new JPanel();
panel.setBackground(new Color(255, 255, 255, 100)); // 半透明白色
frame.setContentPane(panel);
四、關鍵注意事項
- 順序:必須先?
setUndecorated(true)
,再設置形狀 / 透明度 - 系統檢查:使用前檢查系統支持:
java
boolean supportsShape = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().isWindowTranslucencySupported(WindowTranslucency.PERPIXEL_TRANSPARENT);
- 性能:復雜形狀 / 透明度可能影響性能
- 拖動邏輯:移除修飾后需手動實現窗口拖動(見之前示例中的?
WindowDragListener
)
多面板和分割面板:
在 Java 的 Swing GUI 編程里,多面板和分割面板是組織和管理界面的重要組件。下面為你詳細介紹它們的概念、用法和區別。
多面板(Multi-Panel)
多面板并非 Java 的標準術語,不過在實際應用中,它指的是將多個面板組合到一個容器里的布局方式。這種方式能夠讓界面結構清晰,便于管理。
常見實現方式
- 嵌套 JPanel:可以把多個 JPanel 添加到一個父容器中,每個子面板負責管理特定區域的組件。
- 卡片布局(CardLayout):這是一種特殊的布局管理器,它能讓多個組件共享同一顯示空間,組件之間可以像卡片一樣切換。
- 選項卡面板(JTabbedPane):它會創建帶有選項卡的界面,每個選項卡下面都可以放置不同的面板。
示例代碼
下面是一個嵌套 JPanel 的例子:
import javax.swing.*;
import java.awt.*;public class MultiPanelExample {public static void main(String[] args) {JFrame frame = new JFrame("多面板示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(400, 300);// 創建主面板,使用邊界布局JPanel mainPanel = new JPanel(new BorderLayout());// 頂部面板 - 包含按鈕JPanel topPanel = new JPanel();topPanel.add(new JButton("按鈕1"));topPanel.add(new JButton("按鈕2"));// 中部面板 - 包含文本區域JPanel centerPanel = new JPanel();centerPanel.add(new JTextArea(10, 30));// 將子面板添加到主面板mainPanel.add(topPanel, BorderLayout.NORTH);mainPanel.add(centerPanel, BorderLayout.CENTER);// 將主面板添加到窗口frame.setContentPane(mainPanel);frame.setVisible(true);}
}
分割面板(JSplitPane)
JSplitPane 是 Swing 提供的標準組件,其主要功能是創建一個可調整的分割線,把容器分為兩個區域。用戶能夠通過拖動分割線來改變兩個區域的大小。
關鍵特性
- 方向支持:支持水平分割(HORIZONTAL_SPLIT)和垂直分割(VERTICAL_SPLIT)。
- 連續重繪:在拖動分割線時,可以選擇實時重繪界面或者在拖動結束后再重繪。
- 固定比例:能夠設置分割線的位置,既可以使用像素值,也可以使用相對于容器大小的比例。
示例代碼
下面是一個使用 JSplitPane 的例子:
java
import javax.swing.*;
import java.awt.*;public class SplitPaneExample {public static void main(String[] args) {JFrame frame = new JFrame("分割面板示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);// 創建左側面板JPanel leftPanel = new JPanel();leftPanel.add(new JList<>(new String[]{"項目1", "項目2", "項目3"}));// 創建右側面板JPanel rightPanel = new JPanel();rightPanel.add(new JTextArea(20, 30));// 創建水平分割面板JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,leftPanel,rightPanel);// 設置分割線位置(相對于容器寬度的比例)splitPane.setDividerLocation(0.3);// 設置連續重繪,使拖動更流暢splitPane.setContinuousLayout(true);// 將分割面板添加到窗口frame.setContentPane(splitPane);frame.setVisible(true);}
}
多面板與分割面板的主要區別
特性 | 多面板(嵌套 JPanel) | 分割面板(JSplitPane) |
---|---|---|
布局方式 | 需要手動管理每個面板的大小和位置 | 自動管理兩個區域,可通過拖動分割線調整 |
用戶交互 | 面板大小固定,用戶無法動態調整 | 用戶可以實時調整兩個區域的大小 |
應用場景 | 適合界面布局固定的情況,例如表單、工具欄 | 適合需要動態調整空間分配的場景,如圖文混排、資源管理器 |
實現復雜度 | 需要處理多個面板的布局,相對復雜 | 只需設置一次,自動處理大部分布局邏輯 |
SWing和Awt的區別?
1.?歷史與定位
-
AWT(1995 年):
- Java 最早的 GUI 庫,屬于 Java 基礎類庫(JRE)的一部分。
- 稱為 “重量級” 組件,依賴底層操作系統的原生窗口系統(如 Windows 的 Win32 API)。
-
Swing(1997 年):
- 作為 AWT 的擴展,屬于 Java Foundation Classes (JFC)。
- 稱為 “輕量級” 組件,完全由 Java 代碼實現,不依賴原生窗口系統。
2.?核心架構差異
特性 | AWT(重量級) | Swing(輕量級) |
---|---|---|
組件實現 | 依賴原生窗口系統(如 Windows/Linux) | 純 Java 實現,跨平臺一致性好 |
渲染方式 | 由操作系統負責繪制 | 由 Java 虛擬機(JVM)負責繪制 |
內存占用 | 高(每個組件對應一個原生窗口句柄) | 低(共享一個窗口句柄) |
性能 | 受限于操作系統繪制效率 | 通常更高,但復雜 UI 可能有性能開銷 |
外觀一致性 | 與操作系統風格一致 | 可定制外觀(如 Nimbus、Metal) |
3.?組件對比
組件類型 | AWT 類 | Swing 等效類 |
---|---|---|
窗口 | Frame ,?Dialog | JFrame ,?JDialog |
面板 | Panel | JPanel |
按鈕 | Button | JButton |
標簽 | Label | JLabel |
文本框 | TextField | JTextField |
滾動面板 | ScrollPane | JScrollPane |
菜單 | MenuBar ,?Menu ,?MenuItem | JMenuBar ,?JMenu ,?JMenuItem |
對話框 | FileDialog | JFileChooser |
4.?功能特性對比
特性 | AWT | Swing |
---|---|---|
透明效果 | 不支持 | 支持(如setOpaque(false) ) |
自定義邊框 | 無內置支持 | 豐富的邊框選項(BorderFactory ) |
雙緩沖 | 需手動實現 | 默認啟用,減少閃爍 |
事件處理 | 基于接口(如ActionListener ) | 支持匿名內部類和 Lambda 表達式 |
數據模型 | 無統一數據模型 | 支持 MVC 模式(如TableModel ) |
組件豐富度 | 基礎組件 | 提供更多高級組件(如JTable ,?JTree ) |
主題支持 | 依賴操作系統 | 支持多種主題(如 Nimbus、Windows 風格) |
5.?線程安全性
-
AWT:
- 非線程安全,但早期 Java 版本允許在任意線程更新 UI(可能導致繪制異常)。
-
Swing:
- 嚴格要求在事件調度線程(Event Dispatch Thread, EDT)中操作 UI,否則可能出現競態條件。
- 使用
SwingUtilities.invokeLater()
或SwingUtilities.invokeAndWait()
確保線程安全。
java
// 示例:在EDT中創建Swing UI
SwingUtilities.invokeLater(() -> {JFrame frame = new JFrame("線程安全示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.add(new JLabel("Hello, Swing!"));frame.pack();frame.setVisible(true);
});
6.?應用場景
-
選擇 AWT:
- 開發簡單工具或小程序。
- 需要與操作系統原生組件深度集成。
- 維護舊 Java 項目(如 JDK 1.1 時代的代碼)。
-
選擇 Swing:
- 開發跨平臺的桌面應用。
- 需要豐富的 UI 組件(如表格、樹狀結構)。
- 需要自定義外觀或動畫效果。
- 開發復雜的企業級應用(如 IDE、數據可視化工具)。
7.?現代替代方案
雖然 Swing 和 AWT 仍被廣泛使用,但 Java 的 GUI 生態已發展出更現代的框架:
-
JavaFX(自 Java 8 引入):
- 官方推薦的下一代 GUI 框架,支持 FXML、CSS 樣式、3D 圖形和多媒體。
- 逐漸取代 Swing 成為 Java 桌面應用的首選。
-
第三方框架:
- Apache Pivot:基于 Batik 的輕量級框架,支持多種 UI 風格。
- MigLayout:增強的布局管理器,簡化復雜布局的實現。
- JGoodies Forms:提供更靈活的表單布局解決方案。
總結
維度 | AWT | Swing |
---|---|---|
年代 | 早期(JDK 1.0) | 后期(JDK 1.2+) |
技術路線 | 重量級,依賴原生系統 | 輕量級,純 Java 實現 |
外觀控制 | 受限(與系統一致) | 高度可定制 |
性能 | 低(原生調用開銷) | 高(Java 優化) |
學習曲線 | 簡單(基礎 API) | 較復雜(更多概念) |
推薦場景 | 簡單工具、原生集成 | 復雜 UI、跨平臺應用 |