个人笔记GUI
GUI
Gui的核心技术:Swing AWT 1.因为界面不美观。 2.需要 jre 环境! 为什么我们要学习? 1.可以写出自己心中想要的一些小工具2.工作时候,也可能需要维护到swing界面,概率极小!3.了解MVC架构,了解监听!
AWT
Frame
import java.awt.*; public static void main(String[] args) {//new Frame();//Frame, JDK, 看源码!Frame frame = new Frame("我的第一个Java图像界面窗口"); //需要设置可见性 w hframe.setVisible(true); //设置窗口大小frame.setSize(400,400); //设置背景颜色 colorframe.setBackground(new Color(85, 150, 68)); //弹出的初始位置frame.setLocation(200,200); //设置大小固定frame.setResizable(true);}
import java.awt.*; public static void main(String[] args) {//展示多个窗口MyFrame myFrame1 = new MyFrame(100, 100, 200, 200, Color.blue);MyFrame myFrame2 = new MyFrame(300, 100, 200, 200, Color.yellow);MyFrame myFrame3 = new MyFrame(100, 300, 200, 200, Color.red);MyFrame myFrame4 = new MyFrame(300, 300, 200, 200, Color.MAGENTA);} } 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); // 使用Frame类的setBackground方法setBounds(x, y, w, h);setVisible(true);}
Panel
Panel 可以看成是一个空间,但是不能单独存在
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)); //panel设置坐标,相对于framepanel.setBounds(50, 50, 400, 400);panel.setBackground(new Color(193, 15, 60)); //frame.add(panel)frame.add(panel); frame.setVisible(true); //监听事件,监听窗口关闭事件 System.exit(0) //适配器模式:frame.addWindowListener(new WindowAdapter() {//窗口点击关闭的时候需要做的事情@Overridepublic void windowClosing(WindowEvent e) {//结束程序System.exit(0);}}); }
布局管理器
流式布局
import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public static void main(String[] args) {Frame frame = new Frame(); //组件-按钮Button button1 = new Button("button1");Button button2 = new Button("button2");Button button3 = new Button("button3"); //设置为流式布局//frame.setLayout(new FlowLayout());//布局默认居中//frame.setLayout(new FlowLayout(FlowLayout.LEFT));//布局靠左frame.setLayout(new FlowLayout(FlowLayout.RIGHT)); frame.setSize(200, 200); //把按钮添加上去frame.add(button1);frame.add(button2);frame.add(button3); frame.setVisible(true); frame.addWindowListener(new WindowAdapter() {//窗口点击关闭的时候需要做的事情@Overridepublic void windowClosing(WindowEvent e) {//结束程序System.exit(0);}});}
东西南北中
import java.awt.*; public static void main(String[] args) {Frame frame = new Frame("TestBorderLayout");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(200, 200);frame.setVisible(true);}
表格布局
import java.awt.*; public static void main(String[] args) {Frame frame = new Frame("TestGridLayout");Button btn1 = new Button("btn1");Button btn2 = new Button("btn2");Button btn3 = new Button("btn3");Button btn4 = new Button("btn4");Button btn5 = new Button("btn5");Button btn6 = new Button("btn6"); frame.setLayout(new GridLayout(3, 2)); frame.add(btn1);frame.add(btn2);frame.add(btn3);frame.add(btn4);frame.add(btn5);frame.add(btn6); frame.pack();frame.setVisible(true);}
实例
import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public static void main(String[] args) { // GridLayout gridLyaout = new GridLayout();Frame frame = new Frame();frame.setSize(400,400);//大小frame.setLocation(500,500);//初始位置frame.setBackground(new Color(50,80,90));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)); Button btn1E = new Button("but-1-E");btn1E.setBackground(Color.RED);// 设置背景色为红色btn1E.setForeground(Color.WHITE);// 设置文字颜色为白色p1.add(btn1E,BorderLayout.EAST);//p1.add(new Button("but-1-E"),BorderLayout.EAST);p1.add(new Button("but-2-W"),BorderLayout.WEST);p2.add(new Button("but-1-N"));p2.add(new Button("but-2-S"));p1.add(p2,BorderLayout.CENTER); p3.add(new Button("but-1-E"),BorderLayout.EAST);p3.add(new Button("but-2-W"),BorderLayout.WEST);for (int i = 0; i < 4; i++) {p4.add(new Button("but"+"-"+(i+1)+"-"+(i+1)));}p3.add(p4,BorderLayout.CENTER); frame.add(p1);frame.add(p3); frame.addWindowListener(new WindowAdapter() {//窗口点击关闭的时候需要做的事情@Overridepublic 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 static void main(String[] args) {//按下按钮,触发一些事件Frame frame = new Frame("66666"); frame.setSize(400,400);frame.setLocation(200,200);//frame.pack();//会和上面的冲突 Button button = new Button();//因为,addActionListener()需要一个 ActionListener,所以我们需要构造一个 ActionListenerMyActionListener myActionListener = new MyActionListener();button.addActionListener(myActionListener);button.setBackground(Color.red); frame.add(button, BorderLayout.CENTER); windowClose(frame);frame.setVisible(true);}//关闭窗体的事件private static void windowClose(Frame frame){frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}static class MyActionListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("aaa");}}
多个按钮共享一个事件
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public static void main(String[] args) {// 两个按钮,实现同一个监听// 开始 停止Frame frame = new Frame("开始-停止");Button button1 = new Button("start");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.SOUTH);frame.pack();frame.setVisible(true);}static class MyMonitor implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("按钮被点击了:msg"+e.getActionCommand());}}
输入框
输入框事件监听
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public static void main(String[] args) {new MyFrame();}static 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();}}static class MyActionListener2 implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {TextField field = (TextField) e.getSource(); // 获得一些资源,返回的一个对象System.out.println(field.getText()); // 获得输入框的文本field.setText(""); // null ""}}
简易计算器
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public static void main(String[] args) {new Frame();new Calculator();}static class Calculator extends Frame{public Calculator(){//构造器TextField num1 = new TextField(10);TextField num2 = new TextField(10);TextField num3 = new TextField(20);Button button = new Button("=");button.addActionListener(new MyCalculatorListener(num1,num2,num3));Label label = new Label("+");setLayout(new FlowLayout());add(num1);add(label);add(num2);add(button);add(num3);pack();setVisible(true);}}static class MyCalculatorListener implements ActionListener{private TextField num1,num2,num3;public MyCalculatorListener(TextField num1,TextField num2,TextField num3){this.num1= num1;this.num2= num2;this.num3= num3;}@Overridepublic void actionPerformed(ActionEvent e) {int n1 = Integer.parseInt(num1.getText());int n2 = Integer.parseInt(num2.getText());num3.setText(""+(n1+n2));num1.setText("");num2.setText("");}}
完全面向对象
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class TestCalc2 {public static void main(String[] args) {new Frame();new TestCalc.Calculator();}class Calculator extends Frame {//属性TextField num1, num2, num3;//方法public void loadFrame() {num1 = new TextField(10); //字符数num2 = new TextField(10); //字符数num3 = new TextField(20); //字符数Button button = new Button("=");Label label = new Label("+");button.addActionListener(new TestCalc2.MyCalculatorListener(this));//布局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;}@Overridepublic 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("");}} }
画笔
import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent;public class TestPaint {public static void main(String[] args) {new MyPaint().loadFrame();}static class MyPaint extends Frame {public void loadFrame() {setBounds(200, 200, 600, 500);setVisible(true);addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}// 画笔@Overridepublic void paint(Graphics g) {// 画笔,需要有颜色,画笔可以画画// g.setColor(Color.red);// g.drawOval(100,100,100,100);g.fillOval(100, 100, 100, 100); // 实心的圆// g.setColor(Color.GREEN);g.fillRect(150, 200, 200, 200);// 养成习惯,画笔用完,将他还原到最初的颜色}} }
图画
import java.awt.*; import java.awt.event.*; import java.util.ArrayList; import java.util.Iterator;public class TestMouseListener {public static void main(String[] args) {//2.2 名字new MyFrame("画图");}//1 自己的类static class MyFrame extends Frame {//4.4//画画需要画笔,需要监听鼠标当前的位置,需要集合来存储这个点ArrayList points;//2.构造器public MyFrame(String title){//2.1标题名字super(title);setBounds(200,200,400,300);//4.5//存鼠标点击的点points = new ArrayList<>();//3 鼠标监听器,针对这个窗口//4.2 new MyMouseListener()this.addMouseListener(new MyMouseListener());setVisible(true);addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}//3.重写画笔@Overridepublic void paint(Graphics g) {//画画,监听鼠标的事件//5Iterator iterator = points.iterator();while (iterator.hasNext()){Point point = (Point) iterator.next();g.setColor(Color.BLACK);g.fillOval(point.x,point.y,10,10);}}//5.1//添加一个点到界面上public void addPaint(Point point){points.add(point);}//4 需要写一个内部类,适配器模式private class MyMouseListener extends MouseAdapter{//4.1 获取鼠标按下@Overridepublic void mousePressed(MouseEvent e) {//4.3//这个我们点击的时候,就会在界面上产生一个点MyFrame frame = (MyFrame) e.getSource();//5.2//这个点就是鼠标的点//new Point(e.getX(),e.getY());frame.addPaint(new Point(e.getX(),e.getY()));//6//每次点击鼠标都需要重新画一遍frame.repaint();//刷新}}} }
窗口监听
import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent;public class TsetWindow {public static void main(String[] args) {new WindowFrame();}static class WindowFrame extends Frame {public WindowFrame() {setBackground(Color.blue);setBounds(100, 100, 200, 200);setVisible(true);//addWindowListener(new MyWindowListener());this.addWindowListener(//匿名内部类new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {setVisible(true);System.exit(0);}});}} }
键盘监听
import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent;public class TestKeyListener {public static void main(String[] args) {new KeyFrame();}static class KeyFrame extends Frame {public KeyFrame() {setBounds(1, 2, 300, 400);setVisible(true);this.addKeyListener(new KeyAdapter() {// 键盘按下@Overridepublic void keyPressed(KeyEvent e) {// 获得键盘下的键是哪一个,当前的码int keyCode = e.getKeyCode(); // 不需要去记录这个数值,直接使用静态属性 VK_XXXSystem.out.println(keyCode);if (keyCode == KeyEvent.VK_UP) {System.out.println("你按下了上键");}// 根据按下不同操作,产生不同结果;}});}} }
Swing
Container!
窗口,面板
import javax.swing.*; import java.awt.*;public class JFramedemo2 {public static void main(String[] args) {new MyJframe2().init();}static class MyJframe2 extends JFrame{public void init(){this.setBounds(1100,300,400,400);this.setVisible(true);JLabel label = new JLabel("这是一个label");this.add(label);//让文本标签居中label.setHorizontalAlignment(SwingConstants.CENTER);//获得一个容器Container container = this.getContentPane();container.setBackground(Color.RED);}} }
import javax.swing.*; import java.awt.*;public class JFramedemo {//init();初始化public void init(){JFrame jframe = new JFrame("这是一个JFrame");jframe.setVisible(true);jframe.setBounds(1100,300,400,400);//jframe.setBackground(Color.RED);//设置文字JLabelJLabel label = new JLabel("这是一个JLabel");jframe.add(label);//关闭事件jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {//建立一个窗口new JFramedemo().init();} }
弹窗
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent;public class Dialogdemo extends JFrame {public Dialogdemo() {this.setVisible(true);this.setSize(800,800);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//Jfame 放东西容器Container container =this.getContentPane();//绝对布局container.setLayout(null);//按钮JButton button = new JButton("点击弹出一个对话框");button.setBounds(50,50,200,200);//点击这个按钮的时候弹出一个弹窗button.addActionListener(new AbstractAction() {//监听器@Overridepublic void actionPerformed(ActionEvent e) {//弹窗new MyDialogdemo();}});container.add(button);}public static void main(String[] args) {new Dialogdemo();} } //弹窗的窗口 class MyDialogdemo extends JDialog{public MyDialogdemo() {this.setVisible(true);this.setBounds(100,100,500,500);//this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);Container container = this.getContentPane();container.setLayout(null);//container.add(new Label("这是一个lllabel"));Label label = new Label("111111111111");label.setBounds(50,50,500,50);container.add(label);} }
import javax.swing.*; import java.awt.*;public class Icondemo extends JFrame{private int width;private int height;public Icondemo() {}public Icondemo(int width,int height) {this.width = width;this.height = height;}public void init(){Icondemo icondemo = new Icondemo(15,15);//图标放在标签上,也可以放在按钮上面JLabel label = new JLabel("icontest",icondemo,SwingConstants.CENTER);Container container = getContentPane();container.add(label);this.setVisible(true);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new Icondemo().init();}@Overridepublic void paintIcon(compoment c, Graphics g, int x, int y) {g.fillOval(10,10,10,10);} }
JPanel
import javax.swing.*; import java.awt.*;public class JPaneldemo extends JFrame {public JPaneldemo() {Container container = getContentPane();container.setLayout(new GridLayout(2, 2, 10, 10)); // 修改为2x2网格布局// 使用JPanel而非JPaneldemo创建面板JPanel panel1 = new JPanel(new GridLayout(1, 3));JPanel panel2 = new JPanel(new GridLayout(1, 2));JPanel panel3 = new JPanel(new GridLayout(2, 1));JPanel panel4 = new JPanel(new GridLayout(3, 2));// 添加按钮到面板panel1.add(new JButton("1"));panel1.add(new JButton("1"));panel1.add(new JButton("1"));panel2.add(new JButton("2"));panel2.add(new JButton("2"));panel3.add(new JButton("3"));panel3.add(new JButton("3"));panel4.add(new JButton("4"));panel4.add(new JButton("4"));panel4.add(new JButton("4"));panel4.add(new JButton("4"));panel4.add(new JButton("4"));panel4.add(new JButton("4"));// 将面板添加到容器container.add(panel1);container.add(panel2);container.add(panel3);container.add(panel4);// 设置窗口属性setVisible(true);setSize(500, 500);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 更推荐的写法}public static void main(String[] args) {// 在事件调度线程中创建和操作Swing组件SwingUtilities.invokeLater(() -> new JPaneldemo());} }
Icon???
Imageicon
import javax.swing.*; import java.awt.*; import java.net.URL;public class ImageIcondemo extends JFrame {public ImageIcondemo() {// 获取图片的地址JLabel label = new JLabel("ImageIcon");URL url = ImageIcondemo.class.getResource("111.jpg");ImageIcon imageIcon = new ImageIcon(url);label.setIcon(imageIcon);label.setHorizontalAlignment(SwingConstants.CENTER);Container container = getContentPane();container.add(label);setVisible(true);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);setBounds(100, 100, 200, 200);}public static void main(String[] args) {new ImageIcondemo();} }
JScroll
import javax.swing.*; import java.awt.*;public class JScrolldemo extends JFrame{public JScrolldemo() {Container container = this.getContentPane();// 文本域JTextArea textArea = new JTextArea(20, 50);textArea.setText("111111111111");// Scroll面板JScrollPane scrollPane = new JScrollPane(textArea);container.add(scrollPane);this.setVisible(true);this.setBounds(100, 100, 300, 350);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new JScrolldemo();} }
图片按钮
import javax.swing.*; import java.awt.*; import java.net.URL;public class JButtondemo01 extends JFrame {public JButtondemo01() {Container container = this.getContentPane();//将一个图片变为图标URL resource = JButtondemo01.class.getResource("111.jpg");Icon icon = new ImageIcon(resource);//把这个图标放在按钮上JButton button = new JButton();button.setIcon(icon);button.setToolTipText("图片按钮");//addcontainer.add(button);this.setVisible(true);this.setSize(500, 300);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new JButtondemo01();} }
单选框
import javax.swing.*; import java.awt.*; import java.net.URL;public class JButtondemo02 extends JFrame {public JButtondemo02() {Container container = this.getContentPane();//将一个图片变为图标URL resource = JButtondemo01.class.getResource("111.jpg");Icon icon = new ImageIcon(resource);//单选框JRadioButton jRadioButton1 = new JRadioButton("单选框1");JRadioButton jRadioButton2 = new JRadioButton("单选框2");JRadioButton jRadioButton3 = new JRadioButton("单选框3");//由于单选框只能选择一个,分组,一个组中只能选择一个ButtonGroup group = new ButtonGroup();group.add(jRadioButton1);group.add(jRadioButton2);group.add(jRadioButton3);container.add(jRadioButton1,BorderLayout.CENTER);container.add(jRadioButton2,BorderLayout.NORTH);container.add(jRadioButton3,BorderLayout.SOUTH);this.setVisible(true);this.setSize(500, 300);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new JButtondemo02();} }
复选框
import javax.swing.*; import java.awt.*; import java.net.URL;public class JButtondemo03 extends JFrame {public JButtondemo03() {Container container = this.getContentPane();//将一个图片变为图标URL resource = JButtondemo01.class.getResource("111.jpg");Icon icon = new ImageIcon(resource);//多选框JCheckBox jCheckBox1 = new JCheckBox("多选框1");JCheckBox jCheckBox2 = new JCheckBox("多选框2");container.add(jCheckBox1,BorderLayout.NORTH);container.add(jCheckBox2,BorderLayout.SOUTH);this.setVisible(true);this.setSize(500, 300);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new JButtondemo03();} }
列表
下拉框
import javax.swing.*; import java.awt.*;public class TestComboboxdemo01 extends JFrame {public TestComboboxdemo01() {Container container = this.getContentPane();JComboBox status = new JComboBox();status.addItem(null);status.addItem("正在热映");status.addItem("已下架");status.addItem("即将上映");container.add(status);this.setVisible(true);this.setSize(500, 350);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new TestComboboxdemo01();} }
列表框
import javax.swing.*; import java.awt.*;public class TestComboboxdemo02 extends JFrame {public TestComboboxdemo02() {Container container = this.getContentPane();//生成列表的内容String [] contents = {"1","2","3"};//列表中需要放入内容JList jList = new JList(contents);container.add((jList));this.setVisible(true);this.setSize(500, 350);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new TestComboboxdemo02();} }
文本框
import javax.swing.*; import java.awt.*;public class TestTextdemo01 extends JFrame {public TestTextdemo01() {Container container = this.getContentPane();JTextField textField1 = new JTextField("11111111111");JTextField textField2 = new JTextField("2222222222222");container.add(textField1,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();} }
密码框
import javax.swing.*; import java.awt.*;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();} }
文本域
贪吃蛇
帧,如果时间片足够小,就是动画,一秒30帧 60帧。连起来是动画,拆开就是静态的图片! 键盘监听
StartGame
import javax.swing.*;public class StartGame {public static void main(String[]args){JFrame frame = new JFrame();frame.setResizable(false);frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);frame.setBounds(500,10,900,720);frame.add(new GamePanel());frame.setVisible(true);} }
GamePanel
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Date; import java.util.Random;public class GamePanel extends JPanel implements KeyListener, ActionListener {//定义蛇的数据结构int length;int[]snakeX = new int[600];//25*25int[]snakeY = new int[500];String fx;//食物的坐标int foodx;int foody;Random random = new Random();int score;//成绩//游戏的当前状态开始或停止boolean isStart = false;//默认是不开始boolean isFail = false;//定时器Timer timer = new Timer(50,this);//100毫秒执行一次//构造器public GamePanel() {setBackground(Color.white);init();//获得焦点和键盘事件this.setFocusable(true);//获得焦点事件this.addKeyListener(this);//获得键盘监听事件timer.start();//游戏一开始就启动定时器}//初始化方法public void init(){length = 3;snakeX[0] = 100;snakeY[0] = 100;//脑袋的坐标snakeX[1] = 75;snakeY[1] = 100;//第一个身体的坐标snakeX[2] = 50;snakeY[2] = 100;//第二个身体的坐标fx = "R";//把食物随机分布在界面上foodx = 25 + 25*random.nextInt(34);foody = 75 + 25*random.nextInt(24);score =0;}@Overrideprotected void paintComponent(Graphics g) {super.paintComponent(g);//清屏,不用的话,会出现闪屏闪烁//绘制静态的面板Data.header.paintIcon(this,g,25,11);g.fillRect(25,75,850,600);//画出积分g.setColor(Color.BLACK);g.setFont(new Font("微软雅黑",Font.BOLD,10));//设置字体g.drawString("长度"+ length,750,35);//g.drawString("分数"+ score,750,50);////画出食物Data.food.paintIcon(this,g,foodx,foody);//把小蛇画上去Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);//蛇头初始化向右if (fx.equals("R")) {Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);} else if (fx.equals("L")) {Data.left.paintIcon(this, g, snakeX[0], snakeY[0]);} else if (fx.equals("U")) {Data.up.paintIcon(this, g, snakeX[0], snakeY[0]);} else if (fx.equals("D")) {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]);//第一个身体的坐标} // Data.body.paintIcon(this,g,snakeX[1],snakeY[1]); // Data.body.paintIcon(this,g,snakeX[2],snakeY[2]);//游戏状态if(isStart == false){g.setColor(Color.white);g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体g.drawString("还没开始,按空格开始",300,300);}if(isFail == true){g.setColor(Color.RED);g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体g.drawString("游戏结束重新开始",300,300);}}//键盘监听事件@Overridepublic void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();if (keyCode == KeyEvent.VK_SPACE){//如果按下的是空格if (isFail){//重新开始isFail =false;init();}else {isStart = !isStart;}}//小蛇移动if (keyCode == KeyEvent.VK_UP){fx = "U";}else if (keyCode == KeyEvent.VK_DOWN){fx = "D";}else if (keyCode == KeyEvent.VK_LEFT){fx = "L";}else if (keyCode == KeyEvent.VK_RIGHT){fx = "R";}}//事件监听事件--需要通过固定事件来刷新 1s=10次@Overridepublic void actionPerformed(ActionEvent e) {if(isStart && isFail == false){//如果游戏是开始状态//吃食物if (snakeX[0] == foodx && snakeY[0] == foody){length++;score++;//再次随机食物//把食物随机分布在界面上foodx = 25 + 25*random.nextInt(34);foody = 75 + 25*random.nextInt(24);}//移动for (int i = length-1; i > 0; i--) {snakeX[i] = snakeX[i-1];snakeY[i] = snakeY[i-1];}//走向if (fx.equals("R")){snakeX[0] = snakeX[0]+25;if (snakeX[0]>850){ snakeX[0] = 25;}//边界判断}else if (fx.equals("L")){snakeX[0] = snakeX[0]-25;if (snakeX[0]<25){ snakeX[0] = 850;}//边界判断}else if (fx.equals("U")){snakeY[0] = snakeY[0]-25;if (snakeY[0]<75){ snakeY[0] = 650;}//边界判断}else if (fx.equals("D")){snakeY[0] = snakeY[0]+25;if (snakeY[0]>650){ snakeY[0] = 75;}//边界判断}//失败判定,撞到自己for (int i =1;i <length; i++){if (snakeX[0]==snakeX[i]&& snakeY[0] == snakeY[i]){isFail = true;}}//边界判断if (snakeX[0]>850){snakeX[0] = 25;}repaint();//重画页面}timer.start();//定时器开启}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic void keyTyped(KeyEvent e) {}}
Data
import javax.swing.*; import java.net.URL;public class Data {//相对路径 tx.jpg //绝对路径 相当于当前的项目public static URL headerURL = Data.class.getResource("/images/header.png");public static ImageIcon header = new ImageIcon(headerURL);public static URL upURL = Data.class.getResource("/images/up.png");public static URL downURL = Data.class.getResource("/images/down.png");public static URL leftURL = Data.class.getResource("/images/left.png");public static URL rightURL = Data.class.getResource("/images/right.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 URL bodyURL = Data.class.getResource("/images/body.png");public static ImageIcon body = new ImageIcon(bodyURL);public static URL foodURL = Data.class.getResource("/images/food.png");public static ImageIcon food = new ImageIcon(foodURL);// 工具方法:安全创建ImageIcon(带错误提示)private static ImageIcon createImageIcon(URL url, String description) {if (url != null) {return new ImageIcon(url, description);} else {// 打印具体哪个图片加载失败,方便排查System.err.println("❌ 找不到图片:" + description + "(路径:/images/" + description + ".png)");return null;}} }