The elegant JavaFX interface development of Netty network chat room

Source: Internet
Author: User
Tags gettext i18n

Java can dominate the server domain, however, it has been tepid in the client domain. Java client technology, from AWT,SWING,SWT to JavaFX, even if each generation has a very big improvement, but still can not change its awkward position. In my opinion, using Java to develop desktop applications, I'm probably the only one who has our batch of Javaer.

In any case, JavaFX's design philosophy is still very good. It draws on the characteristics of the HTML development, the code, interface, style separation of the three. Use Java code to control logic, use XML to design the interface, and use CSS to control styles.

This article will use a simple example to illustrate the JavaFX development case. Development Tools E (FX) Eclipse is an eclipse version with a JavaFX development plug-in that comes with Css,xml code completion. JavaFX Scene Builder 2.0 is an auxiliary tool for JavaFX interface development, which is to support the design of the interface using the drag-and-drop approach. is useful for adjusting the position of the interface.
interface style Logic the separation of powers with efxeclipse, we can develop our JavaFX project. The login interface controls are very small and can be used as an introductory example. In JavaFX, stage represents an application-level window with a user interface, and under stage, the interface container is represented by scene. Scene contains all interface components, such as various UI controls and UI child containers. Similar to flex development, our JavaFX interface design is written in the Fxml file. As follows:

<?xml version= "1.0" encoding= "UTF-8"?> <?import javafx.geometry.*?> <?import, javafx.scene.paint.*? > <?import javafx.scene.text.*?> <?import javafx.scene.control.*?> <?import javafx.scene.chart.*? > <?import javafx.scene.image.*?> <?import java.lang.*?> <?import javafx.scene.layout.*?> <
	Anchorpane maxheight= "-infinity" maxwidth= "-infinity" minheight= "-infinity" minwidth= "-Infinity" prefHeight= "330.0" Prefwidth= "430.0" xmlns= "HTTP://JAVAFX.COM/JAVAFX/8" xmlns:fx= "HTTP://JAVAFX.COM/FXML/1" fx:controller= " Com.kingston.ui.controller.LoginViewController "stylesheets=" @ ... /css/login.css "> <children> <imageview fitheight=" 330.0 fitwidth= "430.0" layoutx= "91.0" layouty= "90.0"
			Pickonbounds= "true" preserveratio= "true" anchorpane.bottomanchor= "0.0" anchorpane.leftanchor= "0.0" anchorpane.rightanchor= "0.0" anchorpane.topanchor= "0.0" > <image> <image url= "@ ...
	/img/login.png "/> </image>	</ImageView> <button fx:id= "Login" layoutx= "135.0" layouty= "288.0" false "mnemonicparsing=" #login "onmouseentered=" #login_en "onmouseexited=" #login_ex "prefheight=" 32.0 "prefwidth=" 194.0 "text="% 
		Login.safelogin "textfill=" white "> <font> <font size=" 18.0 "/> </font> </Button> <imageview fitheight= "80.0" fitwidth= "80.0" layoutx= "38.0" layouty= "195.0" true "pickonbounds=" preserveratio= E "> <image> <image url=" @ ... 
			/img/head.jpg "/> </image> </ImageView> <textfield fx:id= userId" layoutx= "135.0" layouty= "195.0"  prefheight= "25.0" prefwidth= "194.0" prompttext= "%login.account" text= "1000"/> <passwordfield fx:id= "Password" layoutx= "135.0" layouty= "226.0" prefheight= "25.0" prefwidth= "194.0" prompttext= "%login.password"/> <checkbox Fx:id= "REMEMBERPSW" layoutx= "135.0" layouty= "258.0" mnemonicparsing= "false" text= "%LOGIN.REMEMBERPSW"/> &LT CheckBox fx:id= "Autologin" layoutx= "260.0" layouty= "258.0" mnemonicparsing= "false" text= "%login.autologin"/> < Label/> <label/> <imageview fx:id= "closebtn" fitheight= "30.0" fitwidth= "30.0" layoutx= "399.0" Onmouse Clicked= "#close" onmouseentered= "#closeEntered" onmouseexited= "#closeExited" pickonbounds= "true" preserveratio= " True "anchorpane.rightanchor=" 0.0 "anchorpane.topanchor=" 0.0 "> <image> <image url=" @. /img/close.png "/> </image> <rotationAxis> <point3d/> </rotationAxis> </imag eview> <imageview fx:id= "minbtn" fitheight= "30.0" fitwidth= "30.0" layoutx= "346.0" onmouseclicked= "#min" OnMouse Entered= "#minEntered" onmouseexited= "#minExited" pickonbounds= "true" preserveratio= "true" anchorpane.rightanchor= " 30.0 "anchorpane.topanchor=" 0.0 "> <image> <image url=" @. /img/min.png "/> </image> </ImageView> <progressbar layoutx=" 132.0"Layouty=" 289.0 "prefheight=" 32.0 "fx:id=" loginprogress "prefwidth=" 200.0 "visible=" false "/> <pane fx:id=" err Orpane "layouty=" 36.0 "prefheight=" 307.0 "prefwidth=" 430.0 "style="-fx-background-color: #9AD3EE; "visible=" false "A Nchorpane.topanchor= "30.0" > <children> <label fx:id= "errortips" layoutx= "118.0" layouty= "52.0" Prefheig ht= "153.0" prefwidth= "194.0" wraptext= "true" > <font> <font size= "27.0"/> </font&gt
				; </Label> <button layoutx= "118.0" layouty= "223.0" mnemonicparsing= "false" onmouseclicked= "#backToLogin" p refheight= "32.0" prefwidth= "194.0" style= "-fx-background-color: #09A3DC;" text= "%login.backtologin" textfill= "White "> <font> <font size=" 18.0 "/> </font> </Button> </children> ;/pane> Fxml has a variety of ID definitions, with these IDs, we can use Java code to control it. In Fxml, there is a fx:controller element that is used to define the corresponding controller.
