Java实训项目一一拼图游戏(附源码)

简介: Java实训项目一一拼图游戏(附源码)

1 实训基本信息

1.1 实训项目名称

(1)拼图游戏

1.2 实训环境

本次实训内容主要针对专业学生,实训形式以实战讲解为主导。实训课程由实训老师主讲,实训老师教学严谨又平易近人,讲解的内容非常细致和认真,对于重要的知识点内容老师还特意的标注下来,方便同学们回顾学习。

2 实训内容简介

2.1 拼图游戏

拼图游戏内容由若干小图像块组成的,其中有一个空白的小图像块,该图像块是来与别的图像块交换的,以此来实现大图像的拼凑。在Java标准环境下运行,通过鼠标点击图像块上下左右移动,完成大图像的拼凑。

通过所创建的窗体类、菜单、中间面板和左右面板完成设计拼图的交互界面 ,实现游戏登录、开始游戏、退出游戏、选择图片、图片缩放、图片分割、调整难易度、计数计时、打乱图片、判断拼图成功等功能。

游戏可以通过对图片文件的读取和加载,从多张图片中选择来进行拼图游戏,通过设置图像块的个数来实现对游戏难易度的调整,最后将游戏完成后所用时间和步数记录到游戏记录中,方便用户查看游戏记录。

3 项目开发过程

3.1 拼图游戏

3.1.1开发步骤

1、了解拼图游戏基本功能:

拼图游戏内容由若干小图像块组成的,通过鼠标点击图像块上下左右移动,完成图像的拼凑。

2、拼图游戏交互界面设计与开发:

通过创建窗体类、菜单、中间面板和左右面板完成设计拼图的交互界面 ,实现拼图游戏的基本功能。

3、图片的加载与分割:

使用Image类实现图片的缩放,ImageIO类实现图片的读写加载,通过接口类Icon,BufferedImage类获取BufferedImage类的对象实现图片分割。

4、图片随机打乱和交换:

产生随机数 Random rand=new Random();

          rand.nextInt(hs*ls)------[0,8]

具体操作:生成两个随机数表示数组下标,互换两个数组元素的位置,按钮的方法getX和getY可以获取按钮的坐标,利用按钮的单击事件的处理ActionListener可以使其图片交换。

5、判赢:

当用户移动按钮后进行判断,代码写在监听器的actionPerformed方法中,判断拼图是否成功,主要取决于每一个按钮通过索引下标获取的位置值,与当前按钮的位置值是否相同。

6、计时和计数功能的实现:

计时功能的实现主要是线程的设计,线程的定义方法:第一:继承Thread类,第二:实现Runnable接口,创建带实现接口的子类对象的Thread对象,MainJFrame实现Runnable接口,重写run方法;而计数则在主窗体中通过rp.times实现对变量的使用来计数。

7、游戏记录的保存:

当用户拼图成功后,记录当前信息到文件中,FileWriter追加写信息,FileReader完成读取数据。

4 游戏截图

5 程序源代码

登录界面部分(用户名:admin  密码:123)

