Chapter 10 Java GUI Programming (Part 1) - AWT

Chapter 10 Java GUI Programming (Part 1) - AWT


1. Basic concepts

  • GUI (Graphical User Interface, also known as Graphical User Interface) refers to a computer operation user interface displayed graphically.
  • AWT (Abstract Window Toolkit) is a class library used for basic GUI programming included in Java 1.0. It provides a set of interfaces for interacting with local graphical interfaces and is a user interface provided by Java. Basic tools for building and setting up Java graphical user interfaces.

2. Overview of AWT inheritance system

Insert image description here

  • LayoutManager
    FlowLayout Fluid layout BorderLayout border layout
    GridLayout grid layout GridBagLayout Grid package layout(*)
    BoxLayout Box layout (provided by Swing) CardLayout card layout

3. Basic use of container components

1. Commonly used methods

  • setLocation(): Set the location of the component
  • setSize(): Set the size of the component
  • setBounds(): Set the position and size of the component
  • pack(): automatically sets the optimal size
  • setVisible(): Set whether to display the component
  • add(): Add other components to the container (can be a normal component or a container) and return the added component
  • getComponent(): Get the component at the specified point

2. Display the first window (Frame)

package com.awt.java;
import org.testng.annotations.Test;
import java.awt.*;

public class awt_Test {
    
    
    @Test
    public void windowTest(){
    
    
        /* 1.实例化一个Frame窗口对象 */
        Frame frame = new Frame("第一个窗口");
        /* 2.设置窗口的位置,大小 */
        frame.setBounds(200,200,450,300);	//单位是像素px
        frame.setBackground(new Color(2,2,2));  //设置窗口背景颜色
        /* 3.显示窗口 */
        frame.setVisible(true);
        while (true);	//这里用了单元测试,加入while true使程序不退出
    }
}

Insert image description here

3. Display the second window (Panel)

package com.awt.java;
import org.testng.annotations.Test;
import java.awt.*;

public class awt_Test {
    
    
    @Test
    public void panellTest(){
    
    
        /* 1.实例化一个Frame框架 */
        Frame frame = new Frame("第二个窗口");
        /* 2.实例化一个Panel面板 */
        Panel panel = new Panel();
        /* 3.往Panel面板添加文本框和按钮 */
        panel.add(new TextField("文本框"));
        panel.add(new Button("按钮"));
        /* 4.把panel添加到Frame中 */
        frame.add(panel);
        /* 5.设置Frame位置大小 */
        frame.setBounds(200,200,350,300);
        /* 6.显示Frame */
        frame.setVisible(true);
        while (true);
    }
}

Insert image description here

4. Display the third window (ScrollPane)

package com.awt.java;
import org.testng.annotations.Test;
import java.awt.*;

public class awt_Test {
    
    
    @Test
    public void scrollPaneTest(){
    
    
        /* 1.实例化一个Frame框架 */
        Frame frame = new Frame("第三个窗口");
        /* 2.实例化一个scrollPane,并添加文本框和按钮 */
        ScrollPane scrollPane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
        scrollPane.add(new TextField("文本框"));
        scrollPane.add(new Button("按钮"));
        /* 3.把ScrollPane添加到Frame中 */
        frame.add(scrollPane);
        frame.setBounds(200,200,350,300);
        /* 6.显示Frame */
        frame.setVisible(true);
        while (true);
    }
}

Insert image description here

  • [Why] Here we added a text box and a button, but only the button is displayed and the text box is not visible?
    (Because the default layout BorderLayout used by ScrollPane causes only one component to be displayed in the container, we will learn about the layout manager below)

4. Layout Manager - LayoutManager

1. Flow layout - FlowLayout

  • Fluid layout: Components are arranged in a certain direction/alignment, and do not start on the next line until they reach the border.
  • FlowLayout(): Default alignment, vertical spacing and horizontal spacing
  • FlowLayout( int align ): Specify alignment, default vertical spacing and horizontal spacing
  • FlowLayout(int align, int hgap, int vgap): Specify alignment, vertical spacing and horizontal spacing
  • Several constants: ①FlowLayout.LEFT (left-aligned), ②FlowLayout.RIGHT (right-aligned), FlowLayout.CENTER (centered)
