GUI
1 简介
图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面。
Gui的核心技术: Swing AWT
- 因为界面不美观
- 需要jre环境
为什么我们要学习?
- 可以写出自己心中想要的小工具
- 工作时候,也可能需要维护到swing界面,概率极小!
- 了解MVC架构,了解监听!
2 AWT
2.1 AWT介绍
- AWT:抽象的窗口工具,包含了很多的类和接口
- 元素:窗口、按钮、文本框
- java.awt包下
![]()
2.2 组件和容器
frame
public class TestFrame {
public static void main(String[] args) {
Frame frame = new Frame("第一个frame窗口");
// 设置可见性
frame.setVisible(true);
// 设置frame大小
frame.setSize(500,500);
// 设置frame出现位置
frame.setLocation(200,200);
// 设置frame背景颜色
frame.setBackground(new Color(2,52,65));
// 设置是否可以改变大小(false不可改变)
frame.setResizable(false);
}
}
-
封装实现打开多个frame
public class TestFrame02 { public static void main(String[] args) { MyFrame myFrame1 = new MyFrame(200, 200, 200, 200, Color.red); MyFrame myFrame2 = new MyFrame(400, 200, 200, 200, Color.green); MyFrame myFrame3 = new MyFrame(200, 400, 200, 200, Color.yellow); MyFrame myFrame4 = new MyFrame(400, 400, 200, 200, Color.green); } } 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); } }Panel
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("带面板的Frame"); Panel panel = new Panel(); frame.setBounds(400,400,500,500); frame.setBackground(Color.BLACK); frame.setLayout(null); panel.setBounds(100,100,300,300); panel.setBackground(Color.YELLOW); // 将面板放入frame中 frame.add(panel); frame.setVisible(true); // 添加监听(实现在frame上关闭这个窗口) frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } }![]()
2.3 布局管理器
1.流式布局 FlowLayout(从左至右)
import java.awt.*;
//流式布局
public class TestFlowLayout {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(400,400,500,500);
Button button1 = new Button("按钮1");
Button button2 = new Button("按钮2");
Button button3 = new Button("按钮3");
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.setLayout(new FlowLayout(FlowLayout.RIGHT));
}
}
2.东西南北中 BorderLayout
package com.jiu.demo01;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestBorderLayout {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(400,400,500,500);
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.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
3.表格式布局 GridLayout
package com.jiu.demo01;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestGridLayout {
public static void main(String[] args) {
Frame frame = new Frame("表格布局");
frame.setVisible(true);
// frame.setBounds(400,400,500,500);
Button button1 = new Button("but1");
Button button2 = new Button("but2");
Button button3 = new Button("but3");
Button button4 = new Button("but4");
Button button5 = new Button("but5");
Button button6 = new Button("but6");
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
frame.add(button5);
frame.add(button6);
frame.setLayout(new GridLayout(3,2));
// 自动布局大小,测试过程中发现不能在第一行写这个,需要在添加完毕后增加会分配默认size
frame.pack();
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
练习
package com.jiu.demo01;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 分析:分四部分写
*/
public class ExDemo {
public static void main(String[] args) {
//总frame
Frame frame = new Frame();
frame.setLocation(400, 400);
frame.setSize(300, 300);
frame.setBackground(Color.blue);
frame.setVisible(true);
frame.setLayout(new GridLayout(2, 1));
//四个面板
Panel p1 = new Panel(new BorderLayout());
Panel p2 = new Panel(new GridLayout(2, 1));
Panel p3 = new Panel(new BorderLayout());
Panel p4 = new Panel(new GridLayout(2, 2));
//上面
p1.add(new Button("Eset-1"), BorderLayout.EAST);
p1.add(new Button("West"), BorderLayout.WEST);
p2.add(new Button("p2-btn-1"));
p2.add(new Button("p2-btn-2"));
p1.add(p2, BorderLayout.CENTER);
//下面
p3.add(new Button("Eset-1"), BorderLayout.EAST);
p3.add(new Button("West"), BorderLayout.WEST);
for (int i = 0; i < 4; i++) {
p4.add(new Button("btn-" + i));
}
p3.add(p4, BorderLayout.CENTER);
frame.add(p1);
frame.add(p3);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
效果:

4.监听器
// 添加监听
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
2.4 监听器
一个按钮添加多个监听
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestActionEvent1 {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(100,100,500,500);
// 一个按钮可以同时添加多个监听
Button button = new Button();
button.addActionListener((actionEvent) -> System.out.println("1"));
button.addActionListener((actionEvent) -> System.out.println("2"));
frame.add(button,BorderLayout.NORTH);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
一个监听可以给多个按钮共同使用
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 TestActionEvent2 {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(100,100,500,500);
// 顶一个一个监听可以多个按钮共同使用
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
}
};
Button button1 = new Button("1");
// 可以为按钮带参数来控制同一个监听执行不同按钮的方法
button1.setActionCommand("11111111111111");
button1.addActionListener(actionListener);
Button button2 = new Button("2");
button2.addActionListener(actionListener);
frame.add(button1,BorderLayout.NORTH);
frame.add(button2,BorderLayout.SOUTH);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
总结
frame是一个顶级容器
- panel面板不能单独存在,需要放到容器中使用
- 布局管理器
- 流式布局
- 东西南北中
- 表格布局
- 监听器
2.5 输入框监听
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 TestActionEvent3 {
public static void main(String[] args) {
new MyFrame();
}
}
class MyFrame extends Frame{
public MyFrame(){
TextField textArea = new TextField();
textArea.addActionListener((event)-> {
System.out.println(textArea.getText());
textArea.setText("");
});
this.setVisible(true);
this.setBounds(100,100,500,500);
add(textArea);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
2.6 简易计算器
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestCalc {
public static void main(String[] args) {
Calc calc = new Calc();
}
}
class Calc extends Frame{
public Calc(){
TextField jia1 = new TextField("10");
TextField jia2 = new TextField("10");
TextField rest = new TextField("20");
setLayout(new FlowLayout());
add(jia1);
add(new Label("+"));
add(jia2);
Button button = new Button("=");
button.addActionListener(e -> {
int jia = Integer.parseInt(jia1.getText());
int beijia = Integer.parseInt(jia2.getText());
rest.setText(jia+beijia+"");
jia1.setText("");
jia2.setText("");
});
add(button);
add(rest);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setVisible(true);
pack();
}
}
2.7 画笔
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestPaint {
public static void main(String[] args) {
new MyPaint().loadMyPaint();
}
}
class MyPaint extends Frame{
public void loadMyPaint(){
setVisible(true);
setBounds(100,100,800,600);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
@Override
public void paint(Graphics g) {
// super.paint(g);
g.setColor(Color.blue);
g.drawOval(100,100,100,100);
g.fillOval(100,200,100,100);
g.fillRect(100,300,200,100);
}
}
2.8 鼠标监听
思路:

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
//测试鼠标监听
public class TestMouseListenter {
public static void main(String[] args) {
new Paint("画图").loadMyPaint();
}
}
class Paint extends Frame {
private List<Point> pointList;
private Paint cuttorPaint;
public Paint(String title){
super(title);
cuttorPaint = this;
pointList = new ArrayList<>();
}
public void loadMyPaint(){
setVisible(true);
setBounds(100,100,800,600);
addMouseListener(new MyMouseListenter());
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
@Override
public void paint(Graphics g) {
Iterator<Point> iterator = pointList.iterator();
while (iterator.hasNext()){
Point point = iterator.next();
//循环画列表的点坐标
g.fillOval(point.x,point.y,10,10);
}
}
private class MyMouseListenter extends MouseAdapter{
// 按下鼠标时触发
@Override
public void mousePressed(MouseEvent e) {
pointList.add(new Point(e.getX(),e.getY()));
//画笔重新画点
cuttorPaint.repaint();
}
}
}
2.9 窗口监听
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestWindow {
public static void main(String[] args) {
new MyWindow().loadMyPaint();
}
}
class MyWindow extends Frame{
public MyWindow(){
super("默认窗口名称");
}
public void loadMyPaint(){
setVisible(true);
setBounds(100,100,800,600);
addWindowListener(new WindowAdapter() {
// 点击窗口关闭按钮
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
@Override
public void windowDeactivated(WindowEvent e) {
System.out.println("窗口失去焦点");
}
// 打开窗口时执行
@Override
public void windowOpened(WindowEvent e) {
System.out.println("windowOpened");
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println("windowClosed");
}
@Override
public void windowIconified(WindowEvent e) {
System.out.println("缩小");
}
@Override
public void windowDeiconified(WindowEvent e) {
System.out.println("缩小对应的弹出窗口");
}
@Override
public void windowActivated(WindowEvent e) {
setTitle("被激活了窗口");
}
@Override
public void windowStateChanged(WindowEvent e) {
System.out.println("windowStateChanged");
}
@Override
public void windowGainedFocus(WindowEvent e) {
System.out.println("windowGainedFocus");
}
@Override
public void windowLostFocus(WindowEvent e) {
System.out.println("windowLostFocus");
}
});
}
}
2.10 键盘监听
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestKeyListener {
public static void main(String[] args) {
new MyKeyFrame().loadMyPaint();
}
}
class MyKeyFrame extends Frame{
public MyKeyFrame(){
super("默认窗口名称");
}
public void loadMyPaint(){
setVisible(true);
setBounds(100,100,800,600);
addKeyListener(new KeyAdapter() {
// 按下键时执行
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
System.out.println(keyCode);
if(keyCode == KeyEvent.VK_ENTER){
System.out.println("按了回车");
}
}
});
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
3. Swing
3.1 JFrame
import javax.swing.*;
import java.awt.Container;
import static java.awt.Color.YELLOW;
public class TestJFrame1 {
public static void main(String[] args) {
JFrame jFrame = new JFrame();
jFrame.setBounds(10,10,400,400);
jFrame.setVisible(true);
JLabel jLabel = new JLabel("测试标签");
// jFrame.setBackground(Color.BLACK);
Container contentPane = jFrame.getContentPane();
contentPane.setBackground(YELLOW);
//标签居中
jLabel.setHorizontalAlignment(SwingConstants.CENTER);
jFrame.add(jLabel);
// 不设置,默认是隐藏窗口
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
3.2 Dialog
public class DialogDemo extends JFrame {
public DialogDemo(){
this.setVisible(true);
this.setBounds(100,100,500,500);
this.setDefaultCloseOperation(3); //默认关闭的方法
// this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// JFrame 容器 放东西
Container contentPane = this.getContentPane();
// 绝对布局
contentPane.setLayout(null);
contentPane.setBackground(Color.green);
// 按钮
JButton jButton = new JButton("这是一个弹出dialog的按钮");
// jButton.setVisible(true);
jButton.setBounds(100,100,300,100);
contentPane.add(jButton);
// 点击按钮弹出一个窗口
jButton.addActionListener(new ActionListener() {//监听器
@Override
public void actionPerformed(ActionEvent e) {
new MyDialogDemo();//创建一个弹窗dialog
}
});
}
public static void main(String[] args) {
new DialogDemo();
}
}
class MyDialogDemo extends JDialog{
public MyDialogDemo() {
this.setVisible(true);
this.setBounds(500,500,500,500);
Container contentPane = this.getContentPane();
contentPane.setLayout(null);
Label label = new Label("aaaaaaaaaaaaaaa");
label.setSize(50,50);
contentPane.add(label);
JButton jButton = new JButton("这是一个弹窗里边的按钮");
jButton.setBounds(100,100,300,100);
contentPane.add(jButton);
}
}
3.3 标签
label
new JLabel("xxx");
图标 Icon
public class IconDemo extends JFrame implements Icon {
private int height;
private int width;
// 无参构造
public IconDemo() {
}
// 有参构造
public IconDemo(int height, int width){
this.height = height;
this.width = width;
}
public void init(){
IconDemo iconDemo = new IconDemo(30, 30);
// 突变放在标签上
JLabel jLabel = new JLabel("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,height);
}
// 获取宽
@Override
public int getIconWidth() {
return this.width;
}
//获取高
@Override
public int getIconHeight() {
return this.height;
}
public static void main(String[] args) {
new IconDemo().init();
}
}
图片 Icon
URL url = ImageDemoIcon.class.getResource("1.jpg");这个方法时要保证图片被编写在class文件中,及out文件夹下包含有此图片,否则URL返回为null
public class ImageDemoIcon extends JFrame {
public ImageDemoIcon(){
JLabel label = new JLabel("一个带图片的label");
// 获取图片地址
URL url = ImageDemoIcon.class.getResource("1.jpg");
System.out.println(url);
ImageIcon imageIcon = new ImageIcon(url);
// ImageIcon imageIcon = new ImageIcon("G:\\IDEA\\21.12.28\\GUI\\src\\com\\jiu\\demo04\\2.jpg");
label.setIcon(imageIcon);
label.setHorizontalAlignment(SwingConstants.CENTER);
Container contentPane = getContentPane();
contentPane.add(label);
// 对JFrame设置可见性、大小、实现关闭的方法
setVisible(true);
setBounds(200,200,200,200);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new ImageDemoIcon();
}
}
3.4 JPanel
public class JPanelDemo extends JFrame {
public JPanelDemo(){
Container contentPane = getContentPane();
// 两行两列 间距为10
contentPane.setLayout(new GridLayout(2,2,20,20));
JPanel jPanel1 = new JPanel(new GridLayout(1, 3,10,10));
JPanel jPanel2 = new JPanel(new GridLayout(3, 1));
JPanel jPanel3 = new JPanel(new GridLayout(2, 2,10,10));
JPanel jPanel4 = new JPanel(new GridLayout(2, 1));
contentPane.add(jPanel1);
contentPane.add(jPanel2);
contentPane.add(jPanel3);
contentPane.add(jPanel4);
jPanel1.add(new Button("button1"));
jPanel1.add(new Button("button2"));
jPanel1.add(new Button("button3"));
jPanel2.add(new Button("button4"));
jPanel2.add(new Button("button5"));
jPanel2.add(new Button("button6"));
jPanel3.add(new Button("button7"));
jPanel3.add(new Button("button8"));
jPanel3.add(new Button("button9"));
jPanel3.add(new Button("button10"));
jPanel4.add(new Button("button11"));
jPanel4.add(new Button("button12"));
setBounds(500,500,500,500);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JPanelDemo();
}
}
3.5 JScrollPanel
public class JScrollDemo extends JFrame {
public JScrollDemo() {
Container contentPane = getContentPane();
TextArea textArea = new TextArea(20, 50);
textArea.setText("文本区域的默认内容");
JScrollPane scrollPane = new JScrollPane(textArea);
contentPane.add(scrollPane);
setBounds(500,500,500,500);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JScrollDemo();
}
}
3.6 按钮
图片JButton
public class JButtonIconDemo extends JFrame {
public JButtonIconDemo() {
JButton jButton = new JButton("这是一个带图片以及提示的按钮");
jButton.setToolTipText("这就是一个图片按钮啊");
URL resource = JButtonIconDemo.class.getResource("2.jpg");
System.out.println(resource);
Icon icon = new ImageIcon(resource);
jButton.setIcon(icon);
jButton.setBounds(100,100,200,100);
Container contentPane = getContentPane();
contentPane.add(jButton);
setLayout(null);
setSize(500,500);
contentPane.setBackground(Color.green);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JButtonIconDemo();
}
}
单选框
public class RadioDemo extends JFrame {
public RadioDemo() {
// 单选框
JRadioButton jRadioButton1 = new JRadioButton("jRadioButton1");
JRadioButton jRadioButton2 = new JRadioButton("jRadioButton1");
JRadioButton jRadioButton3 = new JRadioButton("jRadioButton1");
JRadioButton jRadioButton4 = new JRadioButton("jRadioButton1");
// 单选框放入一个组中才能保证是单选的
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(jRadioButton1);
buttonGroup.add(jRadioButton2);
buttonGroup.add(jRadioButton3);
buttonGroup.add(jRadioButton4);
Container contentPane = getContentPane();
contentPane.add(jRadioButton1,BorderLayout.CENTER);
contentPane.add(jRadioButton2,BorderLayout.NORTH);
contentPane.add(jRadioButton3,BorderLayout.SOUTH);
contentPane.add(jRadioButton4,BorderLayout.WEST);
setVisible(true);
setBounds(500,500,500,500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new RadioDemo();
}
}
复选框
public class CheckboxDemo extends JFrame {
public CheckboxDemo() {
JCheckBox checkbox1 = new JCheckBox("checkbox1");
JCheckBox checkbox2 = new JCheckBox("checkbox2");
Container contentPane = getContentPane();
contentPane.add(checkbox1,BorderLayout.NORTH);
contentPane.add(checkbox2,BorderLayout.WEST);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setBounds(500,500,500,500);
setVisible(true);
}
public static void main(String[] args) {
new CheckboxDemo();
}
}
3.7文本框
文本框
public class TestTextDemo01 extends JFrame {
public TestTextDemo01(){
Container container = this.getContentPane();
JTextField textField = new JTextField("hello");
JTextField textField2 = new JTextField("world",20);
container.add(textField,BorderLayout.NORTH);
container.add(textField2,BorderLayout.SOUTH);
this.setVisible(true);
this.setSize(500,350);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestTextDemo01();
}
}
密码框
public class TestTextDemo02 extends JFrame {
public TestTextDemo02(){
Container container = this.getContentPane();
// 面板
JPasswordField passwordField = new JPasswordField(); // ****
passwordField.setEchoChar('*');
container.add(passwordField);
this.setVisible(true);
this.setSize(500,350);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestTextDemo02();
}
}
文本域
public class TestTextDemo03 extends JFrame {
public TestTextDemo03(){
Container container = this.getContentPane();
//文本域
JTextArea textArea = new JTextArea(20,50);
textArea.setText("阿巴阿巴阿巴");
//Scroll面板
JScrollPane scrollPane = new JScrollPane(textArea);
container.add(scrollPane);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setVisible(true);
this.setSize(400,350);
}
public static void main(String[] args) {
new TestTextDemo03();
}
}
4 贪吃蛇
/**
* 数据中心
*/
class Data {
public static URL headerUrl = Data.class.getResource("static/header.png");
public static URL upUrl = Data.class.getResource("static/up.png");
public static URL downUrl = Data.class.getResource("static/down.png");
public static URL leftUrl = Data.class.getResource("static/left.png");
public static URL rightUrl = Data.class.getResource("static/right.png");
public static URL bodyUrl = Data.class.getResource("static/body.png");
public static URL foodUrl = Data.class.getResource("static/food.png");
public static ImageIcon header = new ImageIcon(headerUrl);
// public static ImageIcon header = new ImageIcon("G:\\IDEA\\21.12.28\\GUI\\src\\com\\jiu\\snake\\static\\header.png");
public static ImageIcon up = new ImageIcon(upUrl);
public static ImageIcon down = new ImageIcon(downUrl);
public static ImageIcon left = new ImageIcon(leftUrl);
public static ImageIcon right = new ImageIcon(rightUrl);
public static ImageIcon body = new ImageIcon(bodyUrl);
public static ImageIcon food = new ImageIcon(foodUrl);
}
/**
* 逻辑与界面编写类
*/
public class GamePanel extends JPanel implements KeyListener, ActionListener {
// 定义蛇的数据结构
int length = 0;//蛇的长度
int []snakeX = new int[500];//蛇的X坐标
int []snakeY = new int[600];//蛇的Y坐标
String direction;//蛇头的方向
boolean state = false;//游戏状态 是否开始 默认不开始的
Timer timer = new Timer(100,this);
int foodX;//事务的X坐标
int foodY;//食物的Y坐标
Random random = new Random();//生成随机数 让事务随机产生
boolean isFiled;//判断游戏是否结束标志
int score;//定义分数
//构造器
public GamePanel() {
init();
// 获得焦点和键盘事件
this.setFocusable(true);//获得焦点事件
this.addKeyListener(this);//获得键盘监听事件
}
//初始化方法
public void init(){
length = 10;
// length = 400;
snakeX[0] = 100;snakeY[0] = 100;//小蛇头坐标
snakeX[1] = 75;snakeY[1] = 100;//小蛇第一个身体坐标
snakeX[2] = 50;snakeY[2] = 100;//小蛇第二个社体做标
direction = "right";
// 随机产生食物位置
foodX = 25+random.nextInt(34)*25;
foodY = 25+random.nextInt(24)*25;
System.out.println(foodX+foodY);
isFiled = false;
timer.start();//初始化启动定时器
}
//绘制面板 游戏中的所有东西都是通过画笔去画上去的
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //清屏
this.setBackground(Color.white);
Data.header.paintIcon(this,g,25,11);//头部广告栏
g.fillRect(25,75,850,600);//默认的游戏界面
// 画食物
Data.food.paintIcon(this,g,foodX,foodY);
// 把小蛇画上去
if(("right").equals(direction)){
Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);//小蛇头坐标 需要判断蛇头的方向
}else if(("left").equals(direction)){
Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);//小蛇头坐标 需要判断蛇头的方向
}else if(("up").equals(direction)){
Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);//小蛇头坐标 需要判断蛇头的方向
}else if(("down").equals(direction)){
Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);//小蛇头坐标 需要判断蛇头的方向
}
//循环画上去小蛇的身体
for (int i = 1; i < length; i++) {
Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);
}
// 画分数与长度
g.setColor(Color.white);
g.setFont(new Font("楷体",Font.BOLD,18));
g.drawString("长度:"+length,750,33);
g.drawString("分数:"+score,750,50);
// 判断游戏状态
if(state == false){//游戏未开始
g.setColor(Color.white);//设置字体颜色
g.setFont(new Font("楷体",Font.BOLD,40));//设置字体样式
g.drawString("按下空格开始游戏!",300,300);//画字
}
if(isFiled){//游戏失败
g.setColor(Color.red);//设置字体颜色
g.setFont(new Font("楷体",Font.BOLD,40));//设置字体样式
g.drawString("游戏失败,按下空格重新开始游戏!",120,300);//画字
}
}
//键盘监听事件
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();//获取按下的键盘键
// System.out.println(keyCode);
if(keyCode == KeyEvent.VK_SPACE){//如果按下的是空格键
if(isFiled){//true 游戏结束
isFiled = false;
init();
}else {//游戏没有结束
state = !state;
}
repaint();
}
// 监控小蛇头的移动
if(keyCode == KeyEvent.VK_UP){
direction = "up";
}else if(keyCode == KeyEvent.VK_DOWN){
direction = "down";
}else if(keyCode == KeyEvent.VK_LEFT){
direction = "left";
}else if(keyCode == KeyEvent.VK_RIGHT){
direction = "right";
}
}
//事件监听
@Override
public void actionPerformed(ActionEvent e) {
if(state && isFiled == false){//如果游戏是开始的就让小蛇动起来
// 吃食物
if(snakeX[0] == foodX && snakeY[0] ==foodY){//判断 吃到食物
length++;//长度加一
score += 10;//分数计算
// 重新画食物 生成新的食物坐标
foodX = 25 + random.nextInt(34)*25;
foodY = 25 + random.nextInt(24)*25;
}
//右移 只需要让后边的点移动到前一个点就行
for (int i = length-1; i > 0 ; i--) {
snakeX[i] = snakeX[i-1];
snakeY[i] = snakeY[i-1];
}
// 判断蛇头走向
if(("up").equals(direction)){
snakeY[0] -= 25;//头右移X不变
//判断边界 不能让蛇跑出去了
if(snakeY[0] < 75){ snakeY[0] = 600; }
}else if(("down").equals(direction)){
snakeY[0] += 25;//头右移X不变
//判断边界 不能让蛇跑出去了
if(snakeY[0] > 600){ snakeY[0] = 75; }
}else if(("left").equals(direction)){
snakeX[0] -= 25;
if(snakeX[0] < 0){ snakeX[0] = 850; }
}else if(("right").equals(direction)){
snakeX[0] += 25;//头右移Y不变
//判断边界 不能让蛇跑出去了
if(snakeX[0] > 850){ snakeX[0] = 25; }
}
// 失败判断 自己撞到自己
for (int i = 1; i < length; i++) {
if(snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]){
isFiled = true;
}
}
repaint();//重画页面
}
// timer.start();
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
/**
* 启动类
*/
public class StartGame {
public static void main(String[] args) {
JFrame jFrame = new JFrame();
jFrame.add(new GamePanel());
jFrame.setBounds(10,10,900,720);
jFrame.setResizable(false); //窗口大小不可变
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jFrame.setVisible(true);
}
}


浙公网安备 33010602011771号