Java學習之AWT GUI程式設計

nice_0e3發表於2020-11-20

Java學習之AWT GUI程式設計

0x00 前言

既然前面提到了要重寫冰蠍和一些反序列化工具,當然就不能隨便說說而已。在編寫這些工具還是要使用圖形化工具來的方便一些,所以提前把GUI的框架給學習一遍。

其實重寫webshell工具這個也就是實現部分,現在就差個gui框架。

這裡其實是已經完善了單向加密和雙向加密的功能,並且服務端aes動態金鑰加密也寫好了,且可以定義128和256位aes的加密。

Java安全之JSP動靜態免殺思路實現與服務端編寫

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 (選單項)等子類。

多的體系什麼的就不看了,主要是實用為主。

0x03 AWT程式碼實現

Frame

第一個GUI介面

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);
    }
}

Panel皮膚

Panel可以看成是一個皮膚,簡單來說就是一個容器。

程式碼例項:

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);
            }
        });



    }
}

佈局管理器

流式佈局

程式碼:

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);






    }
}

東西南北中佈局

程式碼:

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);







    }
}

表格佈局

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);






    }
}

文字框

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);



    }
}

常用元件

元件名 功能
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
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);




    }
}

FileDialog

Dialog 類還有 一個子類 : FileDialog ,它代表一個檔案對話方塊,用於開啟或者儲存 檔案,需要注意的是FileDialog無法指定模態或者非模態,這是因為 FileDialog 依賴於執行平臺的實現,如果執行平臺的檔案對話方塊是模態的,那麼 FileDialog 也是模態的;否則就是非模態的 。

方法名稱 方法功能
FileDialog(Frame parent, String title, int mode) 建立一個檔案對話方塊:
parent:指定父視窗
title:對話方塊標題
mode:檔案對話方塊型別,如果指定為FileDialog.load,用於開啟檔案,如果指定為FileDialog.SAVE,用於儲存檔案
String getDirectory() 獲取被開啟或儲存檔案的絕對路徑
String getFile() 獲取被開啟或儲存檔案的檔名

程式碼:

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);

    }
}

事件監聽器

定義:

​ 當在某個元件上發生某些操作的時候,會自動的觸發一段程式碼的執行。

在GUI事件處理機制中涉及到4個重要的概念需要理解:

事件源(Event Source):操作發生的場所,通常指某個元件,例如按鈕、視窗等;
事件(Event):在事件源上發生的操作可以叫做事件,GUI會把事件都封裝到一個Event物件中,如果需要知道該事件的詳細資訊,就可以通過Event物件來獲取。
事件監聽器(Event Listener):當在某個事件源上發生了某個事件,事件監聽器就可以對這個事件進行處理。

註冊監聽:把某個事件監聽器(A)通過某個事件(B)繫結到某個事件源(C)上,當在事件源C上發生了事件B之後,那麼事件監聽器A的程式碼就會自動執行。

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();
    }
    }

程式碼二:

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);
    }





    }


選單元件

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

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框架。

相關文章