package com.awt.java;
import org.testng.annotations.Test;
import java.awt.*;

public class awt_Test {
    
    
    @Test
    public void FlowLayoutTest(){
    
    
        Frame frame = new Frame("测试FlowLayout");
        /* 设置panel布局为流式布局,右对齐,水平垂直间距20 */
        Panel panel = new Panel(new FlowLayout(FlowLayout.LEFT,20,20));
        /* 添加100个按钮 */
        for (int i = 0; i < 101; i++) {
    
    
            panel.add(new Button("按钮"+i));
        }
        frame.add(panel);
        frame.setBounds(300,200,850,500);
        frame.setVisible(true);
        while (true);
    }
}

Insert image description here

2. Border layout - BorderLayout

  • BorderLayout.NORTH: Place the component on the north side
  • BorderLayout.SOUTH: Place the component on the south side
  • BorderLayout.WEST: Places the component on the west side
  • BorderLayout.EAST: Place the component on the south side
  • BorderLayout.CENTER: Center the component
package com.awt.java;

import org.testng.annotations.Test;
import java.awt.*;

public class awt_Test {
    
    
    @Test
    public void BorderLayoutTest() {
    
    
        Frame frame = new Frame("测试BorderLayout");
        frame.setLayout(new BorderLayout(10, 10));
        frame.add(new Button("按钮北"), BorderLayout.NORTH);
        frame.add(new Button("按钮南"), BorderLayout.SOUTH);
        frame.add(new Button("按钮西"), BorderLayout.WEST);
        frame.add(new Button("按钮东"), BorderLayout.EAST);
        frame.add(new Button("按钮中"), BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
        while (true) ;
    }
}

Insert image description here

3. Grid layout - GridBagLayout

  • Grid layout: The container will be divided into grids based on vertical and horizontal lines, and the area of ​​each grid will be the same size
  • GridLayout(int rows, int cols): Specify the number of rows and columns, and the default vertical and horizontal spacing
  • GridLayout(int rows, int cols, int hgap, int vgap): Specify the number of rows, columns, and vertical and horizontal spacing
package com.awt.java;

import org.testng.annotations.Test;

import javax.swing.*;
import java.awt.*;

public class awt_Test {
    
    
    @Test
    public void GridLayoutTest(){
    
    
        Frame frame = new Frame("计算器");
        frame.add(new TextField(30),BorderLayout.NORTH);
        Panel panel = new Panel(new GridLayout(3,5,5,5));
        for (int i = 0; i < 10; i++) {
    
    
            panel.add(new Button(i+""));
        }
        panel.add(new Button("+"));
        panel.add(new Button("-"));
        panel.add(new Button("*"));
        panel.add(new Button("/"));
        panel.add(new Button("="));
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
        while (true);
    }
}

Insert image description here

4. Card layout - CardLayout

  • CardLayout(): default card layout
  • CardLayout(int hgap, int vgap): Card layout that specifies vertical and horizontal spacing
  • first(Container target): Display the first card
  • last(Container target): Display the last card
  • previous(Container target): Display the previous card
  • next(Container target): Display the next card
  • show(Container target, String name): Display the card with the specified name
package com.awt.java;

import org.testng.annotations.Test;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class awt_Test {
    
    
   @Test
    public void CardLayout(){
    
    
        Frame frame = new Frame("测试CardLayout卡片布局");
        /* 1.创建两个Panel,p1卡片布局,p2按钮 */
        Panel p1 = new Panel();
        Panel p2 = new Panel();
        CardLayout cardLayout = new CardLayout();
        p1.setLayout(cardLayout);
        
        /* 2.向p1添加4个按钮,4张卡片名字同按钮 */
        for (int i = 0; i < 5; i++) {
    
    
            p1.add("第"+(i+1)+"张",new Button("第"+(i+1)+"张"));
        }
        
        /* 3.向p2添加下方的控制按钮 */
        Button b1 = new Button("上一张");
        Button b2 = new Button("下一张");
        Button b3 = new Button("第一张");
        Button b4 = new Button("最后一张");
        Button b5 = new Button("第三张");
        p2.add(b1);
        p2.add(b2);
        p2.add(b3);
        p2.add(b4);
        p2.add(b5);
        
        /* 4.组装frame整体 */
        frame.add(p1);
        frame.add(p2,BorderLayout.SOUTH);
        
        /* 5.添加控制按钮的监听器 */
        ActionListener listener = new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                String actionCommand = e.getActionCommand();
                switch(actionCommand){
    
    
                    case "上一张":
                        cardLayout.previous(p1);
                        break;
                    case "下一张":
                        cardLayout.next(p1);
                        break;
                    case "第一张":
                        cardLayout.first(p1);
                        break;
                    case "最后一张":
                        cardLayout.last(p1);
                        break;
                    case "第三张":
                        cardLayout.show(p1,"第3张");
                        break;
                }
            }
        };
        b1.addActionListener(listener);
        b2.addActionListener(listener);
        b3.addActionListener(listener);
        b4.addActionListener(listener);
        b5.addActionListener(listener);
        frame.pack();
        frame.setVisible(true);
        while (true);
    }
}