1. import java.awt.Color;
2. import java.awt.Font;
3. import java.awt.GridLayout;
4. import java.awt.event.ActionEvent;
5. import java.awt.event.ActionListener;
6. 
7. import javax.swing.JButton;
8. import javax.swing.JFrame;
9. import javax.swing.JLabel;
10. import javax.swing.JOptionPane;
11. import javax.swing.JPasswordField;
12. import javax.swing.JTextField;
13. 
14. public class LoginPintu extends JFrame{
15.   JLabel jl1,jl2,jl3,jl4;
16.   JTextField jtf;//文本框
17.   JPasswordField jpf;//密码
18.   JButton jb1,jb2;
19.  public LoginPintu() {
20.   this.setTitle("拼图游戏");
21.   setBounds(400,350,500,400);
22.   //设置窗体为流式布局
23.   setLayout(new GridLayout(20,1));
24.   //空布局
25.   setLayout(null);
26.   init();
27.   setVisible(true);
28.   setDefaultCloseOperation(EXIT_ON_CLOSE);
29.   jb1.addActionListener(new ActionListener(){
30.     public void actionPerformed(ActionEvent e) {
31.       if(jtf.getText().trim().equals("admin")&&
32.       new String(jpf.getPassword()).trim().equals("123")) 
33.       {JOptionPane.showMessageDialog(null, "欢迎进入游戏!");
34.       new MainJFrame();}
35.       else if(jtf.getText().trim().length()==0||
36.       new String(jpf.getPassword()).trim().length()==0) 
37.       {JOptionPane.showMessageDialog(null, "用户名或密码不能为空!");}
38.       else {JOptionPane.showMessageDialog(null, "用户名或密码错误!");}
39.     }
40.   });
41.   jb2.addActionListener(new ActionListener() {
42.     public void actionPerformed(ActionEvent e) {
43.     //  System.exit(0);
44.       //获取事件源对象
45.       JButton jb=(JButton)e.getSource();
46.       jtf.setText(jb.getText());
47.     }
48.   });
49. 
50. }
51.  public void init() {
52.   jl1=new JLabel("拼图游戏登录窗口");
53.   jl2=new JLabel("用户名:");
54.   jl3=new JLabel("密码:");
55.   jtf=new JTextField(10);
56.   jpf=new JPasswordField(10);
57.   jb1=new JButton("登录");
58.   jb2=new JButton("取消");
59.     jl1.setBounds(150,30,200,60);
60.   jl2.setBounds(100, 120, 180, 30);
61.   jtf.setBounds(200, 120, 180, 30);
62.   jl3.setBounds(100, 180, 180, 30);
63.   jpf.setBounds(200, 180, 180, 30);
64.   jb1.setBounds(100, 260, 100, 30);
65.   jb2.setBounds(220, 260, 100, 30);
66.   Font font = new Font("楷体",Font.PLAIN,25);
67.   jl1.setFont(font);
68.   jl1.setForeground(Color.red);
69.   add(jl1);
70.   add(jl2);
71.   add(jtf);
72. add(jl3);
73. add(jpf);
74.   add(jb1);
75.   add(jb2);
76. }
77. public static void main(String[] args) {
78.   new LoginPintu(); 
79.   }
80. }

左面板部分

1. import java.awt.Image;
2. import java.net.MalformedURLException;
3. import java.net.URL;
4. 
5. import javax.swing.ImageIcon;
6. import javax.swing.JLabel;
7. import javax.swing.JPanel;
8. //左面板类
9. public class LeftJPanel extends JPanel {
10.    JLabel  jl;
11.    int width=700;
12.    int height=700;
13. 
14. //构造方法
15. //标签创建,指定图片,放置到面板中
16.    public LeftJPanel(){
17.      //左面板大小
18.      setSize(width,height);
19.      jl=new JLabel();
20.      jl.setSize(width,height);
21.      //把标签添加到面板中
22.      this.add(jl);
23.    }
24.    public void init(URL url){
25. 
26. 
27.      //绝对路径:访问文件是从盘符开始
28.     // ImageIcon icon=new ImageIcon("D:\\1picture\\s4.jpg");
29.      //相对路径:访问路径不是从盘符开始,可以是\,也可以是一个文件夹
30.     // ImageIcon icon=new ImageIcon("s4.jpg");//参数是字符串的相对路径,相对于当前项目根目录
31.      //相对路径下url的获取
32. 
33. //     //绝对路径的url的获取
34. //     URL url=null;
35. //  try {
36. //    url = new URL("file:\\D:\\1picture\\5.jpg");
37. //  } catch (MalformedURLException e) {
38. //    // TODO Auto-generated catch block
39. //    e.printStackTrace();
40. //  }
41.      ImageIcon icon=new ImageIcon(url);
42.      //方法一:图片缩放
43. //     Image image = icon.getImage();
44. //     Image image2 = image.getScaledInstance(700, 700, 1);
45. //     ImageIcon icon2 = new ImageIcon(image2);
46. //     jl.setIcon(icon2);
47.      //链式编程方式实现图片缩放
48.      jl.setIcon(new ImageIcon(icon.getImage().getScaledInstance(width, height, 1)));
49.     //刷新界面
50.      validate();
51.    }
52. }

右面板部分

