JavaFX is currently a set of UI framework (jfxrt.jar) that comes with JDK8. Compared with AWT and SWING, its documentation is relatively more complete and complete, and the use of controls is clearer and simpler. Most importantly, it is used as a Java client UI development framework. He is compatible with CSS, making the interface more beautiful and in line with the trend.
There are more detailed documents and downloads such as special DEMO programs (libraries), APIs, and control css descriptions on oracle. https://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html .
Here is a sample UI program for self-study:
package com.merrick.japanese; import java.util.ArrayList; import java.util.List; import java.util.Random; import javafx.application.Application; import javafx.geometry.Side; import javafx.scene.Scene; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.stage.Stage; public class JaToCnFx extends Application { /** * Controls * */ private TabPane frametab; private Tab jatocntab; private Tab cntojatab; /** * method * */ @Override public void start(Stage stg) throws Exception { frametab = new TabPane(); frametab.setPrefSize(800, 475); frametab.setMinSize(TabPane.USE_PREF_SIZE, TabPane.USE_PREF_SIZE); frametab.setMaxSize(TabPane.USE_PREF_SIZE, TabPane.USE_PREF_SIZE); frametab.setSide(Side.TOP); frametab.setRotateGraphic(false); frametab.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE); jatocntab = new Tab(); jatocntab.setText(""Japanese"->"Chinese""); jatocntab.setStyle("-fx-font-size: 15px;"); cntojatab = new Tab("[Chinese]->[Japanese]"); cntojatab.setStyle("-fx-font-size: 15px;"); frametab.getTabs().add(jatocntab); frametab.getTabs().add(cntojatab); JaToCnTab jtc = new JaToCnTab (); jatocntab.setContent(jtc.createJAtoCNpane()); CnToJaTab ctj = new CnToJaTab(); cntojatab.setContent(ctj.createCNtoJApane()); //Scene sc = new Scene(gp,800,475); Scene sc = new Scene(frametab,800,475); /**CSS style added*/ sc.getStylesheets().add(JaToCnFx.class.getResource("/com/merrick/japanese/fx.css").toExternalForm()); stg.setTitle("Vocabulary Translation test"); stg.setScene(sc); stg.show(); } public static void main(String[] args) { launch(args); } public static List<Integer> getRandomIntsSerialNoRepeated(int maxelem) { /*** * Generate a random sequence without repetition (related to the order of the initial set content) * */ int size = maxelem; List<Integer> tmplst = new ArrayList<Integer>(); int rx = 0; Random rn = new Random(); for (int i = 0; i < size; i++) { if(tmplst.size()!=0) { do { rx = rn.nextInt(size); }while(tmplst.contains(rx)); tmplst.add(rx); }else { rx = rn.nextInt(size); tmplst.add(rx); } } return tmplst; } } package com.merrick.japanese; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.scene.Parent; import javafx.scene.control.Button; import javafx.scene.control.ChoiceBox; import javafx.scene.control.Label; import javafx.scene.control.ProgressBar; import javafx.scene.control.TextField; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.GridPane; import javafx.scene.paint.Color; import javafx.scene.text.Text; public class CnToJaTab { public static final int CURRENT_LESSON_MAX = 9; private boolean onoff = false;//Start and stop button status flag private String currentcn = null;// private int currentlesson = 1; //The corresponding number of the course vocabulary private static Properties cntoja = new Properties(); //lesson vocabulary file, key: Chinese, value: Japanese (loaded, current) private int testorder = 0; //Number of words currently tested private List<Integer> lst_order = null;//Specify the lesson, the order in which the test vocabulary is initially generated, and is related to the number of lines in the vocabulary prop file private String[] keyarr = null;//Array of key values of vocabulary prop public void loadVocabularyViaLessonnumberCNtoJA(int lesson) { try { cntoja.clear(); cntoja.load(JaToCnFx.class.getResourceAsStream("/com/merrick/chinese/props/lessoncn"+ String.valueOf(lesson) +".properties")); } catch (IOException e) { System.err.println(e.toString()); } } public Parent createCNtoJApane() { GridPane gp = new GridPane(); gp.setHgap(15); gp.setVgap(15); gp.setPadding(new Insets(35,35,35,35)); //Construction to test page control Text title = new Text("Show Chinese, fill Japanese:"); //Title control title.setStyle("-fx-fill:linear-gradient(to top left, blue,red );-fx-font-size: 15px;"); Label lb_lesson = new Label("Choose Lesson:");//Drop-down box label lb_lesson.setStyle("-fx-font-weight:bold;-fx-font-size:13px;"); ChoiceBox<String> cb_lesson = new ChoiceBox<String>(); //drop-down box control cb_lesson.setPrefWidth(100); ArrayList<String> items = new ArrayList<String>(); for (int i = 1; i <= CURRENT_LESSON_MAX; i++) { items.add(String.valueOf(i)); } cb_lesson.getItems().addAll(items);//Visible content cb_lesson.getSelectionModel().select(currentlesson-1);//初始 cb_lesson.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> arg0, Number oldval, Number newval) { currentlesson = newval.intValue() + 1; } }); Button btn_start = new Button("Press to Start Lesson ");//Start button control Label cnname = new Label("Chinese:"); //The current Chinese label Text cntxt = new Text(); //Current Chinese (dynamic) controls cntxt.setStyle("-fx-font-weight:bold;-fx-font-size:13px;"); cntxt.setText(""); Label input = new Label("Input:"); //Input box label final TextField inputtxt = new TextField();//Chinese input box control inputtxt.setMinWidth(150); inputtxt.setMinSize(330, 15); input.setStyle("-fx-font-size:15px;"); Button btn_valid = new Button("Validate");//Validate button control Label lb_prog = new Label("Progress:");//Drop-down box label ProgressBar prog = new ProgressBar(0);//Progress control prog.setPrefWidth(200); final Text msgtxt_current = new Text(); //Status prompt text text control msgtxt_current.setText(""); //msgtxt_current.setStyle("-fx-font-weight:bold;-fx-font-size:15px;"); final Text msgtx_torf = new Text(); // Prompt control for correctness or not final Text msgtxt_correct = new Text(); //Correct result display control msgtxt_correct.setStyle("-fx-font-weight:bold;-fx-font-size:15px;"); EventHandler<ActionEvent> starttestAction = (ActionEvent event)->{ loadVocabularyViaLessonnumberCNtoJA(currentlesson); testorder = 0; lst_order = JaToCnFx.getRandomIntsSerialNoRepeated(cntoja.size()); keyarr = cntoja.keySet().toArray(new String[0]); getspecifiedVocabulary(currentlesson,cntoja.size(), testorder); cntxt.setText(currentcn); msgtxt_current.setText(" [LESSON "+currentlesson +", TOTAL:"+cntoja.size()+",CURRENT:"+(testorder)+"]");// prog.setProgress(1.0*testorder/cntoja.size()); onoff =! onoff; if(onoff) { btn_start.setText("Going......"); }else { btn_start.setText("Press to Start Lesson "); //"Lesson Start" msgtxt_current.setText(""); cntxt.setText(""); } }; btn_start.setOnAction (starttestAction); EventHandler<ActionEvent> validaction = (ActionEvent event)->{ String userinput = inputtxt.getText(); String rightvalue = null; String key = currentcn; if (key==null) return; rightvalue = (String) cntoja.get(key);//Get the answer for a specific map if(userinput.equals(rightvalue)) { msgtx_torf.setFill(Color.GREEN); msgtx_torf.setText("CORRECT INPUT."); }else { msgtx_torf.setFill(Color.RED); msgtx_torf.setText("WRONG INPUT: " + userinput ); } msgtxt_correct.setText("[correct result]: "+key+"<====>"+ rightvalue); getspecifiedVocabulary(1,cntoja.size(),testorder); msgtxt_current.setText(" [LESSON "+currentlesson +", TOTAL:"+cntoja.size()+",CURRENT:"+(testorder)+"]"); prog.setProgress(1.0*testorder/cntoja.size()); cntxt.setText(currentcn); inputtxt.clear(); }; btn_valid.setOnAction(validaction); inputtxt.setOnKeyPressed(new EventHandler<KeyEvent>() {//The input box responds to the Enter key @Override public void handle(KeyEvent kev) { if(kev.getCode() == KeyCode.ENTER) { validaction.handle((ActionEvent) btn_valid.getOnKeyPressed()); } } }); gp.add(title, 0, 0, 3, 1); gp.add(lb_lesson, 0, 1, 1, 1); gp.add(cb_lesson, 1, 1, 1, 1); gp.add(btn_start, 2, 1, 1, 1); gp.add( cnname, 0, 2, 1, 1); gp.add( cntxt, 1, 2, 1, 1); gp.add( input, 0, 3, 1, 1); gp.add( inputtxt, 1, 3, 1, 1); gp.add( btn_valid, 2, 3, 1, 1); gp.add( lb_prog, 0, 4, 1, 1); gp.add( prog, 1, 4, 2, 1); gp.add(msgtxt_current, 0, 5, 3, 1); gp.add(msgtx_torf, 0, 6, 3, 1); gp.add(msgtxt_correct, 0, 7, 3, 1); return gp; } public void getspecifiedVocabulary(int lesson, int len, int order) { if(order>=len) { return; } currentcn = keyarr[lst_order.get(order)]; System.out.println(currentcn); testorder ++; } }