视频课程来源:狂神说Java
有兴趣学习Java的可以关注一下狂神老师的课程 Java系类每个阶段的视频都有 非常适合自学 自己也是看的这个视频总结的笔记 非常推荐给想自学Java编程的小伙伴。 课程都是全免费的。
GUI:图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面,
图形用户界面是一种人与计算机通信的界面显示格式,允许用户使用鼠标等输入设备操纵屏幕上的图标或菜单选项,以选择命令、调用文件、启动程序或执行其它一些日常任务。
Window操作系统就是一个图形用户界面(GUI)操作系统
我们平时操作的一些应用程序 比如说 QQ 微信的登陆页面 QQ 微信的聊天页面 英雄联盟的登陆页面 这些都是图形用户界面
GUI的核心:AWT 和 swing 两个jar包
关系:AWT和Swing都是java中的包。
AWT(Abstract Window Toolkit):抽象窗口工具包,早期编写图形界面应用程序的包。
Swing :为解决 AWT 存在的问题而新开发的图形界面包。Swing是对AWT的改良和扩展。
深度了解可参考:Java中AWT、Swing与SWT三大GUI技术的原理与效率差异
GUI的主要组成:容器 和 组件
容器:(container)
Windows
窗口 Frame
面板 Panel
弹出框 Dialog
等等……
组件:(component)
等等……
Frame frame=new Frame("我的第一个窗口"); //Fram类的构造方法传进一个String类型的窗口 标题
Frame中的常用方法:
frame.setVisble() //boolean型参数调整窗口是否可视化
frame.setSize(width:int,height:int) //调整窗口的宽度和高度
frame.setLoaction(x:int,y:int) //调整初始话窗口显示的位置
frame.setBackground(Color:color) //调整窗口背景颜色需要穿进一个Color的对象
new Color(r:int,g:int,b:int) or new Color(rgb:int) //通过rgb调色调试想要的颜色
//RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化
//以及它们相互之间的叠加来得到各式各样的颜色
Color.green //绿色
Color.red //红色 public final static Color green = new Color(0, 255, 0); Color类中包含的对象 源码
//Color类中已经包含了很多 Color对象 这些对象已经调试好使用的大多数颜色,可以通过 Color. 来获取这些对象
frame.setResizable(Boolean) //设置窗口大小是否可以被调整;
add方法:
Frame frame=new Frame("我的第一个窗口");
frame.add(Component comp,Object constraints) // 向Frame中添加组件 constraints为控件的布局位置
//Component 组件 组成部分 | constraints 约束条件
Panel必须存在与容器中显示 不能独立显示
Panel面板和Frame窗口用法基本一致
通过add来进行添加一些组件
frame.setLayout(LayoutManager mgr) //参数为LayoutManage对象 LayouMannager是一个接口
BorderLayout类 东南西北中布局模式
FlowLayout类 流式布局模式 从左到右 从上到下
GridLayout类 栅格式布局模式 表格模式 几行几列
这三个类都是LayouManager接口的实现类
frame.setLayout(new FlowLayout()); //流式布局 组件呈流失分布 从左向右 从上到下
frame.setLayout(new BorderLayout(int hgap, int vgap)) //东南西北中布局 组件呈特定方向排布 默认为中 center
frame.setLayout(new GridLayout(int rows, int cols, int hgap, int vgap)) //将窗口分成几行几列的表单 每个组件占一格分布 //hgap vgap 为容器内行 列 间隔 可以不填默认无间隔
具体用法:
Button b=new Button("我是按钮组件");
frame.add(b); //自动流式布局
frame.add(b,BoderLayout.WEST); //将按钮向西排列布局 BoderLayout类中已经设置好了布局位置的静态常量可以直接调用
//BoderLayout.EAST : 东 BoderLayout.CENTER : 中
frame.setLayout(new GridLayout(2,2)) //栅格布局 将窗口分为两行两列
frame.add(b) //按钮位置在窗口左上方 占窗口四分之一大小
上面是三种布局模式
绝对定位布局:
根据组件设置的坐标 自动相对于窗口定位
设置坐标: 1. setLocation(int : x , int : y) 2. setBounds(int : x , int : y ,int : width , int : height)
frame.setLayout(null) //绝对定位
Button b=new Button("按钮")
b.setLocation(100,100); //设置按钮在窗口内的位置坐标
frame.add(b) //将按钮添加到窗口上 按钮在 x 为100 Y 为100的位置上
//创建按钮对象
Button button =new Button(String : lable); //Butoon的构造方法传进一个String的值 设置按钮上显示的文本
button.setActionCommand(String:Conmand); //设置按钮的别名 ActionCommand: 操作命令
bu
TextField t=new Textfield(int:columns);//创建一个单行文本框 columns 字符数
t.getText() //获取输入框文本
t.setEchoChar(String: text) //设置输入时文本框的替换字符 换成* 输入显示文字显示*
画笔是Frame类中的一个方法,
通过重写这个方法拿到参数可以用参数在面板或者窗口上画出自己想要的图案
不能通过new来创建画笔
public class PaintTest {
public static void main(String[] args) {
new myFrame(); //调用
}
}
class myFrame extends Frame{ //创建一个窗口类继承 Frame类
public myFrame(){ //构造方法
super("我的第一个画板"); //调用父类的构造方法
setVisible(true); //设置窗口可见
setBounds(200,200,500,500); //设置初始位置 长宽
}
@Override //重写paint方法
public void paint(Graphics g) { //通过 g. 可以实现多种画笔功能
g.setColor(Color.red); //设置画笔的颜色 用完后将画笔调回本色
g.drawOval(100,300,200,200); //用画笔画一个空心的圆
g.fillOval(100,100,200,200); //用画笔画一个实心圆
//参数为 初始坐标 x y 和长 宽
g.setColor(Color.BLACK); //将画笔调为原始的黑色
}
}
WindowClosing 窗口关闭事件
WindowActvate 窗口激活事件
frame.addWindowListener(WindowListener l) //添加监听事件 传进一个 windowsListener 对象 WindowsListener为接口
//WindowsAdapter 抽象类 实现了windowListener接口的方法
frame.addWindowListener(new WindowsAdapter(){ //匿名内部类 实现了WindowAdapter类
@Override //重写了windowclosing 方法
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0); //关闭窗口
}
})
通过addactionListener来添加按钮点击事件
addactionListener(ActionListener: alr) 调用该方法需要传进 ActionListener类型的数据 ActionListener为一个接口 需要创建类去实现ActionListener接口 并重写其中方法
public static void main(String[] args) {
Button button = new Button("按钮-1");
button.setActionCommand("button 1-1"); //给按钮1设置别名
Button button1 = new Button("按钮-2");
ActionListen actionListen = new ActionListen(); //该对象实现了 ActionListener接口
button.addActionListener(actionListen); //需要传入一个 ActionListener类型 的参数
button1.addActionListener(actionListen); //上面创建的ActionListen对象继承实现了该接口的方法
Frame frame1 = new Frame("按钮程序");
frame1.add(button,BorderLayout.WEST);//将按钮添加到窗口的西边
frame1.add(button1,"East");//将按钮添加到窗口的东边
frame1.setVisible(true);
}
}
//创建一个内部类继承ActrionListener接口 实现方法共用
class ActionListen implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) { //实现ActionListener 的方法
System.out.println("我是=>:"+e.getActionCommand());//输出 获取到的按钮信息
}
}
//先点击按钮-1 后点击按钮-2
控制台输出:
我是=>:button 1-1
我是=>:按钮-2
//如果进行setActionCommand操作 输出为设置文本 没有则输出按钮文本
//ActionListener接口的实例是需要传入addactionListener监听事件的参数
public class ActionListen implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) { //可以通过ActionEvent e来获取到被监听组件的一些行为
e.getActionCommand() //获取控件的labal或者别名 别名需要用set方法设置
e.getSource()//获得一些资源 返回一个Object类型的对象;
}
}
public class PaintTest2 {
public static void main(String[] args) { //思路 监听鼠标 将每次鼠标点击的点储存在集合中
new Mypaint("简易画图"); //创建画笔 遍历集合 在这些点的坐标上画圆⚪
} //每点击一次就遍历一次画一次
}
class Mypaint extends Frame{ //建一个内部类继承Frame 重写paint方法
ArrayList list=null; //建立一个集合用来存储鼠标点击时的坐标\
public Mypaint(String title){//有参构造方法
super(title); //调用父类构造方法创建一个窗口
setVisible(true);
setBounds(300,300,500,500);
list= new ArrayList(); //集合初始化
addMouseListener(new myListen());//添加鼠标监听事件
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {//关闭事件
super.windowClosing(e);
}
});
}
@Override
public void paint(Graphics g) { //画笔方法
Iterator it=list.iterator(); //迭代集合 将鼠标点击的坐标遍历出来 在坐标上画⚪
while (it.hasNext()){
Point point=(Point)it.next();
g.setColor(Color.blue);
g.fillOval(point.x,point.y,10,10);
}
}
private class myListen extends MouseAdapter{ //建立内部类继承鼠标点击事件适配器
//鼠标按压产生的事件
@Override
public void mousePressed(MouseEvent e) {
list.add(e.getPoint()); //获取鼠标点击时的点 添加到集合中
repaint(); //重画 每点击一次就重画一次
}
}
}
通过addKeyListener(KeyListener: k) 来添加键盘监听事件
具体用法:
public static void main(String[] args) {
Frame frame = new Frame("键盘敲击事件");
frame.setVisible(true);
frame.setBounds(200,200,500,500);
frame.addKeyListener(new KeyAdapter() { //匿名内部类 需要传入一个KeyListener的实例 KeyListener为接口
@Override //创建它的适配器 重写 keyPressed方法 三种方法用法一致 事件时间不同
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
int code=e.getKeyCode(); //获取触发键的Code值
if (code==KeyEvent.VK_SPACE){//如果 Code值等于空格键的Code值
System.out.println("我是空格键, 我被按压了");
};
}
});
}
按下空格键 控制台输出:
我是空格键, 我被按压了
重点:
//键盘上的每一个键都有一个相应的Code码 这些Code码在 KeyEvent 中都以静态常量的方式储存 都已VK_开头 可以直接调用;
//如 A的Code码 KeyEvent.VK_A B: KeyEvent.VK_B 回车键 KeyEvent.VK_Enter
//通过这些 Code码 可以识别出相应的触发键 判断出按压的键是哪个键;
Swing是对AWT的改良和扩展。
容器和组件与awt用法基本相同;
Swing中的容器和组件都以 J 开头 如: JFrame JButton JLabel …………
JFrame窗口和Frame窗口用法大致相同
JFrame jFrame = new JFrame("我的第一个swing窗口"); //初始化一个JFrame窗口
Container container=jFrame.getContentPane() //在jFrame上获取一个容器
container.add(Component comp) //在这个容器上添加组件 Component 组件
//在JDK1.5版以前要用上面这种方式才能在JFrame中添加组件 在之前JFrame相当与一个顶级的框架里面的容器需要手动获取/创建
jFrame.add(Component comp) //Jdk1.5 以后可以直接向 JFrame中添加组件
弹窗是一个新的窗口 继承于 Window类 其中的方法和JFrame中大多数都一样\
实例: 在一个窗口上点击按钮 显示 弹窗
public class JDialogDeom1 extends JFrame { //创建一个类继承JFrame类
public void init() { //窗口初始化方法
setVisible(true); //设置窗口可见
setLayout(null); //绝对定位布局
setSize(500,500); //设置窗口大小
Button button = new Button("弹出框"); //创建按钮
button.setBounds(0,250,500,50); //设置按钮的坐标和宽高
button.setBackground(Color.yellow); //设置按钮背景颜色
add(button); //将按钮添加到窗口
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //设置窗口关闭事件 结束所有进程
button.addActionListener(new ActionListener() { // 添加按钮点击监听事件
@Override
public void actionPerformed(ActionEvent e) {
new myDialog().setVisible(true); //按钮点击时 实例化弹窗并显示弹窗
}
});
}
public static void main(String[] args) {
new JDialogDeom1().init(); //实例化窗口 运行初始化方法
}
}
class myDialog extends JDialog { //内部类 继承JDialog
public myDialog() { //构造方法 实例化弹窗时会触发
setBounds(300,300,300,300); //设置弹窗坐标 宽高
setResizable(false); //设置弹窗
JLabel jLabel = new JLabel("我在B站学习狂神说Java系列课程"); //创建一个标签
jLabel.setBounds(100,100,100,100); //设置标签 在弹窗中的坐标 宽高
add(jLabel); //将标签添加到弹窗上
}
}
Jscroll简单理解就是 当文本或内容超出一个屏幕后会出现滚动条的面板
Font类中存在四种默认的字体格式:
Font.PLAIN(普通)
Font.BOLD(加粗)
Font.ITALIC(斜体)
Font.BOLD+ Font.ITALIC(粗斜体)
实例: 创建一个有滚动条的面板 并在文本域上设置字体样式
public class JscrollPaneTest {
public void init(){
JFrame jFrame = new JFrame(); //创建一个窗口
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //设置窗口关闭事件
jFrame.setBounds(200,200,300,390); //设置坐标 大小
JTextArea j=new JTextArea(); //创建一个文本域对象
j.setFont(new Font("微软雅黑", Font.BOLD, 20)); //设置文本域字体格式 :粗体 大小
JScrollPane jPane = new JScrollPane(j); //创建可滚动面板并将文本域添加到面板上
jFrame.add(jPane); //将面板添加到窗口
jFrame.setVisible(true); //设置窗口可见
}
public static void main(String[] args) {
new JscrollPaneTest().init(); //运行
}
}
JButton jButton = new JButton(String:title, Icon: icon) //title 按钮文本 icon :标签 可不传 可全传 可单传
jButton.setToolTipText("我是一个按钮"); //设置鼠标悬浮在按钮上的提示信息
用于放文字文本
JLabel jlabel=new JLabel(); //创建一个标签
jlabel.Horizontalalignment(int: alignment) //设置文本对齐 参数为 int类型
//如: //在SwingConstants常量类中这些参数已经被定义为静态常量 可以直接使用
jlabel.Horizontalalignment(SwingConstants.Center) //设置文本居中对齐 常量值为 0
jlabel.Horizontalalignment(SwingConstants.Left) //设置文本靠左对齐 常量值为 2
jlabel.Horizontalalignment(SwingConstants.Top) //设置文本靠上对齐 常量值为 1
可以将图片 或者 特殊形状 添加进Label中
实例: 画一个实心黑色圆的图标添加进Label中
//首先在下面创建一个内部类实现Icon接口 作为我们要创建的图标
public class IconLable extends JFrame { //创建一个类继承Frame 面向对象编程思想 将需要构建的窗口作为对象供外部调用
public void init(){ //窗口初始化方法
setBounds(100,100,500,500); //设置窗口坐标 宽高
Icon1 iconLable = new Icon1(20,20);
JLabel jLabel;
jLabel= new JLabel("图标标签",SwingConstants.CENTER); //创建一个Jlabel 参数为 显示文本 和 布局格式
jLabel.setIcon(iconLable); //向JLabel中添加 Icon图标对象
// jLabel=new JLabel("图标标签",iconLable,SwingConstants.CENTER); //也可以在创建Jlabel时直接添加Icon对象
jLabel.setBounds(100,100,100,100); //设置标签 坐标 宽高
add(jLabel); //将标签添加到窗口上那;
setVisible(true); //设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //设置关闭事件 终止进程
}
public static void main(String[] args) {
new IconLable().init();
}
}
class Icon1 implements Icon{ //实现Icon接口重写方法 创建我们需要的图标 Icon
private int width; //创建变量 宽高
private int height;
public Icon1() {} //无参构造
public Icon1(int width,int height) { //有参构造 外部调用时传参设置宽高
this.width=width;
this.height=height;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) { //画笔功能
g.fillOval(x,y,width,height); //画一个实心的圆 坐标为添加图标组件坐标 宽高为外部传参
}
@Override
public int getIconWidth() { //返回标签宽
return width;
}
@Override
public int getIconHeight() { //返回标签高
return height;
}
}
ImageIcon 类 可以直接创建对象使用
图片的缩放:
image.getscaledinstance(int width,5 int height,int hints) 方法创建此图像的缩放版本。返回一个新的 image 对象。
hints 为图片缩放模式 在 Image类 中已经创建好五种模式的静态常量 可以直接使用
关于五种图片的缩放模式 和 自适应组件窗口 可参考: JAVA中图片缩放getscaledinstance使其自适应JFrame
实例: 创建一个图画标签(JLabel) 并实现图片的缩放
public class ImageIconTest extends JFrame{ //创建一个JFrame窗口
public ImageIconTest() { //构造方法 实例化时执行
URL url=ImageIconTest.class.getResource("C.png"); //根据当前类获取图片的路径
ImageIcon i=new ImageIcon(url); //创建ImageIcon对象 将图片路径添加进去
Image image = i.getImage(); //获取ImageIcon对象中的图片 重新设置大小
image=image.getScaledInstance(100,100,Image.SCALE_DEFAULT); //采用默认的图像缩放算法创建此图像的缩放版本。返 回一个新的 image 对象。
//Image.SCALE_DEFAULT 为默认的图像缩放算法 是Imgage中的静态常量之一 这些常量分别代表不同的缩放方式 可以直接调用
i.setImage(image); //将新的图片对象添加到 ImageIcon 图片标签上
JLabel jLabel = new JLabel("图片标签",i,SwingConstants.CENTER); //将图片标签添加到 JLable中
jLabel.setSize(100,100); //设置标签大小
setBounds(200,200,500,500); //设置窗口坐标 大小
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //关闭事件
add(jLabel); //将图片标签添加到 窗口上
setVisible(true); //设置可见
}
public static void main(String[] args) {
new ImageIconTest(); //实例化窗口
}
}
注意:在一个选项里 单选按钮要放在同一个按钮组中 才能实现单选效果 在窗口添加组件时不能直接添加按钮组 需要添加按钮
按钮组:ButtonGroup ButtonGroup类实现了Serializable接口 是一个序列化对象 将添加进的按钮序列化 然后告诉jvm这几个按钮是一个选项的 而不是一个容器、组件 不能添加到窗口
实例 : 创建一组单选按钮 实现性别的单选功能
public class JRadioButtonTest {
public void init(){
JFrame jFrame = new JFrame();
jFrame.setLayout(new GridLayout(1,3)); //设置栅格式布局 一行 三列
jFrame.setBounds(200,200,300,300); //设置 窗口 坐标 宽高
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //窗口关闭事件
JRadioButton jRadioButton = new JRadioButton("男"); //单选按钮
JRadioButton jRadioButton1 = new JRadioButton("女"); //单选按钮
ButtonGroup buttonGroup = new ButtonGroup(); //建一个按钮组
buttonGroup.add(jRadioButton); //将两个单选按钮放在一个组中 实现单选效果
buttonGroup.add(jRadioButton1);
jFrame.add(new JLabel("性别:")); //在窗口添加一个标签
jFrame.add(jRadioButton); //窗口添加两个单选按钮
jFrame.add(jRadioButton1);
jFrame.setVisible(true); //设置窗口可见
}
public static void main(String[] args) {
new JRadioButtonTest().init(); //运行
}
}
和图片标签用法基本一致 关于用法和图片缩放详解 可参考上面图片标签
实例: 创建一个图片按钮
public class ImageButtonTest {
public void init() {
JFrame jFrame = new JFrame(); //新建窗口
jFrame.setLayout(null); //绝对布局
jFrame.setBounds(200,200,300,300); //设置窗口 坐标 大小
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //关闭事件
URL url=ImageButtonTest.class.getResource("C.png"); //获取图片路径
ImageIcon imageIcon = new ImageIcon(url); //建图片标签 并将图片添加进去
Image image = imageIcon.getImage().getScaledInstance(100,100,Image.SCALE_DEFAULT); //将图片缩放生成一个新的图片对象
imageIcon.setImage(image); //将缩放后的图片添加到图片标签里
JButton jButton= new JButton(imageIcon); //将图片标签添加到按钮中
jButton.setToolTipText("图片按钮"); //鼠标悬浮到按钮上的提示
jButton.setSize(100,100); //设置按钮大小
jFrame.add(jButton); //添加到窗口上
jFrame.setVisible(true); //设置窗口可见
}
public static void main(String[] args) {
new ImageButtonTest().init(); //运行初始化
}
}
可以实现多选功能 像QQ的登录面板一样 可以同时选择 自动登录 记住密码 也可以不选 也可以选一个
用法:
JCheckBox jCheckButton = new JCheckBox("学习");//通过add添加到窗口
实例: 创建 一个爱好的选项 实现爱好的多选功能
public class JCheckButtonTest {
public void init(){
JFrame jFrame = new JFrame();
jFrame.setLayout(new GridLayout(1,4)); //设置栅格式布局 一行 三列
jFrame.setBounds(200,200,300,300); //设置 窗口 坐标 宽高
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //窗口关闭事件
//创建三个复选按钮
JCheckBox jCheckButton = new JCheckBox("学习");
JCheckBox jCheckButton1 = new JCheckBox("打代码");
JCheckBox jCheckButton2 = new JCheckBox("调Bug");
jFrame.add(new JLabel("爱好:")); //在窗口添加一个标签
//窗口添加三个复选按钮
jFrame.add(jCheckButton);
jFrame.add(jCheckButton1);
jFrame.add(jCheckButton2);
jFrame.setVisible(true); //设置窗口可见
}
public static void main(String[] args) {
new JCheckButtonTest().init(); //运行
}
}
用法:
JComboBox comboBox = new JComboBox(Item:item) ; // item:集合中的一个元素
comboBox.addItem(); //添加一个集合元素
实例: 创建一个省份的下拉框
public class ComboboxTest {
public void init(){
JFrame jFrame = new JFrame();
jFrame.setLayout(null); //设置绝对定位布局
jFrame.setBounds(200,200,300,300); //设置 窗口 坐标 宽高
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //窗口关闭事件
//创建一个 ComboBox 下拉框对象 并添加三条item 选项
JComboBox comboBox = new JComboBox();
comboBox.setSize(100,30); //设置下拉框宽高
comboBox.addItem("省份");
comboBox.addItem("河南");
comboBox.addItem("广东");
jFrame.add(comboBox); //将下拉框添加到从窗口上
jFrame.setVisible(true); //设置窗口可见
}
public static void main(String[] args) {
new ComboboxTest().init(); //运行
}
}
属性及扩展用法参考 : Java——列表框:JList
用法
JList jList = new JList(final E[] listData); //listData: 列表数据 可以是数组、集合
//通过add来添加到容器上
实例 建立一个列表框放
public class JListTest {
public void init(){
JFrame jFrame = new JFrame();
jFrame.setLayout(null); //设置绝对定位布局
jFrame.setBounds(200,200,300,300); //设置 窗口 坐标 宽高
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //窗口关闭事件
String[] strings=new String[]{"选项一","选项二","选项三"}; //建立一个字符串数组
JList jList = new JList(strings); // JList(final E[] listData) listdata 集合 创建一个列表对象 将数组 或者集合放进去
jList.setSize(50,1000); //设置宽高
jFrame.add(jList); //组件添加到窗口
jFrame.setVisible(true); //设置窗口可见
}
public static void main(String[] args) {
new JListTest().init(); //运行
}
}
TextField 文本框
JPasswordField 密码框
TextArea 文本域
TextField(String text, int columns)
new JPasswordField(Document doc, String txt, int columns) //doc 保存JTextField的数据 还有监听数据的变化
new TextArea(int rows, int columns)
在swing中封装了窗口关闭事件方法 可以直接使用 不用再像awt中那样定义窗口监听事件来进行窗口关闭
关闭方法 :setDefaultCloseOperation( int : operation ) // 参数在window常量池中已经定义好 可以直接使用
实例:
public static void main(String[] : args){
JFrame jf=new JFrame("窗口关闭事件");
setBounds(300,300,500,500) //设置窗口初始化位置和宽高
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE) //结束窗口所有进程 程序停止运行
}
各个电脑运行配置不同 仅供参考。
以idea为例
修改idea运行配置 VM options:
修改为:
-Dfile.encoding=GB18030;
参考文章: [Idea解决AWT组件中文显示乱码] (https://blog.csdn.net/qq_15653601/article/details/80502594)
作用: 很好的代替了匿名内部类 简化代码
了解 : 百度百科
详解:深入浅出 Java8 lambda表达式
Java 中的 Lambda 表达式通常使用 (argument) -> (body)
语法书写,例如:
(arg1, arg2...) -> { body }
(type1 arg1, type2 arg2...) -> { body }
以下是一些 Lambda 表达式的例子:
(int a, int b) -> { return a + b; }
() -> System.out.println("Hello World");
(String s) -> { System.out.println(s); }
() -> 42
() -> { return 3.1415 };
//小蛇类
public class Snake {
public int length;//小蛇的长度
public int[] snakeX=new int[816]; //将游戏画面 分为长宽都为25的方块 宽为800 一行能存34个坐标 长600 能存25个坐标 x坐标最多存816 个坐标
public int[] snakeY=new int[816];
public String fx;
public Snake(){
length=3;
snakeX[0]=125;snakeY[0]=100; //初始化时小蛇头的坐标
snakeX[1]=100;snakeY[1]=100; //初始化时第一节体的坐标
snakeX[2]=75;snakeY[2]=100;
fx="R"; //初始时小蛇的方向
}
}
//食物类
public class Gamefood {
private static int foodx; //食物的坐标
private static int foody;
public static int getFoodx() {
return foodx;
}
public static int getFoody() {
return foody;
}
Random r=new Random();//随机数
public void Gamefood(){
//刷新食物坐标 Random.nextInt( int: ) 返回一个区间范围内的随机整数
foodx=25+25*r.nextInt(32); //设置食物X随机坐标
foody=75+25*r.nextInt(24); //设置食物Y随机坐标
}
}
//面板 方法类
public class GameJPanel extends JPanel{
public static int j=0; //测试键盘的点击次数
private Boolean isstart; //判断游戏是否为开始状态
private Boolean islose;
private int integral;
Gamefood gamefood ; //创建食物对象
Snake snake;
Timer t=new Timer(100,new GameActionlister()); ;
public GameJPanel(){ //构造方法 初始化游戏
init();
this.setFocusable(true); //获得焦点事件
addKeyListener(new GameKeyLinster()); //添加游戏键盘监听器和事件监听器
}
public void init(){
integral=0;
isstart=false;
islose=false;
snake=new Snake(); //初始化小蛇
gamefood=new Gamefood(); //初始化食物
setfood();
setBackground(Color.white); //设置背景颜色为白色
//事件类的方法不能重复向一个组件绑定会进行事件的累加
//addKeyListener(new GameKeyLinster());
}
public void setfood(){ //判断食物和身体不能重合
gamefood.Gamefood();
for (int i = 0; i <snake.length ; i++) {
if (Gamefood.getFoodx() == snake.snakeX[i] && Gamefood.getFoody() == snake.snakeY[i]) {
setfood();
}
}
}
//重写JPanel中的画板组件方法 paint用于直接向窗口中画图 paintComponent用于画组件 只能用add向容器中添加
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //清屏
g.fillRect(25,75,850,600); //画出游戏框
GameData.H.paintIcon(this,g,25,11); //将头部广告画入 窗口宽900 图片宽850 广告两边各留25;
//画头 头部方向判断画图
if (snake.fx.equals("R")) {
GameData.R.paintIcon(this,g,snake.snakeX[0],snake.snakeY[0]);
} else if (snake.fx.equals("L")) {
GameData.L.paintIcon(this,g,snake.snakeX[0],snake.snakeY[0]);
} else if (snake.fx.equals("U")) {
GameData.U.paintIcon(this,g,snake.snakeX[0],snake.snakeY[0]);
}else if (snake.fx.equals("D")) {
GameData.D.paintIcon(this,g,snake.snakeX[0],snake.snakeY[0]);
}
//画身体
for (int i = 1; i <snake.length ; i++) {
GameData.B.paintIcon(this,g,snake.snakeX[i],snake.snakeY[i]);
}
//画食物
GameData.F.paintIcon(this,g,Gamefood.getFoodx(),Gamefood.getFoody());
//判断游戏开始的状态
if (isstart==false){ //游戏未开始状态
g.setColor(Color.white); //将画笔颜色调成白色
g.setFont(new Font("微软雅黑",Font.BOLD,30)); // 设置画笔的颜色
g.drawString("按下空格开始游戏!",300,350); //将字符串画到面板上
}else {t.start();}
if (islose){
g.setColor(Color.red); //将画笔颜色调成红色
g.setFont(new Font("微软雅黑",Font.BOLD,30)); // 设置画笔的颜色
g.drawString("游戏失败,按下空格重新开始!",300,350); //将字符串画到面板上
}else {t.start();} //如果游戏状态为开始 定时器开始;
//画分数和积分
g.setColor(Color.white); //将画笔颜色调成白色
g.setFont(new Font("微软雅黑",Font.BOLD,17)); // 设置画笔的颜色
g.drawString("长度:"+snake.length,700,30); //将字符串画到面板上
g.drawString("分数:"+integral,700,50); //将字符串画到面板上
}
//键盘监听类
class GameKeyLinster implements KeyListener{
//键盘按压事件
@Override
public void keyPressed(KeyEvent e) {
//获取键盘Code码
int key=e.getKeyCode();
if (key==KeyEvent.VK_SPACE){ //按压空格事件
// System.out.println("我被点击了"+(j++)+"次"); 测试代码
//让游戏状态开启
if (islose){
init();
}else { isstart=!isstart;}
repaint(); //重画
}
if (isstart) { //当游戏状态为开始时
if (snake.fx=="R"&&key==KeyEvent.VK_LEFT){
return;
}
if (snake.fx=="L"&&key==KeyEvent.VK_RIGHT){
return;
}
if (snake.fx=="U"&&key==KeyEvent.VK_DOWN){
return;
}
if (snake.fx=="D"&&key==KeyEvent.VK_UP){
return;
}
if (key == KeyEvent.VK_RIGHT) { //按压上下左右时让蛇头随之变化
snake.fx = "R";
} else if (key == KeyEvent.VK_LEFT) {
snake. fx = "L";
} else if (key == KeyEvent.VK_DOWN) {
snake.fx = "D";
} else if (key == KeyEvent.VK_UP) {
snake.fx = "U";
}
repaint();//改变后重画
}
}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyReleased(KeyEvent e) {
}
}
//事件监听类
class GameActionlister implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
//事件监听
// 判断游戏是否开始
if (isstart&&islose==false) {
//调用一次就让 身体的坐标等于上一节身体的坐标 实现小蛇身体的移动
for (int i = snake.length - 1; i > 0; i--) {
snake.snakeX[i] = snake.snakeX[i - 1];
snake.snakeY[i] = snake.snakeY[i - 1];
}
//根据按键判断小蛇移动的方向,让头部移动每次移动一格
if (snake.fx.equals("R")) {
snake.snakeX[0] = snake.snakeX[0] + 25;
} else if (snake.fx.equals("L")) {
snake.snakeX[0] = snake.snakeX[0] - 25;
} else if (snake.fx.equals("U")) {
snake.snakeY[0] = snake.snakeY[0] - 25;
} else if (snake.fx.equals("D")) {
snake.snakeY[0] = snake.snakeY[0] + 25;
}
repaint(); //坐标更改后重画
//判断边距边框 超出边框时将坐标改为相反的第一个格的坐标
if (snake.snakeX[0] > 850) {
snake.snakeX[0] = 25;
}
if (snake.snakeX[0] < 25) {
snake.snakeX[0] = 850;
}
if (snake.snakeY[0] > 650) {
snake.snakeY[0] = 75;
}
if (snake.snakeY[0] < 75) {
snake.snakeY[0] = 650;
}
//当蛇头的坐标和食物的坐标的重合时 改变食物的坐标 让长度=1
if (snake.snakeX[0] == Gamefood.getFoodx() && snake.snakeY[0] == Gamefood.getFoody()) {
snake.length++;
integral+=5;
setfood();
}
//判断游戏失败 遍历小蛇坐标 如果蛇头和身体任意一节的坐标相同 就认定小蛇吃到自己 游戏失败;
for (int i = 1; i < snake.length; i++) {
if (snake.snakeX[0] == snake.snakeX[i] && snake.snakeY[0] == snake.snakeY[i]) {
islose = true; //让游戏状态等于失败
repaint();//重画
}
}
}
}
}
}
//窗口类 启动类
public class Gamestart {
public void init() {
JFrame frame = new JFrame("贪吃蛇小游戏");
frame.setBounds(300,150,900,720);
frame.setResizable(false);
frame.add(new GameJPanel());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
new Gamestart().init();
}
}