1. import java.awt.Image;
2. import java.awt.event.ActionEvent;
3. import java.awt.event.ActionListener;
4. import java.awt.image.BufferedImage;
5. import java.io.FileInputStream;
6. import java.io.FileWriter;
7. import java.io.IOException;
8. import java.net.URL;
9. import java.util.Random;
10. 
11. import javax.imageio.ImageIO;
12. import javax.swing.ImageIcon;
13. import javax.swing.JButton;
14. import javax.swing.JOptionPane;
15. import javax.swing.JPanel;
16. 
17. import jdk.jfr.events.FileWriteEvent;
18. //右面板实现ActionListener接口,右面板也就成为了监听器
19. public class RightJPanel extends JPanel implements ActionListener{
20. 
21.   //面板的大小
22.   int width=700;
23.   int height=700;
24.   //定义按钮数组
25.   JButton[] jbs;
26.   //设置分割的行列数
27.   int hs=2,ls=2;
28.   //按钮的宽度和高度,指定是小图图片缩放的尺寸
29.   int widthbut,heightbut;
30. 
31.   //图片原始高度宽度
32.    int widthtp,heighttp;
33. 
34.    //小图的原始宽度高度
35.    int widthxt,heightxt;
36. 
37.    //实现步数计算的变量
38.    int times;
39. 
40.    //空白按钮
41.    JButton kb;
42.   public RightJPanel(){
43.     //面板布局是空布局
44.     setLayout(null);
45.     setSize(width,height);
46.       //init();
47. 
48.   }
49.   //创建按钮,并放置到右面板
50.   public void init(URL url) {
51.     //面板组件初始化前,先清除所有已有的组件
52.     this.removeAll();
53.     //创建按钮数组
54.     jbs=new JButton[hs*ls];
55.     //为每一个按钮实现初始化
56.     //计算按钮的宽度和高度
57.     //面板是700*700,拆分成3*3的9个区域
58.     //每一块区域的宽度  700/3
59.     //每一块区域的高度 700/3
60.     widthbut=width/ls;
61.     heightbut=height/hs;
62. 
63.      BufferedImage buf=null;
64.     try {
65.       buf = ImageIO.read(url);
66.       //获取原图的宽度、高度
67.        widthtp=buf.getWidth();
68.       heighttp=buf.getHeight();
69.       //获取小图的宽度和高度
70.        widthxt=widthtp/ls;
71.        heightxt=heighttp/hs;
72.     //每一块按钮的坐标位置确定
73.     for(int i=0;i<jbs.length;i++){
74.       jbs[i]=new JButton();
75.       jbs[i].setSize(widthbut,heightbut);
76.       //jbs[i].setText(i+"");
77.       //添加按钮前要确定坐标位置
78.       //横坐标 i=0   0    i=1   233    i=2   466
79.       //i=3   0   i=4  233
80.       //纵坐标 i=3
81.       jbs[i].setLocation((i%ls)*widthbut, i/ls*heightbut);
82.       //jbs[i].setIcon(null);
83.       //小图的获取
84.        BufferedImage subimage = buf.getSubimage(i%ls*widthxt, i/ls*heightxt, widthxt, heightxt);
85.        //小图的缩放
86.        Image image = subimage.getScaledInstance(widthbut, heightbut, 1);
87.        //将小图图片放置到按钮上
88.        jbs[i].setIcon(new ImageIcon(image));
89.       //添加按钮到右面板
90.       add(jbs[i]);
91.       //设置按钮不可用
92.       jbs[i].setEnabled(false);
93.       //设置按钮的监听,当按钮被单击,会到右面板中找actionPerformed方法执行
94.       jbs[i].addActionListener(this);
95.     }
96.     jbs[hs*ls-1].setIcon(null);
97.     kb=jbs[hs*ls-1];
98.     } catch (IOException e) {
99.       // TODO Auto-generated catch block
100.      e.printStackTrace();
101.    }
102. 
103. 
104.  }
105. 
106.  //打乱按钮在面板中显示的顺序
107.  public void randomOrder(){
108.    //创建随机数对象
109.    Random rand=new Random();
110.    //打乱多次
111.    for(int i=0;i<hs*ls;i++){
112.    //随机索引
113.    int index1=rand.nextInt(hs*ls);
114.    int index2=rand.nextInt(hs*ls);
115.    int x1=jbs[index1].getX();
116.    int y1=jbs[index1].getY();
117.    int x2=jbs[index2].getX();
118.    int y2=jbs[index2].getY();
119.    jbs[index1].setLocation(x2, y2);
120.    jbs[index2].setLocation(x1, y1);
121.    jbs[i].setEnabled(true);
122.    }
123.  }
124. 
125.  //按钮的单击事件执行的代码
126.  @Override
127.  public void actionPerformed(ActionEvent e) {
128.    // 判断单击按钮和空白按钮是否相邻,如果相邻,则位置互换
129.    //获取用户单击的按钮 ,通过ActionEvent e的方法gerSource获取事件源
130.    JButton jb=(JButton)(e.getSource());
131.    //获取单击按钮和空白按钮的坐标
132.    int x1=jb.getX();
133.    int y1=jb.getY();
134.    int x2=kb.getX();
135.    int y2=kb.getY();
136.    //判断是否可以移动
137.    //Math.abs(x1-x2)/widthbut + Math.abs(y1-y2)/heightbut==1
138.    if (Math.abs(x1-x2)/widthbut + Math.abs(y1-y2)/heightbut==1){
139.      jb.setLocation(x2, y2);
140.      kb.setLocation(x1, y1);
141.      times++;
142.    }
143.    //判断是否拼图成功
144.    if (isWin()){
145.      JOptionPane.showMessageDialog(null, "恭喜你,拼图成功");
146.      //使得按钮不可用
147.      for(int i=0;i<jbs.length;i++){
148.        jbs[i].setEnabled(false);
149.      }
150.      //提示用户输入名称
151.      //使用输入对话框
152.      String name = JOptionPane.showInputDialog("请输入你的姓名:");
153.      String info = hs+"*"+ls+"拼图记录:"+name+"的步数是:"+times+"\r\n";
154.      JOptionPane.showMessageDialog(null, hs+"*"+ls+"拼图记录:"+name+"的步数是:"+times+"\r\n");
155.      try {
156.        FileWriter fw = new FileWriter("D:\\游戏记录.dat",true);
157.        fw.write(info);
158.        fw.close();
159.      }catch (IOException e1) {
160.        e1.printStackTrace();
161.      }
162.    }
163. 
164.  }
165. 
166.  //判断是否拼图成功
167.  public boolean isWin() {
168. 
169.    //获取每一个按钮的坐标
170.    for(int i=0;i<jbs.length;i++){
171.      //jbs[i].setLocation((i%ls)*widthbut, i/ls*heightbut);由之前坐标设置给出下面的x,y
172.      int x=jbs[i].getX()/widthbut;
173.      int y=jbs[i].getY()/heightbut;
174.      //判断,通过下标值,也可以获取按钮的坐标   横坐标  i%ls    纵坐标 i/ls
175.      if (i%ls!=x || i/ls!=y  ){
176.        return false;
177.      }
178.    }
179.    return true;
180.  }
181. }

