Java提供了三个主要包做GUI开发:
java.awt 包 – 主要提供字体/布局管理器
javax.swing 包[商业开发常用] – 主要提供各种组件(窗口/按钮/文本框)
java.awt.event 包 – 事件处理,后台功能的实现。
目录
AWT中大量引入了Windows函数,所以经常被称为重量级组件。而Swing使用Java语言实现的轻量级组件,没有本地代码,直接使用Swing可以更加轻松的构建用户界面。
在Java中所有的Swing都保存在javax.swing包中,从包名可以清楚的发现这个是一个扩展包,所有的组件是从JComponent扩展出来的。
如图所示:swing组件主要可分为三个部分,后面会详细介绍
(1)顶层容器::常用有JFrame,JDialog
(2)中间容器:JPanel,JOptionPane,JScrollPane,JLayeredPane 等,主要以panel结尾。
(3)基本组件:JLabel,JButton,JTextField,JPasswordField,JRadioButton 等。
Swing中的窗口其实和AWT中的类似,只不过是对其做了升级改进,添加了更加人性化的方法。Swing中的Frame叫做JFrame,同样是一个顶级窗口,JFrame比较突出的一个特点就是不需要再去绑定监听事件去关闭窗口了,直接给我们一个方法:
void setDefaultCloseOperation(WindowConstants.常量);
//传入一个WindowConstants类型的常量去决定关闭的方式
Frame或JFrame类用于创建一个具有标题栏的框架窗口作为程序的主要界面,它不依赖其他容器可以单独存在。?
JFrame fr = new JFrame();
fr.setTitle("这是一个窗口");
JFrame fr = new JFrame("这是一个窗口");
·setTitle("窗体名称");
设置窗口名字·setSize(int width, int height);
设置窗体的大小·setBackground(Color c));
设置窗体的背景颜色·setLocation(int x, int y);
设置窗体的坐标(原点在左上角),传入坐标即可。·setBounds(int x, int y, int width, int height);
设置窗体的大小·setVisible(boolean b);
设置窗体是否可见,默认是不可见的,所以要可见必须用这个方法传入参数true。·setDefaultCloseOperation(int opreation);
设置点击窗体关闭按钮的时候,做出的响应。通常都是如下面这样写(调用WindowConstants这个类中的静态成员EXIT_ON_CLOSE,表示点击关闭按钮时的默认响应为关闭此窗口并结束程序)。fr.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
WindowConstants的相关静态成员如下:DO_NOTHING_ON_CLOSE(什么也不做)
HIDE_ON_CLOSE (隐藏当前窗口)
DISPOSE_ON_CLOSE (隐藏当前窗口,并释放窗体占有的其他资源,这个重点记一下,后面讲JDialog会用到)
EXIT_ON_CLOSE (结束窗口所在的应用程序)。
import javax.swing.*;
public class Main{
public static void creatGUI() {
// 初始化窗口
JFrame jFrame = new JFrame("这个是窗口的标题");
// 设置窗口的位置和大小
jFrame.setBounds(400, 300, 500, 500);
// 设置窗口的背景颜色
jFrame.setBackground(new Color(175, 114, 114));
// 设置窗口是否可见
jFrame.setVisible(true);
// 设置窗口关闭时的响应
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
createGUI();
}
}
弹窗,使用 JDialog 类可以创建自定义有的弹窗,或者调用 JOptionPane 中的多个静态方法快速创建各种标准的弹窗。弹窗需要明白的一个最重要的概念:弹窗也是一个窗口,是通过另外一个窗口调出的。
·有参构造1
JDialog(Frame owner);
用于创建一个非模态的对话框。参数owner为对话框所有者(顶级窗口JFrame)。
·有参构造2
JDialog(Frame owner,String title);
创建一个具有指定标题的非模态对话框。
·有参构造3
JDialog(Frame owner,boolean modal);
创建一个有指定模式(模态或非模态)的无标题对话框。
·setTitle("窗体名称");
·setModal(boolean modal);
//用来设置子窗口的模态①setSize(int width, int height);
②setLocation(int x, int y);
③setBounds(int x, int y, int width, int height);
④setVisible(boolean b);//基本必写
⑤setDefaultCloseOperation(int opreation);
通常作如下写法,表示点击子窗口的关闭按钮时,响应操作为隐藏子窗口,释放它占有的其它资源。Swing中使用JDialog用来被弹出,默认就存在关闭方法,请勿自己写,否则报错dia.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
import javax.swing.*;
public class Main {
public static void createGUI() {
JFrame fr = new JFrame("这是主窗口");setTitle()方法命名了。
fr.setSize(400, 250);
fr.setLocation(400, 300);
fr.setVisible(true);
fr.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JDialog dia = new JDialog(fr);
dia.setModal(true);//设置子窗口为模态
dia.setTitle("这是一个子窗口");//设置子窗口标题
dia.setBounds(500, 400, 400, 250);
dia.setVisible(true);
dia.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
public static void main(String[] args) {
createGUI();
}
}
? ? 为了实现跨平台并获得动态的布局效果,java将容器内的所有组件安排给一个“布局管理器”负责管理,如:排列顺序、组件大小、位置、当窗口移动或调整大小后组件变化等功能授权给对应的容器布局管理器来管理。
组件从左到右、从上到下,一个挨一个的放在容器中。(Panel和Applet的默认容器布局)如果容器足够宽,第一个组件先添加到容器中第一行的最左边,后续的组件依次添加到上一个组件的右边,如果当前行已放置不下该组件,则放置到下一行的最左边。
import java.awt.*;
import java.swing.*;
public class FlowLayoutDemo {
public static void main(String[] args) {
JFrame frame = new JFrame("FlowLayout"); //Frame默认的布局管理器为BorderLayout
frame.setLayout(new FlowLayout(FlowLayout.CENTER,3,3));
//设置布局管理器为FlowLayout,所有组件居中对齐,水平和垂直间距为3
JButton but1 = new JButton("button1");
JButton but2 = new JButton("button2");
but1.setBackground(Color.blue);
but2.setBackground(Color.yellow);
frame.add(but1);
frame.add(but2);
frame.setBounds(100, 100, 400, 300);
frame.setVisible(true);
}
}
? ?按照东、西、南、北、中放组件。(Window/Frame/Dialog的默认容器布局)BorderLayout布局管理器把容器分成5个区域:North,South,East,West和Center,每个区域只能放置一个组件。
?
import java.awt.*;
import java.swing.*;
public class BorderLayoutDemo {
public static void main(String[] args) {
JFrame frame = new JFrame("BorderLayt");
frame.setLayout(new BorderLayout());
//设置 frame的布局为BorderLayout,默认也是此布局
JButton btn1 = new JButton("button1");
JButton btn2 = new JButton("button2");
btn1.setBackground(Color.blue);
btn2.setBackground(Color.yellow);
frame.add(btn1,BorderLayout.EAST);
frame.add(btn2,BorderLayout.NORTH);
frame.setBounds(100, 100, 400, 300);
frame.setVisible(true);
}
}
?使容器中各个组件呈网格状布局,平均占据容器的空间。
import java.awt.*;
import java.swing.*;
public class GridLayoutDemo {
public static void main(String[] args) {
JFrame frame = new JFrame("GridLayout");
frame.setLayout(new GridLayout(3,2,5,5));
//设置表格为3行两列排列,表格横向间距为5个像素,纵向间距为5个像素
JButton but1 = new JButton("button1");
JButton but2 = new JButton("button2");
JButton but3 = new JButton("button3");
JButton but4 = new JButton("button4");
but1.setBackground(Color.blue);
but2.setBackground(Color.yellow);
but3.setBackground(Color.red);
but4.setBackground(Color.green);
frame.add(but1);
frame.add(but2);
frame.add(but3);
frame.add(but4);
frame.setBounds(100, 100, 400, 300);
frame.setVisible(true);
}
}
import java.awt.*;
import java.swing.*;
public class GridBagLayoutDemo {
private Frame f = new Frame("GridBagLayout Test");
private GridBagLayout gbl = new GridBagLayout();
private GridBagConstraints gbc = new GridBagConstraints();
private Button[] btns = new Button[10];
private void addButton(Button btn) {
gbl.setConstraints(btn, gbc);
f.add(btn);
}
public void init() {
for (int i = 0; i < 10; i++) { // 先初始化10个按钮
btns[i] = new Button("button" + i);
}
f.setLayout(gbl); // 设定框架的布局模式
//为了设置如果组件所在的区域比组件本身要大时的显示情况
gbc.fill = GridBagConstraints.BOTH; // 使组件完全填满其显示区域
//NONE:不调整组件大小。
//HORIZONTAL:加宽组件,使它在水平方向上填满其显示区域,但是不改变高度。
//VERTICAL:加高组件,使它在垂直方向上填满其显示区域,但是不改变宽度。
//BOTH:使组件完全填满其显示区域。
gbc.weighty = 1;
//该方法是设置组件水平所占用的格子数,如果为0,就说明该组件是该行的最后一个,为1则只占一格
// 第1行的4个按钮
gbc.weightx = 1;
//该方法设置组件水平的拉伸幅度,如果为0就说明不拉伸,不为0就随着窗口增大进行拉伸,0到1之间
addButton(btns[0]);
addButton(btns[1]);
addButton(btns[2]);
gbc.gridwidth = GridBagConstraints.REMAINDER;
// 该组件是该行的最后一个,第4个添加后就要换行了
addButton(btns[3]);
// 第2行1个按钮,仍然保持REMAINDER换行状态
addButton(btns[4]);
//第3行
gbc.gridwidth = 2; //按钮分别横跨2格
gbc.weightx = 1; //该方法设置组件水平的拉伸幅度
addButton(btns[5]);
gbc.gridwidth = GridBagConstraints.REMAINDER;
addButton(btns[6]);
// 按钮7纵跨2个格子,8、9一上一下
gbc.gridheight = 2; //按钮7纵跨2格
gbc.gridwidth = 1; //横跨1格
gbc.weightx = 1; //该方法设置组件水平的拉伸幅度
addButton(btns[7]); // 由于纵跨2格因此纵向伸缩比例不需要调整,默认为1*2格,比例刚好
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.gridheight = 1;
gbc.weightx = 1;
addButton(btns[8]);
addButton(btns[9]);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
new GridBagLayoutDemo().init();
}
}
?
import java.awt.*;
public class ComponentTest {
public static void main(String[] args) {
Frame frame = new Frame("基本组件测试");
frame.setBounds(100, 100, 600, 300);
frame.setLayout(new GridLayout(4,2,5,5));
//设置表格为3行两列排列,表格横向间距为5个像素,纵向间距为5个像素
//按钮组件
Button but1 = new Button("测试按钮");
Panel pn0 = new Panel();
pn0.setLayout(new FlowLayout());
pn0.add(but1);
frame.add(pn0);
//复选框组件
Panel pn1 = new Panel();
pn1.setLayout(new FlowLayout());
pn1.add(new Checkbox("one",null,true));
pn1.add(new Checkbox("two"));
pn1.add(new Checkbox("three"));
frame.add(pn1);
//复选框组(单选)
Panel pn2 = new Panel();
CheckboxGroup cg = new CheckboxGroup();
pn2.setLayout(new FlowLayout());
pn2.add(new Checkbox("one",cg,true));
pn2.add(new Checkbox("two",cg,false));
pn2.add(new Checkbox("three",cg,false));
frame.add(pn2);
//下拉菜单
Choice cC = new Choice();
cC.add("red");
cC.add("green");
cC.add("yellow");
frame.add(cC);
//单行文本框
Panel pn3 = new Panel();
pn3.setLayout(new FlowLayout());
TextField tf = new TextField("",30); //30列长度
pn3.add(tf);
frame.add(pn3);
//多行文本框
TextArea ta = new TextArea();
frame.add(ta);
frame.setVisible(true);
}
}
?
Swing组件中的事件处理专门用于响应用户的操作,例如响应用户鼠标单机、按下键盘等操作。
?事件处理的工作流程:
写一个自定义类my_listener,实现ActionListener这个接口,并重写其中的actionPerformed方法
class my_listener implements ActionListener {
? ? @Override
? ? public void actionPerformed(ActionEvent e) {
? ? ? ? System.out.println("click");
? ? }
}
JPanel pane = new JPanel();
JButton button = new JButton("按钮");
button.addActionListener(new my_listener());
pane.add(button);
利用匿名内部类的思路去创建ActionListener的实例化化对象
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("click");
}
});
利用Swing包创建一个窗口,窗口位置为(220,160)、大小为320×240,并在窗口(20,80)、(120,80)、(220,80)处各设置一个按钮,按钮大小为80 X 40。
?
点击左按钮将窗口背景的红色分量增加10,点击中间按钮将窗口背景的绿色分量增加10,点击右按钮将窗口背景的蓝色分量增加10,上述三种分量大于255时变成0,下面面板的颜色同步改变,点击窗口关闭按钮时退出程序运行。
代码
package DEMO230201.gui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class gui1 {
int r=100,g=100,b=255;
public void creatGUI() {
JFrame f = new JFrame("窗口"); //创建窗口
f.setBounds(220, 160, 320, 240); //设置大小位置
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //设置关闭
f.setVisible(true); //设置可视化
f.addWindowListener(new WindowAdapter() { //点击窗口关闭按钮时退出程序运行
@Override
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
JPanel p = new JPanel(); //添加面板
p.setBackground(new Color(r, g, b)); //设置颜色
p.setLayout(null); //布局方式
f.add(p); //把面板加进窗口
JButton b1 = new JButton("红色"); //添加按钮
JButton b2 = new JButton("绿色");
JButton b3 = new JButton("蓝色");
b1.setBounds(20, 80, 80, 40); //设置大小位置
b2.setBounds(120, 80, 80, 40);
b3.setBounds(220, 80, 80, 40);
b1.setBackground(Color.red); //设置颜色
b2.setBackground(Color.green);
b3.setBackground(Color.blue);
b1.addActionListener(new ActionListener() { //添加事件处理
@Override
public void actionPerformed(ActionEvent e) {
r += 10;
if (r > 255) r = 0;
p.setBackground(new Color(r, g, b));
}
});
b2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
g += 10;
if (g > 255) g = 0;
p.setBackground(new Color(r, g, b));
}
});
b3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
b += 10;
if (b > 255) b = 0;
p.setBackground(new Color(r, g, b));
}
});
p.add(b1); //把按钮加进面板
p.add(b2);
p.add(b3);
}
public static void main(String[] args){
gui1 test=new gui1();
test.creatGUI();
}
}
鼠标事件处理:要求创建一个按钮,鼠标选中按钮不放开,将按钮拖拽到窗口其它他位置后,放开鼠标。
package DEMO230201.gui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class gui2 {
private int dragStartX;
private int dragStartY;
public void creatGUI() {
JFrame f=new JFrame("鼠标事件");
f.setSize(500,300);
f.setLayout(new FlowLayout());
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JButton b=new JButton("拖动我");
b.addMouseMotionListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
dragStartX = e.getX();
dragStartY = e.getY();
}
});
b.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
int deltaX = e.getX() - dragStartX;
int deltaY = e.getY() - dragStartY;
int newX = b.getX() + deltaX;
int newY = b.getY() + deltaY;
b.setLocation(newX, newY);
}
});
f.add(b);
f.setVisible(true);
}
public static void main(String[] args){
gui2 test=new gui2();
test.creatGUI();
}
}