📜 ⬆️ ⬇️

Java instead of javascript (gwt + netbeans)

When I saw gwt and gwt-ext, I thought that I was deceived somewhere when I wasn’t told about it before. The torment with debugging scripts using ExtJS was long, we used Java as a server platform, manually handled the serialization / deserialization of server objects, adjusted blocks with css and did many other things that took a lot of time. However, all this can be left behind. Now you can draw beautiful windows with Java code (not js)! GWT is a great thing. It allows us to get away from writing js-code, because it generates js-code on its own; and the programmer can even not watch it, because it can also be debugged in the source code in Java! Next, I will try to tell you how to configure gwt under netbeans.

Getting started

So, the goal is to create a web application in java. Without further ado, we will hang the interface on extJS, the server logic on java, and we will work with DB using hibernate. Getting the components We will need the following components:
  1. Netbeans 6.5 Java or All (for Windows 212 and 249 MB, respectively, for other OSs the size should not differ much) ;
  2. ExtJs version 2.0.2 , and no older ;
  3. Google Web Toolkit 1.5 ;
  4. hibernate core ;
  5. gwt-ext 2.0.5 .
Next, pumping all the necessary set Netbeans, do not forget to include support for web-development and tick the installation Tomcat, on which we will run all our good.
Required options when installing Netbeans.


We put on the Netbeans plugin for GWT:

Naked gwt

After that we create a new web project ( File -> New project -> Java web -> Web application ). The project must be given a name and indicate the place where it will be saved. We specify Tomcat as the server (or, by preference, another one). On the last page are the frameworks necessary for our project. Turn on Google Web Toolkit and Hibernate. In this case, for GWT, you must select the directory where we unpacked gwt. I selected the $ ProjectPath / lib / gwt folder for this. You also need to specify the name of the module GWT, which we will develop. Let be our.sample.Face. You also need to configure the hibernate connection, I will not describe this process, a lot has already been said about it, for example, you can see the article by the respected habrachelovek garbuz . Next, click Finish, and you can continue. Immediately I recommend setting an option for the execution environment that increases the memory limits for execution. This is done in the project properties, Run -> VM Options set to "-Xmx512m". You also need to increase the maximum memory for the compiler, and here you have to go for a little trick - you need to open the netbeans / build-gwt.xml file and change it to look like this:
....<br/> < java classpath ="${javac.classpath}:${src.dir}" failonerror ="true" <br/> classname ="com.google.gwt.dev.GWTCompiler" fork ="true" > <br/> < arg value ="-out" /> <br/> < arg path ="${build.web.dir}/" /> <br/> < arg value ="-style" /> <br/> < arg value ="${gwt.compiler.output.style}" /> < arg value ="-logLevel" /> <br/> < arg value ="${gwt.compiler.logLevel}" /> <br/> < arg value ="${gwt.module}" /> <br/> < jvmarg value ="-Xmx512m" /> <br/> </ java > <br/>.... < target name ="debug-connect-gwt-shell" if ="netbeans.home" depends ="init" > http://bankinform.ru/habraeditor/images/yu-logo.png<br/>... <br/> < java fork ="true" classname ="com.google.gwt.dev.GWTShell" failonerror ="true" > <br/> < jvmarg value ="-Xmx512m" /> <br/> ....<br/> </ java > <br/> </ target > <br/>.... <br/><br/> * This source code was highlighted with Source Code Highlighter .
The environment created the packages our.sample.client and our.sample.server . I beg to love and favor - in these directories will lie, respectively, client and server code. To be more precise, after the compilation, classes from the client package remain on the server, but the classes from the server do not fall on the client. However, our softphone is not yet ready to launch. Then you can run the project to see the module that is created by default. For each gwt-module, the entry point is specified, the class - which is some analogue of the class with the main () method, and starts the system on the client. It is there that the drawing of the first form begins, then the second call usually comes from it, etc. All, like people :). The default entry point is the $ ModuleName + EntryPoint class , in our case our.sample.FaceEntryPoint. We click the Debug button (we will be offered a choice: we want to start server or client debugging) and be patient while the application is assembled. Then we see our sample running:
Trial run.

