GUI 编程
Swing和AWT 是java开发GUI常用的技术,但是由于外观不太美观, 组件数量偏少, 并且运行需要JRE环境(动不动就上百M的JRE包....), 所以没有流行起来。但是 ,建议简单的学习和了解。
-
组件(JTable,JList等)很多都是MVC的经典示范,学习GUI可以了解mvc架构。
-
工作时,有可能遇见需要维护N年前awt/swing写的软件 ,虽然可能性很小。
-
可以写一些自己使用用的软件,还是相当的方便。
swing是建立在awt基础上的。有必要学习一下,原因如下:
-
知识的关联性,比如布局、颜色、字体、事件机制等....这些都是awt里的内容,但在swing里也经常使用到。
-
学习成本低,因为awt和swing在编码上区别不大,写法基本一致,组件使用上也差不多(只需要记住少数有区别的地方就可以了)。
-
使用场景存在不同:awt消耗资源少,运行速度快,适合嵌入式等;swing跨平台,组件丰富。
虽然现在用Java做cs的很少,但是对于学习Java基础来说,还是很好的资源,可以利用它把以前的所有知识贯穿起来,做一些小应用、游戏等都可以,可以将自己的一些小想法,做成工具分享出来!
AWT
一、AWT介绍
-
AWT(Abstract Window Toolkit,抽象窗口工具)包括了很多类和接口,用于Java Application的GUI(Graphics User Interface 图形用户界面)编程。
-
GUI的各种元素(如:窗口、按钮、文本框等)由Java类来实现。
-
使用AWT所涉及的类一般在
Java.AWT
包及其子包中。
-
Container(容器) 和 Component(组件) 是AWT中的两个核心类。
所有的可以显示出来的图形元素都称为Component,Component代表了所有的可见的图形元素。
Component里有一种比较特殊的图形元素叫Container,Container(容器)在图形界面里面是一种可以容纳其它Component元素的一种容器,Container本身也是一种Component,Container里面也可以容纳别的Container。
Container里面又分为Window和Pannel,Window是可以独立显示出来的,平时看到的各种各样的应用程序的窗口都可以称为Window,Window作为一个应用程序窗口独立显示出来。
Pannel也可以容纳其它的图形元素,但一般看不见Pannel,Pannel不能作为应用程序的独立窗口显示出来,Pannel要想显示出来就必须得把自己装入到Window里面才能显示出来。Pannel应用比较典型的就是Applet(JAVA的页面小应用程序),现在基本已经不用了,AJAX和JAVASCRIPT完全取代了它的应用。
Window本身又可以分为Frame和Dialog,Frame就是平时看到的一般的窗口,而Dialog则是需要用户进行某些操作(如点击某个下拉菜单的项)才出现的对话框,这种对话框就是Dialog。
二、组件和容器(Component & Container)
-
Java的图形用户界面的最基本组成部分是Component,Component类及其子类的对象用来描述以图形化的方式显示在屏幕上并能与用户进行交互的GUI元素。例如,一个按钮,一个标签等。
-
一般的Component对象不能独立地显示出来,必须将 “放在” 某一个Container对象中才可以显示出来。
-
Container是Component的子类,Container子类对象可以 “容纳” 别的Component对象。
-
Container对象可使用add(...)方法向其中添加其他的Component对象。
-
Container是Component的子类,因此Container对象也可以被当作Component对象添加到其他的Container对象中。
-
有两种常用的Container:
-
Window:其对象表示自由停泊的顶级窗口。
-
Panel:其对象可作为容纳其它Component对象,但不能独立存在,必须被添加到其它Container中(如Window或Applet)
-
-
2.1 Fram
-
Frame是Window的子类,由Frame或其子类创建的对象为一个窗体。
-
Frame的常用构造方法:
-
Frame()
-
Frame(String s):创建标题栏为字符串s的窗口
-
-
Frame的属性方法
-
setBounds(int x,int y,int width,int height)
:设置窗体位置和大小。x、y是左上角坐标,width、height是宽度和高度。 -
setSize(int width,int height)
:设置窗体的大小,x、y是左上角坐标。 -
setLocation(int x,int y)
:设置窗体位置,x、y是左上角坐标。 -
setBackground(Color c)
:设置背景颜色,参数为Color对象。 -
setVisible(boolean b)
:设置是否可见。 -
setTitle(String name)
:设置标题栏。 -
setResizable(boolean b)
:设置窗体是否可以调整大小。
-
【Frame范例】
package com.kuang;
import java.awt.*;
//GUI编程编写的第一个图形界面窗口
public class TestFrame {
public static void main(String[] args) {
//只是在内存里面创建了一个窗口对象,还不能真正显示出来
Frame frame = new Frame("我的第一个JAVA图形界面窗口");
//设置窗体的背景颜色
//三个参数分别代表RGB
frame.setBackground(new Color(110, 217, 119));
//设置窗体是否可见
//要想看到在内存里面创建出来的窗口对象,必须调用setVisble()方法,并且把参数true传入才能看得见窗体
//如果传入的参数是false,那窗体就是看不见的
frame.setVisible(true);
//设置窗体的初始大小
frame.setSize(400,400);
//设置窗体出现时的位置,如果不设置则默认在左上角(0,0)位置显示
frame.setLocation(200,200);
// 设置窗体能否被改变大小
// 默认是true,设置为false后表示不能改变窗体的显示大小
// 这里窗体显示的大小设置为200X200,不能再使用鼠标拖大或者缩小
frame.setResizable(false);
}
}
运行结果:
发现问题:关闭不掉。
解决方法:停止Java程序的运行
【演示二:展示多个窗口】
package com.kuang;
import java.awt.*;
public class TestMultiFrame {
public static void main(String[] args) {
MyFrame f1 = new MyFrame(100,100,200,200,Color.blue);
MyFrame f2 = new MyFrame(300,100,200,200,Color.yellow);
MyFrame f3 = new MyFrame(100,300,200,200,Color.red);
MyFrame f4 = new MyFrame(300,300,200,200,Color.MAGENTA);
}
}
//自定义一个类MyFrame,并且从Frame类继承,这样自定义类MyFrame类就拥有了Frame类的一切属性和方法,并且MyFrame类还可以自定义属性和方法
//使用从Frame类继承而来的自定义类来创建图形窗口比直接使用Frame类来创建图形窗口要灵活,所以一般使用从Frame类继承而来的自定义类创建图形窗口界面比较好,不推荐直接使用Frame类来创建图形窗口界面
class MyFrame extends Frame{
//定义一个静态成员变量id,用来记录创建出来的窗口的数目
static int id = 0;
//自定义构成方法,在构造方法体内使用super调用父类Frame的构造方法
public MyFrame(int x,int y,int w,int h,Color color){
super("MyFrame"+(++id));
/*使用从父类Frame继承而来的方法设置窗体的相关属性*/
setBackground(color);//设置背景色
setLayout(null);//
setBounds(x,y,w,h);//设置初始位置、大小
setVisible(true);//设置是否可见
}
}
运行结果:
2.2 Panel
-
Panel对象可以堪称可以容纳Component的空间
-
Panel对象可以拥有自己的布局管理器
-
Panel类拥有从其父类继承来的方法:
-
setBounds(int x,int y,int width,int height)
:设置窗体位置和大小。x、y是左上角坐标,width、height是宽度和高度。 -
setSize(int width,int height)
:设置窗体的大小,x、y是左上角坐标。 -
setLocation(int x,int y)
:设置窗体位置,x、y是左上角坐标。 -
setBackground(Color c)
:设置背景颜色,参数为Color对象。 -
setLayout(LayoutManager mgr)
:设置布局管理器
-
-
Panel的构造方法为:
-
Panel()
:使用默认的FlowLayout类布局管理器初始化。 -
Panel(LayoutManager layout)
:使用指定的布局管理器初始化。
-
【演示】
package com.wang.gui.awt;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* @Author wangjin
* @Date 2022/04/21 20:30
* @Description
*/
//Panel 可以看成是一个空间,但是不能单独存在
public class PanelTest {
public static void main(String[] args) {
Frame frame = new Frame();
Panel panel = new Panel();
//设置布局
frame.setLayout(null);
//设置位置和大小
frame.setBounds(300,300,500,500);
//设置背景颜色
frame.setBackground(new Color(83, 218, 84));
//panel 设置坐标,相对于Frame
panel.setBounds(50,50,400,400);
panel.setBackground(new Color(232, 78, 78));
//frame.add(panel)
frame.add(panel);
//设置可见性
frame.setVisible(true);
//监听事件解决窗口关闭问题
//监听窗口关闭事件 System.exit(0)
//适配器模式
frame.addWindowListener(new WindowAdapter() {
//窗口点击关闭时需要做的事情
@Override
public void windowClosing(WindowEvent e) {
//结束程序
System.exit(0);
}
});
}
}
结果如下:
三、布局管理器
-
Java语言中,提供了布局管理器类的对象可以管理
-
管理Component在Container中的布局,不必直接设置Component的位置和大小。
-
每个Container都有一个布局管理器对象,当容器需要对某个组件进行定位或判断其大小尺寸时,就会调用其对应的布局管理器,调用Container的setLayout()方法改变其布局管理器对象。
-
-
AWT提供了5中布局管理器:
-
FlowLayout
-
BorderLayout
-
GridLayout
-
CardLayout
-
GridBagLayout
-
3.1 第一种布局管理器——FlowLayout
-
FlowLayout时Panel类的默认布局管理器。
-
FlowLayout布局管理器对组件逐行定位,行内从左到右,一行排满后换行。
-
不改变组件的大小,按组件原有尺寸显示组件,可设置不同组件间距、行距以及对齐方式。
-
-
FlowLayout布局管理器默认的对齐方式是居中。
-
FlowLayout的构造方法
-
new FlowLayout(FlowLayout.RIGHT,20,40)
:右对齐,组件之间水平间距20个像素,垂直间距40个像素。 -
new FlowLayout(FlowLayout.LEFT)
:左对齐,水平和垂直间距为缺省值(5)。 -
new FlowLayout()
:使用默认的居中对齐方式,水平和垂直间距为缺省值(5)。
-
【演示】
package com.kuang;
import java.awt.*;
public class TestFlowLayout {
public static void main(String[] args) {
Frame frame = new Frame("FlowLayout");
//使用Button类创建按钮
//按钮类的其中一个构造方法:Button(String label) label为按钮显示的文本
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3");
// setLayout方法的定义:public void setLayout(LayoutManager mgr)
// 使用流式布局管理器 - FlowLayout
//默认水平居中
frame.setLayout(new FlowLayout());
//布局时使用FlowLayout.LEFT常量,将按钮设置为左对齐
// frame.setLayout(new FlowLayout(FlowLayout.LEFT));
//布局时使用FlowLayout.RIGHT常量,就将按钮设置为右对齐
// frame.setLayout(new FlowLayout(FlowLayout.RIGHT));
frame.setSize(200,200);
frame.add(button1); // 把创建出来的按钮放置到Frame窗体中
frame.add(button2); // 这里并没有设置按钮的大小与位置
frame.add(button3); // 设置按钮的大小与位置都是由布局管理器来做的
frame.setVisible(true);
}
}
运行结果:
3.2 第二种布局管理器——BorderLayout
-
BorderLayout时Frame类的默认布局管理器
-
BorderLayout将整个容器的布局划分成:
-
东(EAST)
-
西(WEST)
-
南(SOUTH)
-
北(NORTH)
-
中(CENTER)五个区域,组件只能被添加到指定的区域。
-
-
如不指定组件的加入部位,则默认加入到CENTER区。
-
每个区域只能加入一个组件,如加入多个,则先前加入的会被覆盖。
-
BorderLayout型布局管理器尺寸缩放原则:
-
北、南两个区域在水平方向缩放。
-
东、西两个区域在垂直方向缩放。
-
中部可在两个方向上缩放。
-
package com.kuang;
import java.awt.*;
public class BorderLayoutTest{
public static void main(String[] args) {
Frame frame = new Frame("BorderLayoutTest");
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);
//也可以使用这样的方式排列按钮,在把按钮放置到Frame窗体时使用方向定位的字符串指定按钮的放置位置
//这种使用方向定位的字符串指定按钮的放置方式不推荐使用 一旦写错了方向字符串就不好检查出来
//因为即使是写错了仍然可以编译通过
/*
frame.add(east,"EAST");
frame.add(west,"West");
frame.add(south,"South");
frame.add(north,"North");
frame.add(center,"Center");
*/
frame.setSize(200,200);
frame.setVisible(true);
}
}
运行结果:
3.3 第三种布局管理器——GridLayout(表格布局管理器)
-
GridLayout型布局管理器将空间划分成规则的矩形网格,每个单元格区域大小相等。组件被添加到每个单元格中,先从左到右填满一行后换行,再从上到下。
-
在GridLayout构造方法中指定分割的行数和列数:
-
如:
GridLayout(3,4);
-
【演示】
package com.kuang;
import java