public class Loginviewcontroller implements Controlledstage, initializable {

	@FXML
	private Button login;
	@FXML
	private TextField userId;
	@FXML
	private Passwordfield password;
	@FXML
	private CheckBox rememberpsw;
	@FXML
	private CheckBox autologin;
	@FXML
	private ImageView closebtn;

	@FXML
	private void Login () throws IOException {
		final long Useid = Long.parselong (Userid.gettext ());
		Final String PSW = Password.gettext ();

		if (! IoBaseService.INSTANCE.isConnectedSever ()) {
			errorpane.setvisible (true);
			Errortips.settext (I18n.get ("Login.failtoconnect"));
			return;
		}

		Loginprogress.setvisible (true);
		Login.setvisible (false);

		Loginmanager.getinstance (). Begintologin (Useid, PSW);
	}
Like in Loginviewcontroller, if we need to control the controls in the XML, we need to write a @fxml annotation of the control type in the code, and the name of the variable is the ID in Fxml. At the same time, various triggering events for the control, such as clicking and sliding events, also need to be written with @fxml annotations, and the method names will be the same as those in fxml files, such as onmouseclicked= "#login". HTML-like CSS files, our UI control style is best written in a separate CSS file, and then pointed through Fxml, for example: stylesheets= "@ ... /css/login.css ". One of the special considerations here is that if the code needs to update the UI display, we have to do it on the JavaFX UI thread
/**
	 * Transfer task to fxapplication thread deferred execution
	 * @param task
	 /public
	void Runtaskinfxthread (Runnable task) {
		Platform.runlater (Task);
	}

internationalization support for text resourcesClient development Program, we will inevitably have to internationalization support, to different international regions to display different text. JavaFX also did well in this area.
When loading the fxml, we can specify the internationalized resource file, as follows
URL url = thread.currentthread (). Getcontextclassloader (). getresource (Resource);
			Fxmlloader loader = new Fxmlloader (URL);
			Loader.setresources (Resourcebundle.getbundle ("I18n/message"));
In this way, Fxml can use the text= "%LOGIN.REMEMBERPSW" approach to the introduction of international resources. The way to use internationalized text in a fxml file. Define a tool class to load the use of internationalized text (I18n.java)
/**
 * International resource pool
 * @author Kingston/Public
class i18n {

    private static ResourceBundle resourcepool;< c5/>static {
        try {
            resourcepool = Resourcebundle.getbundle ("I18n/message");
        } catch (Exception e) {
            E.printstacktrace ();
        }

    public static string get (String key, Object ... args) {
        if (!resourcepool.containskey (key)) {return
           "internationalized resource does not exist" ;
        }
        String message = resourcepool.getstring (key);
        if (args!= null) {return
            messageformat.format (message, args);
        } else {return message
            ;
        }
    }
}
In the code, use I18n.get ("REGISTER.OPERATESUCC").
Unified management of stage loading and switching In JavaFX, it is often necessary to switch between different stage. In order to efficiently unify the management of stage, we can cache all stage and dynamically display hidden windows as needed.
public class Stagecontroller {private map<string, stage> stages = new hashmap<> ();

	Private map<string, controlledstage> controllers = new hashmap<> ();
	public void Addstage (String name, Stage Stage) {this.stages.put (name, Stage);
	Public Stage Getstageby (String name) {return this.stages.get (name);
	public void Setprimarystage (String name, Stage Stage) {this.addstage (name, Stage);
		Public Stage loadstage (string name, string resource, Stagestyle ... styles) {Stage result = null;
			try{URL url = thread.currentthread (). Getcontextclassloader (). getresource (Resource);
			Fxmlloader loader = new Fxmlloader (URL);
			Loader.setresources (Resourcebundle.getbundle ("I18n/message"));
			Pane Tmppane = (Pane) loader.load ();
			Controlledstage controlledstage = (controlledstage) loader.getcontroller ();
			This.controllers.put (name, controlledstage);
			Scene tmpscene = new Scene (Tmppane);
			result = new Stage ();

			Result.setscene (Tmpscene); For (Stagestyle style:styles) {result.initstyle (style);
		} this.addstage (name, result);
		}catch (Exception e) {e.printstacktrace ();
	return result; @SuppressWarnings ("unchecked") public <T> t Load (String resource, class<t> clazz) {try{URL url = t
			Hread.currentthread (). Getcontextclassloader (). getresource (Resource);
			Fxmlloader loader = new Fxmlloader (URL);
		Return (T) loader.load ();
		}catch (Exception e) {e.printstacktrace ();
	return null; @SuppressWarnings ("unchecked") public <T> T Load (String resource, class<t> clazz, ResourceBundle Resource
			s) {try{URL url = thread.currentthread (). Getcontextclassloader (). getresource (Resource);
		Return (T) fxmlloader.load (URL, resources);
		}catch (Exception e) {e.printstacktrace ();
	return null;
		Public Stage setstage (String name) {Stage Stage = This.getstageby (name);
		if (stage = = null) {return null;
		} stage.show ();
	return stage; } public Boolean Switchstage (String toshow, String toclose) {Getstageby (toclose). Close ();

		Setstage (toshow);
	return true;
		public void Closestge (String name) {Stage target = Getstageby (name);
	Target.close ();
	public boolean unloadstage (String name) {return This.stages.remove (name)!= null;
	Public Controlledstage Getcontroller (String name) {return this.controllers.get (name); }

}


All code is hosted on the GitHub

Service-side code please--> Netty Chat room Server

Client code please--> Netty Chat room Client



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.