Insert image description here

5. Box layout - BoxLayout

  • Box layout: components can be placed vertically and horizontally (actually it is provided by Swing)
  • BoxLayout(Container target, int axis): Create a BoxLayout layout manager based on the target container, and the components are arranged according to the axis direction. Among them, axis can pass BoxLayout.X_AIXS (horizontal), BoxLayout.Y_AIXS (vertical)
  • In swing, a container Box is also provided, and the default layout is the BoxLayout box layout.
  • Box类中,提供了以下静态方法可设置各组件的间隔(注意:添加的分割也是一种组件)
    ✒️createHorizontalGlue( ):创建一条水平的分割线(可拉伸)
    ✒️createVerticalGlue( ):创建一条垂直的分割线(可拉伸)
    ✒️createHorizontalStrut( int width ):创建一条指定宽度的水平分割线(仅垂直方向可拉伸)
    ✒️createVerticalStrut( int height):创建一条指定宽度的垂直分割线(仅水平方向可拉伸)
package com.awt.java;

import org.testng.annotations.Test;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class awt_Test {
    
    
    @Test
    public void BoxLayoutTest1(){
    
    
        Frame frame = new Frame("测试BoxLayout");
        BoxLayout boxLayout = new BoxLayout(frame,BoxLayout.Y_AXIS);
        frame.add(new Button("按钮1"));
        frame.add(new Button("按钮2"));
        frame.setLayout(boxLayout);
        frame.setBounds(220,120,400,240);
        frame.setVisible(true);
        while (true);
    }
    @Test
    public void BoxTest2(){
    
    
        Frame frame = new Frame("测试容器Box");
        /* 1.创建两个Box容器 */
        Box box1 = new Box(BoxLayout.Y_AXIS);
        Box box2 = new Box(BoxLayout.X_AXIS);
        /* 2.box1存放两个垂直按钮 */
        box1.add(new Button("垂直按钮1"));
        box1.add(new Button("垂直按钮2"));
        /* 3.box2存放两个水平按钮 */
        box2.add(new Button("水平按钮1"));
        box2.add(new Button("水平按钮2"));
        /* 4.添加box到frame中 */
        frame.add(box1,BorderLayout.SOUTH);
        frame.add(box2);
        frame.setBounds(220,120,400,240);
        frame.setVisible(true);
        while (true);
    }
    @Test
    public void BoxTest3(){
    
    
        Frame frame = new Frame("测试Box的分割");
        Box box1 = new Box(BoxLayout.X_AXIS);   //水平
        Box box2 = new Box(BoxLayout.Y_AXIS);   //垂直
        box1.add(new Button("水平按钮1"));
        box1.add(Box.createHorizontalGlue());   //添加水平分割(可拉伸)
        box1.add(new Button("水平按钮2"));
        box1.add(Box.createHorizontalStrut(20));//添加指定宽度的水平分割
        box1.add(new Button("水平按钮3"));

        box2.add(new Button("垂直按钮1"));
        box2.add(Box.createVerticalGlue()); //添加垂直分割
        box2.add(new Button("垂直按钮2"));
        box2.add(Box.createVerticalStrut(20));//添加指定高度的垂直分割
        box2.add(new Button("垂直按钮3"));

        frame.add(box1,BorderLayout.NORTH);
        frame.add(box2);
        frame.setBounds(220,120,400,240);
        frame.setVisible(true);
        while (true);
    }
}

