GUI编程
GUI (Graphical User Interface) 图形用户界面
组件
- 窗口
- 弹窗
- 面板
- 文本框
- 列表框
- 按钮
- 图片
- 监听事件
- 鼠标
- 键盘事件
1. 简介
GUI核心技术:Swing AWT
简单来说AWT是底层技术,而Swing是封装了的,可以画出更多更精美的东西。
GUI的缺点:1. 界面不美观 。
2. 需要jre(Java Runtime Environment)环境。
学习原因:1. 它是MVC架构的基础,学习监听。
2. 可以写出自己想要的一些小工具。
2. AWT
2.1 AWT介绍
Abstract Windows Toolkit 抽象窗口工具包
1.包含了很多类和接口,用于GUI编程。
2.包含很多元素:窗口,按钮,文本框
2.2 组件和容器
2.2.1 窗口Frame
建立第一个窗口
package com.chen.lesson1;
import java.awt.*;
//GUI的第一个界面
public class TestFrame {
public static void main(String[] args) {
//Frame
Frame frame = new Frame("我的第一个java图形界面窗口");
//需要设置可见性
frame.setVisible(true);
//设置窗口大小
frame.setSize(800,800);
//设置背景颜色
frame.setBackground(new Color(191,255,243));
//frame.setBackground(Color.BLACK);
//弹出的初始位置
frame.setLocation(800,300);
//设置大小是否固定 即窗口大小能否拉伸
frame.setResizable(false);
}
}
运行结果:
PS:由于未设置关闭功能,所以只能通过停止程序来关闭窗口。
通过封装和继承 实现同时运行多个窗口
package com.chen.lesson1;
import java.awt.*;
public class TestFrame2 {
public static void main(String[] args) {
//展示多个窗口
MyFrame myFrame1 = new MyFrame(100, 100, 200, 200, Color.blue);
MyFrame myFrame2 = new MyFrame(300, 100, 200, 200, Color.green);
MyFrame myFrame3 = new MyFrame(100, 300, 200, 200, Color.yellow);
MyFrame myFrame4 = new MyFrame(300, 300, 200, 200, Color.red);
}
}
class MyFrame extends Frame {
static int id = 1;//可能存在多个窗口,我们需要一个计数器
public MyFrame(int x,int y,int w,int h,Color color) {
super("MyFrame"+(id++));
setVisible(true);
//直接设置大小和初始位置
setBounds(x,y,w,h);
setBackground(color);
setResizable(false);
}
}
运行结果:
2.2.2 面板Panel
在Frame里添加一个面板Panel,并且通过监听事件解决窗口关闭的问题
package com.chen.lesson1;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//Panel,可以看成是一个空间 但是不能单独存在
public class TestPanel {
public static void main(String[] args) {
Frame frame = new Frame();
//布局的概念
Panel panel = new Panel();
//Frame设置
//设置布局
frame.setLayout(null);
//坐标及大小
frame.setBounds(300,300,500,500);
//设置颜色
frame.setBackground(new Color(20, 127, 8));
//Panel设置
//设置坐标及大小 相对于Frame
panel.setBounds(50,50,300,300);
//设置Panel颜色
panel.setBackground(new Color(222, 51, 69));
//将Panel组件添加到Frame中
frame.add(panel);
//设置Frame可见性
frame.setVisible(true);
//监听事件 监听窗口关闭事件 System.exit(0)
//适配器模式
frame.addWindowListener(new WindowAdapter() {
//窗口点击关闭的时候需要做的事
@Override
public void windowClosing(WindowEvent e) {
//结束程序
System.exit(0);
}
});
}
}
运行结果:
2.2.3 布局管理器
- 流式布局 FlowLayout
package com.chen.lesson1;
import java.awt.*;
public class TestFlowLayout {
public static void main(String[] args) {
//初始化窗口并设置大小及可见性
Frame frame = new Frame();
frame.setSize(400,400);
frame.setVisible(true);
//设置 组件-按钮
Button button1 = new Button("Button1");
Button button2 = new Button("Button2");
Button button3 = new Button("Button3");
//设置为流式布局 默认在中间
//frame.setLayout(new FlowLayout());
//流式布局 在左边布局
frame.setLayout(new FlowLayout(FlowLayout.LEFT));
//把按钮添加到Frame上
frame.add(button1);
frame.add(button2);
frame.add(button3);
}
}
运行结果:
- 东西南北中 BorderLayout
package com.chen.lesson1;
import java.awt.*;
public class TestBorderLayout {
public static void main(String[] args) {
//初始化窗口并设置大小及可见性
Frame frame = new Frame("BorderLayout");
frame.setSize(400,400);
frame.setVisible(true);
//设置按钮
Button East = new Button("East");
Button West = new Button("West");
Button South = new Button("South");
Button North = new Button("North");
Button Center = new Button("Center");
//把按钮添加到Frame上
frame.add(East,BorderLayout.EAST);
frame.add(West,BorderLayout.WEST);
frame.add(South,BorderLayout.SOUTH);
frame.add(North,BorderLayout.NORTH);
frame.add(Center,BorderLayout.CENTER);
}
}
运行结果:
- 表格式布局 GridLayout
package com.chen.lesson1;
import java.awt.*;
public class TestGridLayout {
public static void main(String[] args) {
//初始化窗口并设置大小及可见性
Frame frame = new Frame("GridLayout");
frame.setSize(400,400);
frame.setVisible(true);
//设置按钮
Button button1 = new Button("Button1");
Button button2 = new Button("Button2");
Button button3 = new Button("Button3");
Button button4 = new Button("Button4");
Button button5 = new Button("Button5");
Button button6 = new Button("Button6");
//设置表格布局
frame.setLayout(new GridLayout(3,2));
//把按钮添加到Frame上.
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
frame.add(button5);
frame.add(button6);
}
}
运行结果:
2.3 事件监听
事件监听:当进行某个动作(点击按钮、点击窗口关闭)或 通过输入设备(鼠标、键盘)进行操作时,完成自己设定的功能。
点击按钮时,输出aaa
package com.chen.lesson2;
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 TestActionEvent {
public static void main(String[] args) {
//初始化Frame
Frame frame = new Frame();
frame.setLayout(new FlowLayout());
frame.setVisible(true);
Button button = new Button("Button1");
//addActionListener()需要一个ActionListener的接口,所以需要构造一个ActionListener(接口用实现类、父类用继承)
MyActionListener myActionListener = new MyActionListener();
button.addActionListener(myActionListener);
frame.add(button);
frame.pack();//自动适应大小
windowsClose(frame);
}
//关闭窗口事件
private static void windowsClose(Frame frame){
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
class MyActionListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
//事件发生时 输入aaa
System.out.println("aaa");
}
}
运行结果:
2.4 输入框TextField监听
添加一个输入框,并且通过监听在控制台获得输入框中的文本信息
package com.chen.lesson2;
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 TestText1 {
public static void main(String[] args) {
new MyFrame();
}
}
class MyFrame extends Frame{
public MyFrame() {
TextField textField = new TextField();
add(textField);
//监听文本框输入的文字 按下Enter就会触发输入框的事件
MyActionListener2 myActionListener2 = new MyActionListener2();
textField.addActionListener(myActionListener2);
//设置替换编码
//textField.setEchoChar('*');
//设置关闭功能
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setVisible(true);
pack();
}
}
class MyActionListener2 implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
TextField field = (TextField) e.getSource(); //获得资源 返回一个对象
System.out.println(field.getText()); //将获得的资源通过这个对象输出出来
//field.setText("");//监听一次后输入框清空
}
}
运行结果:
2.5 画笔Paint
package com.chen.lesson3;
import java.awt.*;
public class TestPaint {
public static void main(String[] args) {
new MyPaint().loadPaint();
}
}
class MyPaint extends Frame{
public void loadPaint(){
setBounds(500,300,1500,1000);
setVisible(true);
}
//画笔
@Override
public void paint(Graphics g) {
//将画笔设置为蓝色
g.setColor(Color.blue);
//画一个空心圆 draw
g.drawOval(300,300,200,200);
//将画笔设置为绿色
g.setColor(Color.green);
//画一个实心矩形 fill
g.fillRect(600,600,400,200);
//画笔用完 还原成最初的颜色
g.setColor(Color.black);
}
}
运行结果:
2.6 鼠标监听
通过鼠标监听实现在画板上用鼠标按下画点
package com.chen.lesson3;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
public class TestMouseListener {
public static void main(String[] args) {
new MyFrame("画点");
}
}
class MyFrame extends Frame {
//声明一个存放点的动态数组的全局变量
ArrayList points;
//在构造器中初始化画板
public MyFrame(String name) {
//初始化画板
super(name);
setBounds(500,300,1500,1000);
setVisible(true);
//初始化动态数组
points = new ArrayList<>();
//添加鼠标监听
addMouseListener(new MyMouse());
}
//设置画笔
@Override
public void paint(Graphics g) {
//设置画笔颜色
g.setColor(Color.green);
//使用迭代器遍历动态数组 取出其中的点 并画在画板上
Iterator iterator = points.iterator();
while (iterator.hasNext()){
Point point = (Point) iterator.next();
g.fillOval(point.x,point.y,10,10);
}
}
//适配器模式 设置鼠标监听
class MyMouse extends MouseAdapter {
//鼠标按下
@Override
public void mousePressed(MouseEvent e) {
//获取鼠标按下后的信息
MyFrame myFrame = (MyFrame) e.getSource();
//将监听器中获取的点添加到动态数组中的方法
points.add(new Point(e.getX(),e.getY()));
myFrame.repaint();
}
}
}
运行结果:
2.7 键盘监听
按下某按键时在控制台输出文本信息
package com.chen.lesson3;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class TestKeyListener {
public static void main(String[] args) {
KeyFrame keyFrame = new KeyFrame();
}
}
class KeyFrame extends Frame{
public KeyFrame() throws HeadlessException {
setBounds(50,30,150,100);
setVisible(true);
//添加键盘监听
addKeyListener(new KeyAdapter() {
//监听键盘按下事件
@Override
public void keyPressed(KeyEvent e) {
//如果按下上键 输出文字
if (e.getKeyCode() == KeyEvent.VK_UP){
System.out.println("你按下了上键");
}
if (e.getKeyCode() == KeyEvent.VK_W){
System.out.println("你按下了W键");
}
}
});
}
}
3. Swing
3.1 窗口JFrame
Swing中的组件的名称比AWT中的都多了一个J
PS:JFrame、JLabel等
package com.chen.lesson4;
import javax.swing.*;
import java.awt.*;
public class JFrameDemo {
//初始化
public void init(){
JFrame jf = new JFrame("这是一个JFrame窗口");
jf.setBounds(500,300,500,300);
jf.setVisible(true);
//关闭事件
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//JFrame与Frame不同 JFrame并不是直接布局在窗口上,而是在窗口上的一个ContentPane上面布局
//设置颜色 必须在ContentPane上设置 否则是看不到设置的颜色的
Container container = jf.getContentPane();//获得ContentPane
container.setBackground(Color.yellow);
//定义标签文本
JLabel jLabel = new JLabel("这是一个JLabel标签");
container.add(jLabel);
//设置标签居中
jLabel.setHorizontalAlignment(SwingConstants.CENTER);
}
public static void main(String[] args) {
new JFrameDemo().init();
}
}
运行结果:
3.2 弹窗JDialog
PS:弹窗默认有关闭事件,不用像画板一样自己再去写
点击窗口中的按钮,弹出一个弹窗
package com.chen.lesson4;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class DialogDemo extends JFrame {
//在构造器中初始化
public DialogDemo() {
this.setVisible(true);
this.setBounds(500,300,400,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Container container = this.getContentPane(); //容器
container.setBackground(Color.yellow);
//绝对布局 通过指定组件坐标来布局且窗口不能随意拉伸
container.setLayout(null);
//定义按钮
JButton button = new JButton("我是一个按钮");
container.add(button);
//设置按钮位置
button.setBounds(130,80,150,50);
//给按钮添加事件监听
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new MyDialog();
}
});
}
public static void main(String[] args) {
new DialogDemo();
}
class MyDialog extends JDialog{
//使用构造方法初始化弹窗
public MyDialog() {
this.setVisible(true);
this.setBounds(1000,300,200,150);
Container container = this.getContentPane();//容器
//设置标签 作为弹窗内容
JLabel jLabel = new JLabel("我是一个弹窗");
jLabel.setHorizontalAlignment(SwingConstants.CENTER);
container.add(jLabel);
}
}
}
运行结果:
3.3 图标、图片
实现图标接口,绘制一个圆形图标并放在标签上
package com.chen.lesson4;
import javax.swing.*;
import java.awt.*;
//图标Icon是一个接口 实现类需重写其中的方法
public class IconDemo extends JFrame implements Icon {
//定义图标的宽高
private int width;
private int height;
//无参构造
public IconDemo() {}
//有参构造
public IconDemo(int width, int height) throws HeadlessException {
this.width = width;
this.height = height;
}
//初始化
public void init(){
//初始化画板
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//初始化图标
IconDemo iconDemo = new IconDemo(20, 20);
//图标放在标签上 也可以放在按钮上
JLabel jLabel = new JLabel("IconText",iconDemo,SwingConstants.CENTER); //(标签文本,图标,位置)
//添加标签
Container container = this.getContentPane();
container.add(jLabel);
}
public static void main(String[] args) {
new IconDemo().init();
}
//重写方法 画图标
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
//画一个圆形图标
g.fillOval(x,y,width,height);
}
//重写方法 返回图标的宽
@Override
public int getIconWidth() {
return width;
}
//重写方法 返回图标的高
@Override
public int getIconHeight() {
return height;
}
}
运行结果:
在标签中添加图片
package com.chen.lesson4;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class ImageIconDemo extends JFrame {
public static void main(String[] args) {
new ImageIconDemo();
}
public ImageIconDemo() {
//获取图片地址 .class.getResource("name")为获取当前class目录的同级资源 图片需和本类放在同一目录下
URL url = ImageIconDemo.class.getResource("img.jpg");
ImageIcon imageIcon = new ImageIcon(url);
//添加图片到标签里
JLabel jLabel = new JLabel("这谁顶得住啊",imageIcon,SwingConstants.CENTER);
//分步设置
//JLabel jLabel = new JLabel("这谁顶得住啊");
//jLabel.setIcon(imageIcon);
//jLabel.setHorizontalAlignment(SwingConstants.CENTER);
//添加标签到容器里
Container container = this.getContentPane();
container.add(jLabel);
//初始化画板
setVisible(true);
setBounds(600,100,1000,1200);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
运行结果:
3.4 面板JPanel、滚动面板JScroll
JPanel用法与Panel基本一致
package com.chen.lesson5;
import com.chen.lesson4.JFrameDemo;
import javax.swing.*;
import java.awt.*;
public class JPanelDemo extends JFrame {
public JPanelDemo() {
//初始化面板 并添加按钮
JPanel jPanel = new JPanel();
JPanel jPane2 = new JPanel();
JPanel jPane3 = new JPanel();
JPanel jPane4 = new JPanel();
jPanel.setLayout(new GridLayout(1,3));
jPane2.setLayout(new GridLayout(2,2));
jPane3.setLayout(new GridLayout(3,1));
jPane4.setLayout(new GridLayout(2,2));
jPanel.add(new JButton("1"));
jPanel.add(new JButton("2"));
jPanel.add(new JButton("3"));
jPane2.add(new JButton("3"));
jPane2.add(new JButton("3"));
jPane2.add(new JButton("3"));
jPane2.add(new JButton("3"));
jPane3.add(new JButton("3"));
jPane3.add(new JButton("3"));
jPane3.add(new JButton("3"));
jPane4.add(new JButton("3"));
jPane4.add(new JButton("3"));
jPane4.add(new JButton("3"));
jPane4.add(new JButton("3"));
//将面板添加到窗口中
Container container = this.getContentPane();
container.add(jPanel);
container.add(jPane2);
container.add(jPane3);
container.add(jPane4);
//初始化窗口
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setBounds(500,300,500,500);
setLayout(new GridLayout(2,1,10,10)); //后两个参数为间距
setVisible(true);
}
public static void main(String[] args) {
new JPanelDemo();
}
}
运行结果:
滚动面板即面板可以上下左右滑动
package com.chen.lesson5;
import javax.swing.*;
import java.awt.*;
public class JScrollDemo extends JFrame {
public JScrollDemo() {
//建立一个文本域 即可以换行的文本框
TextArea textArea = new TextArea();
//初始化滚动面板 并添加文本域
ScrollPane scrollPane = new ScrollPane();
scrollPane.add(textArea);
//将面板添加到窗口
Container container = this.getContentPane();
container.add(scrollPane);
//初始化窗口
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
setSize(500,500);
}
public static void main(String[] args) {
new JScrollDemo();
}
}
运行结果:
3.5 单选按钮JRadioButton、复选按钮JCheckBox
单选按钮 只能选择一个 不能多选
package com.chen.lesson5;
import javafx.scene.control.RadioButton;
import javax.swing.*;
import java.awt.*;
public class JButton1 extends JFrame {
public JButton1() {
Container container = this.getContentPane();
//初始化按钮
JRadioButton radioButton1 = new JRadioButton("Button1");
JRadioButton radioButton2 = new JRadioButton("Button2");
JRadioButton radioButton3 = new JRadioButton("Button3");
//建立按钮分组 在一个分组中的按钮只能选择一个 否则按钮就可以同时选择多个
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(radioButton1);
buttonGroup.add(radioButton2);
buttonGroup.add(radioButton3);
//添加按钮
container.add(radioButton1,BorderLayout.NORTH);
container.add(radioButton2,BorderLayout.CENTER);
container.add(radioButton3,BorderLayout.SOUTH);
//初始化窗口
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(300,300);
}
public static void main(String[] args) {
new JButton1();
}
}
运行结果:
复选按钮 可以同时选择多个按钮
package com.chen.lesson5;
import javax.swing.*;
import java.awt.*;
public class JButton2 extends JFrame {
public JButton2() {
Container container = this.getContentPane();
//初始化按钮
JCheckBox checkBox1 = new JCheckBox("button1");
JCheckBox checkBox2 = new JCheckBox("button2");
//添加按钮
setLayout(new FlowLayout());
container.add(checkBox1);
container.add(checkBox2);
//初始化窗口
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(300,300);
}
public static void main(String[] args) {
new JButton2();
}
}
运行结果:
3.6 下拉框、列表框
下拉框
package com.chen.lesson6;
import javax.swing.*;
import java.awt.*;
public class ComboBoxTest extends JFrame {
public ComboBoxTest() {
Container container = this.getContentPane();
//初始化下拉框
JComboBox comboBox = new JComboBox();
comboBox.addItem(null);
comboBox.addItem("正在热映");
comboBox.addItem("已下架");
comboBox.addItem("即将上映");
//添加下拉框
container.add(comboBox);
//初始化窗口
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(300,100);
}
public static void main(String[] args) {
new ComboBoxTest();
}
}
运行结果:
列表框
package com.chen.lesson6;
import javax.swing.*;
import java.awt.*;
public class ComboBoxTest2 extends JFrame {
public ComboBoxTest2() {
Container container = this.getContentPane();
//生成列表的内容
String[] contents = {"江畔何人初见月?","江月何年初照人?", "人生代代无穷已,","江月年年望相似。"};
//放入列表中
JList jList = new JList(contents);
//添加下拉框
container.add(jList);
//初始化窗口
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(300,200);
}
public static void main(String[] args) {
new ComboBoxTest2();
}
}
运行结果:
3.7 文本框、密码框、文本域
package com.chen.lesson6;
import javax.swing.*;
import java.awt.*;
public class TextTest extends JFrame {
public TextTest() {
Container container = this.getContentPane();
//文本框
JTextField textField = new JTextField("hello world!");
//密码框
JPasswordField jPasswordField = new JPasswordField();
//文本域
JTextArea textArea = new JTextArea();
//添加
container.add(textField,BorderLayout.NORTH);
container.add(jPasswordField,BorderLayout.CENTER);
container.add(textArea,BorderLayout.SOUTH);
//初始化窗口
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(300,200);
}
public static void main(String[] args) {
new TextTest();
}
}
运行结果: