黑馬程式設計師 —— 圖形使用者介面GUI (第二十二天)
一 概述
1.GUI
- Graphical User InterFace (圖形使用者介面)
- 用圖形的方式,來顯示計算機操作的介面,這樣更方便、更直觀。
2、CLI
- Command line User Interface(命令列使用者介面)
- 就是常見的Dos命令列操作
- 需要記憶一些常用的命令,操作不直觀
3.舉例:比如,建立資料夾,或者刪除資料夾等
4.Javs為GUI提供的物件都存在java.Awt和javax.Swing兩個包中。
5.Awt和Swing
java.Awt:Abstract Window Tookit(抽象視窗工具包),需要呼叫本地系統方法實現功能。屬重量級控制元件
javax.Swing:
二 GUI佈局
1.容器中的元件的排放方式,就是佈局。
2.常見的佈局管理器:
(1)Flow Layout(流式佈局管理器)
- 從左到右的順序排列
- Panel預設的佈局管理器
(2)BorderLayout(邊界佈局管理器)
- 東、南、西、北、中(上下左右中)
- Frame預設的佈局管理器
(3)GridLayout(網格佈局管理器)
- 規則的矩陣
(4)CardLayout(卡片佈局管理器)
- 選項卡
(5)GridBagLayout(網格包佈局管理器)
- 非規則的佈局
三 GUI_Frame
建立圖形化介面步驟如下:
- 常見frame窗體
- 對窗體進行基本設定(比如大小、位置、佈局等等)
- 定義元件
- 將元件通過窗體的add方法新增到窗體中
- 讓窗體顯示,通過setVisible(true)
示例程式碼:
import java.awt.*; public class Demo { public static void main(String[] args) throws Exception { // 預設是邊界佈局 Frame f = new Frame("my awt"); // 視窗的長寬 f.setSize(500, 400); // 視窗距離顯示器邊距的距離 f.setLocation(300, 200); // 預設是邊界佈局 f.setLayout(new FlowLayout()); Button b = new Button("我是一個按鈕"); f.add(b); // 設定可見 f.setVisible(true); sop("my awt"); } public static void sop(Object obj) { System.out.println(obj); } }
上面的程式碼只是弄了個窗體顯示,不會有任何反應。
四 事件監聽機制
1.Container常用子類:Window Panel(面邊,不能單獨存在)
2.Window常用子類:Frame Dialog
3.簡單的窗體建立過程:
Frame f = new Frame("my window");
f.setLayout(new FlowLayout());
f.setSize(500,400);//設定窗體大小
f.setLocation(300,200);//設定窗體出現在螢幕的位置
f.setVisible(true);
4.事件監聽機制組成- 事件源(元件):就是awt或者swing包中的那些圖形介面元件
- 事件(Event):每一個事件源,都有自己的特有的對應事件,和共性事件
- 監聽器(Listener):將可以觸發某一個事件的動作(不止一個動作)都已經封裝到了監聽器中
- 事件處理方式(引發事件後處理方式)
5.元件、Event、Listener在Java中,都已經定義好了,直接獲取其物件來用就可以了。我們要做的就是對產生的動作進行處理。
五 窗體事件
要使圖形化視窗的按鈕有反應,要了解下面這些方法:
void addWindowListener(WindowListener l):新增指定的視窗偵聽器,以從此視窗接收視窗事件
1.WindowListener為介面,要想使用,必須先實現方法,很麻煩。他有一個實現類,子類,實現了介面,不過為空方法。
public abstract class WindowAdapter extends Object implements WindowListener, WindowStateListener, WindowFocusListener
接收視窗事件的抽象介面卡類。此類中的方法為空。此類存在的目的是方便建立偵聽器物件。
2.事件
void windowActivated(WindowEvent e): 啟用視窗時呼叫
void windowClosed(WindowEvent e):當視窗已被關閉時呼叫
void windowClosing(WindowEvent e): 視窗正處在關閉過程中時呼叫
void windowDeactivated(WindowEvent e):停用視窗時呼叫
void windowDeiconified(WindowEvent e):取消圖示化視窗時呼叫
void windowGainedFocus(WindowEvent e)
該 Window 被設定為聚焦 Window 時呼叫,聚焦 Window 意味著該 Window 或其某個子元件將接收鍵盤事件。
void windowIconified(WindowEvent e):圖示化視窗時呼叫
void windowLostFocus(WindowEvent e)
該 Window 不再為聚焦 Window 時呼叫,不再為聚焦 Window 意味著鍵盤事件不再傳遞到該 Window 或其任意子元件。
void windowOpened(WindowEvent e)
已開啟視窗時呼叫。
void windowStateChanged(WindowEvent e)
視窗狀態改變時呼叫。
示例程式碼:
/*
建立圖形化介面
1、常見frame窗體
2、對窗體進行基本設定
比如大小、位置、佈局。
3、定義元件
4、將元件通過窗體的add方法新增到窗體中
5、讓窗體顯示,通過setvisible(true)
*/
import java.awt.*;
import java.awt.event.*;
public class Demo{
public static void main(String[] args) throws Exception{
//預設是邊界佈局
Frame f = new Frame("my awt");
//視窗的長寬
f.setSize(500,400);
//視窗距離顯示器邊距的距離
f.setLocation(300,200);
//預設是邊界佈局
f.setLayout(new FlowLayout());
//新增指定的視窗偵聽器,以從此視窗接收視窗事件。
f.addWindowListener(new MyWin());
Button b = new Button("我是一個按鈕");
f.add(b);
//設定可見
f.setVisible(true);
sop("my awt");
}
public static void sop(Object obj){
System.out.println(obj);
}
}
//因為WindowListener的子類WindowAdapter已經實現了WindowListener介面。
//並覆蓋了其中的所有方法,那麼我只要繼承自WindowAdapter覆蓋我需要的方法即可。
class MyWin extends WindowAdapter{
public void windowClosing(WindowEvent e){
Demo.sop("將要關閉");
System.exit(0);
}
public void windowOpened(WindowEvent e){
Demo.sop("我被開啟");
}
public void windowActivated(WindowEvent e){
Demo.sop("啟用");
}
}
六 Action事件
事件監聽機制
- 確定事件源(容器或元件)
- 通過事件源物件的addXXXLIstener()方法將監聽器註冊到該事件源上
- 該方法中接收XXXListener的子類物件,或者XXXListener的子類XXXAdaper的子類物件
- 一般用匿名內部類來表示
- 在覆蓋方法的時候,方法的引數一般是XXXEvent型別的變數接收
- 事件出發後會把事件打包成物件傳遞給該變數。(其中包括事件源物件。通過getSource()或者,getComponet()獲取)
import java.awt.*;
import java.awt.event.*;
public class Demo{
//定義圖形中所需的元件的引用
private Frame f;
private Button but;
Demo(){
init();
}
public static void main(String[] args) throws Exception{
new Demo();
}
public void init(){
f = new Frame("my frame");
//對frame進行基本設定
//f.setSize(500,400);
//void setBounds(int x, int y, int width, int height) 移動元件並調整其大小。
f.setBounds(300,400,600,500);
f.setLayout(new FlowLayout());
but = new Button("退出");
//將元件新增到frame中
f.add(but);
//載入一下窗體上的事件
myEvent();
//顯示窗體
f.setVisible(true);
}
private void myEvent(){
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
/*讓按鈕具備退出程式的功能
按鈕就是事件源
那麼選擇哪個監聽器呢?
通過關閉窗體示例瞭解到,想要知道那個元件具備什麼樣的特有監聽器。
需要產看該元件物件的功能。
通過查閱button的描述,發現按鈕支援一個特有監聽,addActionListener
*/
but.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("按鈕退出");
System.exit(0);
}
});
}
public static void sop(Object obj){
System.out.println(obj);
}
}
七 滑鼠事件
import java.awt.*;
import java.awt.event.*;
public class Demo {
// 定義圖形中所需的元件的引用
private Frame f;
private Button but;
Demo() {
init();
}
public static void main(String[] args) throws Exception {
new Demo();
}
public void init() {
f = new Frame("my frame");
// 對frame進行基本設定
// f.setSize(500,400);
// void setBounds(int x, int y, int width, int height) 移動元件並調整其大小。
f.setBounds(300, 400, 600, 500);
f.setLayout(new FlowLayout());
but = new Button("退出");
// 將元件新增到frame中
f.add(but);
// 載入一下窗體上的事件
myEvent();
// 顯示窗體
f.setVisible(true);
}
private void myEvent() {
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
/*
* 讓按鈕具備退出程式的功能 按鈕就是事件源 那麼選擇哪個監聽器呢? 通過關閉窗體示例瞭解到,想要知道那個元件具備什麼樣的特有監聽器。
* 需要產看該元件物件的功能。 通過查閱button的描述,發現按鈕支援一個特有監聽,addActionListener
*/
but.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sop("滑鼠活動");
}
});
but.addMouseListener(new MouseAdapter() {
private int count = 1;
private int clickCount = 1;
public void mouseEntered(MouseEvent e) {
sop("滑鼠進入事件" + (count++));
}
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
sop("滑鼠雙擊事件");
} else {
sop("滑鼠點選事件" + (clickCount++));
}
}
});
}
public static void sop(Object obj) {
System.out.println(obj);
}
}
八 鍵盤事件
import java.awt.*;
import java.awt.event.*;
public class Demo {
// 定義圖形中所需的元件的引用
private Frame f;
private Button but;
private TextField tf;
Demo() {
init();
}
public static void main(String[] args) throws Exception {
new Demo();
}
public void init() {
f = new Frame("my frame");
// 對frame進行基本設定
// f.setSize(500,400);
// void setBounds(int x, int y, int width, int height) 移動元件並調整其大小。
f.setBounds(300, 400, 600, 500);
f.setLayout(new FlowLayout());
but = new Button("退出");
// 文字框
tf = new TextField(20);
// 將元件新增到frame中
f.add(tf);
f.add(but);
// 載入一下窗體上的事件
myEvent();
// 顯示窗體
f.setVisible(true);
}
private void myEvent() {
but.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
System.exit(0);
}
if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER) {
sop("ctrl + enter");
}
sop(KeyEvent.getKeyText(e.getKeyChar()) + "...."
+ e.getKeyCode());
}
});
tf.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (!(code >= KeyEvent.VK_0 && code <= KeyEvent.VK_9)) {
sop(code + "是非法的");
// 遮蔽鍵
e.consume();
}
}
});
}
public static void sop(Object obj) {
System.out.println(obj);
}
}
九 練習:列出指定目錄內容
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
public class Demo {
private Frame f;
private TextField tf;
private Button but;
private TextArea ta;
Demo() {
init();
}
public static void main(String[] args) throws Exception {
new Demo();
}
public void init() {
f = new Frame("my window");
f.setLayout(new FlowLayout());
f.setBounds(300, 100, 600, 500);
tf = new TextField(60);
but = new Button("轉到");
ta = new TextArea(25, 70);
f.add(tf);
f.add(but);
f.add(ta);
myEvent();
f.setVisible(true);
}
private void myEvent() {
f.addWindowListener(new WindowAdapter() {
public void windowCloseing(WindowEvent e) {
System.exit(0);
}
});
but.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String dirPath = tf.getText();
tf.setText("");
File dir = new File(dirPath);
if (dir.exists() && dir.isDirectory()) {
ta.setText("");
String[] names = dir.list();
for (String name : names) {
ta.append(name + "\r\n");
}
}
}
});
}
public static void sop(Object obj) {
System.out.println(obj);
}
}
十 對話方塊Dialog
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
public class Demo {
private Frame f;
private TextField tf;
private Button but;
private TextArea ta;
private Dialog dl;
private Label lab;
private Dialog d;
private Button okBut;
Demo() {
init();
}
public static void main(String[] args) throws Exception {
new Demo();
}
public void init() {
f = new Frame("my window");
f.setLayout(new FlowLayout());
f.setBounds(300, 100, 600, 500);
tf = new TextField(60);
but = new Button("轉到");
ta = new TextArea(25, 70);
f.add(tf);
f.add(but);
f.add(ta);
lab = new Label();
d = new Dialog(f, "提示資訊-self", true);
okBut = new Button("確定");
d.setBounds(400, 200, 240, 150);
d.setLayout(new FlowLayout());
d.add(lab);
d.add(okBut);
myEvent();
f.setVisible(true);
}
private void myEvent() {
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
but.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showDir();
}
});
d.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
d.setVisible(false);
}
});
okBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
d.setVisible(false);
}
});
tf.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
showDir();
}
}
});
}
public void showDir() {
String dirPath = tf.getText();
tf.setText("");
File dir = new File(dirPath);
if (dir.exists() && dir.isDirectory()) {
ta.setText("");
String[] names = dir.list();
for (String name : names) {
ta.append(name + "\r\n");
}
} else {
String info = "您輸入的資訊:" + dirPath + "是錯誤路徑,請重新輸入。";
lab.setText(info);
d.setVisible(true);
}
}
public static void sop(Object obj) {
System.out.println(obj);
}
}
十一 選單
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
public class Demo {
private Frame f;
private MenuBar mb;
private Menu m, subMenu;
private MenuItem closeItem, subItem;
Demo() {
init();
}
public static void main(String[] args) throws Exception {
new Demo();
}
public void init() {
f = new Frame("my window");
f.setLayout(new FlowLayout());
f.setBounds(300, 100, 500, 600);
mb = new MenuBar();
subMenu = new Menu("子選單");
m = new Menu("檔案");
closeItem = new MenuItem("退出");
subItem = new MenuItem("子條目");
subMenu.add(subItem);
m.add(subMenu);
m.add(closeItem);
mb.add(m);
myEvent();
f.setMenuBar(mb);
f.setVisible(true);
}
private void myEvent() {
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
closeItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
public static void sop(Object obj) {
System.out.println(obj);
}
}
十二、十三 練習-開啟、儲存檔案
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
public class Demo{
private Frame f;
private TextArea ta;
private MenuBar bar;
private Menu fileMenu;
private MenuItem openItem,saveItem,closeItem;
private FileDialog openDia,saveDia;
private File file;
Demo(){
init();
}
public static void main(String[] args) throws Exception{
new Demo();
}
public void init(){
f = new Frame("my window");
//f.setLayout(new FlowLayout());
f.setBounds(300,100,500,600);
ta = new TextArea();
bar = new MenuBar();
fileMenu = new Menu("檔案");
openItem = new MenuItem("開啟");
saveItem = new MenuItem("儲存");
closeItem = new MenuItem("退出");
fileMenu.add(openItem);
fileMenu.add(saveItem);
fileMenu.add(closeItem);
bar.add(fileMenu);
myEvent();
f.add(ta);
f.setMenuBar(bar);
openDia = new FileDialog(f,"我要開啟",FileDialog.LOAD);
saveDia = new FileDialog(f,"我要儲存",FileDialog.SAVE);
f.setVisible(true);
}
private void myEvent(){
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
openItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
openDia.setVisible(true);
String dirPath = openDia.getDirectory();
String fileName = openDia.getFile();
if(dirPath==null||fileName==null)
return;
ta.setText("");
openFile(dirPath,fileName);
f.setTitle("檔案:"+dirPath+fileName);
}
});
saveItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(file == null){
saveDia.setVisible(true);
String dirPath = saveDia.getDirectory();
String fileName = saveDia.getFile();
if(dirPath==null||fileName==null)
return;
saveFile(dirPath,fileName);
f.setTitle("檔案:"+dirPath+fileName);
}else{
saveFile();
}
}
});
closeItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
}
public void openFile(String dirPath,String fileName){
file = new File(dirPath,fileName);
try{
BufferedReader bufr = new BufferedReader(new FileReader(file));
String line = null;
while((line = bufr.readLine())!=null){
ta.append(line+"\r\n");
}
}catch(IOException ioe){
throw new RuntimeException("讀取失敗");
}
}
public void saveFile(){
saveFile(null,null);
}
public void saveFile(String dirPath,String fileName){
if(file==null){
file = new File(dirPath,fileName);
}
try{
BufferedWriter bufw = new BufferedWriter(new FileWriter(file));
String text = ta.getText();
bufw.write(text);
bufw.close();
}catch(IOException ioe){
throw new RuntimeException("讀取失敗");
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
十四 jar包雙擊執行
jar -cvfm my.jar 1.txt mymenu
Main-class: mymenu.Demo //要有空格和回車