1. 程式人生 > >Java學習之AWT GUI程式設計

Java學習之AWT GUI程式設計

# Java學習之AWT GUI程式設計 ## 0x00 前言 既然前面提到了要重寫冰蠍和一些反序列化工具,當然就不能隨便說說而已。在編寫這些工具還是要使用圖形化工具來的方便一些,所以提前把GUI的框架給學習一遍。 其實重寫webshell工具這個也就是實現部分,現在就差個gui框架。 ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001520276-1989281962.png) 這裡其實是已經完善了單向加密和雙向加密的功能,並且服務端aes動態金鑰加密也寫好了,且可以定義128和256位aes的加密。 ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001529387-1765054782.png) ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001547685-1419420377.png) [Java安全之JSP動靜態免殺思路實現與服務端編寫](https://www.cnblogs.com/nice0e3/p/13998892.html) ## 0x01 AWT概述 當 JDK 1.0釋出時, Sun 提供了 一套基本的GUI類庫,這個GUI類庫希望可以在所有平臺下都能執行 , 這套基本類庫被稱為"抽象視窗工具集 CAbstract Window Toolkit )",它為Java應用程式提供了基本的圖形元件 。 AWT是視窗框架,它從不同平臺的視窗系統中抽取出共同元件 , 當程式執行時,將這些元件的建立和動作委託給程式所在的執行平臺 。 簡而言之 ,當使用 AWT 編寫圖形介面應用 時, 程式僅指定了介面元件的位置和行為,並未提供真正的實現,JVM呼叫作業系統本地的圖形介面來建立和平臺 一致的對等體 。 ​ 使用AWT建立的圖形介面應用和所在的執行平臺有相同的介面風格 , 比如在 Windows 作業系統上,它就表現出 Windows 風格 ; 在 UNIX 作業系統上,它就表現出UNIX 風格 。 Sun 希望採用這種方式來實現 " Write Once, Run Anywhere "(一次編寫多次執行) 的目標 。 ## 0x02 AWT體系 所有和 AWT 程式設計相關的類都放在 java.awt 包以及它的子包中, AWT 程式設計中有兩個基類 :Component和 MenuComponent。 ``` Component:代表一個能以圖形化方式顯示出來,並可與使用者互動的物件,例如 Button 代表一個按鈕,TextField 代表 一個文字框等; MenuComponent:則代表圖形介面的選單元件,包括 MenuBar (選單條)、 Menultem (選單項)等子類。 ``` ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001602176-865315983.png) 多的體系什麼的就不看了,主要是實用為主。 ## 0x03 AWT程式碼實現 ### Frame #### 第一個GUI介面 ```java package com.test; import java.awt.*; public class test { public static void main(String[] args) { Frame frame = new Frame("nwebshell"); frame.setVisible(true); frame.setSize(400,400); frame.setLocation(500,500); } } ``` ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001612875-805438250.png) ### Panel面板 Panel可以看成是一個面板,簡單來說就是一個容器。 #### 程式碼例項: ```java package com.test; import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class test { public static void main(String[] args) { Frame frame = new Frame("nwebshell"); //設定佈局 frame.setLayout(null); //視窗可見 frame.setVisible(true); //設定座標 frame.setBounds(300,300,500,500); Panel panel = new Panel(); //設定panel座標,相對於frame panel.setBounds(50,50,400,400); panel.setBackground(new Color(219, 185, 185)); frame.add(panel); // frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { //結束程式 System.exit(0); } }); } } ``` ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001623396-866172505.png) ### 佈局管理器 #### 流式佈局 程式碼: ```java package com.test; import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class test { public static void main(String[] args) { Frame frame = new Frame("nwebshell"); Button button1 = new Button("submit"); Button button2 = new Button("submit"); Button button3 = new Button("submit"); frame.setSize(500,500); //設定佈局 frame.setLayout(null); //視窗可見 frame.setVisible(true); //設定流式佈局 frame.setLayout(new FlowLayout(FlowLayout.RIGHT)); //新增按鈕 frame.add(button1); frame.add(button2); frame.add(button3); } } ``` ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001634941-379862727.png) #### 東西南北中佈局 程式碼: ```java package com.test; import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class test { public static void main(String[] args) { Frame frame = new Frame("nwebshell"); Button button1 = new Button("submit"); Button button2 = new Button("submit"); Button button3 = new Button("submit"); Button button4 = new Button("submit"); Button button5 = new Button("submit"); frame.setSize(500,500); //新增按鈕 frame.add(button1,BorderLayout.EAST); frame.add(button2,BorderLayout.WEST); frame.add(button3,BorderLayout.SOUTH); frame.add(button4,BorderLayout.NORTH); frame.add(button5,BorderLayout.CENTER); frame.setVisible(true); } } ``` ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001646601-1902303013.png) #### 表格佈局 ```java package com.test; import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class test { public static void main(String[] args) { Frame frame = new Frame("nwebshell"); Button button1 = new Button("submit"); Button button2 = new Button("submit"); Button button3 = new Button("submit"); Button button4 = new Button("submit"); Button button5 = new Button("submit"); frame.setSize(500,500); //設定表格佈局 frame.setLayout(new GridLayout(3,2)); frame.add(button1); frame.add(button2); frame.add(button3); frame.add(button4); frame.add(button5); //自動佈局 frame.pack(); frame.setVisible(true); } } ``` ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001656142-1078989728.png) ### 文字框 ```java package com.test; import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class test { public static void main(String[] args) { Frame frame = new Frame("nwebshell"); Panel panel=new Panel(); Button button = new Button("submit"); TextField textField = new TextField(); textField.setText("普通文字框"); textField.setVisible(true); frame.setVisible(true); frame.setSize(500,500); panel.add(button); panel.add(textField); frame.add(panel); } } ``` ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001707167-1660489636.png) ### 常用元件 | 元件名 | 功能 | | ------------- | ------------------------------------------------------------ | | Button | Button | | Canvas | 用於繪圖的畫布 | | Checkbox | 複選框元件(也可當做單選框元件使用) | | CheckboxGroup | 用於將多個Checkbox 元件組合成一組, 一組 Checkbox 元件將只有一個可以 被選中 , 即全部變成單選框元件 | | Choice | 下拉選擇框 | | Frame | 視窗 , 在 GUI 程式裡通過該類建立視窗 | | Label | 標籤類,用於放置提示性文字 | | List | JU表框元件,可以新增多項條目 | | Panel | 不能單獨存在基本容器類,必須放到其他容器中 | | Scrollbar | 滑動條元件。如果需要使用者輸入位於某個範圍的值 , 就可以使用滑動條元件 ,比如調 色板中設定 RGB 的三個值所用的滑動條。當建立一個滑動條時,必須指定它的方向、初始值、 滑塊的大小、最小值和最大值。 | | ScrollPane | 帶水平及垂直滾動條的容器元件 | | TextArea | 多行文字域 | | TextField | 單行文字框 | #### 對話方塊 Dialog | 方法名稱 | 方法功能 | | ------------------------------------------------ | ------------------------------------------------------------ | | Dialog(Frame owner, String title, boolean modal) | 建立一個對話方塊物件:
owner:當前對話方塊的父視窗
title:當前對話方塊的標題
modal:當前對話方塊是否是模式對話方塊,true/false | ```java package com.test; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class test { public static void main(String[] args) { Frame frame = new Frame("nwebshell"); final Dialog d1 = new Dialog(frame, "command", true); final Dialog d2 = new Dialog(frame, "connection", true); // 往對話方塊中新增內容 Box vBox = Box.createVerticalBox(); vBox.add(new TextField(15)); vBox.add(new Button("submit")); d1.add(vBox); // 設定對話方塊大小 Button b1 = new Button("open"); Button b2 = new Button("close"); // 給b1按鈕繫結事件 d1.setBounds(20,30,300,100); d2.setBounds(20,30,300,400); b1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { d1.setVisible(true); } }); b2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { d2.setVisible(true); } }); //把按鈕新增到frame中 frame.add(b1); frame.add(b2,BorderLayout.SOUTH); //設定frame最佳大小並可見 frame.pack(); frame.setVisible(true); frame.setSize(1024,700); } } ``` ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001725146-44532713.png) ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001734922-553249788.png) #### FileDialog Dialog 類還有 一個子類 : FileDialog ,它代表一個檔案對話方塊,用於開啟或者儲存 檔案,需要注意的是FileDialog無法指定模態或者非模態,這是因為 FileDialog 依賴於執行平臺的實現,如果執行平臺的檔案對話方塊是模態的,那麼 FileDialog 也是模態的;否則就是非模態的 。 | 方法名稱 | 方法功能 | | ------------------------------------------------ | ------------------------------------------------------------ | | FileDialog(Frame parent, String title, int mode) | 建立一個檔案對話方塊:
parent:指定父視窗
title:對話方塊標題
mode:檔案對話方塊型別,如果指定為FileDialog.load,用於開啟檔案,如果指定為FileDialog.SAVE,用於儲存檔案 | | String getDirectory() | 獲取被開啟或儲存檔案的絕對路徑 | | String getFile() | 獲取被開啟或儲存檔案的檔名 | 程式碼: ```java package com.test; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class test { public static void main(String[] args) { Frame frame = new Frame("nwebshell"); // 載入檔案 final FileDialog load_file = new FileDialog(frame, "load_file", FileDialog.LOAD); final FileDialog save_file = new FileDialog(frame, "save_file", FileDialog.SAVE); Button open_file_b = new Button("open_file"); Button save_file_b = new Button("save_file"); //給按鈕新增事件 open_file_b.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { load_file.setVisible(true); // 列印使用者選擇的檔案路徑和名稱 System.out.println(load_file.getDirectory()); System.out.println(load_file.getFile()); } }); save_file_b.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println(save_file.getDirectory()); System.out.println(save_file.getFile()); } }); // 配置完按鈕事件,將按鈕新增到frame中 frame.add(open_file_b); frame.add(save_file_b,BorderLayout.SOUTH); frame.pack(); frame.setVisible(true); } } ``` ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001750285-2048170869.png) ### 事件監聽器 **定義:** ​ 當在某個元件上發生某些操作的時候,會自動的觸發一段程式碼的執行。 在GUI事件處理機制中涉及到4個重要的概念需要理解: **事件源(Event Source)**:操作發生的場所,通常指某個元件,例如按鈕、視窗等; **事件(Event)**:在事件源上發生的操作可以叫做事件,GUI會把事件都封裝到一個Event物件中,如果需要知道該事件的詳細資訊,就可以通過Event物件來獲取。 **事件監聽器(Event Listener)**:當在某個事件源上發生了某個事件,事件監聽器就可以對這個事件進行處理。 **註冊監聽**:把某個事件監聽器(A)通過某個事件(B)繫結到某個事件源(C)上,當在事件源C上發生了事件B之後,那麼事件監聽器A的程式碼就會自動執行。 ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001802790-1751755729.png) ```java package com.test; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class test { Frame frame = new Frame("nwebshell"); Button button = new Button("submit"); TextField textField = new TextField(30); public void init(){ button.addActionListener(new MyActionLitst()); frame.add(textField); frame.add(button,BorderLayout.SOUTH); frame.pack(); frame.setVisible(true); } private class MyActionLitst implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { textField.setText("Hello World"); } } public static void main(String[] args) { new test().init(); } } ``` ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001817905-339752724.png) 程式碼二: ```java package com.test; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class test { public static void main(String[] args) { Frame frame = new Frame("nwebshell"); final TextField textField = new TextField(30); textField.addTextListener(new TextListener() { @Override public void textValueChanged(TextEvent e) { System.out.println(textField.getText()); } }); frame.add(textField); frame.pack(); frame.setVisible(true); } } ``` ![](https://img2020.cnblogs.com/blog/1993669/202011/1993669-20201120001830892-1413542784.png) ### 選單元件 ```java import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class SimpleMenu { //建立視窗 private Frame frame = new Frame("這裡測試選單相關元件"); //建立選單條元件 private MenuBar menuBar = new MenuBar(); //建立檔案選單元件 private Menu fileMenu = new Menu("檔案"); //建立編輯選單元件 private Menu editMenu = new Menu("編輯"); //建立新建選單項 private MenuItem newItem = new MenuItem("新建"); //建立儲存選單項 private MenuItem saveItem = new MenuItem("儲存"); //建立退出選單項 private MenuItem exitItem = new MenuItem("退出"); //建立自動換行選擇框選單項 private CheckboxMenuItem autoWrap = new CheckboxMenuItem("自動換行"); //建立複製選單項 private MenuItem copyItem = new MenuItem("複製"); //建立貼上選單項 private MenuItem pasteItem = new MenuItem("貼上"); //建立格式選單 private Menu formatMenu = new Menu("格式"); //建立註釋選單項 private MenuItem commentItem = new MenuItem("註釋"); //建立取消註釋選單項 private MenuItem cancelItem = new MenuItem("取消註釋"); //建立一個文字域 private TextArea ta = new TextArea(6, 40); public void init(){ //定義選單事件監聽器 ActionListener listener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); ta.append("單擊“"+command+"”選單\n"); if (command.equals("退出")){ System.exit(0); } } }; //為註釋選單項和退出選單項註冊監聽器 commentItem.addActionListener(listener); exitItem.addActionListener(listener); //為檔案選單fileMenu新增選單項 fileMenu.add(newItem); fileMenu.add(saveItem); fileMenu.add(exitItem); //為編輯選單editMenu新增選單項 editMenu.add(autoWrap); editMenu.add(copyItem); editMenu.add(pasteItem); //為格式化選單formatMenu新增選單項 formatMenu.add(commentItem); formatMenu.add(cancelItem); //將格式化選單新增到編輯選單中,作為二級選單 editMenu.add(new MenuItem("-")); editMenu.add(formatMenu); //將檔案選單和編輯選單新增到選單條中 menuBar.add(fileMenu); menuBar.add(editMenu); //把選單條設定到frame視窗上 frame.setMenuBar(menuBar); //把文字域新增到frame中 frame.add(ta); //設定frame最佳大小並可見 frame.pack(); frame.setVisible(true); } public static void main(String[] args) { new SimpleMenu().init(); } } ``` #### PopupMenu ```java import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class PopupMenuTest { private Frame frame = new Frame("這裡測試PopupMenu"); //建立PopubMenu選單 private PopupMenu popupMenu = new PopupMenu(); //建立選單條 private MenuItem commentItem = new MenuItem("註釋"); private MenuItem cancelItem = new MenuItem("取消註釋"); private MenuItem copyItem = new MenuItem("複製"); private MenuItem pasteItem = new MenuItem("儲存"); //建立一個文字域 private TextArea ta = new TextArea("!!!", 6, 40); //建立一個Panel private Panel panel = new Panel(); public void init(){ //把選單項新增到PopupMenu中 popupMenu.add(commentItem); popupMenu.add(cancelItem); popupMenu.add(copyItem); popupMenu.add(pasteItem); //設定panel大小 panel.setPreferredSize(new Dimension(300,100)); //把PopupMenu新增到panel中 panel.add(popupMenu); //為panel註冊滑鼠事件 panel.addMouseListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { boolean flag = e.isPopupTrigger(); //判斷當前滑鼠操作是不是觸發PopupMenu的操作 if (flag){ //讓PopupMenu顯示在panel上,並且跟隨滑鼠事件發生的地方顯示 popupMenu.show(panel,e.getX(),e.getY()); } } }); //把ta新增到frame中間區域中 frame.add(ta); //把panel新增到frame底部 frame.add(panel,BorderLayout.SOUTH); //設定frame最佳大小,並可視; frame.pack(); frame.setVisible(true); } public static void main(String[] args) { new PopupMenuTest().init(); } } ``` ## 0x04 結尾 其實,在開發中會發現,Java寫gui介面真挺繁雜的。配置頁面都得手工去適配,就沒有像C#這些這麼方便,直接畫框,配置事件就完事了。AWT這個類其實不能夠做到跨平臺,因為他是藉助windows的介面。後面會接著學習Swing