一、相关概述
GUI编程是指通过图形化的方式来实现计算机程序的编写,它可以让用户通过鼠标、键盘等设备来操作计算机,而不是通过命令行来输入指令。在Java中,GUI编程主要使用的是Swing和AWT两种技术
二、AWT
2.1介绍
AWT是Java提供的用来建立和设置Java的图形用户界面的基本工具,它提供了一套与本地图形界面进行交互的接口12。AWT的图形函数与操作系统提供的图形函数有着一一对应的关系,也就是说,当使用AWT时,Java程序会调用操作系统的图形函数来绘制界面
2.2组件和容器
容器是Component的子类,一个容器可以容纳多个组件,并使他们成为一个整体。容器可以简化图形化界面的设计,以整体结构来布置界面,所有的组件都可以通过add()方法加入容器中。
组件
- 窗口
- 弹窗
- 面板
- 文本框
- 列表框
- 按钮
- 图片
- 监听事件
- 鼠标
- 键盘事件
- 破解工具
2.2.1窗口(Frame)
package com.tanchise;
import java.awt.*;
public class FirstFrame extends Frame{
public static void main(String[] args) {
// TODO Auto-generated method stub
FirstFrame fr = new FirstFrame("Hello world!"); //构造方法
fr.setSize(240,240); //设置Frame的大小
fr.setBackground(Color.blue); //设置Frame的背景色
fr.setLocation(200,200);//弹出初始位置
fr.setVisible(true); //设置Frame为可见,默认不可见
fr.setResizable(false);//设置Frame大小固定
}
public FirstFrame(String str){
super(str);
}
}
效果图
注:awt在实际运行过程中,是调用所在平台的图形系统,底层实现依赖操作系统,为此在Windows平台下运行,则显示Windows风格。
package com.tanchise;
import java.awt.*;
public class FirstFrame2 {
public static void main(String[] args) {
MyFrame myFrame1 = new MyFrame(100,100,200,200,Color.yellow);
MyFrame myFrame2 = new MyFrame(300,200,200,200,Color.blue);
}
}
class MyFrame extends Frame{
static int count = 0;
public MyFrame(int x,int y,int w,int h,Color color) {
super("Myframe+"+(++count));
setBackground(color);
setBounds(x,y,w,h);
setVisible(true);
}
}
2.2.2、面板(Panel)
Panel是一种透明的容器,既没有标题,也没有边框。它不能作为最外层的容器单独存在,首先必须先作为一个组件放置在其他容器中,然后在把它当做容器。
package com.tanchise;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class panel {
public static void main(String[] args) {
// TODO Auto-generated method stub
Frame fr = new Frame("Hello");
fr.setSize(240,240);
fr.setBackground(Color.green);
fr.setLayout(null); //取消默认的布局BorderLayout
Panel pan = new Panel(); //创建面板
pan.setSize(100,100);
pan.setBackground(Color.yellow);
fr.add(pan);
fr.setVisible(true);
//
fr.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
效果图
2.3、布局管理器(LayoutManager)
为了实现跨平台并获得动态的布局效果,java将容器内的所有组件安排给一个“布局管理器”负责管理,如:排列顺序、组件大小、位置、当窗口移动或调整大小后组件变化等功能授权给对应的容器布局管理器来管理。
- 流式布局
- 东、西、南、北、中布局
- 表格布局
2.3.1、FlowLayout——流式布局管理器
FlowLayout 会将组件按照从上到下、从左到右的放置规律逐行进行定位。与其他布局管理器不同的是,FlowLayout 布局管理器不限制它所管理组件的大小,而是允许它们有自己的最佳大小。FlowLayout 布局管理器的构造方法如下:
- FlowLayout ():创建一个布局管理器,使用默认的居中对齐方式和默认 5 像素的水平和垂直间隔。
- FlowLayout (int align):创建一个布局管理器,使用默认 5 像素的水平和垂直间隔。
package com.tanchise;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class FlowLayoutDemo {
public static void main(String[] args) {
Frame frame = new Frame("FlowLayout"); //Frame默认的布局管理器为BorderLayout
frame.setBounds(100, 100, 400, 300);
frame.setLayout(new FlowLayout(FlowLayout.CENTER)); //设置布局管理器为FlowLayout
Button but1 = new Button("button1");
Button but2 = new Button("button2");
Button but3 = new Button("button3");
Button but4 = new Button("button4");
Button but5 = new Button("button5");
but1.setBackground(Color.blue);
but2.setBackground(Color.yellow);
but3.setBackground(Color.red);
but4.setBackground(Color.green);
but5.setBackground(Color.pink);
frame.add(but1);
frame.add(but2);
frame.add(but3);
frame.add(but4);
frame.add(but5);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
效果图
FlowLayout的对齐方式默认为居中对齐,但是我们也可以自己指定对齐方式及横纵向间隔。
2.3.2、BorderLayout——边框布局管理器
边框布局管理器是Java Swing中的一种布局管理器,它将容器分为五个区域:东、南、西、北和中。每个区域只能包含一个组件,如果没有指定组件的位置,则默认将其放置在中央区域。
package com.tanchise;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class BorderLayoutDemo {
public static void main(String[] args) {
Frame frame = new Frame("BorderLayt");
frame.setBounds(100, 100, 400, 300);
//frame.setLayout(new BorderLayout()); //设置 frame的布局为BorderLayout,默认也是此布局
Button btn1 = new Button("button1");
Button btn2 = new Button("button2");
Button btn3 = new Button("button3");
Button btn4 = new Button("button4");
Button btn5 = new Button("button5");
btn1.setBackground(Color.blue);
btn2.setBackground(Color.yellow);
btn3.setBackground(Color.pink);
btn4.setBackground(Color.green);
btn5.setBackground(Color.red);
frame.add(btn1,BorderLayout.EAST);
frame.add(btn2,BorderLayout.NORTH);
frame.add(btn3,BorderLayout.SOUTH);
frame.add(btn4,BorderLayout.WEST);
frame.add(btn5);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
效果图
2.3.3、GridLayout——网格布局管理器
网格布局管理器是Java Swing中的一种布局管理器,它将容器分成行数和列数相等的网格,每个网格放置一个组件,按照从左往右,从上往下的顺序依次添加
package com.tanchise;
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class GridLayoutDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Frame frame = new Frame("GridLayout");
frame.setBounds(400, 400, 500, 400);
GridLayout gl = new GridLayout(3,2,5,5); //设置表格为3行两列排列,表格横向间距为5个像素,纵向间距为5个像素
frame.setLayout(gl);
Button but1 = new Button("button1");
Button but2 = new Button("button2");
Button but3 = new Button("button3");
Button but4 = new Button("button4");
Button but5 = new Button("button5");
but1.setBackground(Color.blue);
but2.setBackground(Color.yellow);
but3.setBackground(Color.red);
but4.setBackground(Color.green);
but5.setBackground(Color.pink);
frame.add(but1);
frame.add(but2);
frame.add(but3);
frame.add(but4);
frame.add(but5);
// frame.pack();//自动布局
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
效果图
2.3.4GridBagLayout——网格包布局管理器
GridBagLayout是Java Swing中的一个布局管理器,它可以在一个网格中放置组件,每个组件占用一个或多个网格单元格。GridBagLayout是最灵活和复杂的布局管理器之一,它可以让指定的组件跨越多行或多列。不是所有的行都必须具有相同的高度
package com.tanchise;
import java.awt.Button;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class GridBagLayoutDemo {
// 创建一个 Frame 对象,名为 "GridBagLayout Test"
private Frame f = new Frame("GridBagLayout Test");
// 创建一个 GridBagLayout 布局管理器对象
private GridBagLayout gbl = new GridBagLayout();
// 创建一个 GridBagConstraints 对象
private GridBagConstraints gbc = new GridBagConstraints();
// 创建一个 Button 类型的数组对象,长度为 10
private Button[] btns = new Button[10];
// 添加按钮的方法,接收一个 Button 类型的参数 btn
private void addButton(Button btn) {
// 使用 gbl 对象设置按钮的约束条件
gbl.setConstraints(btn, gbc);
// 将按钮添加到 Frame 对象中
f.add(btn);
}
// 初始化方法
public void init() {
// 循环创建 10 个按钮,将它们添加到数组中
for (int i = 0; i < 10; i++) {
btns[i] = new Button("button" + i);
}
// 设定 Frame 的布局模式为 GridBagLayout
f.setLayout(gbl);
// 设置组件填充方式为 BOTH,即组件完全填满其显示区域
gbc.fill = GridBagConstraints.BOTH;
// 设置组件水平所占用的格子数为 1,如果为 0,说明该组件是该行的最后一个,为 1 则只占一格
gbc.weighty = 1;
// 第 1 行的 4 个按钮
// 设置组件水平的拉伸幅度为 1,即随着窗口增大进行拉伸,0 到 1 之间
gbc.weightx = 1;
// 将按钮 0、1、2 添加到 Frame 中
addButton(btns[0]);
addButton(btns[1]);
addButton(btns[2]);
// 该组件是该行的最后一个,第 4 个添加后就要换行了
gbc.gridwidth = GridBagConstraints.REMAINDER;
// 将按钮 3 添加到 Frame 中
addButton(btns[3]);
// 第 2 行 1 个按钮,仍然保持 REMAINDER 换行状态
// 将按钮 4 添加到 Frame 中
addButton(btns[4]);
// 第 3 行
// 按钮分别横跨 2 格
gbc.gridwidth = 2;
// 设置组件水平的拉伸幅度为 1
gbc.weightx = 1;
// 将按钮 5 添加到 Frame 中
addButton(btns[5]);
// 该组件是该行的最后一个
gbc.gridwidth = GridBagConstraints.REMAINDER;
// 将按钮 6 添加到 Frame 中
addButton(btns[6]);
// 按钮 7 纵跨 2 个格子,8、9 一上一下
// 按钮 7 纵跨 2 格
gbc.gridheight = 2;
gbc.gridwidth = 1;
gbc.weightx = 1;
addButton(btns[7]);
// 该组件是该行的最后一个
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.gridheight = 1;
gbc.weightx = 1;
addButton(btns[8]);
addButton(btns[9]);
// 将 Frame 自适应大小,并显示
f.pack();
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) {
new GridBagLayoutDemo().init();
}
}
2.3.5CardLayout——卡片布局管理器
卡片布局管理器(CardLayout)是Java Swing中的一种布局管理器,它能够帮助用户实现多个成员共享同一个显示空间,并且一次只显示一个容器组件的内容。CardLayout布局管理器将容器分为很多层,每层的显示空间占据整个容器的大小,但是每层只允许放置一个组件。
package com.tanchise;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.CardLayout;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class aaa {
Frame f = new Frame("测试窗口");
String[] names = { "one", "two", "three", "four", "five" };
Panel p1 = new Panel(); //显示的面板
public void init() {
final CardLayout c = new CardLayout(); //卡片局部
p1.setLayout(c); //面板布局使用卡片布局
for (int i = 0; i < names.length; i++) {
p1.add(names[i], new Button(names[i])); //设置面板的名字和组件
}
Panel p = new Panel(); //创建一个放按钮的面板
// 控制显示上一张的按钮
Button previous = new Button("pre");
//为按钮添加监听
previous.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
c.previous(p1);
}
});
// 控制显示下一张的按钮
Button next = new Button("next");
next.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
c.next(p1);
}
});
// 控制显示第一张的按钮
Button first = new Button("first");
first.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
c.first(p1);
}
});
// 控制显示最后一张的按钮
Button last = new Button("last");
last.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
c.last(p1);
}
});
// 控制根据Card显示的按钮
Button third = new Button("Third");
third.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
c.show(p1, "three");
}
});
p.add(previous);
p.add(next);
p.add(first);
p.add(last);
p.add(third);
f.add(p1);
f.add(p, BorderLayout.SOUTH);
f.pack(); //紧凑排列
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) {
new aaa().init();
}
}
2.4、组件(Component)
awt组件库中还有很多比较常用的组件,如:按钮(Button)、复选框(Checkbox)、复选框组(CheckboxGroup)、下拉菜单(Choice)、单行文本输入框(TextField)、多行文本输入框(TextArea)、列表(List)、对话框(Dialog)、文件对话框(Filedialog)、菜单(Menu)、MenuBar、MenuItem、Canvas等;
2.4.1、基本组件
package com.tanchise;
import java.awt.Button;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Choice;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.List;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
public class ComponentTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Frame frame = new Frame("基本组件测试");
frame.setBounds(100, 100, 600, 300);
GridLayout gl = new GridLayout(4,2,5,5); //设置表格为3行两列排列,表格横向间距为5个像素,纵向间距为5个像素
frame.setLayout(gl);
//按钮组件
Button but1 = new Button("bottom");
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);
//列表
List ls = new List();
ls.add("a");
ls.add("b");
ls.add("c");
ls.add("d");
ls.add("e");
ls.add("f");
ls.add("g");
frame.add(ls);
frame.setVisible(true);
}
}
2.4.2Menu组件
Java中的Menu组件是一个下拉菜单,它可以从菜单栏中部署。菜单可以选择是撕开式菜单。撕开式菜单可以从其父菜单栏或菜单中打开并拖动。鼠标按钮释放后,它仍然保留在屏幕上。
package com.tanchise;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
public class MenuDemo {
private Frame f;
public MenuDemo(){
f = new Frame("测试菜单");
f.setBounds(100, 100, 200, 200);
//Menu无法直接添加到容器中,只能直接添加到菜单容器中
MenuBar mb = new MenuBar(); //创建菜单容器
f.setMenuBar(mb);
//添加菜单
Menu m1 = new Menu("File");
Menu m2 = new Menu("Edit");
Menu m3 = new Menu("Help");
mb.add(m1);
mb.add(m2);
mb.add(m3);
//添加菜单项
MenuItem mi1 = new MenuItem("Save");
MenuItem mi2 = new MenuItem("Load");
MenuItem mi3 = new MenuItem("Quit");
m1.add(mi1);
m1.add(mi2);
m1.addSeparator(); //添加分隔线
m1.add(mi3);
f.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MenuDemo md = new MenuDemo();
}
}
三、事件监听
在Java GUI编程中,事件监听器是一种机制,用于处理用户与GUI组件交互时发生的事件。Java中,事件处理的基本思路是:一个源(事件源)产生一个事件,并把它送到监听器那里,监听器只是简单的对待,直到它收到一个事件,一旦事件被接收,监听器将处理这些事件。一个事件源必须注册监听器以便监听器可以接收关于一个特定事件的通知
与AWT有关的所有事件类都由AWTEvent类派生,它是EventObject类的子类。这些AWT事件分为两大类:低级事件和高级事件。低级事件是指基于组件和容器的事件,当一个组件上发生事件,如鼠标进入、点击、拖放或组件的窗口开关等都是低级事件。高级事件是语义事件,它不可以和特点的动作相关联,而依赖于触发此类事件的类,如选中项目列表中的某一项就会触发ActionEvent事件。
低级事件:
1)ComponentEvent 构件事件,构件尺寸的变化以及移动·
2)ContainerEvent 容器事件,构件增加,移动
3)WindowEvent 窗口事件,关闭窗口,窗口闭合,图标化
4)FocusEvent 焦点事件,焦点的获得与丢失
5)KeyEvent 键盘事件,键按下,释放
6)MouseEvent 鼠标事件,鼠标点击,移动
高级事件(语义事件):
1)ActionEvent 动作事件,按键按下,TextField中按下Enter键
2)AdjustmentEvent 调节事件,在滚动条上移动滑块以调节数值
3)ItemEvent 项目事件,选择项目,不选择“项目改变”
· 4)TextEvent 文本事件,文本对象改变
3.1、事件监听器概述
每类事件都有对应的事件监听器,AWT一共10类事件,11个接口。
3.2Button按钮监听器
package com.tanchise;
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 buttonActionEvent {
public static void main(String[] args) {
//按下按钮,触发一些事件
Frame frame = new Frame();
frame.setBounds(100, 100, 400, 400);
Button button = new Button("Button");
button.setBackground(Color.blue);
button.setSize(1,1);
//因为,addActionListener()需要ActionListener,所以需要构造一个ActionListener
MyActionListener myActionListener = new MyActionListener();
button.addActionListener(myActionListener);
frame.add(button);
// frame.pack();
windowClose(frame);//关闭窗口
frame.setVisible(true);
}
//关闭窗体事件
private static void windowClose(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) {
System.out.println("aab");
}
}
多个按钮,共享一个事件
package com.tanchise;
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 TestActionTwo {
public static void main(String[] args) {
//两个按钮,实现同一个监听
//开始 停止
Frame frame = new Frame("开始-停止");
frame.setBounds(100, 100, 400, 400);
Button button1 = new Button("start");
button1.setBackground(Color.blue);
button1.setSize(10, 10);
Button button2 = new Button("stop");
//可以显示的定义触发会返回的命令,如果不显示定义,会走默认的值
//可以多个按钮只写一个监听
button2.setActionCommand("button2-stop");
MyMonitor myMonitor = new MyMonitor();
button1.addActionListener(myMonitor);
button2.addActionListener(myMonitor);
frame.add(button1, BorderLayout.NORTH);
frame.add(button2, BorderLayout.WEST);
// frame.pack();
windowClose(frame);//关闭窗口
frame.setVisible(true);
}
private static void windowClose(Frame frame) {
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
class MyMonitor implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
//e.getActionCommand()获取按钮的信息
System.out.println("按钮被点击了:msg"+e.getActionCommand());
}
}
3.3输入框TextField监听
package tanchishe;
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 TextField1 {
public static void main(String[] args) {
new myframe();
}
}
class myframe extends Frame {
public myframe(){
TextField textField = new TextField();
add(textField);
//监听这个文本框输入的文字
MyActionListener2 myActionListener2 = new MyActionListener2();
//按下enter,就会触发这个输入框的事件
textField.addActionListener(myActionListener2);
//设置替换编码
textField.setEchoChar('*');
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("");
}
}
简易计算机
package tanchishe;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TextCale {
public static void main(String[] args) {
new Calculator().loadFrame();
}
}
//计算机类
class Calculator extends Frame{
//属性
TextField num1,num2,num3;
//方法
public void loadFrame(){
//3个文本框
num1 = new TextField(10);
num2 = new TextField(10);
num3 = new TextField(20);
//1个按钮
Button button = new Button("=");
button.addActionListener(new MyCalculatorListener(this));
//1个标签
Label label = new Label("+");
//布局
setLayout(new FlowLayout());
add(num1);
add(label);
add(num2);
add(button);
add(num3);
pack();
setVisible(true);
}
}
//监听器类
class MyCalculatorListener implements ActionListener{
//获取计算机这个对象,在一个类中组合另一个类
Calculator calculator = null;
public MyCalculatorListener(Calculator calculator){
this.calculator=calculator;
}
@Override
public void actionPerformed(ActionEvent e) {
//1、获得加数和被加数
//2、将这个值+法运算后,放到第三个框
//3、清楚前两个框
int n1 = Integer.parseInt(calculator.num1.getText());
int n2 = Integer.parseInt(calculator.num2.getText());
calculator.num3.setText(""+(n1+n2));
calculator.num1.setText("");
calculator.num2.setText("");
}
}
3.4鼠标监听
3.4.1画笔
package tanchishe;
import java.awt.*;
public class TestPaint {
public static void main(String[] args) {
new MYpaint().loadFrame1();
}
}
class MYpaint extends Frame{
public void loadFrame1(){
setBounds(200,200,600,400);
setVisible(true);
}
@Override
public void paint(Graphics g) {
//super.paint(g);有些类的父类有一些初始化操作,不能随便干掉
//画笔,需要颜色,画笔可以画画
g.setColor(Color.red);
g.drawOval(100,100,100,100);
g.fillOval(200,200,100,100);//实心的⚪
g.setColor(Color.green);
g.fillRect(300,300,40,20);
g.drawRect(300,350,40,20);
//养成习惯 画笔画完,将他还原到最初的颜色
g.setColor(Color.BLACK);
}
}
3.4.2模拟鼠标画画!
package tanchishe;
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 title) {
super(title);
setBounds(100, 100, 500, 400);
//存鼠标的点
points = new ArrayList<>();
//鼠标监听器,针对这个窗口
setVisible(true);
this.addMouseListener(new MyML());
}
@Override
public void paint(Graphics g) {
//画画,监听鼠标的事件
Iterator iterator = points.iterator();
while (iterator.hasNext()){
Point point = (Point) iterator.next();
g.setColor(Color.BLUE);
g.fillOval(point.x,point.y,10,10);
}
}
//添加一个点到界面上
public void addPaint(Point point){
points.add(point);
}
//适配器模式
private class MyML extends MouseAdapter {
//鼠标 按下,弹起,按住不放
@Override
public void mouseClicked(MouseEvent e) {
MyFrame myframe = (MyFrame) e.getSource();
//这里我们点击的时候,就会在界面产生一个点
myframe.addPaint(new Point(e.getX(),e.getY()));
//每次点击鼠标都需要重新画一遍
myframe.repaint();//刷新
}
}
}
3.5窗口监听
package tanchishe;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestWindow {
public static void main(String[] args) {
new WindowF();
}
}
class WindowF extends Frame {
public WindowF() {
setBackground(Color.BLUE);
setBounds(100, 100, 200, 200);
setVisible(true);
this.addWindowListener(
//匿名内部类
new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("windowsClosing");
System.exit(0);
}
@Override
public void windowActivated(WindowEvent e) {
WindowF source = (WindowF) e.getSource();
source.setTitle("已激活");
System.out.println("windowActivated");
}
});
}
/* @Override
public void windowClosing(WindowEvent e) {
setVisible(false);// 隐藏窗口
System.exit(0);//正常退出 1是非正常退出
};*/
}
3.6 键盘监听
package tanchishe;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.sql.SQLOutput;
//键
public class TestKeyListener {
public static void main(String[] args) {
new KeyF();
}
}
class KeyF extends Frame{
public KeyF(){
setBounds(0,0,300,400);
setVisible(true);
this.addKeyListener(new KeyAdapter() {
//键盘按下
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();//不需要去记录这个数值,直接使用静态属性VK_xxx
System.out.println(keyCode);
if (keyCode == KeyEvent.VK_UP){
System.out.println("你按了上键盘");
//根据不同的操作,进行不同的结果
}
}
});
}
}
四、Swing
4.1Swing概述
AWT中大量引入了Windows函数,所以经常被称为重量级组件。而Swing使用Java语言实现的轻量级组件,没有本地代码,直接使用Swing可以更加轻松的构建用户界面。
在Java中所有的Swing都保存在javax.swing包中,从包名可以清楚的发现这个是一个扩展包,所有的组件是从JComponent扩展出来的。
与AWT组件不同,Swing组件不能直接添加到顶层容器中,它必须添加到一个与Swing顶层容器相关的内容面板上。内容面板是顶层容器包含的一个普通容器。
4.2窗体
package com.shuai.lesson4;
import javax.swing.*;
import java.awt.*;
public class JFrameDemo {
//init();初始化
public void init(){
//顶级窗口
JFrame jf = new JFrame("这是一个JFrame窗口");
jf.setBounds(100,100,400,300);
//设置文字Label->JLabel
jf.setBackground(Color.BLUE);
JLabel jl = new JLabel("JJJJJ");
jf.add(jl);
//让文本标签居中
jl.setHorizontalAlignment(SwingConstants.CENTER);
//容器实例化
jf.getContentPane().setBackground(Color.red);
jf.setVisible(true);
//关闭事件
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
//建立一个窗口
new JFrameDemo().init();
}
}
4.3弹窗
package tanchishe;
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(100, 100, 400, 400);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//Jframe 放东西,容器
Container contentPane = this.getContentPane();
//绝对布局
contentPane.setLayout(null);
//设置背景
contentPane.setBackground(Color.BLUE);
//按钮
JButton jButton = new JButton("点击弹出一个对话框");
jButton.setBounds(30, 30, 200, 50);
//点击按钮弹出弹框
jButton.addActionListener(new ActionListener() {//监听器
@Override
public void actionPerformed(ActionEvent e) {
//弹窗
new MyDialog();
}
});
contentPane.add(jButton);
}
public static void main(String[] args) {
new DialogDemo();
}
}
//弹窗的窗口
class MyDialog extends JDialog {
public MyDialog() {
this.setVisible(true);
this.setBounds(100, 100, 500, 500);
// this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
//JDialog退出只能是D0_ONTHING,HIDE,DISPOSE这三个中的一种
//应该是默认就有关闭事件
this.setTitle(a"这是一个弹窗");
Container contentPane = this.getContentPane();
contentPane.setLayout(null);
contentPane.setBackground(Color.ORANGE);
JLabel jjj = new JLabel("学习学习");
contentPane.add(jjj);
jjj.setBounds(20,20,50,50);
}
}
4.4标签
label
new JLabel("xxx");
图标Icon
package com.shuai.lesson4;
import javax.swing.*;
import java.awt.*;
//图标,需要实现类,Frame继承
public class IconDemo extends JFrame implements Icon {
private int width;
private int hight;
public IconDemo(){};//无参构造
//有参构造
public IconDemo(int width,int hight){
this.width = width;
this.hight = hight;
};
public void init(){
IconDemo iconDemo = new IconDemo(15, 15);
//图标可以放在标签,也可以放在按钮上!
JLabel jLabel = new JLabel("标签",iconDemo,SwingConstants.CENTER);
Container contentPane = getContentPane();
contentPane.add(jLabel);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.fillOval(x,y,width,hight);
}
@Override
public int getIconWidth() {
return this.width;
}
@Override
public int getIconHeight() {
return this.hight;
}
public static void main(String[] args) {
new IconDemo().init();
}
}
图片
package tanchishe;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
import java.util.Objects;
public class ImageIconDemo extends JFrame {
public ImageIconDemo(){
JLabel jLabel = new JLabel("图片");
URL resource = ImageIconDemo.class.getResource("1.jpg");
ImageIcon imageIcon = new ImageIcon(resource);
jLabel.setIcon(imageIcon);
jLabel.setHorizontalAlignment(SwingConstants.CENTER);
Container contentPane = getContentPane();
contentPane.add(jLabel);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setBounds(100,100,800,800);
}
public static void main(String[] args) {
new ImageIconDemo();
}
}
4.5面板
4.5.1JPanel
package tanchishe;
import javax.swing.*;
import java.awt.*;
public class JPanelDemo extends JFrame {
public JPanelDemo(){
Container contentPane = this.getContentPane();
contentPane.setLayout(new GridLayout(2,1,10,10));//后边两个是间距
JPanel jPanel = new JPanel(new GridLayout(1, 3));
JPanel jPane2 = new JPanel(new GridLayout(1, 2));
JPanel jPane3 = new JPanel(new GridLayout(1, 1));
jPanel.add(new JButton("aaa"));
jPanel.add(new JButton("bbb"));
jPanel.add(new JButton("ccc"));
jPane2.add(new JButton("111"));
jPane2.add(new JButton("222"));
jPane3.add(new JButton("---"));
setBounds(100,100,500,400);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
contentPane.add(jPanel);
contentPane.add(jPane2);
contentPane.add(jPane3);
setVisible(true);
contentPane.setBackground(Color.YELLOW);
}
public static void main(String[] args) {
new JPanelDemo();
}
}
4.5.2JScrollPanel
package tanchishe;
import javax.swing.*;
import java.awt.*;
public class JScrollPanelDemo extends JFrame {
public JScrollPanelDemo(){
Container contentPane = this.getContentPane();
//文本域
JTextArea jTextArea = new JTextArea(20, 50);
jTextArea.setText("学习学习");
//面板 并添加到contentpane
contentPane.add(new JScrollPane(jTextArea));
this.setVisible(true);
this.setBounds(100,100,400,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
contentPane.setBackground(Color.BLUE);
}
public static void main(String[] args) {
new JScrollPanelDemo();
}
}
4.5.3分层面板
Swing提供了两种分层面板,JLayeredPane和JDesktopPane。JDesktopPane是JLayeredPane的子类,专门为容纳内部框架而设置。
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class JLayeredPaneDemo extends JFrame{
public static void main(String[] args) {
// TODO Auto-generated method stub
new JLayeredPaneDemo();
}
public JLayeredPaneDemo(){
super("分层面板测试");
this.setSize(300, 300);
this.setLocationRelativeTo(null);
JLayeredPane layeredPane = new JLayeredPane();
//红 绿 蓝 依次排列
// 位置1:最顶层
JPanel jp1 = new JPanel();
jp1.setBounds(30, 30, 100, 100);
jp1.setBackground(Color.blue);
layeredPane.add(jp1, 0);
// 位置2:最下层
JPanel jp2 = new JPanel();
jp2.setBounds(60, 60, 100, 100);
jp2.setBackground(Color.red);
layeredPane.add(jp2, 2);
// 位置3:中间层
JPanel jp3 = new JPanel();
jp3.setBounds(90, 90, 100, 100);
jp3.setBackground(Color.green);
layeredPane.add(jp3, 1);
this.getContentPane().add(layeredPane);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
4.6按钮
图片按钮
package tanchishe;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class JButtonDemo01 extends JFrame {
public JButtonDemo01(){
Container contentPane = this.getContentPane();
//图片变为图标
URL resource = JButtonDemo01.class.getResource("1.jpg");
Icon icon = new ImageIcon(resource);
JButton jButton = new JButton();
jButton.setIcon(icon);
//悬浮框
jButton.setToolTipText("这是一个图片按钮");
//jButton.setSize(1,1);
contentPane.add(jButton);
this.setVisible(true);
this.setBounds(100,100,400,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JButtonDemo01();
}
}
单选按钮
package tanchishe;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class JButtonDemo02 extends JFrame {
public JButtonDemo02(){
Container contentPane = this.getContentPane();
//图片变为图标
URL resource = JButtonDemo01.class.getResource("1.jpg");
Icon icon = new ImageIcon(resource);
//单选框
JRadioButton jrb01 = new JRadioButton("jrb01");
JRadioButton jrb02 = new JRadioButton("jrb02");
JRadioButton jrb03 = new JRadioButton("jrb03");
//由于单选框只能选择一个,分组
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(jrb01);
buttonGroup.add(jrb02);
buttonGroup.add(jrb03);
contentPane.add(jrb01,BorderLayout.CENTER);
contentPane.add(jrb02,BorderLayout.NORTH);
contentPane.add(jrb03,BorderLayout.SOUTH);
this.setVisible(true);
this.setBounds(100,100,400,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JButtonDemo02();
}
}
复选按钮
package tanchishe;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class JButtonDemo03 extends JFrame {
public JButtonDemo03(){
Container contentPane = this.getContentPane();
//多选框
JCheckBox jcb1 = new JCheckBox("jcb1");
JCheckBox jcb2 = new JCheckBox("jcb2");
JCheckBox jcb3 = new JCheckBox("jcb3");
//流式布局
contentPane.setLayout(new FlowLayout(FlowLayout.LEFT));
contentPane.add(jcb1);
contentPane.add(jcb2);
contentPane.add(jcb3);
//东西南北中布局
/*
contentPane.add(jcb1,BorderLayout.NORTH);
contentPane.add(jcb2,BorderLayout.CENTER);
contentPane.add(jcb3,BorderLayout.SOUTH);
*/
this.setVisible(true);
this.setBounds(100,100,400,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JButtonDemo03();
}
}
4.7列表
下拉框
package tanchishe;
import javax.swing.*;
import java.awt.*;
public class TestComboboxDemo01 extends JFrame {
public TestComboboxDemo01(){
Container container = this.getContentPane();
JComboBox status = new JComboBox();
status.addItem("未上映");
status.addItem("正在热映");
status.addItem("已下架");
container.add(status);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setBounds(100,100,500,400);
}
public static void main(String[] args) {
new TestComboboxDemo01();
}
}
列表框
package com.shuai.lesson6;
import javax.swing.*;
import java.awt.*;
import java.util.Vector;
public class TestComboboxDemo02 extends JFrame {
public TestComboboxDemo02(){
Container container = this.getContentPane();
//生成列表的内容
// String[] contents = {"1","2","3"};
//列表中需要的内容
Vector contents = new Vector();
JList jList = new JList(contents);
JList jList1 = new JList(contents);
contents.add("2222");
contents.add("333");
container.add(jList);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setBounds(100,100,500,400);
}
public static void main(String[] args) {
new TestComboboxDemo02();
}
}
综合
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class FrameDemo3 extends JFrame{
public static void main(String[] args) {
// TODO Auto-generated method stub
new FrameDemo3("demo");
}
JPanel jp1, jp2;
JLabel jl1, jl2;
JComboBox jcb;
JList jl;
JScrollPane jsp;
public FrameDemo3(String name){
super(name);
jp1 = new JPanel();
jp2 = new JPanel();
jp1.setLayout(new FlowLayout());
jp2.setLayout(new FlowLayout());
jl1 = new JLabel("你的籍贯是");
jl2 = new JLabel("你喜欢去旅游的地区");
String[] jg = { "北京", "上海", "武汉", "随州" };
jcb = new JComboBox(jg);
jp1.add(jl1);
jp1.add(jcb);
jl = new JList(jg);
jl.setVisibleRowCount(3);
jsp = new JScrollPane(jl);
jp2.add(jl2);
jp2.add(jsp);
this.setLayout(new GridLayout(2, 1));
this.add(jp1);
this.add(jp2);
this.setLocation(200, 200);
this.setResizable(false);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
}
}
4.8文本框
4.8.1文本框
package com.shuai.lesson6;
import javax.swing.*;
import java.awt.*;
public class TestTextDemo01 extends JFrame {
public TestTextDemo01(){
Container container = this.getContentPane();
//不布局只会出现WORLD,且位置不对
this.setLayout(new FlowLayout(FlowLayout.RIGHT));
JTextField jTextField1 = new JTextField("HELLO");
JTextField jTextField2 = new JTextField("WORLD",20);
container.add(jTextField1);
container.add(jTextField2);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setBounds(100,100,400,300);
}
public static void main(String[] args) {
new TestTextDemo01();
}
}
4.8.2密码框
import javax.swing.*;
import java.awt.*;
public class TestTextDemo02 extends JFrame {
public TestTextDemo02(){
Container container = this.getContentPane();
JPasswordField jPasswordField = new JPasswordField();//---
jPasswordField.setEchoChar('-');
container.add(jPasswordField);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setBounds(100,100,400,300);
}
public static void main(String[] args) {
new TestTextDemo02();
}
}
4.8.3文本域
//文本域
JTextArea jTextArea = new JTextArea(20, 50);
jTextArea.setText("学习学习");
//面板 并添加到contentpane
contentPane.add(new JScrollPane(jTextArea));
当然关于组件还有很多,包括:选择框(JComboBox)、进程条(JProgressBar)、滑动杆(JSlider)、表格(JTable)、树(JTree)等等,这里就不一一去演示了。
五、