一、实验项目名称

保龄球积分系统

二、实验描述

某甲位为加强团队合作,举行保龄球比赛,(比赛规则和计分规则如五所示)所示.出单位的个人按照白愿的原则自行报名参加,共有60人报名参赛,不分性别比赛,这60人按照比赛要求进行单人赛、双人赛、三人赛,五人赛。其中:双人赛,三人赛和五人赛团队由单位比赛组委会随机安排组队.最后举行精英赛.
具体保龄球规则

要求按照小组团队合作,该保龄球比赛计分系统至少具有如下功能:

  • 参赛的队员的基本信息进行管理
  • 参赛的队员分组管理
  • 比赛抽签模拟
  • 比赛情况模拟,犯规情况统计
  • 比赛计分统计
  • 名次排名统计

设计要求
界面比较美观;有一定的容错能力,例如:输入的成绩要合法,不能为负数,如果输入错误,要求重新输入.

三、实验步骤

获取完整源代码 gitHub 克隆 git@github.com:441712875al/example.git
项目目录结构

运行效果

1. 数据库设计

E-R图描述
数据库建表说明
根据概念设计可以在数据库中建2-3张表

  • . 关系隐式建表的方法是在n端加入关系的属性和另一个实体的主码,需要两张表

    • Player(pid,name,score[10],tid)

    Score[10]是10个分数,简便起见用数组表示,tid是外码

    • Team (tid,contestType,teamTolScore)
  • 显示建表是将关系独立作为一张表,需要三张表
    • Player(pid,name)
    • Team (tid,contestType,teamTolScore)
    • PT(pid,tid,grid1,…,grid10)

这里采用第二种方法建立三张表

