Spring-boot遇上JavaFx

一、实验项目名称

保龄球积分系统

二、实验描述

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

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

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

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

三、实验步骤

获取完整源代码 gitHub 克隆 [email protected]:441712875al/example.git
项目目录结构

Spring-boot遇上JavaFx_第1张图片

运行效果
Spring-boot遇上JavaFx_第2张图片

1. 数据库设计

Spring-boot遇上JavaFx_第3张图片

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. 实体层设计

Spring-boot遇上JavaFx_第4张图片

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;


    @Autowired
    private GroupStrategy groupStrategy;


    @Autowired
    private PTDaoImpl ptDaoImpl;

    @Autowired
    private TeamDaoImpl teamDaoImpl;

    @Autowired
    private 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;
    }

    @Override
    public 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());
    }

    @Override
    public 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 {


    @Autowired
    private  JdbcTemplate jdbcTemplate;


    //插入一个选手SQL
    private final String INSERT_PLAYER_SQL = "insert into player(pid,name) values(?,?)";

    //查询所有选手的SQL
    private 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 选手信息类
     */
    @Override
    public int insertPlayer(Player player) {
        Object[] args = {player.getId(),player.getName()};
        jdbcTemplate.update(INSERT_PLAYER_SQL,args);
        return 1;
    }


    /**
     * 查询所有的选手信息
     * @return
     */
    @Override
    public 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
     */
    @Override
    public 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 {


    @Autowired
    private  JdbcTemplate jdbcTemplate;



    //保存比赛成绩SQL
    private final static String INSERT_GRADE_SQL= "" +
            "INSERT INTO pt (pid,tid," +
            "grid1,grid2,grid3,grid4,grid5," +
            "grid6,grid7,grid8,grid9,grid10,playertolScore,fouls) " +
            "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";

    //查询小组比赛成绩SQL
    private 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=? ";

    //查询每种比赛个人的成绩SQL
    private 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 =?";

    //查询每个小组及其队员的信息SQL
    private 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
     */
    @Override
    public 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
     */
    @Override
    public 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
     */
    @Override
    public 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
     */


    @Override
    public 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 {
    @Autowired
    private JdbcTemplate jdbcTemplate;




    //插入小组信息的sql
    private final String INSERT_TEAM_SQL = "insert into team (tid,teamtolScore,contestType) values (?,?,?)";

    //查询id最大值的SQL
    private final String SELECT_MAX_TID_SQL = "select max(tid) maxID from team";


    /**
     * 将小组的信息插入到team表中
     * @param team 队伍信息类
     */
    @Override
    public void insertTeam(Team team) {
        Object[] args = {team.getId(),team.getTolScore(),team.getContestType().getDesc()};
            jdbcTemplate.update(INSERT_TEAM_SQL,args);
    }




    /**
     * 查询在数据库中的ID最大值
     * @return
     */


    @Override
    public 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 {

    @Autowired
    private Manager manager;

    @FXML
    private VBox Menu;


    @FXML
    private Pane gamePane;

    @FXML
    private TableView<GameScore> gameTable;

    @FXML
    private ChoiceBox<?> gameType;

    @FXML
    private Pane informationPane;

    @FXML
    private Button btnAdd;

    @FXML
    private Button btnDelete;

    @FXML
    private TextField InfoName;

    @FXML
    private TextField InfoId;

    @FXML
    private Label hint2;

    @FXML
    private TextField InfoAge;

    @FXML
    private Label hint3;

    @FXML
    private TextField InfoSex;

    @FXML
    private Label hint21;

    @FXML
    private TextField InfoTel;

    @FXML
    private TableView<Player> playersTable;

    @FXML
    private Button btnQueryPlayer;

    @FXML
    private Pane resultPane;

    @FXML
    private Button btnQueryResult;

    @FXML
    private TextField resultName;

    @FXML
    private TextField resultId;

    @FXML
    private TableView<PersonScore> resultTable;

    @FXML
    private Pane teamPane;

    @FXML
    private TableView<Team> teamTable;

    @FXML
    private TableColumn<?, ?> infoTable1;

    @FXML
    private TableColumn<?, ?> infoTable11;

    @FXML
    private TableColumn<?, ?> infoTable111;

    @FXML
    private Button btnQueryTeam;

    @FXML
    private TextField teamId;

    /**
     * 切换面板,设赛事管理界面可见
     * @param event
     */
    @FXML
    void Game(ActionEvent event) {
        closeAll();
        gamePane.setVisible(true);
    }

    /**
     * 切换面板,信息管理设界面可见
     * @param event
     */
    @FXML
    void Info(ActionEvent event) {
        closeAll();
        informationPane.setVisible(true);
    }

    /**
     * 切换面板,设结果查询界面可见
     * @param event
     */
    @FXML
    void Result(ActionEvent event) {
        closeAll();
        resultPane.setVisible(true);
    }

    /**
     * 切换面板,设分组管理界面可见
     * @param event
     */
    @FXML
    void Team(ActionEvent event) {
        closeAll();
        teamPane.setVisible(true);
    }



    //##################################以下为数据库操作##########################################

    /**
     * 依据输入信息,添加运动员
     * @param event
     */
    @FXML
    void 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
     */
    @FXML

     void 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!");
        else
            showErroMessage("fail to delete player "+name);
        playersTable.refresh();

    }

    /**
     * 显示所有运动员的个人信息
     * @param event
     */
    @FXML
    void 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
     */
    @FXML
    void 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
     */
    @FXML
    public 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
     */
    @FXML
    void 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);
        }
        else
            gameScores = 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.roskenetgroupId>
                <artifactId>springboot-javafx-supportartifactId>
                <version>2.1.6version>
            dependency>


            <dependency>
                <groupId>de.roskenetgroupId>
                <artifactId>springboot-javafx-testartifactId>
                <version>1.3.0version>
                <scope>testscope>
            dependency>

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

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

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

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

你可能感兴趣的:(Spring-boot遇上JavaFx)