900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 打字练习软件——JavaFx

打字练习软件——JavaFx

时间:2019-08-10 13:02:37

相关推荐

打字练习软件——JavaFx

运行效果:

布局有些繁琐,用到多线程(计时)。

菜单窗口(选择文章)以及成绩单窗口不写,留给别人了

不得不说,系统字体有些难看,但是如果用一些个性化字体,别人的电脑如果没有安装这个字体,就会有些问题

代码如下,素材在网盘(自取)

网盘:/s/1tNp1k0sohDZpqJhOja19Rg

素材需放在与.class同一目录下

import javafx.application.Application;import javafx.application.Platform;import javafx.beans.value.ChangeListener;import javafx.geometry.Insets;import javafx.geometry.Orientation;import javafx.geometry.Pos;import javafx.scene.Scene;import javafx.scene.control.*;import javafx.scene.control.Button;import javafx.scene.control.Label;import javafx.scene.control.ScrollPane;import javafx.scene.control.TextField;import javafx.scene.effect.BlendMode;import javafx.scene.image.Image;import javafx.scene.image.ImageView;import javafx.scene.input.KeyCode;import javafx.scene.layout.*;import javafx.scene.paint.Color;import javafx.scene.shape.Rectangle;import javafx.scene.text.*;import javafx.scene.text.Font;import javafx.stage.Stage;import java.io.*;import java.util.HashMap;import java.util.Map;import java.util.Vector;class MyBox extends HBox{public Label key,value;public MyBox(ImageView img,String key,String value,String unit){this.key=new Label(key);this.value=new Label(value);img.setFitHeight(30);img.setFitWidth(30);setAlignment(Pos.CENTER_LEFT);setSpacing(15);getChildren().addAll(img,this.key,new Label(":"),this.value,new Label(unit));}}public class Typist extends Application {Vector<TextFlow> textFlows; //存储文本流 //这些Vector是为了方便创建以后再找到那些组件Vector<TextField> textFields; //存储文本域Vector<Vector<Text>> vectors; //二维文本Vector<Rectangle> rectangles; //矩形背景GridPane pane;ScrollPane inputPane;VBox menu;MyBox rate, right, error, back, count;Scene scene;int second; //计时器Label label,time,textName;ImageView btPause,btStop;Thread thread;//这个进程用来跑时间int now , size , keyCount , backCount , errorCount , Count; //now用来确定当前所在TextFiledImageView clock=new ImageView("clock.png");private boolean pause = false;public void init(){thread=new Thread(()-> {try {while (true){synchronized ((String)" ") {if (!pause) {Platform.runLater(() -> {rate.value.setText(String.valueOf((int)(((double)keyCount/second)*60)));time.setText(String.format("%02d:%02d", second % 3600 / 60, second % 60));});Thread.sleep(1000);second++;}}}} catch (Exception ex) { }});pane=new GridPane();scene=new Scene(pane);menu=new VBox();label=new Label("时间:");time=new Label("00:00");textName=new Label();btPause=new ImageView("pause.png");btStop=new ImageView("stop.png");menu.setPrefSize(200,400);menu.setAlignment(Pos.TOP_CENTER);btPause.setOnMouseClicked(e->changePause());btPause.setFitWidth(75);btPause.setFitHeight(35);btStop.setFitWidth(75);btStop.setFitHeight(35);menu.setSpacing(5);menu.setPadding(new Insets(15,10,10,10));time.setFont(Font.font("System",FontWeight.BOLD,30));time.setTextFill(Color.rgb(239,169,37));clock.setFitWidth(120);clock.setFitHeight(120);Label label=new Label("开始输入时计时!");label.setTextFill(Color.rgb(192,36,33));HBox hbox=new HBox(label,new Label("文章名:"),textName);hbox.setPrefSize(550,20);hbox.setSpacing(60);hbox.setPadding(new Insets(10,10,0,10));pane.add(hbox,0,0);Rectangle rectangle=new Rectangle(200,420);rectangle.setArcWidth(20);rectangle.setArcHeight(20);rectangle.setFill(Color.rgb(203,230,222));pane.add(rectangle,1,1);pane.setBackground(new Background(new BackgroundFill(Color.rgb(217,228,242),null,null)));}private void loadText(File file)throws FileNotFoundException ,IOException{ //从file中读取文本并更新组件的数据。textFlows=new Vector<>();textFields=new Vector<>();vectors=new Vector<>();rectangles=new Vector<>();inputPane=new ScrollPane();now=0;size=0;errorCount=0;keyCount=0;backCount=0;rate=new MyBox(new ImageView("rate.png"),"速 度","-","KPM");right=new MyBox(new ImageView("right.png"),"正确率","100","%");error=new MyBox(new ImageView("error.png"),"错 误","0","字");back= new MyBox(new ImageView("back.png"),"退 格","0","次");count=new MyBox(new ImageView("count.png"),"总字数","0","字");HBox bt=new HBox(btPause,btStop);bt.setPrefWidth(200);bt.setAlignment(Pos.CENTER);bt.setSpacing(10);bt.setPadding(new Insets(5,5,5,5));pane.add(menu,1,1);menu.getChildren().addAll(clock,new Label("时间"),time, rate, right, error,back,count, bt);int count=1;second=0;BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "gbk"));textName.setText(file.getName().substring(0,file.getName().indexOf('.')));String str;GridPane grid=new GridPane();while ((str=reader.readLine())!=null) { //读取文本TextFlow textFlow = new TextFlow();TextField textField = new TextField();Vector<Text> texts=new Vector<>();textFlow.getChildren().add(new Text(" "));for (int i = 0; i < str.length(); i++) { //将每行的每个文字设为一个组件Text t = new Text(str.substring(i, i + 1));size++;t.setFont(Font.font("System", FontWeight.BOLD,20));t.setTextAlignment(TextAlignment.CENTER);textFlow.getChildren().add(t);texts.add(t);}textField.setFont(Font.font("System",20));textFlow.setMinHeight(30);textField.setEditable(false);pane.setVgap(10);pane.setHgap(5);pane.setAlignment(Pos.TOP_CENTER);Rectangle rectangle=new Rectangle(550,80);rectangle.setArcHeight(20);rectangle.setArcWidth(10);rectangle.setFill(Color.rgb(212,233,254));grid.add(rectangle,0,count);VBox box=new VBox(textFlow,textField);box.setPadding(new Insets(10,1,10,1));textField.textProperty().addListener(ov->{ //监听文本域变动if(!thread.isAlive())thread.start(); //开始计时String s=textField.getText();for(int i=0;i<texts.size();i++){if(i<s.length()){ //修改文字高亮if(s.charAt(i)==texts.get(i).getText().charAt(0)) {texts.get(i).setFill(Color.rgb(78,203,107));texts.get(i).setUnderline(false);}else {texts.get(i).setFill(Color.rgb(219,88,96));texts.get(i).setUnderline(true);}}else {texts.get(i).setFill(Color.BLACK);texts.get(i).setUnderline(false);}}update();});textField.setOnKeyPressed(e->{//绑定面板的回车事件,当回车时切换焦点if(e.getCode()== KeyCode.BACK_SPACE){backCount++;back.value.setText(String.valueOf(backCount));}else if(e.getCode()== KeyCode.ENTER &&textField.getText().length() >= texts.size()){textFields.get(now).setEditable(false);rectangles.get(now).setFill(Color.rgb(212,233,254));textFields.get(++now).setEditable(true);textFields.get(now).requestFocus();rectangles.get(now).setFill(Color.rgb(240,209,210));}else{keyCount++;}});vectors.add(texts);textFlows.add(textFlow);textFields.add(textField);rectangles.add(rectangle);grid.add(box,0,count++);}textFields.lastElement().setOnKeyPressed(e->{if(e.getCode()== KeyCode.ENTER &&textFields.lastElement().getText().length() >= vectors.lastElement().size()){textFields.get(now).setEditable(false);rectangles.get(now).setFill(Color.rgb(212,233,254));changePause();}});inputPane.setContent(grid);inputPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);inputPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);inputPane.setMinSize(580,420);inputPane.setPadding(new Insets(5,5,5,5));pane.add(inputPane,0,1);reader.close();textFields.get(now).setEditable(true); //初始化第一个文本框rectangles.get(now).setFill(Color.rgb(240,209,210));textFields.get(now).requestFocus();}private boolean changePause(){ //改变暂停状态if(thread.isAlive()){if(pause){pause=false;btPause.setImage(new Image("pause.png"));textFields.get(now).setEditable(true);}else {pause = true;btPause.setImage(new Image("run.png"));textFields.get(now).setEditable(false);}}return pause;}private void update(){ //更新数据errorCount=0;Count=0;for(int i=0;i<=now;i++){for(int j=0;j<textFields.get(i).getText().length()&&j<vectors.get(i).size();j++){if(textFields.get(i).getText().charAt(j)!=vectors.get(i).get(j).getText().charAt(0)) {errorCount++;}Count++;}}error.value.setText(String.valueOf(errorCount));right.value.setText(String.valueOf((int)((1-(double)errorCount/Count)*100)));count.value.setText(String.valueOf(Count));}private void mainMenu(){ //显示选择(文章)菜单}private void over(){ //显示成绩单}public void start(Stage stage)throws FileNotFoundException ,IOException{stage.setScene(scene);stage.setWidth(800);stage.setHeight(480);stage.setResizable(false);//尺寸不可变stage.show();loadText(new File("test.txt"));}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。