JavaGUI编程
Posted woodwhale
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaGUI编程相关的知识,希望对你有一定的参考价值。
GUI编程
前言
任务罢了,好在狂神老师居然有GUI的课,只能说是有救星了。
1、了解GUI
组建:
- 窗口
- 弹窗
- 面板
- 文本框
- 列表框
- 按钮
- 图片
- 监听事件
- 鼠标
- 键盘事件
- (狂神老师提到逆向破解游戏基本使用java来写
2、简介
GUI的核心:
Swing AWT
为什么javaGUI不流行?
- 界面丑
- 需要jre环境
那么为什么要学?
- 自制工具(确实,ctf许多工具都是用javaGUI写成打包的jar
- 极小概率在工作中维护Swing界面(大概我这辈子见不到了吧
- 重点是学习监听事件,可以由此了解MVC架构
3、AWT
3.1 AWT介绍
用于GUI编程,AWT就是抽象窗口工具
(Eclipse和IDEA就是用java Swing写出来的)
- 包含了很多类和接口
- 包含了很多元素:窗口、按钮、文本框
- 在java.awt包中
3.2 组件和容器
1、Frame
我们现来看看第一个frame
package top.woodwhale.study;
import java.awt.*;
// GUI的第一个界面
public class TestFrame {
public static void main(String[] args) {
// Frame
Frame frame = new Frame("First Java Window");
// 需要设置可见性,长度、宽度
frame.setVisible(true);
frame.setSize(400,400);
// 设置背景颜色 Color
frame.setBackground(new Color(22, 87, 220));
// 弹出的初始位置
frame.setLocation(200,200);
// 设置大小固定
frame.setResizable(false);
}
}
效果就是一个蓝色的、不可拉伸、不可关闭的窗口
思考:
- 为什么无法关闭?
- 如何让窗口关闭?只能靠关闭程序吗?
如果我们需要同时开启多个窗口,有没有什么好的方法呢?
- 可以写一个自类,继承自Frame,然后实现我们需要的功能
package top.woodwhale.study;
import java.awt.*;
public class TestFrame2 {
public static void main(String[] args) {
// 展示多个窗口
MyFrame mf1 = new MyFrame(100,100,200,200,Color.black);
MyFrame mf2 = new MyFrame(300,100,200,200,Color.orange);
MyFrame mf3 = new MyFrame(100,300,200,200,Color.green);
MyFrame mf4 = new MyFrame(300,300,200,200,Color.pink);
}
}
class MyFrame extends Frame{
static int id = 0; // 可能存在多个窗口,需要一个计数器
public MyFrame(int x,int y,int w,int h,Color color) {
super("Myframe"+ (++id));
setBackground(color);
setBounds(x,y,w,h);
setVisible(true);
}
}
效果如下:(有点好看
2、Panel
面板Panel可以看成是一个空间,但是不能单独存在,可以存在与一个框架中。类似于前段的div(大概
以下的例子通过适配器模式来监听窗口关闭事件
package top.woodwhale.study;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestPanel {
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(40,161,35));
// 面板设置坐标,相对于frame
panel.setBounds(50,50,400,400);
panel.setBackground(new Color(190,15,60));
// frame.add()
frame.add(panel);
// 将面板设置为可见
frame.setVisible(true);
// 监听窗口关闭事件
// 适配器模式:
frame.addWindowListener(new WindowAdapter() {
// 窗口点击关闭的时候需要做的事情
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
效果如下:(我们点击关闭按钮可以结束进程,也就是退出
3、布局管理
-
流式布局
这个按钮的年代感直接出来了,有种wine打开exe的味道了
package top.woodwhale.study; import java.awt.*; public class TestFlowLayout { public static void main(String[] args) { Frame frame = new Frame("114514"); // 组件-按钮 Button button1 = new Button("button1"); Button button2 = new Button("button2"); Button button3 = new Button("button3"); // 设置为流式布局 默认是居中 frame.setLayout(new FlowLayout()); // frame.setLayout(new FlowLayout(FlowLayout.RIGHT)); frame.setSize(200,200); // 把按钮添加上去 frame.add(button1); frame.add(button2); frame.add(button3); frame.setVisible(true); } }
-
东西南北中
狂神老师说这是视频软件的布局,为什么我第一反应是,上下左右都是广告,中间是小视频(bushi
package top.woodwhale.study; import java.awt.*; public class TestBorderLayout { public static void main(String[] args) { Frame frame = new Frame("114514"); 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.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.setSize(300,300); frame.setVisible(true); } }
-
表格布局
就是类似表格的形式,这里使用了pack()方法来使大小、内容自动填充
package top.woodwhale.study; import java.awt.*; public class TestGridLayout { public static void main(String[] args) { Frame frame = new Frame("114514"); Button bt1 = new Button("bt1"); Button bt2 = new Button("bt2"); Button bt3 = new Button("bt3"); Button bt4 = new Button("bt4"); Button bt5 = new Button("bt5"); Button bt6 = new Button("bt6"); frame.setLayout(new GridLayout(3,2)); frame.add(bt1); frame.add(bt2); frame.add(bt3); frame.add(bt4); frame.add(bt5); frame.add(bt6); frame.pack(); // java方法,用来自动填充 frame.setVisible(true); } }
4、狂神老师的作业time
如何完成下图的格式布局?
直接动手
动手之前先进行构思,一个好的项目,构思占据80%,代码只有20%!!!
我们现构建一个两行一列的frame,然后在中间部分上下各设置一个面板,frame的上半部分和下半部分都使用东西南北中的布局管理,再在两个面板中设置东西南北中格式,其中上面的嵌套一个两行一列的面板,下面的嵌套一个两行两列的面板
最终效果:
代码:
package top.woodwhale.study;
import java.awt.*;
import java.awt.image.ImageObserver;
public class MyLayout {
public static void main(String[] args) {
Frame frame = new Frame("114514");
frame.setSize(400,300);
frame.setLocation(300,300);
frame.setBackground(Color.orange);
frame.setVisible(true);
// 两行一列
frame.setLayout(new GridLayout(2,1));
// 4个面板
Panel panel1 = new Panel(new BorderLayout());
Panel panel2 = new Panel(new GridLayout(2,1));
Panel panel3 = new Panel(new BorderLayout());
Panel panel4 = new Panel(new GridLayout(2,2));
panel1.add(new Button("East-1"),BorderLayout.EAST);
panel1.add(new Button("West-1"),BorderLayout.WEST);
panel2.add(new Button("p2-btn-1"));
panel2.add(new Button("p2-btn-2"));
panel1.add(panel2,BorderLayout.CENTER);
panel3.add(new Button("East-2"),BorderLayout.EAST);
panel3.add(new Button("West-2"),BorderLayout.WEST);
for (int i = 0; i < 4; i++) {
panel4.add(new Button("for-"+i));
}
panel3.add(panel4,BorderLayout.CENTER);
frame.add(panel1);
frame.add(panel3);
}
}
5、总结
- Frame是一个顶级窗口
- Panel无法单独显示,得放入Frame(容器)中
- 布局管理:
- 流式
- 东西南北中
- 表格
- 设置大小、定位、背景、监听
- 设计模式不要直接写,先去构想!
3.3 监听事件
1、监听测试
监听就是,当发生某事件后,我们监听到了这个动态,应该有某种反馈
先来点效果图:
可以观察到,我们第一次这个巨大按钮,就会在控制台输出一次114514,这是为啥呢?
package top.woodwhale.study2;
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 = new Frame();
// 按下按钮的时候,触发一些事件
Button button = new Button("点我控制台输出114514");
// 因为addActionListener需要一个ActionListener,所以我们字节写一个MyActionListener类
MyActionListener myActionListener = new MyActionListener();
button.addActionListener(myActionListener);
frame.add(button);
frame.setSize(300,300);
frame.setVisible(true);
windowClose(frame);
}
// 关闭窗口事件
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 actionEvent) {
System.out.println("114514");
}
}
其实是因为,我们设置了一个按钮的监听器,我们自己写了一个MyActionListener类,是ActionListener的一个接口,我们重写的方法就是只要有这个事件产生,就输出114514。
而我们在button中使用了addActionListener方法,将我们重写的监听器赋予给了这个按钮,所以我们按下这个按钮的时候就能在控制台看到输出的114514。
并且,我们通过在主类中写了一个windowClose的static方法,这样,我们通过方法的封装直接实现了点击关闭按钮关闭窗口的监听事件。
2、单监听器监听多个事件
如果我们想实现多个按钮同时监听一个事件呢?我们可以只写一个监听类,通过更改setActionCommand达到不同的监听效果。
如下图所示,我们点击start按钮可以在控制台输出“开始”
如果我们点击Stop按钮,会输出“哼哼”
这种效果其实就是一个监听器监听了多个事件
package top.woodwhale.study2;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestActionEvent2 {
public static void main(String[] args) {
// 两个按钮,实现同一个监听
// 开始按钮和停止按钮
Frame frame = new Frame("Start ~ Stop");
Button button = new Button("Start");
Button button1 = new Button("Stop");
// 可以显示的定义触发会返回的命令,如果不显示定义,则会走默认的值
// 这样我们可以多个按钮,但是只需要一个监听类,只需要更改setActionCommand
button1.setActionCommand("Stop");
MyMonitor myMonitor = new MyMonitor();
button.addActionListener(myMonitor);
button1.addActionListener(myMonitor);
frame.add(button,BorderLayout.NORTH);
frame.add(button1,BorderLayout.SOUTH);
frame.setSize(300,300);
frame.以上是关于JavaGUI编程的主要内容,如果未能解决你的问题,请参考以下文章