Insert image description here

五、AWT组件的使用

1、基本组件的使用

组件名 组件功能
Button 按钮
Frame 窗口
Panel 面板,只能放置在其他容器中(如:Frame),不能单独存在
Scrollbar 滚动条
TextArea 多行文本域
TextFirld 单行文本框
Label 标签类,用于放置提示性文本
Canvas 用于绘图的画布
Checkbox 复选框组件(也可以当做单选框组件)
CheckboxGroup 多个Checkbox组成一组CheckboxGroup
Choice 下拉选择框
List 列表框,可添加多条条目
package com.awt.java;

import javax.swing.*;
import java.awt.*;

public class ComponentTest {
    
    
    Frame frame = new Frame("测试基本组件");

    Box box1 = new Box(BoxLayout.X_AXIS);
    Box box2 = new Box(BoxLayout.X_AXIS);
    Box box3 = new Box(BoxLayout.Y_AXIS);
    Box box4 = new Box(BoxLayout.X_AXIS);

    TextArea textArea = new TextArea(5,12);
    TextField textField = new TextField(30);
    Choice choice = new Choice();
    CheckboxGroup checkboxGroup = new CheckboxGroup();
    Checkbox checkbox1 = new Checkbox("男",checkboxGroup,true);
    Checkbox checkbox2 = new Checkbox("女",checkboxGroup,false);
    Checkbox checkbox3 = new Checkbox("是否已婚?");
    Button button = new Button("确认");
    List list = new List(5,false);

    public void Init(){
    
    
        /* box1组装单行文本框和确认按键,放置frame下方 */
        box1.add(textField);
        box1.add(button);
        frame.add(box1,BorderLayout.SOUTH);

        /* box2组装选择框和复选框 */
        choice.add("红色");
        choice.add("绿色");
        choice.add("黄色");
        box2.add(choice);
        box2.add(checkbox1);
        box2.add(checkbox2);
        box2.add(checkbox3);

        /* box3组装box2和多行文本域 */
        box3.add(textArea);
        box3.add(box2);

        /* box4组装box3和列表框 */
        list.add("张三");
        list.add("李四");
        list.add("王五");
        box4.add(box3);
        box4.add(list);

        frame.add(box4,BorderLayout.NORTH);
        frame.pack();
        frame.setVisible(true);
    }
    public static void main(String[] args) {
    
    
        new ComponentTest().Init();
    }
}

Insert image description here

2、普通对话框Dialog的使用

  • Dialog是Windows类的子类,是一个容器类,属于特殊组件,是可独立存在的顶级窗口。
    (也就是说,Dailog可以和前面使用Frame一样,可以添加其他基本组件)
  • 对话框通常依赖其他窗口,也就是通常需要一个父窗口。
  • 对话框有非模式(non-modal)和模式(modal)两种
    ✒️非模式对话框:同模式相反
    ✒️模式对话框:被打开后该对话框只位于父窗口之上,未关闭时父窗口无法操作
  • Dialog( Frame owner,String title,boolean modal );
    ✒️owner:当前对话框的父窗口
    ✒️title:当前对话框的标题
    ✒️modal:当前对话框的模式
package com.awt.java;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class DialogTest {
    
    
    public static void main(String[] args) {
    
    
        Frame frame = new Frame("测试对话框Dialog");
        
        /* 添加两个按钮,一个打开模式对话框,一个打开非模式 */
        Button button1 = new Button("打开模式对话框");
        Button button2 = new Button("打开非模式对话框");
        
        /* 添加两个对话框 */
        Dialog nonModalDailog = new Dialog(frame,"模式对话框",false);
        Dialog modalDailog = new Dialog(frame,"模式对话框",true);
        frame.add(button1,BorderLayout.NORTH);
        frame.add(button2,BorderLayout.SOUTH);
        /* 设置对话框位置大小 */
        nonModalDailog.setBounds(20,30,300,150);
        modalDailog.setBounds(20,30,300,150);

        /* 按钮添加事件监听 */
        button1.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                modalDailog.setVisible(true);
            }
        });
        button2.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                nonModalDailog.setVisible(true);
            }
        });
        
        /* 设置合适大小、可见 */
        frame.pack();
        frame.setVisible(true);
    }
}