游戏功能部分

1. import java.awt.Color;
2. import java.awt.GridLayout;
3. import java.awt.event.ActionEvent;
4. import java.awt.event.ActionListener;
5. import java.io.File;
6. import java.io.FileReader;
7. import java.io.IOException;
8. import java.net.MalformedURLException;
9. import java.net.URL;
10. 
11. import javax.swing.ButtonGroup;
12. import javax.swing.JFileChooser;
13. import javax.swing.JFrame;
14. import javax.swing.JLabel;
15. import javax.swing.JMenu;
16. import javax.swing.JMenuBar;
17. import javax.swing.JMenuItem;
18. import javax.swing.JOptionPane;
19. import javax.swing.JPanel;
20. import javax.swing.JRadioButtonMenuItem;
21. import javax.swing.filechooser.FileNameExtensionFilter;
22. 
23. public class MainJFrame extends JFrame implements Runnable{
24. 
25.   //菜单
26.   //菜单栏
27.   JMenuBar jmenubar;
28.   //菜单  菜单、等级、帮助
29.   JMenu menu,menuclass,menuhelp;
30.   //菜单项  开始、退出、图片更换、关于游戏、游戏记录、清空记录
31.   JMenuItem itembegin,itemend,itemchange,itemabout,itemrecord,itemclear;
32.   //单选菜单项  简单、一般、困难
33.   JRadioButtonMenuItem itemeasy,itemnormal,itemhard;
34.   //中间面板
35.   JPanel jp;
36.   //左面板
37.   LeftJPanel lp;
38.   //右面板
39.   RightJPanel rp;
40.   //访问的图片
41.   URL url;
42.   //显示计时标签
43.   JLabel total_time;
44.   //起止时间
45.   long startTime,endTime;
46.   //创建线程对象,实现计时功能
47.   Thread th;
48.   //显示步数的标签
49.   JLabel total_count;
50.   //构造方法
51.   public MainJFrame(){
52.     //标题设置
53.     setTitle("拼图游戏");
54.     //窗体大小
55.     setSize(1440, 780);
56.     //窗体位置在容器/屏幕的正中间
57.     setLocationRelativeTo(null);
58.     //窗体大小不可变
59.     setResizable(false);
60.     //实现界面菜单初始化
61.     //创建一个线程对象
62.     th=new Thread(this);
63.     //界面菜单初始化
64.     menuinit();
65.     //各面板的初始化
66.     init();
67.     setDefaultCloseOperation(EXIT_ON_CLOSE);
68.     setVisible(true);
69.     //开始菜单
70.     itembegin.addActionListener(new ActionListener() {
71. 
72.       @Override
73.       public void actionPerformed(ActionEvent e) {
74.         //启动线程
75.         //如果线程没有启动,则调用start方法启动
76.         if(!th.isAlive()) th.start();
77.         startTime=System.currentTimeMillis();
78.         rp.times=0;
79.         rp.randomOrder();
80.       }
81.     });
82.     //结束游戏
83.     itemend.addActionListener(new ActionListener() {
84. 
85.       @Override
86.       public void actionPerformed(ActionEvent e) {
87.         System.exit(1);
88.       }
89.     });
90.     //选择难易度itemeasy,itemnormal,itemhard
91.     itemeasy.addActionListener(new ActionListener() {
92. 
93.       @Override
94.       public void actionPerformed(ActionEvent e) {
95.         //第一,传递2*2到右面板
96.         rp.hs=2;
97.         rp.ls=2;
98.         //第二,调用右面板组件初始化的方法
99.         rp.init(url);
100.      }
101.    });
102.    itemnormal.addActionListener(new ActionListener() {
103. 
104.      @Override
105.      public void actionPerformed(ActionEvent e) {
106.        //第一,传递3*3到右面板
107.        rp.hs=3;
108.        rp.ls=3;
109.        //第二,调用右面板组件初始化的方法
110.        rp.init(url);
111.      }
112.    });
113.    itemhard.addActionListener(new ActionListener() {
114. 
115.      @Override
116.      public void actionPerformed(ActionEvent e) {
117.        //第一,传递4*4到右面板
118.        rp.hs=4;
119.        rp.ls=4;
120.        //第二,调用右面板组件初始化的方法
121.        rp.init(url);
122.      }
123.    });
124.    //游戏记录显示
125.    itemrecord.addActionListener(new ActionListener() {
126. 
127.      @Override
128.      public void actionPerformed(ActionEvent e) {
129.        //info存储要显示的内容
130.        String info="";
131.        try {
132.          //判断文件是否存在
133.          File f = new File("D:\\游戏记录.dat");
134.          if(f.exists()) {
135.          //创建指向***的文件字符输入流对象
136.          FileReader fr = new FileReader("D:\\游戏记录.dat");
137.          //读取数据
138.          char[] chs = new char[1024];
139.          int len;
140.          while((len=fr.read(chs))!=-1) {
141.            //读取的结果放在info中
142.            info+=new String(chs,0,len);
143.          }
144. 
145.          fr.close();
146.          //通过消息框显示结果
147.          JOptionPane.showMessageDialog(null, info);
148.          }else {
149.            JOptionPane.showMessageDialog(null, "游戏记录为空!");
150.          }
151.        }catch (IOException e1) {
152.          e1.printStackTrace();
153.        }
154.      }
155.    });
156.    //关于游戏
157.    itemabout.addActionListener(new ActionListener() {
158. 
159.      @Override
160.      public void actionPerformed(ActionEvent e) {
161.        JOptionPane.showMessageDialog(null, "关于拼图游戏\r\n版本:v2.0\r\n作者:LWL\r\n欢迎进入游戏!");
162.      }
163.    });
164.    //清空记录
165.    itemclear.addActionListener(new ActionListener() {
166. 
167.      @Override
168.      public void actionPerformed(ActionEvent e) {
169.        File f = new File("D:\\游戏记录.dat");
170.        if(f.exists()) {
171.           f.delete();
172.        }
173.      }
174.    });
175.    //实现图片的更换
176.    itemchange.addActionListener(new ActionListener() {
177. 
178.      @Override
179.      public void actionPerformed(ActionEvent e) {
180.        //显示一个打开对话框,选择一个图片文件,将文件转换成url对象,调用左右面板的相应方法
181.        JFileChooser jfc=new JFileChooser();
182.        //设置文件的扩展名
183.        jfc.setFileFilter(new FileNameExtensionFilter("图片格式(jpg|png|gif|jpeg)", "jpg","png","gif","jpeg"));
184.        //弹出打开对话框
185.        int sd = jfc.showOpenDialog(MainJFrame.this);
186.        if (sd==jfc.APPROVE_OPTION)//如果用户选择了打开按钮
187.        {
188.          //获取用户选择的文件完整名称
189.          String file=jfc.getSelectedFile().getAbsolutePath();
190.          try {
191.            url=new URL("file:\\"+file);
192.            //更新两个面板的图片
193.            lp.init(url);
194.            rp.init(url);
195.          } catch (MalformedURLException e1) {
196.            // TODO Auto-generated catch block
197.            e1.printStackTrace();
198.          }
199.        }
200.      }
201.    });
202.  }
203. 
204.  public void init() {
205.    jp=new JPanel();
206.    //设置中间面板的布局方式
207.    jp.setLayout(new GridLayout(1,2));
208.    //提供左右面板的图片
209.     url=this.getClass().getResource("小狗.jpg");
210.    //创建左面板
211.    lp=new LeftJPanel();
212.    //对标签初始化
213.    lp.init(url);
214.    //将左面板添加到中间面板
215.    jp.add(lp);
216.    //创建右面板
217.    rp=new RightJPanel();
218.    //右面板的按钮初始化
219.    rp.init(url);
220.    //将右面板添加到中间面板
221.    jp.add(rp);
222.    //将中间面板添加到窗体
223.    add(jp);
224.  }
225. 
226.  public void menuinit() {
227.    jmenubar=new JMenuBar();
228.    menu=new JMenu("菜单");
229.    menuclass=new JMenu("等级");
230.    menuhelp=new JMenu("帮助");
231.    itembegin=new JMenuItem("开始游戏");
232.    itemend=new JMenuItem("结束游戏");
233.    itemchange=new JMenuItem("更换图片");
234.    itemabout=new JMenuItem("关于游戏");
235.    itemrecord=new JMenuItem("游戏记录");
236.    itemclear=new JMenuItem("清空记录");
237.    itemeasy=new JRadioButtonMenuItem("简单");
238.    itemnormal=new JRadioButtonMenuItem("一般");
239.    itemhard=new JRadioButtonMenuItem("困难");
240.    //为单选菜单分组,实现多选一
241.    ButtonGroup bg=new ButtonGroup();
242.    bg.add(itemeasy);
243.    bg.add(itemnormal);
244.    bg.add(itemhard);
245.    //添加菜单
246.    menu.add(itembegin);
247.    menu.add(itemend);
248.    menu.add(itemchange);
249. 
250.    menuclass.add(itemeasy);
251.    menuclass.add(itemnormal);
252.    menuclass.add(itemhard);
253. 
254.    menuhelp.add(itemabout);
255.    menuhelp.add(itemrecord);
256.    menuhelp.add(itemclear);
257. 
258.    jmenubar.add(menu);
259.    jmenubar.add(menuclass);
260.    jmenubar.add(menuhelp);
261. 
262.    //菜单栏添加到窗体
263.    this.setJMenuBar(jmenubar);
264.    itemeasy.setSelected(true);
265.    //创建一个线程对象
266.    th=new Thread(this);
267.    total_time=new JLabel("用时:");
268.    total_time.setForeground(Color.red);
269.    jmenubar.add(new JLabel("                    "));
270.    jmenubar.add(total_time);
271.    total_count=new JLabel("步数:");
272.    total_count.setForeground(Color.red);
273.    jmenubar.add(new JLabel("                    "));
274.    jmenubar.add(total_count);
275.  }
276. 
277.  public static void main(String[] args) {
278.    new MainJFrame();
279.  }
280. //实现计时并定时显示的run()方法
281.  @Override
282.  public void run() {
283.    while(true) {
284.      endTime=System.currentTimeMillis();
285.      total_time.setText("用时:"+(endTime-startTime)/1000+"秒");
286.      total_count.setText("步数:第"+rp.times+"步");
287.      try {
288.        Thread.sleep(500);
289.      }catch (InterruptedException e) {
290.        e.printStackTrace();
291.      }
292.    }
293.  }
294. }
目录
相关文章
|
1天前
|
Java Android开发
Eclipse 创建 Java 项目
Eclipse 创建 Java 项目
12 4
|
1天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
10 2
|
6天前
|
人工智能 监控 数据可视化
Java智慧工地信息管理平台源码 智慧工地信息化解决方案SaaS源码 支持二次开发
智慧工地系统是依托物联网、互联网、AI、可视化建立的大数据管理平台,是一种全新的管理模式,能够实现劳务管理、安全施工、绿色施工的智能化和互联网化。围绕施工现场管理的人、机、料、法、环五大维度,以及施工过程管理的进度、质量、安全三大体系为基础应用,实现全面高效的工程管理需求,满足工地多角色、多视角的有效监管,实现工程建设管理的降本增效,为监管平台提供数据支撑。
17 3
|
7天前
|
SQL Java 数据库连接
从理论到实践:Hibernate与JPA在Java项目中的实际应用
本文介绍了Java持久层框架Hibernate和JPA的基本概念及其在具体项目中的应用。通过一个在线书店系统的实例,展示了如何使用@Entity注解定义实体类、通过Spring Data JPA定义仓库接口、在服务层调用方法进行数据库操作,以及使用JPQL编写自定义查询和管理事务。这些技术不仅简化了数据库操作,还显著提升了开发效率。
17 3
|
11天前
|
运维 自然语言处理 供应链
Java云HIS医院管理系统源码 病案管理、医保业务、门诊、住院、电子病历编辑器
通过门诊的申请,或者直接住院登记,通过”护士工作站“分配患者,完成后,进入医生患者列表,医生对应开具”长期医嘱“和”临时医嘱“,并在电子病历中,记录病情。病人出院时,停止长期医嘱,开具出院医嘱。进入出院审核,审核医嘱与住院通过后,病人结清缴费,完成出院。
40 3
|
9天前
|
前端开发 Java 数据库
如何实现一个项目,小白做项目-java
本教程涵盖了从数据库到AJAX的多个知识点,并详细介绍了项目实现过程,包括静态页面分析、数据库创建、项目结构搭建、JSP转换及各层代码编写。最后,通过通用分页和优化Servlet来提升代码质量。
23 1
|
安全 Java
Java并发编程笔记之CopyOnWriteArrayList源码分析
并发包中并发List只有CopyOnWriteArrayList这一个,CopyOnWriteArrayList是一个线程安全的ArrayList,对其进行修改操作和元素迭代操作都是在底层创建一个拷贝数组(快照)上进行的,也就是写时拷贝策略。
19547 0
|
Java 安全
Java并发编程笔记之读写锁 ReentrantReadWriteLock 源码分析
我们知道在解决线程安全问题上使用 ReentrantLock 就可以,但是 ReentrantLock 是独占锁,同时只有一个线程可以获取该锁,而实际情况下会有写少读多的场景,显然 ReentrantLock 满足不了需求,所以 ReentrantReadWriteLock 应运而生,ReentrantReadWriteLock 采用读写分离,多个线程可以同时获取读锁。
3132 0
|
Java
Java并发编程笔记之FutureTask源码分析
FutureTask可用于异步获取执行结果或取消执行任务的场景。通过传入Runnable或者Callable的任务给FutureTask,直接调用其run方法或者放入线程池执行,之后可以在外部通过FutureTask的get方法异步获取执行结果,因此,FutureTask非常适合用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。
4293 0
|
Java 调度 API
Java并发编程笔记之Timer源码分析
timer在JDK里面,是很早的一个API了。具有延时的,并具有周期性的任务,在newScheduledThreadPool出来之前我们一般会用Timer和TimerTask来做,但是Timer存在一些缺陷,为什么这么说呢?   Timer只创建唯一的线程来执行所有Timer任务。
3005 0