Java GUI编程学习
Java GUI编程学习
GUI编程
告诉大家怎么学?
- 这是什么?
- 他怎么玩?
- 该如何平时运用它?
组件
- 窗口
- 弹窗
- 面板
- 文本框
- 列表框
- 按钮
- 图片
- 监听事件
- 鼠标
- 键盘事件
- 破解工具
1、简介
GUI的核心技术:Swing AWT
- 因为界面不美观
- 需要jre环境!
为什么要学习?
- 可以写出自己想要的小工具
- 工作时候也可能需要维护到Swing界面,概率极小!
- 了解MVC架构,了解监听!
2、AWT
2.1、AWT介绍
- 包含很多类和接口!GUI!
- 元素:窗口,按钮,文本框
- java.awt
2.3、布局管理器
流式布局
public class TestFlowLayout {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.setSize(200,200);//把按钮添加进去frame.add(button1);frame.add(button2);frame.add(button3);//设置可见frame.setVisible(true);}
}
东南西北中布局
public class TestBorderLayout {
public static void main(String[] args) {
Frame frame = new Frame(“TestorderLayout”);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.setVisible(true);frame.setSize(400,400);} }
表格布局 Grid
public class TestGridlLayout {
public static void main(String[] args) {
Frame frame = new Frame(“TestorderLayout”);Button button1 = new Button("button1");Button button2 = new Button("button2");Button button3 = new Button("button3");Button button4 = new Button("button4");Button button5 = new Button("button5");Button button6 = new Button("button6");frame.setLayout(new GridLayout(3,2));frame.add(button1);frame.add(button2);frame.add(button3);frame.add(button4);frame.add(button5);frame.add(button6);frame.pack();//java函数 自动填充frame.setVisible(true);}}
布局练习
分析过程:
代码实现:
public class EXDemo {public static void main(String[] args) {//总frameFrame frame = new Frame();frame.setVisible(true);frame.setSize(500,400);frame.setLocation(300,400);frame.setBackground(Color.black);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("East-1"), BorderLayout.EAST);p1.add(new Button("West-1"), 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("East-2"), BorderLayout.EAST);p3.add(new Button("West-2"), BorderLayout.WEST);//中间4个for (int i = 0; i < 4; i++) {p4.add(new Button("for-" + i));}p3.add(p4, BorderLayout.CENTER);//最后添加到frame里面frame.add(p1);frame.add(p3);}
}
2.4、事件监听
事件监听:当某个事发生时,干什么?
public class TestActionEvent {public static void main(String[] args) {//按下按钮触发事件Frame frame = new Frame();Button button = new Button("button");//因为,addActionListener()需要一个ActionListener,所以需要构造一个ActionListenerMyActionListener myActionListener = new MyActionListener();button.addActionListener(myActionListener);frame.add(button,BorderLayout.CENTER);
// frame.pack();//自适应frame.setSize(500,500);//窗体大小frame.setLocation(400,300);//窗体在桌面的定位windowClose(frame);frame.setVisible(true);}//关闭窗体事件private static void windowClose(Frame frame){frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}}//事件监听
class MyActionListener implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("aaa");}
}
多个事件共享一个事件
public class TestActionEvent02 {public static void main(String[] args) {//两个按钮同时实现同一个监听//开始 停止Frame frame = new Frame("开始-停止");Button button1 = new Button("start");Button button2 = new Button("stop");//可以显示的定义触发会返回的命令,如果不定义会默认button的值//可以多个按钮只写一个监听事类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.setSize(500,500);frame.setLocation(300,400);frame.setVisible(true);}
}//监听事件
class MyMonitor implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {//e.getActionCommand()获取按钮信息System.out.println("按钮被点击:msg"+e.getActionCommand());if (e.getActionCommand().equals("start")) {System.out.println("我是start");}}
}
2.5、输入框TextField 监听
public class TestTest01 {public static void main(String[] args) {//启动!MyFrame myFrame = new MyFrame();}
}
class MyFrame extends Frame{public MyFrame(){TextField textField = new TextField();add(textField);//监听这个文本框输入的文字MyActionListener2 myActionListener2 = new MyActionListener2();//按下Enter就会触发这个输入框的事件textField.addActionListener(myActionListener2);//设置替换编码textField.setEchoChar('*');setSize(500,500);setVisible(true);}
}
class MyActionListener2 implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {TextField field=(TextField) e.getSource();//获得一些资源,返回一个对象System.out.println(field.getText());//获得输入框中的文本field.setText("");//按下enter后清空输入框}
}
2.6、简易计算器,组合+内部类回顾复习!
oop原则:组合大于继承
//组合
class A{public B b;
}//继承
class A extends B{}//简易计算器
public class TextCalc {public static void main(String[] args) {new Calculator();}
}//计算器类
class Calculator extends Frame {public Calculator() {//3 个文本框TextField num1 = new TextField(10);//字符数TextField num2 = new TextField(10);//字符数TextField num3 = new TextField(20);//字符数//1 个提交按钮Button button = new Button("=");button.addActionListener(new MyCalculatorListener(num1,num2,num3));//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 {//获取3个变量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) {//1、获得加数和被加数int n1 = Integer.parseInt(num1.getText());int n2 = Integer.parseInt(num2.getText());//2、将这个值+法运算后放到第三个框num3.setText(""+(n1+n2));//3、清除前两个输入框num1.setText("");num2.setText("");}
}
完全改造成面向对象写法
//简易计算器
public class TextCalc {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;}@Overridepublic void actionPerformed(ActionEvent e) {//1、获得加数和被加数int n1 = Integer.parseInt(calculator.num1.getText());int n2 = Integer.parseInt(calculator.num2.getText());//2、将这个值+法运算后放到第三个框calculator.num3.setText(""+(n1+n2));//3、清除前两个输入框calculator.num1.setText("");calculator.num2.setText("");}
}
内部类:
更好的包装
//简易计算器
public class TextCalc {
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());//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 {@Overridepublic void actionPerformed(ActionEvent e) {//1、获得加数和被加数int n1 = Integer.parseInt(num1.getText());int n2 = Integer.parseInt(num2.getText());//2、将这个值+法运算后放到第三个框num3.setText(""+(n1+n2));//3、清除前两个输入框num1.setText("");num2.setText("");}}}
2.7、画笔
public class TestPaint {public static void main(String[] args) {new MyPaint().loadFrame();}
}class MyPaint extends Frame {public void loadFrame(){setBounds(200,200,600,400);setVisible(true);}//画笔@Overridepublic void paint(Graphics g) {//super.paint(g);// 画笔,需要有颜色,画笔可以画画g.setColor(Color.BLUE);
// g.drawOval(100,100,100,100);//空心的圆g.fillOval(100,100,100,100);//实心的圆g.setColor(Color.GREEN);g.fillRect(150,200,200,200);}
}
2.8、鼠标监听
目的想要实现鼠标画画
public class TestMouseListener {public static void main(String[] args) {new MyFrame("画图");}
}//自己的类
class MyFrame extends Frame {//画画需要画笔,需要监听鼠标当前位置,需要集合来存储这个点ArrayList points;public MyFrame(String title) {super(title);setBounds(200,200,500,400);//存鼠标点击的点points = new ArrayList<>();//鼠标监听器针对这个窗口this.addMouseListener(new MyMouseListener());setVisible(true);}@Overridepublic 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 addPoint(Point point) {points.add(point);}//适配器模式private class MyMouseListener extends MouseAdapter {//鼠标 按下,弹起,按住不放@Overridepublic void mousePressed(MouseEvent e) {MyFrame frame =(MyFrame) e.getSource();//这个时候我们点击的时候,就会产生一个点! 画//这个点就是鼠标的点frame.addPoint(new Point(e.getX(),e.getY()));//每次点击鼠标都需要重画一次frame.repaint();//刷新}}
}
2.9、窗口监听
public class TestWindow {public static void main(String[] args) {new WindowFrame();}
}class WindowFrame extends Frame {public WindowFrame() {setBackground(Color.BLACK);setBounds(100, 100, 300, 300);setVisible(true);
// addWindowListener(new MyWindowListener());this.addWindowListener(//匿名内部类new WindowAdapter(){//关闭窗口@Overridepublic void windowClosing(WindowEvent e) {System.out.println("WindowClose");System.exit(0);}//激活窗口@Overridepublic void windowActivated(WindowEvent e) {WindowFrame source =(WindowFrame) e.getSource();source.setTitle("窗口被激活了");System.out.println("WindowActived");}});}
}
2.10、键盘监听
//key就是键的意思
public class TestKeyListener {public static void main(String[] args) {new KeyFrame();}
}
class KeyFrame extends Frame{public KeyFrame(){setBounds(1,2,300,400);setVisible(true);this.addKeyListener(new KeyAdapter() {//键盘按下@Overridepublic void keyPressed(KeyEvent e) {//获得键盘按下的键是哪一个 getKeyCode()来获取当前键盘码int keycode = e.getKeyCode();//不需要记录这个值,直接使用静态属性System.out.println(keycode);if(keycode==KeyEvent.VK_UP){System.out.println("你按下了上键");}//根据按下的不同产生不同的结果}});}
3、Swing
3.1、窗口、面板
public class JFrameDemo {//init(); 初始化public void init(){//顶级窗口JFrame jFrame = new JFrame("这是一个JFrame窗口");jFrame.setVisible(true);jFrame.setBounds(100, 100, 400, 500);jFrame.setBackground(Color.red);//设置文字 JLabelJLabel lable = new JLabel("欢迎来到Java");jFrame.add(lable);//容器实例化//关闭事件jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {//建立一个窗口new JFrameDemo().init();}
}
标签居中
public class JFrameDemo02 {public static void main(String[] args) {new MyJFrame2().init();}
}
class MyJFrame2 extends JFrame{public void init(){this.setVisible(true);this.setBounds(100,100,300,400);//设置文字 JLabelJLabel lable = new JLabel("欢迎来到Java");add(lable);//让文本标签居中lable.setHorizontalAlignment(SwingConstants.CENTER);//获得一个容器Container container = this.getContentPane();container.setBackground(Color.BLUE);}
}
3.2、弹窗
JDialog 用来被弹出,默认就有关闭事件
//主窗口
public class DialogDemo extends JFrame {public DialogDemo() {this.setVisible(true);this.setSize(400, 500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //设置默认的关闭事件//JFrame 放东西,需要个容器Container container = this.getContentPane();//绝对布局container.setLayout(null);//按钮JButton jButton = new JButton("点击弹出一个对话框");//创建对象jButton.setBounds(30,30,200,50);//点击这个按钮的时候,弹出一个弹窗jButton.addActionListener(new ActionListener() { //监听器@Overridepublic void actionPerformed(ActionEvent e) {//弹窗new MyDialog();}});container.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);Container container = this.getContentPane();container.setLayout(null);container.add(new Label("带你飞"));}
}
3.3、 标签
label
new JLabel("xxx")
图标 icon
图片 image
public class ImageIconDemo extends JFrame {public ImageIconDemo(){//获取图片的地址JLabel label = new JLabel("ImageIcon");URL url = ImageIconDemo.class.getResource("22.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();}
}
3.4、面板
JPanel
public class JPanelDemo extends JFrame {public JPanelDemo() {Container container = this.getContentPane();container.setLayout(new GridLayout(2, 1, 10, 10));//后面两个参数是“间距”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);this.setVisible(true);this.setSize(500,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new JPanelDemo();}
}
JScrollPanel
带滚动条的面板
public class JScrollDemo extends JFrame {public JScrollDemo(){Container container = this.getContentPane();//文本域JTextArea textArea = new JTextArea(20, 50);textArea.setText("欢迎学习Java");//Scroll面板JScrollPane scrollPane = new JScrollPane(textArea);container.add(scrollPane);this.setVisible(true);this.setBounds(100, 100, 300, 400);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new JScrollDemo();}
}
3.5、按钮
package com.liang.lesson05;import javax.swing.*;
import java.awt.*;
import java.net.URL;/*** Created by Dream on 2022/4/20.*/
public class JButtonDemo extends JFrame {public JButtonDemo() {Container container = this.getContentPane();//将图片变为一个图标URL resource = JButtonDemo.class.getResource("22.jpg");Icon icon = new ImageIcon(resource);//把这个图标放在按钮上JButton button = new JButton();button.setIcon(icon);button.setToolTipText("图片按钮");//addcontainer.add(button);this.setVisible(true);this.setBounds(800,300,800,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new JButtonDemo();}
}
单选按钮
package com.liang.lesson05;import javax.swing.*;
import java.awt.*;
import java.net.URL;/*** Created by Dream on 2022/4/20.*/
public class JButtonDemo02 extends JFrame{public JButtonDemo02() {Container container = this.getContentPane();//将图片变为一个图标URL resource = JButtonDemo.class.getResource("22.jpg");Icon icon = new ImageIcon(resource);//单选框JRadioButton radioButton01 = new JRadioButton("JRadioButton01");JRadioButton radioButton02 = new JRadioButton("JRadioButton02");JRadioButton radioButton03 = new JRadioButton("JRadioButton03");//由于单选框只能选择一个,分组,一个组中只可以选择一个ButtonGroup group = new ButtonGroup();group.add(radioButton01);group.add(radioButton02);group.add(radioButton03);container.add(radioButton01, BorderLayout.CENTER);container.add(radioButton02, BorderLayout.NORTH);container.add(radioButton03, BorderLayout.SOUTH);this.setVisible(true);this.setBounds(800,300,800,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new JButtonDemo02();}
}
复选按钮
package com.liang.lesson05;import javax.swing.*;
import java.awt.*;
import java.net.URL;/*** Created by Dream on 2022/4/20.*/
public class JButtonDemo03 extends JFrame{public JButtonDemo03() {Container container = this.getContentPane();//将图片变为一个图标URL resource = JButtonDemo.class.getResource("22.jpg");Icon icon = new ImageIcon(resource);//多选框JCheckBox checkBox01 = new JCheckBox("checkBox01");JCheckBox checkBox02 = new JCheckBox("checkBox02");container.add(checkBox01,BorderLayout.NORTH);container.add(checkBox02,BorderLayout.SOUTH);this.setVisible(true);this.setBounds(800,300,800,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new JButtonDemo03();}
}
3.6、列表
下拉框
package com.liang.lesson06;
import javax.swing.;
import java.awt.;/**
Created by Dream on 2022/4/20.
*/
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.setBounds(300,300,400,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestComboboxDemo01();
}
}
列表框
package com.liang.lesson06;
import javax.swing.;
import java.awt.;
import java.util.Vector;/**
Created by Dream on 2022/4/20.
*/
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);contents.add("张三");contents.add("李四");contents.add("王五");container.add(jList);this.setVisible(true);this.setBounds(300,300,400,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new TestComboboxDemo02();}
}
应用场景
- 选择地区,或者一些单个选项
- 列表,展示信息,一般是动态扩容!
3.7、文本框
文本框
package com.liang.lesson06;
import javax.swing.;
import java.awt.;
import java.util.Vector;/**
Created by Dream on 2022/4/20.
*/
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.setBounds(300,300,400,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestTextDemo01();
}
}
密码框
package com.liang.lesson06;
import javax.swing.;
import java.awt.;/**
Created by Dream on 2022/4/20.
*/
public class TestTextDemo02 extends JFrame {
public TestTextDemo02() {Container container = this.getContentPane();//面板JPasswordField passwordField = new JPasswordField();//*****passwordField.setEchoChar('*');container.add(passwordField);this.setVisible(true);this.setBounds(300,300,400,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestTextDemo02();
}
}
文本域
package com.liang.lesson05;
import javax.swing.;
import java.awt.;/**
Created by Dream on 2022/4/20.
*/
public class JScrollDemo extends JFrame {
public JScrollDemo(){
Container container = this.getContentPane();//文本域JTextArea textArea = new JTextArea(20, 50);textArea.setText("欢迎学习Java");//Scroll面板JScrollPane scrollPane = new JScrollPane(textArea);container.add(scrollPane);this.setVisible(true);this.setBounds(100, 100, 300, 400);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JScrollDemo();
}
}
贪吃蛇
帧,如果时间线足够小,就是动画,一秒30帧 60帧。连起来是动画,拆开就是静态图片!
键盘监听
定时器Timer
游戏主启动类
package com.liang.snake;
import javax.swing.*;
/**
Created by Dream on 2022/4/21.
*/
//游戏主启动类
public class StartGame {
public static void main(String[] args) {
JFrame frame = new JFrame();frame.setBounds(500, 200, 900, 720);frame.setResizable(false);//窗口大小不可变frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//正常游戏界面都应该在面上!frame.add(new GamePanel());frame.setVisible(true);
}
}
游戏面板
package com.liang.snake;
import javax.sql.DataSource;
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;/**
Created by Dream on 2022/4/21.
*/
//游戏的面板
public class GamePanel extends JPanel implements KeyListener,ActionListener{//定义蛇的数据结构
int length;//蛇的长度
int[] snakeX = new int[600];//蛇的X坐标2525
int[] snakeY = new int[600];//蛇的Y坐标2525
String fx;//食物的坐标
int foodx;
int foody;
Random random = new Random();//积分
int score;//游戏当前的状态:开始,停止
boolean isStart = false;//默认是不开始boolean isFail = false;//游戏状态失败
//定时器 以ms为单位 1000ms=1s
Timer timer = new Timer(100,this);//100毫执行一次!//构造器
public GamePanel() {
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;
}
//绘制面板,我们游戏中的所有东西,都是用这个画笔来画
@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);//默认的游戏界面//画积分g.setColor(Color.WHITE);g.setFont(new Font("微软雅黑", Font.BOLD, 18));g.drawString("长度:"+length,750,35);g.drawString("分数:"+score,750,50);//画食物Data.food.paintIcon(this, g, foodx, foody);//把小蛇放上去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]);//第一个身体坐标}//游戏状态if (isStart==false){g.setColor(Color.white);g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体g.drawString("按下空格开始游戏",300,300);}if (isFail) {g.setColor(Color.RED);g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体g.drawString("游戏失败,按下空格重新开始",200,300);}
}
//键盘监听事件
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();//获得键盘按钮是哪一个if (keyCode == KeyEvent.VK_SPACE) {//如果按下的是空格键if (isFail) {//游戏重新开始isFail = false;init();}else{isStart = !isStart;//取反}repaint();}//小蛇移动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次
@Override
public void actionPerformed(ActionEvent e) {
if (isStart && isFail == false) {//如果游戏是开始状态,则让小蛇动起来//吃食物if (snakeX[0] == foodx && snakeY[0] == foody) {length++;//蛇的长度加1//分数+1score = score + 1;//再次随机生成食物foodx = 25 + 25 * random.nextInt(34);foody = 75 + 25 * random.nextInt(24);}//移动for (int i = length - 1; i > 0; i--) {//后一节移到前一节的位置 snakeX[1]=snakeX[0];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;}}repaint();//重画页面}timer.start();//定时器开启!
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
数据中心
package com.liang.snake;
import javax.swing.*;
import java.net.URL;/**
Created by Dream on 2022/4/21.
*/
//数据中心
public class Data {//相对路径 22.jpg
//绝对路径 / 相当于当前的项目
public static URL headerURL = Data.class.getResource(“statics/header.png”);
public static ImageIcon header = new ImageIcon(headerURL);public static URL upURL = Data.class.getResource(“statics/up.png”);
public static URL downURL = Data.class.getResource(“statics/down.png”);
public static URL leftURL = Data.class.getResource(“statics/left.png”);
public static URL rightURL = Data.class.getResource(“statics/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(“statics/body.png”);
public static ImageIcon body = new ImageIcon(bodyURL);public static URL foodURL = Data.class.getResource(“statics/food.png”);
public static ImageIcon food = new ImageIcon(foodURL);
}
总结
Java GUI编程学习相关推荐
- Java之GUI编程学习笔记六 —— AWT相关(画笔paint、鼠标监听事件、模拟画图工具)
Java之GUI编程学习笔记六 -- AWT相关(画笔paint) 参考教程B站狂神https://www.bilibili.com/video/BV1DJ411B75F 了解paint Frame自 ...
- Java GUI编程的几种常用布局管理器
Java GUI编程的几种常用布局管理器 本人是一个大二的学生.因为最近有做JavaGUI界面的需求,因此重新开始熟悉JavaGUI的各种控件和布局.然后以次博文为笔记,总结.完善以及发表最近学习的一 ...
- java 网络编程学习笔记
java 网络编程学习笔记 C/S模式:客户端和服务器 客户端创建流程 1 1.建立Socket端点 2 3 Socket s = new Socket(绑定地址, 绑定端口); 2.确认源数据方式和 ...
- The package javax.swing is not accessible(java GUI 编程时引用swing包和awt包时会报错怎么办)
Java GUI 编程时引用swing包和awt包时会报错怎么办 一.环境与错误现象 使用的编译器为eclipse,情况为: 二.解决方法 问题主要是由工程中的module-info.java这个文件 ...
- python的messagebox的用法_Python GUI编程学习笔记之tkinter中messagebox、filedialog控件用法详解...
本文实例讲述了Python GUI编程学习笔记之tkinter中messagebox.filedialog控件用法.分享给大家供大家参考,具体如下: 相关内容: messagebox 介绍 使用 fi ...
- java并行任务,Java 并发编程学习(五):批量并行执行任务的两种方式
Java 并发编程学习(五):批量并行执行任务的两种方式 背景介绍 有时候我们需要执行一批相似的任务,并且要求这些任务能够并行执行.通常,我们的需求会分为两种情况: 并行执行一批任务,等待耗时最长的任 ...
- Java网络编程学习——简单模拟在线聊天
Java网络编程学习--简单模拟在线聊天 学了java网络,也是该做个小案例来巩固一下了. 本次案例将使用UDP和多线程模拟即时聊天,简单练练手. 1.前提知识 需要知道简单的IO流操作,以及简单的U ...
- java并发编程学习一
java并发编程学习一 什么是进程和线程? 进程是操作系统进行资源分配的最小单位 进程跟进程之间的资源是隔离的,同一个进程之中的线程可以共享进程的资源. 线程是进程的一个实体,是CPU 调度和分派的基 ...
- 基于《狂神说java》GUI编程--学习笔记
前言: 本笔记参考于学友:小尹^_^ :本笔记仅做学习与复习使用,不存在刻意抄袭. ---------------------------------------------------------- ...
最新文章
- rabbitmq消费固定个数消息_SpringBoot+RabbitMQ (保证消息100%投递成功并被消费)
- 【linux草鞋应用编程系列】_2_ 环境变量和进程控制
- 可靠数据传输原理1(构造可靠数据传输协议)
- 允许MySQL 帐号远程登录
- 用python读写excel(xlrd、xlwt)
- 【NLP实战】Task1 数据集探索
- Pytorch cifar100离线加载二进制文件
- linux 串口工具_会C++就能开发Linux/Android应用!这款Yoxios X3串口屏火了...
- Job for smbd.service failed because the control process exited with error code. See “systemctl statu
- numpy序列预处理dna序列_干货 :教你一文掌握数据预处理
- 人工智能+人=强大的网络安全
- 代码评审 16.7.1
- 力软 Learun 是如何验证权限的
- ubuntu20.04安装simhei字体--jupyter中文显示框框的解决方案
- 深度学习简明教程系列 —— 经典模型(合集)
- python处理word文档 查找文字 加下划线_你能用Pythondocx在同一段落的某一部分加下划线吗?...
- 前端开发面试问题及答案整理
- 亮宁机器人套件_亮宁机器人可视化编程V2.2第2讲(图文)
- 飞秋FeiQ可以聊天,但无法传输文件
- 如何将MathType公式编辑器内嵌到WPS工具栏中
热门文章
- 420集的python教程视频_GitHub - kaisar420/codeparkshare: Python初学者(零基础学习Python、Python入门)书籍、视频、资料、社区推荐...
- 初链-解读初链白皮书
- poj2228(dp)
- jQuery 鼠标指针 悬浮在文字上提示信息
- 英文月日年日期格式的实现
- ios开发中打印日志消息控制
- VScode配置latex时 出现 “Cannot find LaTeX root file”且文本无高亮提示,不显示tex图标
- 零基础的人可以去大数据培训机构学习大数据开发吗?
- 第094讲: Pygame:飞机大战5 | 学习记录(小甲鱼零基础入门学习Python)
- 将3DMax编辑的动画,导入给已经绑定蒙皮好的模型给Unity使用