3、文件对话框FileDialog的使用

  • FileDialog是Dialog的一个子类,需要注意的是FIleDialog无法想Dialog一样指定模式还是非模式,这是因为FileDialog的实现依赖运行平台,如果平台是模式对话框那么该文件对话框就是模式文件对话框,反之亦然。
  • FileDialog( Frame parent,String title,int mode )
    ✒️parent:指定父窗口
    ✒️title:对话框的标题
    ✒️mode:对话框类型 - FileDialog.LOAD用于打开文件;FileDialog.SAVE用于保存文件
  • getDirectory( ):获取被打开或保存文件的绝对路径
  • getFile( ):获取被打开或保存文件的文件名
package com.awt.java;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class FileDialogTest {
    
    
    public static void main(String[] args) {
    
    
        Frame frame = new Frame("测试文件对话框");
        Box box = new Box(BoxLayout.Y_AXIS);
        Button btnOpen = new Button("打开文件");
        Button btnSave = new Button("保存文件");
        box.add(btnOpen);
        box.add(btnSave);
        frame.add(box);
        
        /* 创建两个文件对话框,打开+保存 */
        FileDialog fileOpen = new FileDialog(frame,"打开文件",FileDialog.LOAD);
        FileDialog fileSave = new FileDialog(frame,"保存文件",FileDialog.SAVE);
        
        /* 添加事件监听 */
        btnOpen.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                fileOpen.setVisible(true);//注意这里会阻塞
                /* 直到弹出对话框的打开按键触发 */
                System.out.println(fileOpen.getDirectory()+fileOpen.getFile());
            }
        });
        btnSave.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                fileSave.setVisible(true);
                System.out.println(fileSave.getDirectory()+fileSave.getFile());
            }
        });

        frame.pack();
        frame.setVisible(true);
    }
}

4、事件处理机制

(1)基本概念和使用
  • 定义:在某个组件上发生某些操作的时候,会自动触发一段代码的执行
  • 事件源(Event Source):操作发生的场所(如:某个按钮、窗口)—— 开始菜单的关机按钮
  • 事件(Event):在事件源上发生的操作,GUI把事件都封装在一个Event对象中。—— 点击
  • 事件监听器(Event Listener):监听在事件源上发生的事件,并对其进行处理。—— 电脑关机
  • Usage steps:
    ✒️Define the class to implement the corresponding Listener interface, and rewrite the corresponding processing method
    ✒️Create an object of the custom class and pass it to the registered listening method called by the component
package com.awt.java;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class EventHandingTest {
    
    
    /* 1.定义类实现对应的Listener接口,并重写对应的处理方法 */
    private static class MyListener implements ActionListener{
    
    
        private TextField tf;
        public MyListener(TextField tf){
    
    
            this.tf = tf;
        }
        @Override
        public void actionPerformed(ActionEvent e) {
    
    
            tf.setText("Hello World");
        }
    }
    public static void main(String[] args) {
    
    
        TextField tf = new TextField();

        Button btn = new Button("确认");
        Frame frame = new Frame("测试事件处理");
        frame.add(tf,BorderLayout.NORTH);
        frame.add(btn,BorderLayout.SOUTH);
        /* 2.创建自定义类的对象,传到由该组件调用的注册监听方法 */
        MyListener myListener = new MyListener(tf);
        btn.addActionListener(myListener);

        frame.pack();
        frame.setVisible(true);
    }
}

Insert image description here

(2) Commonly used events
  • Event classification: ① Low-level events ② High-level events
low level incident listener Trigger mode
ComponentEvent ComponentListener Component size, position or show/hide state changes
ContainerEvent ContainerListener Triggered when a component is added or removed from the container
WindowEvent WindowListener When the window state changes (open, close, maximize, minimize)
FocusEvent FocusListener Component gets focus or loses focus
KeyEvent KeyListener Triggered when a keyboard key is pressed, released, or clicked
MouseEvent MouseListener Triggered when mouse clicks, moves, etc.
PaintEvent PaintListener Component drawing events, special event types (*)