')
In this case, the following code was created for the client:
package our.sample.client;<br/><br/>import com.google.gwt.core.client.EntryPoint;<br/>import com.google.gwt.user.client.ui.Button;<br/>import com.google.gwt.user.client.ui.ClickListener;<br/>import com.google.gwt.user.client.ui.Label;<br/>import com.google.gwt.user.client.ui.RootPanel;<br/>import com.google.gwt.user.client.ui.Widget;<br/><br/><br/> public class MainEntryPoint implements EntryPoint {<br/> // <br/> public void onModuleLoad() {<br/> // <br/> final Label label = new Label( "Hello, GWT!!!" );<br/> // <br/> final Button button = new Button( "Click me!" );<br/> <br/> // , . <br/> button.addClickListener( new ClickListener(){<br/> public void onClick(Widget w) {<br/> label.setVisible(!label.isVisible());<br/> }<br/> });<br/> <br/> // "" . <br/> RootPanel. get ().add(button);<br/> RootPanel. get ().add(label);<br/> }<br/>} <br/><br/> * This source code was highlighted with Source Code Highlighter .
I don’t think something needs to be explained here.

GWT-Ext>

Next, you need to connect the gwt-ext library itself, because the bare standard web components will not suit us. To do this, open the project properties (context menu Properties with the right click on the root of the project tree), then in Libraries -> Add Library -> Create ; Next, enter the name: “gwt-ext”, and the classes (tab Classpath) and source (tab Sources) indicate the file gwtext.jar from the archive Gwt-ext. Next, click Add Library.
Connecting the gwt-ext library.


You also need to remember to throw ExtJS 2.0.2 into the web / js / ext folder. And to top it off, you need to tell the module that it has new components related to extJs. To do this, open our / sample / Face.gwt.xml file and fix it as follows:
<? xml version ="1.0" encoding ="UTF-8" ? > <br/> < module > <br/> < inherits name ="com.google.gwt.user.User" /> <br/> < inherits name ='com.gwtext.GwtExt' /> <br/> < entry-point class ="our.sample.client.FaceEntryPoint" /> <br/><br/> < stylesheet src ="js/ext/resources/css/ext-all.css" /> <br/> < script src ="js/ext/adapter/ext/ext-base.js" /> <br/> < script src ="js/ext/ext-all.js" /> <br/> </ module > <br/> <br/> * This source code was highlighted with Source Code Highlighter .
And now let's try to write something meaningful. Add a Person class that contains fields with some information about a person, and try to draw data loaded by the server into this class on the client. In this case, I want to show how I work asynchronous services (GWT RPC). Right-click on the package our.sample.client, and add the Person class:
package our.sample.client;<br/><br/>import com.google.gwt.user.client.rpc.IsSerializable;<br/><br/> // Person, <br/> // IsSerializable, . <br/> public class Person implements IsSerializable {<br/> private String name;<br/> private String surname;<br/> private String patronymic;<br/> private String email;<br/> private int age;<br/> // .... <br/> // - <br/> // .... <br/>}<br/> <br/> * This source code was highlighted with Source Code Highlighter .
Next, we create our service, which will give the client an instance of Person upon request. To do this, right-click on the package our.sample.client , select new-> other , select the Google Web Toolkit category and in it the GWT RPC Service . You must enter the name of the new service and, if necessary, uncheck the checkbox “Create a usage example”. This creates two interfaces on the client side, a class on the server side and, if a tick has been set, the client class is an entry point with an example of using the service. Enter the name of the service PersonService. Add code to PersonService.java so that the class looks like this:
package our.sample.client;<br/><br/>import com.google.gwt.user.client.rpc.ServiceDefTarget;<br/>import com.google.gwt.user.client.rpc.RemoteService;<br/>import com.google.gwt.core.client.GWT;<br/> public interface PersonService extends RemoteService{<br/> public Person loadPerson( int someValue);<br/> <br/> public static class App {<br/> private static final PersonServiceAsync ourInstance;<br/> static {<br/> ourInstance = (PersonServiceAsync) GWT.create(PersonService. class );<br/> ((ServiceDefTarget) ourInstance).setServiceEntryPoint(GWT.getModuleBaseURL() + "PersonService" );<br/> }<br/> public static PersonServiceAsync getInstance()<br/> {<br/> return ourInstance;<br/> }<br/> }<br/>} <br/><br/> * This source code was highlighted with Source Code Highlighter .
The nested App class allows you to get a copy of the service, and in general it is not clear why the environment does not create it itself, but cram its analogue in the example of use. So you can generate it and copy it to the right place. After that, the environment will show an error saying that the synchronous and asynchronous versions of the service interface will become unsynchronized, and will suggest correcting this. If you press alt + enter, we will place the text cursor in place of the error.
package our.sample.client;<br/>import com.google.gwt.user.client.rpc.AsyncCallback;<br/><br/> public interface PersonServiceAsync {<br/> public abstract void loadPerson( int someValue, AsyncCallback<Person> asyncCallback);<br/>}<br/> <br/><br/> * This source code was highlighted with Source Code Highlighter .
And in the package our.sample.server we will do the implementation:
package our.sample.server;<br/>import com.google.gwt.user.server.rpc.RemoteServiceServlet;<br/>import our.sample.client.Person;<br/>import our.sample.client.PersonService;<br/><br/> public class PersonServiceImpl extends RemoteServiceServlet implements PersonService {<br/> <br/> public Person loadPerson( int someValue) {<br/> Person person = new Person();<br/> person.setSurname( "Some" );<br/> person.setName( "Usual" );<br/> person.setPatronymic( "Man" );<br/> person.setAge(someValue);<br/> person.setEmail( "man@domain.com" );<br/> return person;<br/> }<br/>}<br/> <br/> * This source code was highlighted with Source Code Highlighter .
Unfortunately, the gwt4nb plugin does not quite adequately perceive the methods of the interfaces that return some kind of result. Suppose our service must return an instance of Person, and gwt4nb will offer to create a method for the asynchronous interface variant that returns Person. However, this is wrong, because All results (as well as error messages) are obtained using the last parameter of the asynchronous method - an instance of a class that implements the AsyncCallback interface. In fact, for a method to return an object, you need to describe the method public abstract void loadPerson (int someValue, AsyncCallback asyncCallback). Here, the first parameter is input, and AsyncCallback should provide processing of the result of the method execution on the server. In order for it to return an object of a particular class, you need to substitute this class into the template (in our case, Person). How to use it, we will see below.
package our.sample.client;<br/><br/>import com.google.gwt.core.client.EntryPoint;<br/>import com.google.gwt.user.client.rpc.AsyncCallback;<br/>import com.google.gwt.user.client.ui.RootPanel;<br/>import com.gwtext.client.core.EventObject;<br/>import com.gwtext.client.core.Position;<br/>import com.gwtext.client.widgets.Button;<br/>import com.gwtext.client.widgets.MessageBox;<br/>import com.gwtext.client.widgets.Panel;<br/>import com.gwtext.client.widgets. event .ButtonListenerAdapter;<br/>import com.gwtext.client.widgets.form.*;<br/><br/><br/> public class FaceEntryPoint implements EntryPoint {<br/><br/> public FaceEntryPoint() {<br/> }<br/><br/> final static TextField txtName = new TextField( "" , "name" , 190);<br/> final static TextField txtSurname = new TextField( "" , "surname" , 190);<br/> final static TextField txtPatronymic = new TextField( "" , "patronymic" , 190);<br/> final static TextField txtEmail = new TextField( "Email" , "email" , 190);<br/> final static TextField txtAge = new TextField( "" , "age" , 190);<br/><br/> public void onModuleLoad() {<br/> Panel panel = new Panel();<br/> panel.setBorder( false );<br/> panel.setPaddings(15);<br/><br/> final FormPanel formPanel = new FormPanel(Position.CENTER);<br/> formPanel.setFrame( true );<br/> formPanel.setTitle( " " );<br/> formPanel.setWidth(500);<br/> formPanel.setLabelWidth(100);<br/><br/> FieldSet fieldSet = new FieldSet( "" );<br/> fieldSet.add(txtName);<br/> fieldSet.add(txtSurname);<br/> fieldSet.add(txtPatronymic);<br/> fieldSet.add(txtEmail);<br/> fieldSet.add(txtAge);<br/> txtEmail.setVtype(VType.EMAIL);<br/> txtAge.setVtype(VType.ALPHANUM);<br/><br/> fieldSet.setWidth(formPanel.getWidth() - 20);<br/> final Button btnLoad = new Button( "" , new ButtonListenerAdapter() {<br/> public void onClick(Button button, EventObject e) {<br/> PersonService.App.getInstance().loadPerson(29, new AsyncCallback<Person>() {<br/><br/> public void onFailure(Throwable caught) {<br/> MessageBox.alert( ", - !" );<br/> }<br/><br/> public void onSuccess(Person result) {<br/> txtName.setValue(result.getName());<br/> txtSurname.setValue(result.getSurname());<br/> txtPatronymic.setValue(result.getPatronymic());<br/> txtAge.setValue( String .valueOf(result.getAge()));<br/> txtEmail.setValue(result.getEmail());<br/> }<br/> });<br/> }<br/> });<br/> formPanel.add(fieldSet);<br/> formPanel.addButton(btnLoad);<br/> panel.add(formPanel);<br/> RootPanel. get ().add(panel);<br/> }<br/>}<br/> <br/> * This source code was highlighted with Source Code Highlighter .
The following happens in the code:That's all. You can run and admire :) result

I note only that in order to compile a war-file for the web server, you need to exclude from the libraries of the project gwt-dev-windows.jar.
And, lastly, you can afford a little self-criticism and comments.I did not try to use gwt in eclipse, it is likely that the plug-ins for it are more solid and functional. But support in IntelliJ IDEA 8 pleased. Rather, it was necessary to streamline knowledge on the use of gwt, and the article was written more for himself. I would be glad if someone would be useful.

upd: so that all this does not seem empty and unnecessary, you can see examples on gwt-ext .

Source: https://habr.com/ru/post/51894/


All Articles