• Java.awt & MFC消息处理机制


    一,MFC消息处理机制

    WINDOWS 消息的种类:
      1、标准WINDOWS消息:这类消息是以WM_为前缀,不过WM_COMMAND例外。 例如: WM_MOVE、WM_QUIT等。
      2、命令消息:命令消息以WM_COMMAND为消息名。在消息中含有命令的标志符ID,以区分具体的命令。由菜单,工具栏等命令接口对象产生。
      3、控件通知消息:控件通知消息也是以WM_COMMAND为消息名。由编辑框、列表框和子窗口发送给父窗口的通知消息。在消息中包含控件通知码,以区分具体控件的通知消息。

    MFC中处理消息的顺序

    1.     AfxWndProc()接收消息,寻找消息所属的CWnd对象,然后调用AfxCallWndProc( )。

    2.     AfxCallWndProc()存储消息(消息标识符和消息参数)供未来参考,然后调用WindowProc( )。

    3.     WindowProc()发送消息给OnWndMsg( ),如果消息未被处理,则发送给DefWindowproc( )。

    4.     OnWndMsg()首先按字节对消息进行排序,对于WM_COMMAND消息,调用OnCommand()消息响应函数;对于WM_NOTIFY消息调用OnNotify()消息响应函数。任何被遗漏的消息将是标准消息。OnWndMsg()函数搜索类的消息映像,以找到一个能处理任何窗口消息的处理函数。如果OnWndMsg()函数不能找到这样的处理函数的话,则把消息返回到WindowProc()函数,由它将消息发送给DefWindowProc()函数。

    5.     OnCommand()查看这是不是一个控件通知(lParam参数不为NULL),如果它是,OnCommand()函数会试图将消息映射到制造通知的控件;如果它不是一个控件通知,或者控件拒绝映射的消息,OnCommand()就会调用OnCmdMsg()函数。

    6.     OnNotify( )也试图将消息映射到制造通知的控件;如果映射不成功,OnNotify( )就调用相同的OnCmdMsg( )函数。

    7.     根据接收消息的类,OnCmdMsg()函数将在一个称为命令传递(Command Routing)的过程中潜在的传递命令消息和控件通知。例如:如果拥有该窗口的类是一个框架类,则命令和控件通知消息也被传递到视图和文档类,并为该类寻找一个消息处理函数。

     

    MFC中创建窗口的顺序

    1.     PreCreateWindow()是一个重载函数,在窗口被创建前,可以在该重载函数中改变创建参数(可以设置窗口风格等等)。

    2.     PreSubclassWindow()也是一个重载函数,允许首先子分类一个窗口OnGetMinMaxInfo()为消息响应函数,响应的是WM_GETMINMAXINFO消息,允许设置窗口的最大或者最小尺寸。

    3.     OnNcCreate()也是一个消息响应函数,响应WM_NCCREATE消息,发送消息以告诉窗口的客户区即将被创建。

    4.     OnNcCalcSize()也是消息响应函数,响应WM_NCCALCSIZE消息,作用是允许改变窗口客户区大小。

    5.     OnCreate()也是消息响应函数,响应WM_CREATE消息,发送消息告诉一个窗口已经被创建。

    6.     OnSize()也是消息响应函数,响应WM_SIZE消息,发送该消息以告诉该窗口大小已经发生变化。

    7.     OnMove()也是消息响应函数,响应WM_MOVE消息,发送此消息说明窗口在移动。

    8.     OnChildNotify()为重载函数,作为部分消息映射被调用,告诉父窗口即将被告知一个窗口刚刚被创建。

    SetTimer与WM_TIMER消息

    Timer被设置后会一直存在,直到用KillTimer(hwnd, ID)删除。

    Timer被创建后,每隔一定时间会发送 WM_TIMER 消息,当收到WM_TIMER 消息后,程序就会调用函数。也可以在创建Timer时指定回调函数。

    SetTimer 原形如下,注意 CWnd 类的 SetTimer 方法没有第一个参数:

    UINT_PTR SetTimer( HWND hWnd, UINT_PTR nIDEvent, UINT uElapse,  TIMERPROC lpTimerFunc);

    四个参数分别是: hWnd 所属的窗口句柄,如果 lpTimerFunc 为空,这个窗口将接收 WM_TIMER 消息。

    nIDEvent 计时器ID值,发送 WM_TIMER消息时会附带发送这个值。

    uElapse 超时时间。每uElapse毫秒发送WM_TIMER

    lpTimerFunc 回调函数,如果为空,将发送 WM_TIMER 消息给 hWnd 指定的窗口的消息队列。

    lpTimerFunc 的函数原型如下:

    VOID CALLBACK TimerProc( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);

    用一个Windows窗口实例来解释消息处理

    #include <windows.h>
    #include <cstdio>
    
    //回调函数
    LRESULT CALLBACK WinSunProc(
        HWND hwnd,          // 窗口句柄
        UINT message,          // 消息代码
        WPARAM wParam,      // 附加参数
        LPARAM lParam
        ) {
            switch(message) {
            case WM_CREATE: {
                HDC hdc;
                PAINTSTRUCT ps;
                hdc = BeginPaint(hwnd, &ps);
                char str[20];
                wsprintf(str, "窗口创建消息");
                MessageBox(hwnd, str, "提示", MB_OK);
                break;
                            }
            case WM_PAINT: {
                SetTimer(hwnd, 10, 100, NULL);
    
                HDC hdc;
                PAINTSTRUCT ps;
                hdc = BeginPaint(hwnd, &ps);
                char str[20];
                wsprintf(str, "Hello World");
                TextOut(hdc, rand()%600, rand()%300, str, strlen(str));
                break;
                           }
            case WM_CHAR:
                char szChar[20];
                sprintf(szChar, "char code is %d", wParam);
                MessageBox(hwnd, szChar, "您的按键", 0);
                break;
            case WM_TIMER:
                InvalidateRect(hwnd, NULL, true);
                break;
            case WM_DESTROY: //销毁窗口
                PostQuitMessage(0);
                return 0;
            }
            return DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    int WINAPI WinMain(
        HINSTANCE hInstance,         // handle to current instance
        HINSTANCE hPrevInstance,     // handle to previous instance
        LPSTR lpCmdLine,             // command line
        int nCmdShow                 // show state
        ) {
            // 窗口类
            WNDCLASS wndcls;
            wndcls.cbClsExtra = 0;                                          // 类附加内存
            wndcls.cbWndExtra = 0;                                          // 窗口附加内存
            wndcls.hbrBackground = (HBRUSH) GetStockObject(COLOR_WINDOW);    // 背景画刷句柄
            wndcls.hCursor = LoadCursor(NULL, IDC_ARROW);                   // 窗口光标句柄
            wndcls.hIcon = LoadIcon(NULL, IDI_APPLICATION);                       // 窗口图标句柄
            wndcls.hInstance = hInstance;                                   // 包含窗口过程函数的程序实例
            wndcls.lpfnWndProc = WinSunProc;                                // 只想窗口过程函数的指针
            wndcls.lpszClassName = "CRoot";                                // 窗口类名称
            wndcls.lpszMenuName = NULL;                                     // 菜单资源
            wndcls.style = CS_HREDRAW | CS_VREDRAW;                         // 窗口样式
            RegisterClass(&wndcls);
    
            // 创建窗口, 定义一个变量用来保存成功创建窗口后返回的句柄
            HWND hwnd  = CreateWindow(        // 窗口创建成功时返回为窗口分配的句柄 失败时返回NULL
                "CRoot",               // 窗口类名
                "Hello World",          // 窗口名字
                WS_CAPTION|WS_SYSMENU,    // 窗口样式
                300, 300,                   // 窗口左上角坐标
                700, 400,               // 窗口宽高
                NULL,                   // 父窗口句柄
                NULL,                   // 窗口菜单句柄
                hInstance,              // 窗口所属应用程序实例
                NULL                    // WM_CREATE消息附加参数lParam传入的数据指针
                );
    
            // 显示及刷新窗口
            ShowWindow(hwnd, SW_SHOWNORMAL);
            UpdateWindow(hwnd);
    
            // 定义消息结构体
            MSG msg;
            while (GetMessage(  // WM_QUIT消息返回0 错误返回-1
                &msg,           // 指向消息的结构体
                NULL,           // 指定接收属于哪一窗口的消息 通常设为NULL,用来接收属于调用线程的所有窗口的窗口消息
                0,              // 获取消息的最小值 通常为0
                0))             // 获取消息的最大值 都设为0表示接收所有消息
            {
                TranslateMessage(&msg);     // 将虚拟消息转换为字符消息 投递到调用线程的消息队列中 下次调用GetMessage时被取出
                DispatchMessage(&msg);      // 将消息传递给操作系统 由操作系统调用窗口过程函数对消息进行处理
            }
            return msg.wParam;
    }

    附加参数WPARAM与WM_COMMAND

    创建一个按钮

    CreateWindowEx(0,"Button","我是按钮",WS_VISIBLE|WS_CHILD,100,100,100,50,hwnd,(HMENU)10,0,0);

    HMENU为按钮的ID号,监听器识别ID执行。

    消息的附加信息在wParam中。

    switch(message) {
            case WM_CREATE: {
                CreateWindowEx(0,"Button","我是按钮",WS_VISIBLE|WS_CHILD,100,100,100,50,hwnd,(HMENU)10,0,0);
                break;
                            }
            case WM_COMMAND: {
                WORD wmId    = LOWORD(wParam); 
                switch (wmId) {
                case (10):
                    MessageBoxA(NULL,"Hello Button!","My TestProject",MB_OK);
                    break;
                }
                break;
                             }

    实例(数据结构课程设计)

    MFC界面的贪吃蛇游戏

    #include <iostream>
    #include <windows.h>
    #include <ctime>
    #include <fstream>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include "resource.h"
    using namespace std;
    
    #define IDT_TIMER 100
    #define HEIGHT 300
    #define WIDTH 500
    
    int POINT_X[2], POINT_Y[2];
    int score = 0;
    int rate = 100;
    int change = 0;
    struct People {
        char name[20];
        int num;
        bool operator < (const People &tmp) const {
            return num > tmp.num;
        }
    } people[10];
    int tot;
    char user[20];
    
    struct point {
        int x, y;
    };
    struct Node {
        point data;
        Node *next;
    } top;
    struct Link {
        Node *head, *last, *pre_last;
        Link() {
            last = head = &top;
            last->next = NULL;
            last->data.x = 5;
            last->data.y = 5;
        }
    } snake;
    char direction = 'r';
    
    void AddList() {
        Node *tmp = new Node;
    
        tmp->data.x = 1000;
        tmp->data.y = 1000;
        tmp->next = NULL;
        snake.pre_last = snake.last;
        snake.pre_last->next = tmp;
        snake.last = tmp;
    }
    void GoAhead(int dx, int dy) {
        snake.pre_last->next = NULL;
        snake.last->data.x = snake.head->data.x + dx;
        snake.last->data.y = snake.head->data.y + dy;
        snake.last->next = snake.head;
        snake.head = snake.last;
        snake.last = snake.pre_last;
    
        snake.pre_last = snake.head;
        while (snake.pre_last->next != snake.last)
            snake.pre_last = snake.pre_last->next;
    }
    void Drow(HWND hwnd) {
        HDC hdc;
        PAINTSTRUCT ps;
        hdc = BeginPaint(hwnd, &ps);
        RECT rc;
        //计分和静态文档
        char sz[20];
        wsprintf(sz, "分数:");
        TextOut(hdc, WIDTH + 20, 40, sz, strlen(sz));
        wsprintf(sz, "%d", score * 100);
        TextOut(hdc, WIDTH + 20, 70, sz, strlen(sz));
        wsprintf(sz, "排行榜:");
        TextOut(hdc, WIDTH + 20, 90, sz, strlen(sz));
        for(int i = 0; i<tot; i++) {
            wsprintf(sz, "%s     %d", people[i].name, people[i].num);
            TextOut(hdc, WIDTH + 20, 110 + i * 20, sz, strlen(sz));
        }
        //画蛇
        HBRUSH hBrush = CreateSolidBrush(RGB(0,0,0));
        Node *tp = snake.head;
        while (tp) {
            rc.left = (tp->data.x) * 11;
            rc.right = rc.left + 10;
            rc.top = (tp->data.y) * 11;
            rc.bottom = rc.top + 10;
            FillRect(hdc, &rc, hBrush);
            tp = tp->next;
        }
        //画点1
        hBrush = CreateSolidBrush(RGB(255,0,0));
        rc.left = POINT_X[0] * 11;
        rc.right = rc.left + 10;
        rc.top = POINT_Y[0] * 11;
        rc.bottom = rc.top + 10;
        FillRect(hdc, &rc, hBrush);
        //画点2
        rc.left = POINT_X[1] * 11;
        rc.right = rc.left + 10;
        rc.top = POINT_Y[1] * 11;
        rc.bottom = rc.top + 10;
        FillRect(hdc, &rc, hBrush);
        //画边界
        MoveToEx(hdc, WIDTH + 15, HEIGHT + 15, NULL);
        LineTo(hdc, WIDTH + 15, 0);
        DeleteObject(hBrush);
        EndPaint(hwnd, &ps);
    }
    int getPoint() {
        if (POINT_X[0] == (snake.head->data.x) && POINT_Y[0] == (snake.head->data.y))
            return 0;
        if (POINT_X[1] == (snake.head->data.x) && POINT_Y[1] == (snake.head->data.y))
            return 1;
        return -1;
    }
    int check() {
        if (snake.head->data.x
                < 0||(snake.head->data.x)*11>WIDTH||snake.head->data.y < 0||(snake.head->data.y)*11>HEIGHT)
            return 1;
        for (Node *p = snake.head->next; p->next; p = p->next)
            if (p->data.x == snake.head->data.x && p->data.y == snake.head->data.y)
                return 2;
        return 0;
    }
    bool isOK(int x, int y) {
        Node *tp = snake.head;
        while (tp) {
            if(tp->data.x == x && tp->data.y == y)
                return 1;
            tp = tp->next;
        }
        return 0;
    }
    //回调函数
    LRESULT CALLBACK FUNC(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
        switch (message) {
        case WM_CREATE: {
            tot = 0;
            ifstream inFile("score_list.txt");
            while (!inFile.eof()) {
                inFile >> people[tot].name >> people[tot].num;
                tot++;
            }
            SetTimer(hwnd, IDT_TIMER, rate, NULL);
            ifstream in("user.txt");
            in >> user;
            for(int i = 0; i<5; i++)
                AddList();
            break;
        }
        case WM_PAINT: { //窗口客户区需要重画
            srand((int)time(0));
            Drow(hwnd);
            change = getPoint();
            if (change >= 0) {
                AddList();
                score++;
                srand((int)time(0));
                do {
                    POINT_X[change] = (rand() % WIDTH) / 11, POINT_Y[change] = (rand() % HEIGHT) / 11;
                } while(isOK(POINT_X[change], POINT_Y[change]));
            }
            int k = check();
            if (k) {
                if(k == 2) {
                    KillTimer(hwnd, IDT_TIMER);
                    MessageBox(NULL, "YOU LOSE !", "message", MB_OK);
                    HDC hdc;
                    PAINTSTRUCT ps;
                    hdc = BeginPaint(hwnd, &ps);
                    char str[20];
                    wsprintf(str, "YOU LOSE !");
                    TextOut(hdc, 400, 100, str, strlen(str));
    
                    strcpy(people[tot].name, user), people[tot].num = score * 100;
                    sort(people, people + tot + 1);
                    if(tot > 5) tot = 5;
                    ofstream inFile("score_list.txt");
                    for(int i = 0; i < tot; i++) {
                        inFile << people[i].name << " " << people[i].num;
                    }
                    return 0;
                }
                int dx = -1, dy = -1;
                if(snake.head->data.x * 11 < WIDTH / 2)
                    dx = 1;
                if(snake.head->data.y * 11 < HEIGHT / 2)
                    dy = 1;
                if(direction == 'r')
                    GoAhead(0, dy), GoAhead(-1, 0), direction = 'l';
                else if(direction == 'u')
                    GoAhead(dx, 0), GoAhead(0, 1), direction = 'd';
                else if(direction == 'l')
                    GoAhead(0, dy), GoAhead(1, 0), direction = 'r';
                else if(direction == 'd')
                    GoAhead(dx, 0), GoAhead(0, -1), direction = 'u';
                //PostQuitMessage(0);
            }
            return 0;
        }
        case WM_TIMER:
            if (direction == 'l')
                GoAhead(-1, 0);
            else if (direction == 'r')
                GoAhead(1, 0);
            else if (direction == 'u')
                GoAhead(0, -1);
            else if (direction == 'd')
                GoAhead(0, 1);
            InvalidateRect(hwnd, NULL, true);
            break;
    
        case WM_KEYDOWN: {
            Node *tp = snake.head;
            {
                switch (LOWORD(wParam)) {
                case VK_UP:
                    if (direction != 'd')
                        direction = 'u';
                    break;
                case VK_DOWN:
                    if (direction != 'u')
                        direction = 'd';
                    break;
                case VK_RIGHT:
                    if (direction != 'l')
                        direction = 'r';
                    break;
                case VK_LEFT:
                    if (direction != 'r')
                        direction = 'l';
                    break;
                }
                InvalidateRect(hwnd, NULL, TRUE);
            }
            return 0;
        }
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                         LPSTR lpCmdLine, int nCmdShow) {
        WNDCLASSEX wndclass;
    
        // 用描述主窗口的参数填充WNDCLASSEX结构
        wndclass.cbSize = sizeof(wndclass);    // 结构的大小
        wndclass.style = CS_HREDRAW | CS_VREDRAW;    // 指定如果大小改变就重画
        wndclass.lpfnWndProc = FUNC;    // 窗口函数指针
        wndclass.cbClsExtra = 0;        // 没有额外的类内存
        wndclass.cbWndExtra = 0;        // 没有额外的窗口内存
        wndclass.hInstance = hInstance;        // 实例句柄
        wndclass.hIcon = LoadIcon(hInstance, (LPCTSTR) IDI_ICON1);    // 使用预定义图标
        wndclass.hCursor = LoadCursor(NULL,
                                      IDC_ARROW);        // 使用预定义的光标
        wndclass.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);     // 使用灰色背景画刷
        wndclass.lpszMenuName = NULL;        // 不指定菜单
        wndclass.lpszClassName = "MainWClass";    // 窗口类的名称
        wndclass.hIconSm = LoadIcon(hInstance, (LPCTSTR) IDI_ICON1);     // 没有类的小图标
    
        // 注册这个窗口类
        RegisterClassEx(&wndclass);
    
        // 创建主窗口
        HWND hwnd = CreateWindowEx(0,            // dwExStyle,扩展样式
                                   "MainWClass",        // lpClassName,类名
                                   "贪吃蛇",    // lpWindowName,标题
                                   WS_OVERLAPPEDWINDOW & (~WS_SIZEBOX) & (~WS_MAXIMIZEBOX),// dwStyle,窗口风格
                                   300,    //CW_USEDEFAULT,        // X,初始 X 坐标
                                   300,    //CW_USEDEFAULT,        // Y,初始 Y 坐标
                                   WIDTH + 150,    //CW_USEDEFAULT,        // nWidth,宽度
                                   HEIGHT + 50,    //CW_USEDEFAULT,        // nHeight,高度
                                   NULL,            // hWndParent,父窗口句柄
                                   NULL,            // hMenu,菜单句柄
                                   hInstance,        // hlnstance,程序实例句柄
                                   NULL);            // lpParam,用户数据
    
        if (!hwnd) {
            MessageBox(NULL, "无法创建游戏窗口", "error", MB_OK);
            return -1;
        }
        srand((int)time(0));
        do {
            POINT_X[0] = (rand() % WIDTH) / 11, POINT_Y[0] = (rand() % HEIGHT) / 11;
        } while(isOK(POINT_X[0], POINT_Y[0]));
        do {
            POINT_X[1] = (rand() % WIDTH) / 11, POINT_Y[1] = (rand() % HEIGHT) / 11;
        } while(isOK(POINT_X[1], POINT_Y[1]));
    
        ShowWindow(hwnd, nCmdShow);
        UpdateWindow(hwnd);
    
        MSG msg;
        while ( GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            //将消息发送到回调函数
            DispatchMessage(&msg);
        }
        //当GetMessage返回0时程序结束
        return msg.wParam;
    }
    View Code

    二,JAVA GUI消息

    toggle.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {}

    }

    对每一个控件设置事件。

    或,implements ActionListener 实现ActionListener接口

    public void actionPerformed(ActionEvent e) {

      if (e.getSource() == btnCalc) {}

      if (e.getSource() == btnCalc2) {}

    }

    import java.awt.BorderLayout;
    import java.awt.Container;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.ItemEvent;
    import java.awt.event.ItemListener;
    
    import javax.swing.*;
    
    class NumberFrame extends JFrame implements ActionListener {
        JTextField txtStart;
        JTextField txtEnd;
        JTextField txtFactor;
        JTextArea txtRes;
        JButton btnCalc, btnCalc2;
        JPanel inputPanel;
        JScrollPane resultPane;
        JPanel panel;
    
        NumberFrame(String title) {
            super(title);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            setSize(400, 150);
            setLocation(300, 200);
            setVisible(true);
            Container cp = getContentPane();
    
            panel = new JPanel();
            panel.setLayout(new BorderLayout());
    
            JPanel lblPane = new JPanel();
            lblPane.setLayout(new GridLayout(4, 1));
            lblPane.add(new JLabel("From"));
            lblPane.add(new JLabel("To"));
            lblPane.add(new JLabel("Factor"));
            lblPane.add(new JLabel());
    
            JPanel txtPane = new JPanel();
            txtPane.setLayout(new GridLayout(4, 1)); // 划分成4行1列
            txtStart = new JTextField();
            txtEnd = new JTextField();
            txtFactor = new JTextField();
            txtPane.add(txtStart);
            txtPane.add(txtEnd);
            txtPane.add(txtFactor);
            btnCalc = new JButton("Calculate");
            btnCalc.addActionListener(this);
            txtPane.add(btnCalc);
    
            inputPanel = new JPanel();
            inputPanel.setLayout(new BorderLayout());
            inputPanel.add(lblPane, BorderLayout.WEST);
            inputPanel.add(txtPane, BorderLayout.CENTER);
    
            panel.add(inputPanel, BorderLayout.WEST);
    
            // result panel
            txtRes = new JTextArea(10, 10);
            txtRes.setLineWrap(true);
            resultPane = new JScrollPane(txtRes);
            panel.add(resultPane, BorderLayout.CENTER);
    
            btnCalc2 = new JButton("clean");
            btnCalc2.addActionListener(this);
            panel.add(btnCalc2, BorderLayout.SOUTH);
    
            cp.add(panel);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == btnCalc) {
                txtRes.setText(null);
                try {
                    int m = Integer.parseInt(txtStart.getText().trim());
                    int n = Integer.parseInt(txtEnd.getText().trim());
                    int factor = Integer.parseInt(txtFactor.getText().trim());
    
                    for (int i = m; i <= n; ++i) {
                        if (i % factor == 0)
                            txtRes.append(String.valueOf(i) + " ");
                    }
                } catch (NumberFormatException e1) {
                    e1.printStackTrace();
                }
            }
            if (e.getSource() == btnCalc2) {
                txtRes.setText(null);
            }
        }
    }
    
    class TestButtons extends JFrame {
        JButton jButton = new JButton("JButton"); // 按钮
        JToggleButton toggle = new JToggleButton("Toggle Button"); // 切换按钮
        JCheckBox checkBox = new JCheckBox("Check Box"); // 复选按钮
        JRadioButton radio1 = new JRadioButton("Radio Button 1"); // 单选按钮
        JRadioButton radio2 = new JRadioButton("Radio Button 2");
        JRadioButton radio3 = new JRadioButton("Radio Button 3");
        JLabel label = new JLabel("Here is Status, look here."); // 不是按钮,是静态文本
    
        public TestButtons() {
            super("Test");
            setVisible(true);
            setLocation(750, 200);
            setSize(200, 250);
    
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            getContentPane().setLayout(new java.awt.FlowLayout());
    
            // 为一般按钮添加动作监听器
            jButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    label.setText("You clicked jButton");
                }
            });
    
            // 为切换按钮添加动作监听器
            toggle.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JToggleButton toggle = (JToggleButton) e.getSource();
                    if (toggle.isSelected()) {
                        label.setText("You selected Toggle Button");
                    } else {
                        label.setText("You deselected Toggle Button");
                    }
                }
            });
    
            // 为复选按钮添加条目监听器
            checkBox.addItemListener(new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    JCheckBox cb = (JCheckBox) e.getSource();
                    label.setText("Selected Check Box is " + cb.isSelected());
                }
            });
    
            // 将单选按钮添加到按钮组中,按钮组中只能选一个
            ButtonGroup group = new ButtonGroup();
            group.add(radio1);
            group.add(radio2);
            group.add(radio3);
    
            // 生成一个新的动作监听器对象,备用
            ActionListener al = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JRadioButton radio = (JRadioButton) e.getSource();
                    if (radio == radio1) {
                        label.setText("You selected Radio Button 1");
                    } else if (radio == radio2) {
                        label.setText("You selected Radio Button 2");
                    } else {
                        label.setText("You selected Radio Button 3");
                    }
                }
            };
            // 为各单选按钮添加动作监听器
            radio1.addActionListener(al);
            radio2.addActionListener(al);
            radio3.addActionListener(al);
    
            getContentPane().add(jButton);
            getContentPane().add(toggle);
            getContentPane().add(checkBox);
            getContentPane().add(radio1);
            getContentPane().add(radio2);
            getContentPane().add(radio3);
            getContentPane().add(label);
    
        }
    }
    
    public class UI {
        public static void main(String[] args) {
            new NumberFrame("Number Game");
            new TestButtons();
        }
    }

     

  • 相关阅读:
    启明星门户网站Portal发布V4.5,并兼论部分功能的实现
    修改SQL数据库dbo所有者
    iphone& android 开发指南 http://mobile.tutsplus.com
    启明星会议室预定系统V5.0.0.0版本说明
    启明星Portal企业内部网站V4.3版 附演示地址 http://demo.dotnetcms.org
    在winform程序里实现最小化隐藏到windows右下角
    【门户网站】启明星Portal系统里,关于天气预报调用的说明
    获取客户端经纬度坐标
    修改表名或者列名SQL
    ER图
  • 原文地址:https://www.cnblogs.com/updateofsimon/p/3496977.html
Copyright © 2020-2023  润新知