Advanced events listener Trigger mode
ActionEvent ActionListener Action event, when a button or menu item is clicked or the Enter key is pressed in a text box
AdjustmentEvent AdjustmentListener Adjustment event, triggered when the slider is moved on the slider to adjust the value
ItemEvent ItemListener Option event, triggered when an item is selected or unchecked
TextEvent TextListener Text events, when changes occur in text boxes and text fields
(3)Use cases
package com.awt.java;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ListenerTest{
    
    
    private Frame f = new Frame("测试监听器");
    private Box box = new Box(BoxLayout.X_AXIS);
    private Choice choice = new Choice();
    private TextField tf = new TextField(25);
    
    /* 1.第一个监听器:打印下拉选择框每次选择的内容(传统写法)*/
    public class ColorListener implements ItemListener {
    
    
        @Override
        public void itemStateChanged(ItemEvent e) {
    
    
            System.out.println("当前选中的是:"+e.getItem());
        }
    }

    public void init(){
    
    
        choice.add("红色");
        choice.add("绿色");
        choice.add("黄色");
        box.add(choice);
        box.add(tf);
        f.add(box);

        /* 注册监听 */
        ColorListener colorListener = new ColorListener();
        choice.addItemListener(colorListener);
        
        /* 2.第二个监听器:打印输出文本框内容(匿名类写法-可改lambda) */
        tf.addTextListener(new TextListener() {
    
    
            @Override
            public void textValueChanged(TextEvent e) {
    
    
                System.out.println("当前文本框内容是:"+tf.getText());
            }
        });
        
        /* 3.第三个监听器:点击X按钮可退出程序 */
        f.addWindowListener(new WindowAdapter() {
    
    
            @Override
            public void windowClosing(WindowEvent e) {
    
    
                System.exit(0);
            }
        });
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args) {
    
    
        new ListenerTest().init();
    }
}

Insert image description here

5. Use of menu components

(1) Common menu component system

Insert image description here

(2)Use cases
  • Menu: Menu, which can be used as a container to add other menu items MenuItem, or can be added to the menu Menu (can be used as a nesting doll)
package com.awt.java;


import java.awt.*;
import java.awt.event.KeyEvent;

public class MenuCompTest {
    
    
    public static void main(String[] args) {
    
    
        Frame f = new Frame("测试菜单");
        TextArea ta = new TextArea(15, 60);
        f.add(ta,BorderLayout.SOUTH);

        /* 创建菜单栏MenuBar */
        MenuBar menuBar = new MenuBar();

        /* 创建菜单栏上的菜单Menu */
        Menu fileMenu = new Menu("文件");
        Menu editMenu = new Menu("编辑");
        Menu formatMenu = new Menu("格式"); //这里有子菜单,注意Menu是可以做MenuItem的

        /* 创建菜单元素MenuItem */
        CheckboxMenuItem autoMenu = new CheckboxMenuItem("自动换行");
        MenuItem copyMenu = new MenuItem("复制");
        MenuItem pasteMenu = new MenuItem("粘贴");

        /* 添加分割线 */
        MenuItem commentMenu = new MenuItem("注释",new MenuShortcut(KeyEvent.VK_Q,true));
        MenuItem cancelCommentMenu = new MenuItem("取消注释");

        /* 开始组装,从局部到整体 */
        formatMenu.add(commentMenu);
        formatMenu.add(cancelCommentMenu);
        editMenu.add(autoMenu);
        editMenu.add(copyMenu);
        editMenu.add(pasteMenu);
        editMenu.add(new MenuItem("-"));
        editMenu.add(formatMenu);

        menuBar.add(fileMenu);
        menuBar.add(editMenu);

        f.setMenuBar(menuBar);
        f.pack();
        f.setVisible(true);
    }
}

Insert image description here

6. AWT drawing (temporarily omitted)

  • Skip this part and continue learning Swing. Learn AWT just for Swing!

Guess you like

Origin blog.csdn.net/weixin_54429787/article/details/127460446