-- 建立player表
CREATE TABLE `player` (`pId` int(11) NOT NULL,`name` char(10) DEFAULT NULL,PRIMARY KEY (`pId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8--建立team表
CREATE TABLE `team` (`tid` int(11) NOT NULL AUTO_INCREMENT,`contestType` char(10) NOT NULL,`teamTolScore` int(11) DEFAULT NULL,PRIMARY KEY (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=290 DEFAULT CHARSET=utf8--建立pt表
CREATE TABLE `pt` (`pId` int(11) NOT NULL,`tId` int(11) NOT NULL,`grid1` int(11) DEFAULT NULL,`grid2` int(11) DEFAULT NULL,`grid3` int(11) DEFAULT NULL,`grid4` int(11) DEFAULT NULL,`grid5` int(11) DEFAULT NULL,`grid6` int(11) DEFAULT NULL,`grid7` int(11) DEFAULT NULL,`grid8` int(11) DEFAULT NULL,`grid9` int(11) DEFAULT NULL,`grid10` int(11) DEFAULT NULL,`playerTolScore` int(11) DEFAULT NULL,`fouls` int(11) DEFAULT NULL,PRIMARY KEY (`pId`,`tId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

2. 实体层设计

Manager类

package com.ncu.example.pojo;import com.ncu.example.dao.PTDaoImpl;
import com.ncu.example.dao.PlayerDaoImpl;
import com.ncu.example.dao.TeamDaoImpl;
import com.ncu.example.view.PersonScore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.*;@Repository
public class Manager {private List<Player> players;private List<Team> teams;@Autowiredprivate GroupStrategy groupStrategy;@Autowiredprivate PTDaoImpl ptDaoImpl;@Autowiredprivate TeamDaoImpl teamDaoImpl;@Autowiredprivate PlayerDaoImpl playerDaoImpl;/*** 参赛选手报名* @param pid* @param name*/public void register (int pid,String name){if(players == null)players = new ArrayList<>();Player newPlayer = new Player(pid,name);players.add(newPlayer);savePlayer(newPlayer);}/*** 为每个参赛选手分组* @param contestType*/public void group(ContestType contestType){players = getPlayers();groupStrategy.setPlayers(players);groupStrategy.setCounter(teamDaoImpl.findMaxId());groupStrategy.setContestType(contestType);//将新产生的分组加入到teams中setTeams(groupStrategy.conduct());}//根据选手每次出手击倒的瓶数进行分数统计public void calcScore(){teams.forEach(team->{for(Player e:team.getMembers()){List<Integer>[] grades= e.play();for(int i=0;i<10;i++){for(Integer o:grades[i]){e.getScores()[i]+=o;}if(i>=9)continue;int count = 0;//根据情形得出本轮分数额外获得加分次数if(grades[i].size()==1) count = 2;else if(e.getScores()[i]==10) count = 1;for(int j=i+1;count>0;j++){for(int k=0;k<grades[j].size();k++){e.getScores()[i]+=grades[j].get(k);count--;if(count<=0)break;}}}//获得个人总分和小组的总分e.setTolScore(getPlayerTolscore(e));team.setTolScore(team.getTolScore()+e.getTolScore());}});saveTeams();//保存每个组信息savePt();//将小组成员的分数保存}public int getPlayerTolscore(Player player){int scoreTmp = 0;for(Integer o:player.getScores())scoreTmp+=o;return scoreTmp;}/*** 保存参赛选手信息* @param*/public void savePlayer(Player player){playerDaoImpl.insertPlayer(player);}/*** 裁判将小组的信息保存到team表中* @param*/public void saveTeams(){teams.forEach(e->teamDaoImpl.insertTeam(e));}/*** 裁判保存每个小组参赛队员的成绩*/public void savePt()  {teams.forEach(e->{ptDaoImpl.insertPt(e);});}/*** 查询个人比赛的所有成绩* @param pid* @param name* @return*/public List<PersonScore> findGrade(int pid,String name){return ptDaoImpl.findPlayerGrade(pid,name);}public List<Player> getPlayers() {players = getPlayerDaoImpl().findAllPlayer();return players;}public void setPlayers(List<Player> players) {this.players = players;}public List<Team> getTeams() {return teams;}public void setTeams(List<Team> teams) {this.teams = teams;}public GroupStrategy getGroupStrategy() {return groupStrategy;}public void setGroupStrategy(GroupStrategy groupStrategy) {this.groupStrategy = groupStrategy;}public PTDaoImpl getPtDaoImpl() {return ptDaoImpl;}public TeamDaoImpl getTeamDaoImpl() {return teamDaoImpl;}public PlayerDaoImpl getPlayerDaoImpl() {return playerDaoImpl;}
}

Player类

package com.ncu.example.pojo;import java.util.ArrayList;
import java.util.List;
import java.util.Random;public class Player {private int id;private String name;private int[] scores = new int[10];private List<Integer>[] grades =new List[10];private int tolScore;private int fouls =0;public Player() {}public Player(int id, String name) {this.id = id;this.name = name;}/*** 返回一个记录选手每次出手击倒的瓶子的数量* @return*/public void initScore(){for(int i=0;i<10;i++)scores[i] = 0;}public List<Integer>[]  play(){initScore();for(int i=0;i<10;i++){grades[i] = new ArrayList<Integer>();int firstRoll = roll(10);int secondRoll = 0;grades[i].add(firstRoll);if(firstRoll <10||i==9){//第一次出手未全部击倒,第十轮肯定要扔第二次secondRoll = roll(10-firstRoll==0?10:10-firstRoll);//第一次全部击倒则此时再扔竖立的瓶子为10,否则为剩余的数量grades[i].add(secondRoll);}if(i==9&&firstRoll+secondRoll>=10){grades[i].add(roll(10-secondRoll==0?10:10-secondRoll));}}return grades;}/*** 返回选手扔一次击倒的瓶数* @param bottleNum 可击倒瓶子的数量* @return*/public int roll(int bottleNum){Random rand = new Random();int grade = rand.nextInt(bottleNum+2);//bottleNum+1作为犯规情况模拟if(grade==bottleNum+1){grade = 0;fouls++;}return grade;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int[] getScores() {return scores;}public void setScores(int[] scores) {this.scores = scores;}public List<Integer>[] getGrades() {return grades;}public void setGrades(List<Integer>[] grades) {this.grades = grades;}public int getTolScore() {return tolScore;}public void setTolScore(int tolScore) {this.tolScore = tolScore;}public int getFouls() {return fouls;}public void setFouls(int fouls) {this.fouls = fouls;}@Overridepublic String toString() {return getName();}
}

Team类

package com.ncu.example.pojo;import java.util.Arrays;
import java.util.List;public class Team {private int id;private List<Player> members;private int tolScore = 0;private ContestType contestType;private String membersDesc;public Team() {}public Team(int id, List<Player> members) {this.id = id;this.members = members;}public  Team(int id, List<Player> members, ContestType contestType) {this.id = id;this.members = members;this.contestType = contestType;}public int getId() {return id;}public void setId(int id) {this.id = id;}public List<Player> getMembers() {return this.members;}public void setMembers(List<Player> members) {this.members = members;}public int getTolScore() {return tolScore;}public void setTolScore(int tolScore) {this.tolScore = tolScore;}public ContestType getContestType() {return contestType;}public void setContestType(ContestType contestType) {this.contestType = contestType;}public String getMembersDesc() {return Arrays.toString(members.toArray());}@Overridepublic String toString() {String desc ="";for (Player e : members) {desc+=e.getName()+" ";}return desc;}
}

GroupStrategy类

使用这个类是为了体现多态性,不管什么类型的比赛都能此类来完成分组的任务

package com.ncu.example.pojo;import org.springframework.stereotype.Repository;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;@Repository
public class GroupStrategy {private List<Player> players;private ContestType contestType;private int counter;/*** 根据比赛形式给每个参赛队员分组*/public List<Team> conduct(){Collections.shuffle(players);List<Team> teams = new ArrayList<>();int num = contestType.getPlayerNum();//获取这种比赛需要的队员人数for(int i=0;i<players.size();i+=num){List<Player> members = new ArrayList<>();for(int j=i;j<i+num;j++){members.add(players.get(j));}teams.add(new Team(++counter,members, getContestType()));}return teams;}public List<Player> getPlayers() {return players;}public void setPlayers(List<Player> players) {this.players = players;}public ContestType getContestType() {return contestType;}public void setContestType(ContestType contestType) {this.contestType = contestType;}public int getCounter() {return counter;}public void setCounter(int counter) {this.counter = counter;}
}

ContestType类

package com.ncu.example.pojo;public enum ContestType {SINGLE("单人赛",1),DOUBLE("双人赛",2),TRIPLE("三人赛",3),QUINTUPLE("五人赛",5),ELITE("精英赛",1);private String desc;private int playerNum;ContestType(String desc, int playerNum) {this.desc = desc;this.playerNum = playerNum;}public String getDesc() {return desc;}public int getPlayerNum() {return playerNum;}
}

3.持久层

PlayerDao

对player表的数据库操作都在此接口中

package com.ncu.example.dao;import com.ncu.example.pojo.Player;
import org.springframework.stereotype.Repository;import java.util.List;@Repository
public interface PlayerDao {/*** 登记参赛选手信息* @param player 选手信息类*/int insertPlayer(Player player);/***查询所有参赛选手* @return 查询到的所有选手*/List<Player> findAllPlayer();/*** 删除指定选手的信息* @param player 选手的信息* @return*/int  deletePlayer(Player player);
}

PlayerDaoImpl

package com.ncu.example.dao;import com.ncu.example.pojo.Player;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;import java.util.ArrayList;
import java.util.List;@Repository
public class PlayerDaoImpl implements PlayerDao {@Autowiredprivate  JdbcTemplate jdbcTemplate;//插入一个选手SQLprivate final String INSERT_PLAYER_SQL = "insert into player(pid,name) values(?,?)";//查询所有选手的SQLprivate final String SELECT_PLAYERS_SQL = "select pid,name from player";//查询某个选手的信息private final String SELECT_PLAYER_SQL = "select count(*) from player where pid=? and name=?";//删除一个选手的信息private final String DELETE_PLAYER_SQL = "delete from player where pid = ? and name =?";/*** 在选手信息表中插入一条信息,表示已报名参赛* @param player 选手信息类*/@Overridepublic int insertPlayer(Player player) {Object[] args = {player.getId(),player.getName()};jdbcTemplate.update(INSERT_PLAYER_SQL,args);return 1;}/*** 查询所有的选手信息* @return*/@Overridepublic List<Player> findAllPlayer() {List<Player> playersTmp = new ArrayList<>();jdbcTemplate.query(SELECT_PLAYERS_SQL,e->{playersTmp.add(new Player(e.getInt("pid"),e.getString("name")));});return playersTmp;}/*** 删除指定选手的信息* @param player 选手信息类* @return*/@Overridepublic int  deletePlayer(Player player) {Object[] args = {player.getId(),player.getName()};if(jdbcTemplate.queryForObject(SELECT_PLAYER_SQL,args,Integer.class)!=1)return 0;//数据库没有改选手信息jdbcTemplate.update(DELETE_PLAYER_SQL,args);return 1;}}

PTDao

对PT表的操作以及表的连接操作都在这个接口中

package com.ncu.example.dao;import com.ncu.example.pojo.ContestType;
import com.ncu.example.pojo.Team;
import com.ncu.example.view.GameScore;
import com.ncu.example.view.PersonScore;import org.springframework.stereotype.Repository;import java.util.List;@Repository
public interface PTDao {/*** 插入team组选手的的选手的比赛成绩* @param team 队伍信息类*/void insertPt(Team team);/*** 查询比赛的成绩,结果按总分排名* @param contestType 比赛类型* @return 赛事分数信息列表*/List<GameScore> findTeamGrade(ContestType contestType);/*** 根据id和姓名查询个人的所有成绩* @param pId 个人的编号* @param name 选手姓名* @return 个人成绩*/List<PersonScore> findPlayerGrade(int pId, String name);/*** 查询小组的队员信息* @return*/List<Team> findTeamINfo();
}

PTDaoImpl

package com.ncu.example.dao;import com.ncu.example.pojo.ContestType;
import com.ncu.example.pojo.Player;
import com.ncu.example.pojo.Team;
import com.ncu.example.view.GameScore;
import com.ncu.example.view.PersonScore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Repository;import java.util.ArrayList;
import java.util.List;@Repository
public class PTDaoImpl implements PTDao {@Autowiredprivate  JdbcTemplate jdbcTemplate;//保存比赛成绩SQLprivate final static String INSERT_GRADE_SQL= "" +"INSERT INTO pt (pid,tid," +"grid1,grid2,grid3,grid4,grid5," +"grid6,grid7,grid8,grid9,grid10,playertolScore,fouls) " +"VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";//查询小组比赛成绩SQLprivate final static String SELECT_TEAMGRADE_SQL ="select t.tid,name,teamtolScore,p.pId,contestType, rank() over(ORDER BY teamTolScore desc) " +"degree " +"from team t,player p,pt\n" +"where p.pid=pt.pid and pt.tId=t.tId and contestType=? ";//查询每种比赛个人的成绩SQLprivate final static String SELECCT_PLAYERGRADE_SQL = "" +"select pt.* ,name,t.tid,t.contestType from player p,pt,team t  " +"where p.pid=pt.pid and t.tId=pt.tid and p.pId = ? and p.name =?";//查询每个小组及其队员的信息SQLprivate final static String SELECT_TEAMANDPLAYER_SQL = "select t.tid,pt.pid,name,contestType from team t,pt,player p " +"where t.tid=pt.tid and pt.pid=p.pid order by 1;";/*** 向Pt表中插入一个小组分数信息* @param team*/@Overridepublic void insertPt(Team team) {//插入的数据对象team.getMembers().forEach(player->{Object[] args = { player.getId(),team.getId(),player.getScores()[0],player.getScores()[1],player.getScores()[2],player.getScores()[3],player.getScores()[4],player.getScores()[5],player.getScores()[6],player.getScores()[7],player.getScores()[8],player.getScores()[9],player.getTolScore(), player.getFouls()};jdbcTemplate.update(INSERT_GRADE_SQL, args);});}/*** 查询指定比赛的成绩并排序* @param contestType* @return*/@Overridepublic List<GameScore> findTeamGrade(ContestType contestType) {List<GameScore> gameScores = new ArrayList<>();Object[] args = {contestType.getDesc()};jdbcTemplate.query(SELECT_TEAMGRADE_SQL,args,e->{GameScore gameScoreTmp = new GameScore(e.getInt("tId"),e.getInt("pId"),e.getString("name"),e.getInt("teamtolScore"),e.getInt("degree"));gameScores.add(gameScoreTmp);});return gameScores ;}/*** 查询个人的所有比赛的成绩* @param pId* @param name* @return*/@Overridepublic List<PersonScore> findPlayerGrade(int pId, String name){List<PersonScore> scores = new ArrayList<>();Object[] args = {pId,name};jdbcTemplate.query(SELECCT_PLAYERGRADE_SQL, args,e->{PersonScore scoretmp = new PersonScore(e.getString("name"),e.getString("contestType"), e.getInt("pId"),e.getInt("tId"),e.getInt("grid1"),e.getInt("grid2"),e.getInt("grid3"),e.getInt("grid4"),e.getInt("grid5"),e.getInt("grid6"),e.getInt("grid7"),e.getInt("grid8"),e.getInt("grid9"),e.getInt("grid10"),e.getInt("fouls"), e.getInt("playerTolScore"));scores.add(scoretmp);});return scores;}/*** 查询小组的队员信息* @return*/@Overridepublic List<Team> findTeamINfo() {List<Team> teamList = new ArrayList<>();jdbcTemplate.query(SELECT_TEAMANDPLAYER_SQL,e-> {if(!teamList.isEmpty()&&teamList.get(teamList.size()-1).getId()==e.getInt("tID")){teamList.get(teamList.size()-1).getMembers().add(new Player(e.getInt("pId"),e.getString("name")));return ;}List<Player> playerList = new ArrayList<>();playerList.add(new Player(e.getInt("pId"),e.getString("name")));teamList.add(new Team(e.getInt("tId"),playerList));});return teamList;}}

TeamDao

对Team表的数据库操作都在这个接口中

package com.ncu.example.dao;import com.ncu.example.pojo.Team;
import org.springframework.stereotype.Repository;@Repository
public interface TeamDao {/*** 向Team表中插入一条数据* @param team 保存了队伍的信息*/void insertTeam(Team team);/*** 查询在数据库中的ID最大值* @return*/int findMaxId();
}

TeamDaoImpl

package com.ncu.example.dao;import com.ncu.example.pojo.Team;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;import java.util.ArrayList;
import java.util.List;@Repository
public class TeamDaoImpl implements TeamDao {@Autowiredprivate JdbcTemplate jdbcTemplate;//插入小组信息的sqlprivate final String INSERT_TEAM_SQL = "insert into team (tid,teamtolScore,contestType) values (?,?,?)";//查询id最大值的SQLprivate final String SELECT_MAX_TID_SQL = "select max(tid) maxID from team";/*** 将小组的信息插入到team表中* @param team 队伍信息类*/@Overridepublic void insertTeam(Team team) {Object[] args = {team.getId(),team.getTolScore(),team.getContestType().getDesc()};jdbcTemplate.update(INSERT_TEAM_SQL,args);}/*** 查询在数据库中的ID最大值* @return*/@Overridepublic int findMaxId() {List<Integer> maxId = new ArrayList<>();jdbcTemplate.query(SELECT_MAX_TID_SQL,e->{maxId.add(e.getInt("maxId"));});return maxId.get(0);}}

持久层都是一些增删改查操作,没有太多的技术含量,因此不再赘述,不太懂得jdbctemplate函数的具体使用方法的请自行百度

4.视图层

该层有许多模型类,写的太恶心了,但是没办法,必须要用在fxml文件中才能渲染出数据

  • GameScore
  • PersonScore
  • Score
  • SampleView ,该类用来加载fxml文件

5.控制层

Controller

这个控制器的主要任务是利用Manager对象获取后端的数据,然后将数据在javafx中渲染出来,不会fxml的请自行去相关网站取经

package com.ncu.example.Controller;import com.ncu.example.pojo.ContestType;
import com.ncu.example.pojo.Manager;
import com.ncu.example.pojo.Player;
import com.ncu.example.pojo.Team;
import com.ncu.example.view.GameScore;
import com.ncu.example.view.PersonScore;
import de.felixroske.jfxsupport.FXMLController;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import org.springframework.beans.factory.annotation.Autowired;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;@FXMLController
public class Controller {@Autowiredprivate Manager manager;@FXMLprivate VBox Menu;@FXMLprivate Pane gamePane;@FXMLprivate TableView<GameScore> gameTable;@FXMLprivate ChoiceBox<?> gameType;@FXMLprivate Pane informationPane;@FXMLprivate Button btnAdd;@FXMLprivate Button btnDelete;@FXMLprivate TextField InfoName;@FXMLprivate TextField InfoId;@FXMLprivate Label hint2;@FXMLprivate TextField InfoAge;@FXMLprivate Label hint3;@FXMLprivate TextField InfoSex;@FXMLprivate Label hint21;@FXMLprivate TextField InfoTel;@FXMLprivate TableView<Player> playersTable;@FXMLprivate Button btnQueryPlayer;@FXMLprivate Pane resultPane;@FXMLprivate Button btnQueryResult;@FXMLprivate TextField resultName;@FXMLprivate TextField resultId;@FXMLprivate TableView<PersonScore> resultTable;@FXMLprivate Pane teamPane;@FXMLprivate TableView<Team> teamTable;@FXMLprivate TableColumn<?, ?> infoTable1;@FXMLprivate TableColumn<?, ?> infoTable11;@FXMLprivate TableColumn<?, ?> infoTable111;@FXMLprivate Button btnQueryTeam;@FXMLprivate TextField teamId;/*** 切换面板,设赛事管理界面可见* @param event*/@FXMLvoid Game(ActionEvent event) {closeAll();gamePane.setVisible(true);}/*** 切换面板,信息管理设界面可见* @param event*/@FXMLvoid Info(ActionEvent event) {closeAll();informationPane.setVisible(true);}/*** 切换面板,设结果查询界面可见* @param event*/@FXMLvoid Result(ActionEvent event) {closeAll();resultPane.setVisible(true);}/*** 切换面板,设分组管理界面可见* @param event*/@FXMLvoid Team(ActionEvent event) {closeAll();teamPane.setVisible(true);}//##################################以下为数据库操作##########################################/*** 依据输入信息,添加运动员* @param event*/@FXMLvoid addPlayer(ActionEvent event) {//运动员信息String name = InfoName.getText();try{int pId =Integer.parseInt(InfoId.getText());manager.register(pId,name);showInfoMessage("register successfully!");}catch (Exception e){showInfoMessage("ID 格式输入有误或编号重复,请重新输入!");}}/*** 依据输入信息,删除运动员* @param event*/@FXMLvoid deletePlayer(ActionEvent event) {//运动员信息String name = InfoName.getText();int pId = Integer.parseInt(InfoId.getText());if(manager.getPlayerDaoImpl().deletePlayer(new Player(pId,name))!=0)showInfoMessage("delete player "+name+" successfully!");elseshowErroMessage("fail to delete player "+name);playersTable.refresh();}/*** 显示所有运动员的个人信息* @param event*/@FXMLvoid displayPlayers(ActionEvent event) {//向数据库获取运动员信息List<Player> players = manager.getPlayers();ObservableList<Player> data = FXCollections.observableList(players);((TableColumn)playersTable.getColumns().get(0)).setCellValueFactory(new PropertyValueFactory<Player, String>("name"));((TableColumn)playersTable.getColumns().get(1)).setCellValueFactory(new PropertyValueFactory<Player, String>("id"));playersTable.setItems(data);}/*** 显示分组情况,* @param event*/@FXMLvoid displayTeam(ActionEvent event) {//存放运动员信息List<Team> teams = manager.getPtDaoImpl().findTeamINfo();ObservableList<Team> data = FXCollections.observableList(teams);String[] list = {"id","membersDesc"};for(int i=0;i<2;i++){((TableColumn)teamTable.getColumns().get(i)).setCellValueFactory(new PropertyValueFactory<Team, String>(list[i]));}teamTable.setItems(data);}/*** 根据姓名和ID查询、显示各种类型比赛的成绩* @param*/@FXMLpublic void queryResult(ActionEvent event){//查询对象信息String name = resultName.getText();int pId = Integer.parseInt(resultId.getText());List<PersonScore> score = manager.getPtDaoImpl().findPlayerGrade(pId,name);ObservableList<PersonScore> data = FXCollections.observableList(score);String[] tableList = {"gameType","pid","tid","name","score1","score2","score3","score4","score5","score6","score7","score8","score9","score10","fouls","totalScore"};for(int i=0;i<16;i++){((TableColumn)resultTable.getColumns().get(i)).setCellValueFactory(new PropertyValueFactory<GameScore, String>(tableList[i]));}resultTable.setItems(data);}/*** 获得比赛的类型,并显示相应比赛类型的结果* @param event*/@FXMLvoid startGame(ActionEvent event) {//获取选择比赛类型ContestType contestType = toContestType((String) gameType.getSelectionModel().getSelectedItem());List<GameScore> gameScores = null;if(contestType!=ContestType.ELITE){//比赛前分组manager.group(contestType);//后台模拟选手击打保龄球后,裁判统计分数manager.calcScore();gameScores = manager.getPtDaoImpl().findTeamGrade(contestType);}elsegameScores = calcEliteScore();//表格中显示数据ObservableList<GameScore> data = FXCollections.observableList(gameScores);String[] list = {"tid","name","pid","score","rank"};for(int i=0;i<5;i++){((TableColumn) gameTable.getColumns().get(i)).setCellValueFactory(new PropertyValueFactory<GameScore, String>(list[i]));}gameTable.setItems(data);}/*** 计算出精英赛的成绩* @return*/List<GameScore> calcEliteScore() {List<GameScore> gameScores = new ArrayList<>();//遍历每个选手的比赛得出总成绩manager.getPlayers().forEach(e -> {int score = 0;for (PersonScore p : manager.getPtDaoImpl().findPlayerGrade(e.getId(), e.getName())) {score += p.getTotalScore();}gameScores.add(new GameScore(e.getId(), e.getId(), e.getName(), score, 0));});//按分数排序Collections.sort(gameScores,(o1,o2)->{return o2.getScore()-o1.getScore();});//设置排名int rank=1;for(GameScore score:gameScores)score.setRank(rank++);return gameScores;}/*** 将右侧所有的面板关闭*/void closeAll(){informationPane.setVisible(false);gamePane.setVisible(false);resultPane.setVisible(false);teamPane.setVisible(false);}public void showInfoMessage(String message){Alert alert = new Alert(Alert.AlertType.INFORMATION);alert.setContentText(message);alert.showAndWait();}public void showErroMessage(String message){Alert alert = new Alert(Alert.AlertType.ERROR);alert.setContentText(message);alert.showAndWait();}/*** 将接受的比赛类型有String转换成ConTestType* @param game* @return*//*** 将接受到的字符串* @param game* @return*/public static ContestType toContestType(String game){ContestType contestType = null;switch (game){case "单人赛" : contestType = ContestType.SINGLE;break;case "双人赛" :contestType = ContestType.DOUBLE;break;case "三人赛" :contestType = ContestType.TRIPLE;break;case "五人赛" :contestType = ContestType.QUINTUPLE;break;case "精英赛" :contestType = ContestType.ELITE;break;}return contestType;}
}

总结

1. 如何将spring和Javafx结合起来

  • 首先需要写一个FXML的view类(上面的SampleView类)让其继承AbstractFxmlView并使用@FXMLView标记给出fxml文件路径就能加载fxml。
  • 然后控制器需要用@FXMLController标记才能让Spring容器管理Controller对象的创建。
  • 最后在Spring的启动类中继承AbstractJavaFxApplicationSupport类,并加载出FXMLView类即可。

ps:使用javafx需要添加第三方依赖

            <dependency><groupId>de.roskenet</groupId><artifactId>springboot-javafx-support</artifactId><version>2.1.6</version></dependency><dependency><groupId>de.roskenet</groupId><artifactId>springboot-javafx-test</artifactId><version>1.3.0</version><scope>test</scope></dependency>

2. 让spring管理JDBC的自动注入

  • 我在创建对象时没有从始至终的使用spring的自动注入,而是在某处使用了new来创建对象,然后就导致新建对象中其他自动注入的对象无法从spring容器自动创建,对于这个问题的解决办法就是一直使用AutoWired就能避免自动注入对象返回null值。

虽然过程有点苦闷,但是在和前端对接后的欣喜是无法言表的,在这次项目中,也学到了如何跟一个团队合作,比如在对接过程中出现了问题,无论前端还是后端都要寻找问题,去发现自己的错误,不能互相推卸责任,否则问题永远解决不了。

百年修炼终可成神,愿与诸君共勉

Spring-boot遇上JavaFx相关推荐

  1. 理论 | 当 Spring Boot 遇上了消息队列......

    这是小小本周的第五篇,当Spring Boot 遇上了消息队列. Spring Boot 1.0 版本 在很远很远的以前,作为单体应用,只有一个Spring Boot 应用,当两个Spring Boo ...

  2. Spring Boot遇上jello

    2019独角兽企业重金招聘Python工程师标准>>> 开篇准备: 你得有准备jello(FIS-java解决方案),npm,maven. 开整: 编写maven配置文件 <? ...

  3. 当 Spring Cloud 遇上 SOFAStack | Meetup#2 回顾

    本文作者:玄北(曹杰),蚂蚁金服 SOFAStack 开源组核心成员. 导读:本文根据 5月26日 SOFA Meetup#2 上海站 <当 Spring Cloud 遇上 SOFAStack& ...

  4. vueform表单文件上传_峰哥说技术系列-8.Spring Boot文件上传(Form表单和Ajax方式)

    今日份主题 Spring Boot文件上传(Form表单和Ajax方式) 在Spring Boot中,和文件上传的主要和MultipartResolver接口有关,他有两个实现类 StandardSe ...

  5. Spring Boot 批量上传: The field files exceeds its maximum permitted size of 1048576 bytes.

    Spring Boot 批量上传异常: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededExcep ...

  6. Spring Boot:上传文件大小超限制如何捕获 MaxUploadSizeExceededException 异常

    Spring Boot 默认上传文件大小限制是 1MB,默认单次请求大小是 10MB,超出大小会跑出 MaxUploadSizeExceededException 异常. 问题来了,当文件超过 1M ...

  7. Spring boot项目上传Linux服务器后 上传图片后,图片路径报404,图片路径映射问题

    问题 spring boot项目上传到Linux服务器后,头像上传后报404.但是我的打包的jar包在idea客户端运行是没问题的 解决 错误代码 @Overridepublic void addRe ...

  8. 全栈开发实战|Spring Boot文件上传与下载

    文件上传与下载是Web应用开发中常用的功能之一.接下来我们将讨论如何在Spring Boot的Web应用开发中,如何实现文件的上传与下载. 01.Spring Boot文件上传与下载 在实际的Web应 ...

  9. Spring Boot文件上传及回显(单/多文件)

    一.单文件上传 1.前端页面 <!DOCTYPE html> <html lang="en"> <head><meta charset=& ...

  10. spring boot 文件上传工具类(bug 已修改)

    以前的文件上传都是之前前辈写的,现在自己来写一个,大家可以看看,有什么问题可以在评论中提出来. 写的这个文件上传是在spring boot 2.0中测试的,测试了,可以正常上传,下面贴代码 第一步:引 ...

最新文章

  1. C语言科学计算器思路,大神教你如何用C语言实现科学计算器
  2. android helloworld程序
  3. 结队作业,小学生3年级数学题出题器
  4. Shell中的case语句
  5. display:table-cell的集中应用
  6. JavaScript单线程和浏览器事件循环简述
  7. 数据为桥迈向智能,渤海财险数据架构智能化演进
  8. 【VMware vSAN 6.6】5.4.vSAN 配置提示:vSAN硬件服务器解决方案
  9. 爱的十个秘密--3.尊重的力量
  10. android uri跳转导航,android:scheme 通过uri跳转到APP应用指定Activity
  11. lnmp mysql 命令_LNMP状态管理命令
  12. 网卡变慢_解Bug之路记一次线上请求偶尔变慢的排查
  13. 内存管理机制和垃圾回收机制
  14. Small Basic 语言 学习笔记
  15. 使用python+selenium清空淘宝购物车
  16. 原来早就被安排了,旅行社用机器学习给你推个性化定制游
  17. 怎样给领导或同事送礼?
  18. 全球上线!ABB中国涡轮增压器分拆 – 数据清理阶段完成
  19. AppStore审核
  20. DOM事件里面的键盘事件

热门文章

  1. 拆书笔记1|善于寻找和留住人才
  2. 使用vs2019写vue
  3. Java程序设计概述
  4. P 1028 人口普查
  5. Java基本微信小程序的适老化老人健康预警系统 springboot+vue
  6. TCL电子2018年首三季度电视机销售量逾2,112万台超预期
  7. Python源码剖析:前言
  8. (翻译)购物车模式(Shopping Cart)
  9. 深圳IDC代理商状态
  10. “魔鬼交易员”不过是赌徒